X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fvirtio%2Fvirtio_user%2Fvirtio_user_dev.c;h=a4400e77206f40497c28e37ae33ad7b3501e590b;hb=85c4bcbcc57326cc63ad52082fa090cdfc7855a0;hp=89d287a740c0cd737936672c70d4bdb98b3ef8f8;hpb=45c224e73a3057bf62cb04f83fc1e97457a21ffa;p=dpdk.git diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c index 89d287a740..a4400e7720 100644 --- a/drivers/net/virtio/virtio_user/virtio_user_dev.c +++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c @@ -13,6 +13,7 @@ #include #include +#include #include #include "vhost.h" @@ -52,11 +53,11 @@ virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel) if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) { addr.desc_user_addr = - (uint64_t)(uintptr_t)pq_vring->desc_packed; + (uint64_t)(uintptr_t)pq_vring->desc; addr.avail_user_addr = - (uint64_t)(uintptr_t)pq_vring->driver_event; + (uint64_t)(uintptr_t)pq_vring->driver; addr.used_user_addr = - (uint64_t)(uintptr_t)pq_vring->device_event; + (uint64_t)(uintptr_t)pq_vring->device; } else { addr.desc_user_addr = (uint64_t)(uintptr_t)vring->desc; addr.avail_user_addr = (uint64_t)(uintptr_t)vring->avail; @@ -124,7 +125,6 @@ is_vhost_user_by_type(const char *path) int virtio_user_start_device(struct virtio_user_dev *dev) { - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; uint64_t features; int ret; @@ -141,7 +141,7 @@ virtio_user_start_device(struct virtio_user_dev *dev) * replaced when we get proper supports from the * memory subsystem in the future. */ - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_lock(); pthread_mutex_lock(&dev->mutex); if (is_vhost_user_by_type(dev->path) && dev->vhostfd < 0) @@ -179,12 +179,12 @@ virtio_user_start_device(struct virtio_user_dev *dev) dev->started = true; pthread_mutex_unlock(&dev->mutex); - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_unlock(); return 0; error: pthread_mutex_unlock(&dev->mutex); - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_unlock(); /* TODO: free resource here or caller to check */ return -1; } @@ -224,17 +224,13 @@ out: static inline void parse_mac(struct virtio_user_dev *dev, const char *mac) { - int i, r; - uint32_t tmp[ETHER_ADDR_LEN]; + struct rte_ether_addr tmp; if (!mac) return; - r = sscanf(mac, "%x:%x:%x:%x:%x:%x", &tmp[0], - &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); - if (r == ETHER_ADDR_LEN) { - for (i = 0; i < ETHER_ADDR_LEN; ++i) - dev->mac_addr[i] = (uint8_t)tmp[i]; + if (rte_ether_unformat_addr(mac, &tmp) == 0) { + memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN); dev->mac_specified = 1; } else { /* ignore the wrong mac, use random mac */ @@ -426,14 +422,15 @@ virtio_user_dev_setup(struct virtio_user_dev *dev) int virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues, int cq, int queue_size, const char *mac, char **ifname, - int mrg_rxbuf, int in_order, int packed_vq) + int server, int mrg_rxbuf, int in_order, int packed_vq) { pthread_mutex_init(&dev->mutex, NULL); - snprintf(dev->path, PATH_MAX, "%s", path); + strlcpy(dev->path, path, PATH_MAX); dev->started = 0; dev->max_queue_pairs = queues; dev->queue_pairs = 1; /* mq disabled by default */ dev->queue_size = queue_size; + dev->is_server = server; dev->mac_specified = 0; dev->frontend_features = 0; dev->unsupported_features = ~VIRTIO_USER_SUPPORTED_FEATURES; @@ -616,6 +613,10 @@ virtio_user_handle_ctrl_msg(struct virtio_user_dev *dev, struct vring *vring, queues = *(uint16_t *)(uintptr_t)vring->desc[idx_data].addr; status = virtio_user_handle_mq(dev, queues); + } else if (hdr->class == VIRTIO_NET_CTRL_RX || + hdr->class == VIRTIO_NET_CTRL_MAC || + hdr->class == VIRTIO_NET_CTRL_VLAN) { + status = 0; } /* Update status */ @@ -627,8 +628,10 @@ virtio_user_handle_ctrl_msg(struct virtio_user_dev *dev, struct vring *vring, static inline int desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter) { - return wrap_counter == !!(desc->flags & VRING_DESC_F_AVAIL(1)) && - wrap_counter != !!(desc->flags & VRING_DESC_F_USED(1)); + uint16_t flags = __atomic_load_n(&desc->flags, __ATOMIC_ACQUIRE); + + return wrap_counter == !!(flags & VRING_PACKED_DESC_F_AVAIL) && + wrap_counter != !!(flags & VRING_PACKED_DESC_F_USED); } static uint32_t @@ -650,30 +653,34 @@ virtio_user_handle_ctrl_msg_packed(struct virtio_user_dev *dev, n_descs++; idx_status = idx_data; - while (vring->desc_packed[idx_status].flags & VRING_DESC_F_NEXT) { + while (vring->desc[idx_status].flags & VRING_DESC_F_NEXT) { idx_status++; if (idx_status >= dev->queue_size) idx_status -= dev->queue_size; n_descs++; } - hdr = (void *)(uintptr_t)vring->desc_packed[idx_hdr].addr; + hdr = (void *)(uintptr_t)vring->desc[idx_hdr].addr; if (hdr->class == VIRTIO_NET_CTRL_MQ && hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) { uint16_t queues; queues = *(uint16_t *)(uintptr_t) - vring->desc_packed[idx_data].addr; + vring->desc[idx_data].addr; status = virtio_user_handle_mq(dev, queues); + } else if (hdr->class == VIRTIO_NET_CTRL_RX || + hdr->class == VIRTIO_NET_CTRL_MAC || + hdr->class == VIRTIO_NET_CTRL_VLAN) { + status = 0; } /* Update status */ *(virtio_net_ctrl_ack *)(uintptr_t) - vring->desc_packed[idx_status].addr = status; + vring->desc[idx_status].addr = status; /* Update used descriptor */ - vring->desc_packed[idx_hdr].id = vring->desc_packed[idx_status].id; - vring->desc_packed[idx_hdr].len = sizeof(status); + vring->desc[idx_hdr].id = vring->desc[idx_status].id; + vring->desc[idx_hdr].len = sizeof(status); return n_descs; } @@ -683,19 +690,24 @@ virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx) { struct virtio_user_queue *vq = &dev->packed_queues[queue_idx]; struct vring_packed *vring = &dev->packed_vrings[queue_idx]; - uint16_t n_descs; + uint16_t n_descs, flags; - while (desc_is_avail(&vring->desc_packed[vq->used_idx], + /* Perform a load-acquire barrier in desc_is_avail to + * enforce the ordering between desc flags and desc + * content. + */ + while (desc_is_avail(&vring->desc[vq->used_idx], vq->used_wrap_counter)) { n_descs = virtio_user_handle_ctrl_msg_packed(dev, vring, vq->used_idx); - rte_smp_wmb(); - vring->desc_packed[vq->used_idx].flags = - VRING_DESC_F_WRITE | - VRING_DESC_F_AVAIL(vq->used_wrap_counter) | - VRING_DESC_F_USED(vq->used_wrap_counter); + flags = VRING_DESC_F_WRITE; + if (vq->used_wrap_counter) + flags |= VRING_PACKED_DESC_F_AVAIL_USED; + + __atomic_store_n(&vring->desc[vq->used_idx].flags, flags, + __ATOMIC_RELEASE); vq->used_idx += n_descs; if (vq->used_idx >= dev->queue_size) { @@ -722,7 +734,7 @@ virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx) /* Update used ring */ uep = &vring->used->ring[avail_idx]; - uep->id = avail_idx; + uep->id = desc_idx; uep->len = n_descs; vring->used->idx++;