| 419 | } |
| 420 | |
| 421 | struct virtqueue * |
| 422 | virtqueue_alloc(struct virtio_hw *hw, uint16_t index, uint16_t num, int type, |
| 423 | int node, const char *name) |
| 424 | { |
| 425 | struct virtqueue *vq; |
| 426 | const struct rte_memzone *mz; |
| 427 | unsigned int size; |
| 428 | |
| 429 | size = sizeof(*vq) + num * sizeof(struct vq_desc_extra); |
| 430 | size = RTE_ALIGN_CEIL(size, RTE_CACHE_LINE_SIZE); |
| 431 | |
| 432 | vq = rte_zmalloc_socket(name, size, RTE_CACHE_LINE_SIZE, node); |
| 433 | if (vq == NULL) { |
| 434 | PMD_INIT_LOG(ERR, "can not allocate vq"); |
| 435 | return NULL; |
| 436 | } |
| 437 | |
| 438 | vq->hw = hw; |
| 439 | vq->vq_queue_index = index; |
| 440 | vq->vq_nentries = num; |
| 441 | if (virtio_with_packed_queue(hw)) { |
| 442 | vq->vq_packed.used_wrap_counter = 1; |
| 443 | vq->vq_packed.cached_flags = VRING_PACKED_DESC_F_AVAIL; |
| 444 | vq->vq_packed.event_flags_shadow = 0; |
| 445 | if (type == VTNET_RQ) |
| 446 | vq->vq_packed.cached_flags |= VRING_DESC_F_WRITE; |
| 447 | } |
| 448 | |
| 449 | /* |
| 450 | * Reserve a memzone for vring elements |
| 451 | */ |
| 452 | size = vring_size(hw, num, VIRTIO_VRING_ALIGN); |
| 453 | vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_VRING_ALIGN); |
| 454 | PMD_INIT_LOG(DEBUG, "vring_size: %d, rounded_vring_size: %d", size, vq->vq_ring_size); |
| 455 | |
| 456 | mz = rte_memzone_reserve_aligned(name, vq->vq_ring_size, node, |
| 457 | RTE_MEMZONE_IOVA_CONTIG, VIRTIO_VRING_ALIGN); |
| 458 | if (mz == NULL) { |
| 459 | if (rte_errno == EEXIST) |
| 460 | mz = rte_memzone_lookup(name); |
| 461 | if (mz == NULL) |
| 462 | goto free_vq; |
| 463 | } |
| 464 | |
| 465 | memset(mz->addr, 0, mz->len); |
| 466 | vq->mz = mz; |
| 467 | vq->vq_ring_virt_mem = mz->addr; |
| 468 | |
| 469 | if (hw->use_va) { |
| 470 | vq->vq_ring_mem = (uintptr_t)mz->addr; |
| 471 | vq->mbuf_addr_offset = offsetof(struct rte_mbuf, buf_addr); |
| 472 | vq->mbuf_addr_mask = UINTPTR_MAX; |
| 473 | } else { |
| 474 | vq->vq_ring_mem = mz->iova; |
| 475 | vq->mbuf_addr_offset = offsetof(struct rte_mbuf, buf_iova); |
| 476 | vq->mbuf_addr_mask = UINT64_MAX; |
| 477 | } |
| 478 |
no test coverage detected