/* * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR * The virtio device sends us the desc, used and avail ring addresses. * This function then converts these to our address space. */ int vhost_set_vring_addr(struct vhost_device_ctx ctx, struct vhost_vring_addr *addr) { struct virtio_net *dev; struct vhost_virtqueue *vq; dev = get_device(ctx); if ((dev == NULL) || (dev->mem == NULL)) return -1; /* addr->index refers to the queue index. The txq 1, rxq is 0. */ vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, addr->desc_user_addr); if (vq->desc == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find desc ring address.\n", dev->device_fh); return -1; } dev = numa_realloc(dev, addr->index); vq = dev->virtqueue[addr->index]; vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, addr->avail_user_addr); if (vq->avail == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find avail ring address.\n", dev->device_fh); return -1; } vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, addr->used_user_addr); if (vq->used == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%"PRIu64") Failed to find used ring address.\n", dev->device_fh); return -1; } vq->log_guest_addr = addr->log_guest_addr; LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address desc: %p\n", dev->device_fh, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address avail: %p\n", dev->device_fh, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") mapped address used: %p\n", dev->device_fh, vq->used); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") log_guest_addr: %"PRIx64"\n", dev->device_fh, vq->log_guest_addr); return 0; }
void *dynarray_destroy(struct dynarray *da) { void *ret = da->elems; //printf("destroy realloc: idx:%lu nr:%lu realloc size:%lu\n", da->next_idx, da->elems_nr, (da->next_idx+1)*da->elem_size); if (da->numa) { ret = numa_realloc(ret, da->elems_nr*da->elem_size, da->next_idx*da->elem_size); numa_free(da, sizeof(*da)); } else { ret = realloc(ret, da->next_idx*da->elem_size); free(da); } return ret; }
static inline void dynarray_expand(struct dynarray *da) { da->elems_nr += da->alloc_grain; //printf("old addr: %p\n", da->elems); //printf("expand realloc: %lu %lu %lu\n", da->next_idx, da->elems_nr, (da->next_idx+1)*da->elem_size); if (da->numa) { da->elems = numa_realloc(da->elems, da->elem_size*(da->elems_nr - da->alloc_grain), da->elem_size*da->elems_nr); } else { da->elems = realloc(da->elems, da->elem_size*da->elems_nr); } if (!da->elems) { fprintf(stderr, "dynarray_expand: realloc failed\n"); exit(1); } //printf("new addr: %p\n", da->elems); }
static struct virtio_net * translate_ring_addresses(struct virtio_net *dev, int vq_index) { struct vhost_virtqueue *vq = dev->virtqueue[vq_index]; struct vhost_vring_addr *addr = &vq->ring_addrs; uint64_t len; /* The addresses are converted from QEMU virtual to Vhost virtual. */ if (vq->desc && vq->avail && vq->used) return dev; len = sizeof(struct vring_desc) * vq->size; vq->desc = (struct vring_desc *)(uintptr_t)ring_addr_to_vva(dev, vq, addr->desc_user_addr, &len); if (vq->desc == 0 || len != sizeof(struct vring_desc) * vq->size) { RTE_LOG(DEBUG, VHOST_CONFIG, "(%d) failed to map desc ring.\n", dev->vid); return dev; } dev = numa_realloc(dev, vq_index); vq = dev->virtqueue[vq_index]; addr = &vq->ring_addrs; len = sizeof(struct vring_avail) + sizeof(uint16_t) * vq->size; vq->avail = (struct vring_avail *)(uintptr_t)ring_addr_to_vva(dev, vq, addr->avail_user_addr, &len); if (vq->avail == 0 || len != sizeof(struct vring_avail) + sizeof(uint16_t) * vq->size) { RTE_LOG(DEBUG, VHOST_CONFIG, "(%d) failed to map avail ring.\n", dev->vid); return dev; } len = sizeof(struct vring_used) + sizeof(struct vring_used_elem) * vq->size; vq->used = (struct vring_used *)(uintptr_t)ring_addr_to_vva(dev, vq, addr->used_user_addr, &len); if (vq->used == 0 || len != sizeof(struct vring_used) + sizeof(struct vring_used_elem) * vq->size) { RTE_LOG(DEBUG, VHOST_CONFIG, "(%d) failed to map used ring.\n", dev->vid); return dev; } if (vq->last_used_idx != vq->used->idx) { RTE_LOG(WARNING, VHOST_CONFIG, "last_used_idx (%u) and vq->used->idx (%u) mismatches; " "some packets maybe resent for Tx and dropped for Rx\n", vq->last_used_idx, vq->used->idx); vq->last_used_idx = vq->used->idx; vq->last_avail_idx = vq->used->idx; } vq->log_guest_addr = addr->log_guest_addr; LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n", dev->vid, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address avail: %p\n", dev->vid, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address used: %p\n", dev->vid, vq->used); LOG_DEBUG(VHOST_CONFIG, "(%d) log_guest_addr: %" PRIx64 "\n", dev->vid, vq->log_guest_addr); return dev; }
/* * Called from CUSE IOCTL: VHOST_SET_VRING_ADDR * The virtio device sends us the desc, used and avail ring addresses. * This function then converts these to our address space. */ int vhost_set_vring_addr(int vid, struct vhost_vring_addr *addr) { struct virtio_net *dev; struct vhost_virtqueue *vq; dev = get_device(vid); if ((dev == NULL) || (dev->mem == NULL)) return -1; /* addr->index refers to the queue index. The txq 1, rxq is 0. */ vq = dev->virtqueue[addr->index]; /* The addresses are converted from QEMU virtual to Vhost virtual. */ vq->desc = (struct vring_desc *)(uintptr_t)qva_to_vva(dev, addr->desc_user_addr); if (vq->desc == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find desc ring address.\n", dev->vid); return -1; } dev = numa_realloc(dev, addr->index); vq = dev->virtqueue[addr->index]; vq->avail = (struct vring_avail *)(uintptr_t)qva_to_vva(dev, addr->avail_user_addr); if (vq->avail == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find avail ring address.\n", dev->vid); return -1; } vq->used = (struct vring_used *)(uintptr_t)qva_to_vva(dev, addr->used_user_addr); if (vq->used == 0) { RTE_LOG(ERR, VHOST_CONFIG, "(%d) failed to find used ring address.\n", dev->vid); return -1; } if (vq->last_used_idx != vq->used->idx) { RTE_LOG(WARNING, VHOST_CONFIG, "last_used_idx (%u) and vq->used->idx (%u) mismatches; " "some packets maybe resent for Tx and dropped for Rx\n", vq->last_used_idx, vq->used->idx); vq->last_used_idx = vq->used->idx; } vq->log_guest_addr = addr->log_guest_addr; LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address desc: %p\n", dev->vid, vq->desc); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address avail: %p\n", dev->vid, vq->avail); LOG_DEBUG(VHOST_CONFIG, "(%d) mapped address used: %p\n", dev->vid, vq->used); LOG_DEBUG(VHOST_CONFIG, "(%d) log_guest_addr: %" PRIx64 "\n", dev->vid, vq->log_guest_addr); return 0; }