From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id B1EBA685D for ; Mon, 20 Oct 2014 06:30:38 +0200 (CEST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 19 Oct 2014 21:38:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="402741623" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by FMSMGA003.fm.intel.com with ESMTP; 19 Oct 2014 21:31:16 -0700 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id s9K4cjqq003171; Mon, 20 Oct 2014 12:38:45 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id s9K4cgjN028176; Mon, 20 Oct 2014 12:38:44 +0800 Received: (from hxie5@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id s9K4cgYd028172; Mon, 20 Oct 2014 12:38:42 +0800 From: Huawei Xie To: dev@dpdk.org Date: Mon, 20 Oct 2014 12:38:16 +0800 Message-Id: <1413779906-28113-5-git-send-email-huawei.xie@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1413779906-28113-1-git-send-email-huawei.xie@intel.com> References: <1413779906-28113-1-git-send-email-huawei.xie@intel.com> Subject: [dpdk-dev] [PATCH 04/14] dev->vdev X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Oct 2014 04:30:39 -0000 define vhost_dev data structure. change reference to virtio_dev to vhost_dev. vhost example use vdev data structure for switching related logic and container for virtio_dev. Signed-off-by: Huawei Xie --- examples/vhost/main.c | 269 ++++++++++++++++++++++++++++---------------------- examples/vhost/main.h | 25 ++++- 2 files changed, 173 insertions(+), 121 deletions(-) diff --git a/examples/vhost/main.c b/examples/vhost/main.c index 169a5f3..03a0f48 100644 --- a/examples/vhost/main.c +++ b/examples/vhost/main.c @@ -896,7 +896,7 @@ gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa) * This is used to convert virtio buffer addresses. */ static inline uint64_t __attribute__((always_inline)) -gpa_to_hpa(struct virtio_net *dev, uint64_t guest_pa, +gpa_to_hpa(struct vhost_dev *vdev, uint64_t guest_pa, uint32_t buf_len, hpa_type *addr_type) { struct virtio_memory_regions_hpa *region; @@ -905,8 +905,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t guest_pa, *addr_type = PHYS_ADDR_INVALID; - for (regionidx = 0; regionidx < dev->mem->nregions_hpa; regionidx++) { - region = &dev->mem->regions_hpa[regionidx]; + for (regionidx = 0; regionidx < vdev->nregions_hpa; regionidx++) { + region = &vdev->regions_hpa[regionidx]; if ((guest_pa >= region->guest_phys_address) && (guest_pa <= region->guest_phys_address_end)) { vhost_pa = region->host_phys_addr_offset + guest_pa; @@ -920,7 +920,7 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t guest_pa, } LOG_DEBUG(VHOST_DATA, "(%"PRIu64") GPA %p| HPA %p\n", - dev->device_fh, (void *)(uintptr_t)guest_pa, + vdev->dev->device_fh, (void *)(uintptr_t)guest_pa, (void *)(uintptr_t)vhost_pa); return vhost_pa; @@ -940,10 +940,11 @@ ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb) * vlan tag to a VMDQ. */ static int -link_vmdq(struct virtio_net *dev, struct rte_mbuf *m) +link_vmdq(struct vhost_dev *vdev, struct rte_mbuf *m) { struct ether_hdr *pkt_hdr; struct virtio_net_data_ll *dev_ll; + struct virtio_net *dev = vdev->dev; int i, ret; /* Learn MAC address of guest device from packet */ @@ -952,7 +953,7 @@ link_vmdq(struct virtio_net *dev, struct rte_mbuf *m) dev_ll = ll_root_used; while (dev_ll != NULL) { - if (ether_addr_cmp(&(pkt_hdr->s_addr), &dev_ll->dev->mac_address)) { + if (ether_addr_cmp(&(pkt_hdr->s_addr), &dev_ll->vdev->mac_address)) { RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh); return -1; } @@ -960,30 +961,30 @@ link_vmdq(struct virtio_net *dev, struct rte_mbuf *m) } for (i = 0; i < ETHER_ADDR_LEN; i++) - dev->mac_address.addr_bytes[i] = pkt_hdr->s_addr.addr_bytes[i]; + vdev->mac_address.addr_bytes[i] = pkt_hdr->s_addr.addr_bytes[i]; /* vlan_tag currently uses the device_id. */ - dev->vlan_tag = vlan_tags[dev->device_fh]; + vdev->vlan_tag = vlan_tags[dev->device_fh]; /* Print out VMDQ registration info. */ RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n", dev->device_fh, - dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1], - dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3], - dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5], - dev->vlan_tag); + vdev->mac_address.addr_bytes[0], vdev->mac_address.addr_bytes[1], + vdev->mac_address.addr_bytes[2], vdev->mac_address.addr_bytes[3], + vdev->mac_address.addr_bytes[4], vdev->mac_address.addr_bytes[5], + vdev->vlan_tag); /* Register the MAC address. */ - ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh); + ret = rte_eth_dev_mac_addr_add(ports[0], &vdev->mac_address, (uint32_t)dev->device_fh); if (ret) RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n", dev->device_fh); /* Enable stripping of the vlan tag as we handle routing. */ - rte_eth_dev_set_vlan_strip_on_queue(ports[0], (uint16_t)dev->vmdq_rx_q, 1); + rte_eth_dev_set_vlan_strip_on_queue(ports[0], (uint16_t)vdev->vmdq_rx_q, 1); /* Set device as ready for RX. */ - dev->ready = DEVICE_RX; + vdev->ready = DEVICE_RX; return 0; } @@ -993,33 +994,33 @@ link_vmdq(struct virtio_net *dev, struct rte_mbuf *m) * queue before disabling RX on the device. */ static inline void -unlink_vmdq(struct virtio_net *dev) +unlink_vmdq(struct vhost_dev *vdev) { unsigned i = 0; unsigned rx_count; struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - if (dev->ready == DEVICE_RX) { + if (vdev->ready == DEVICE_RX) { /*clear MAC and VLAN settings*/ - rte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address); + rte_eth_dev_mac_addr_remove(ports[0], &vdev->mac_address); for (i = 0; i < 6; i++) - dev->mac_address.addr_bytes[i] = 0; + vdev->mac_address.addr_bytes[i] = 0; - dev->vlan_tag = 0; + vdev->vlan_tag = 0; /*Clear out the receive buffers*/ rx_count = rte_eth_rx_burst(ports[0], - (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); + (uint16_t)vdev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); while (rx_count) { for (i = 0; i < rx_count; i++) rte_pktmbuf_free(pkts_burst[i]); rx_count = rte_eth_rx_burst(ports[0], - (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); + (uint16_t)vdev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); } - dev->ready = DEVICE_MAC_LEARNING; + vdev->ready = DEVICE_MAC_LEARNING; } } @@ -1028,11 +1029,13 @@ unlink_vmdq(struct virtio_net *dev) * the packet on that devices RX queue. If not then return. */ static inline unsigned __attribute__((always_inline)) -virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m) +virtio_tx_local(struct vhost_dev *vdev, struct rte_mbuf *m) { struct virtio_net_data_ll *dev_ll; struct ether_hdr *pkt_hdr; uint64_t ret = 0; + struct virtio_net *dev = vdev->dev; + struct virtio_net *tdev; /* destination virito device */ pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); @@ -1040,22 +1043,23 @@ virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m) dev_ll = ll_root_used; while (dev_ll != NULL) { - if ((dev_ll->dev->ready == DEVICE_RX) && ether_addr_cmp(&(pkt_hdr->d_addr), - &dev_ll->dev->mac_address)) { + if ((dev_ll->vdev->ready == DEVICE_RX) && ether_addr_cmp(&(pkt_hdr->d_addr), + &dev_ll->vdev->mac_address)) { /* Drop the packet if the TX packet is destined for the TX device. */ - if (dev_ll->dev->device_fh == dev->device_fh) { + if (dev_ll->vdev->dev->device_fh == dev->device_fh) { LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: Source and destination MAC addresses are the same. Dropping packet.\n", - dev_ll->dev->device_fh); + dev->device_fh); return 0; } + tdev = dev_ll->vdev->dev; - LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: MAC address is local\n", dev_ll->dev->device_fh); + LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: MAC address is local\n", tdev->device_fh); - if (dev_ll->dev->remove) { + if (dev_ll->vdev->remove) { /*drop the packet if the device is marked for removal*/ - LOG_DEBUG(VHOST_DATA, "(%"PRIu64") Device is marked for removal\n", dev_ll->dev->device_fh); + LOG_DEBUG(VHOST_DATA, "(%"PRIu64") Device is marked for removal\n", tdev->device_fh); } else { uint32_t mergeable = dev_ll->dev->features & @@ -1070,13 +1074,13 @@ virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m) if (enable_stats) { rte_atomic64_add( - &dev_statistics[dev_ll->dev->device_fh].rx_total_atomic, + &dev_statistics[tdev->device_fh].rx_total_atomic, 1); rte_atomic64_add( - &dev_statistics[dev_ll->dev->device_fh].rx_atomic, + &dev_statistics[tdev->device_fh].rx_atomic, ret); - dev_statistics[dev->device_fh].tx_total++; - dev_statistics[dev->device_fh].tx += ret; + dev_statistics[tdev->device_fh].tx_total++; + dev_statistics[tdev->device_fh].tx += ret; } } @@ -1093,7 +1097,7 @@ virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m) * or the physical port. */ static inline void __attribute__((always_inline)) -virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag) +virtio_tx_route(struct vhost_dev *vdev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag) { struct mbuf_table *tx_q; struct vlan_ethhdr *vlan_hdr; @@ -1103,37 +1107,38 @@ virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool * const uint16_t lcore_id = rte_lcore_id(); struct virtio_net_data_ll *dev_ll = ll_root_used; struct ether_hdr *pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); + struct virtio_net *dev = vdev->dev; /*check if destination is local VM*/ - if ((vm2vm_mode == VM2VM_SOFTWARE) && (virtio_tx_local(dev, m) == 0)) + if ((vm2vm_mode == VM2VM_SOFTWARE) && (virtio_tx_local(vdev, m) == 0)) return; if (vm2vm_mode == VM2VM_HARDWARE) { while (dev_ll != NULL) { - if ((dev_ll->dev->ready == DEVICE_RX) + if ((dev_ll->vdev->ready == DEVICE_RX) && ether_addr_cmp(&(pkt_hdr->d_addr), - &dev_ll->dev->mac_address)) { + &dev_ll->vdev->mac_address)) { /* * Drop the packet if the TX packet is * destined for the TX device. */ - if (dev_ll->dev->device_fh == dev->device_fh) { + if (dev_ll->vdev->dev->device_fh == dev->device_fh) { LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: Source and destination" " MAC addresses are the same. Dropping " "packet.\n", - dev_ll->dev->device_fh); + dev_ll->vdev->device_fh); return; } offset = 4; vlan_tag = (uint16_t) - vlan_tags[(uint16_t)dev_ll->dev->device_fh]; + vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh]; LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: pkt to local VM device id:" "(%"PRIu64") vlan tag: %d.\n", - dev->device_fh, dev_ll->dev->device_fh, + dev->device_fh, dev_ll->vdev->dev->device_fh, vlan_tag); break; @@ -1232,6 +1237,7 @@ switch_worker(__attribute__((unused)) void *arg) { struct rte_mempool *mbuf_pool = arg; struct virtio_net *dev = NULL; + struct vhost_dev *vdev = NULL; struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; struct virtio_net_data_ll *dev_ll; struct mbuf_table *tx_q; @@ -1299,20 +1305,21 @@ switch_worker(__attribute__((unused)) void *arg) while (dev_ll != NULL) { /*get virtio device ID*/ - dev = dev_ll->dev; + vdev = dev_ll->vdev; + dev = vdev->dev; mergeable = dev->features & (1 << VIRTIO_NET_F_MRG_RXBUF); - if (dev->remove) { + if (vdev->remove) { dev_ll = dev_ll->next; - unlink_vmdq(dev); - dev->ready = DEVICE_SAFE_REMOVE; + unlink_vmdq(vdev); + vdev->ready = DEVICE_SAFE_REMOVE; continue; } - if (likely(dev->ready == DEVICE_RX)) { + if (likely(vdev->ready == DEVICE_RX)) { /*Handle guest RX*/ rx_count = rte_eth_rx_burst(ports[0], - (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); + vdev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); if (rx_count) { if (likely(mergeable == 0)) @@ -1326,10 +1333,10 @@ switch_worker(__attribute__((unused)) void *arg) if (enable_stats) { rte_atomic64_add( - &dev_statistics[dev_ll->dev->device_fh].rx_total_atomic, + &dev_statistics[dev_ll->vdev->dev->device_fh].rx_total_atomic, rx_count); rte_atomic64_add( - &dev_statistics[dev_ll->dev->device_fh].rx_atomic, ret_count); + &dev_statistics[dev_ll->vdev->dev->device_fh].rx_atomic, ret_count); } while (likely(rx_count)) { rx_count--; @@ -1339,7 +1346,7 @@ switch_worker(__attribute__((unused)) void *arg) } } - if (!dev->remove) { + if (!vdev->remove) { /*Handle guest TX*/ if (likely(mergeable == 0)) virtio_dev_tx(dev, mbuf_pool); @@ -1461,12 +1468,13 @@ attach_rxmbuf_zcp(struct virtio_net *dev) struct rte_mbuf *mbuf = NULL; struct vpool *vpool; hpa_type addr_type; + struct vhost_dev *vdev = (struct vhost_dev *)dev->priv; - vpool = &vpool_array[dev->vmdq_rx_q]; + vpool = &vpool_array[vdev->vmdq_rx_q]; vq = dev->virtqueue[VIRTIO_RXQ]; do { - if (unlikely(get_available_ring_index_zcp(dev, &res_base_idx, + if (unlikely(get_available_ring_index_zcp(vdev->dev, &res_base_idx, 1) != 1)) return; desc_idx = vq->avail->ring[(res_base_idx) & (vq->size - 1)]; @@ -1475,12 +1483,12 @@ attach_rxmbuf_zcp(struct virtio_net *dev) if (desc->flags & VRING_DESC_F_NEXT) { desc = &vq->desc[desc->next]; buff_addr = gpa_to_vva(dev, desc->addr); - phys_addr = gpa_to_hpa(dev, desc->addr, desc->len, + phys_addr = gpa_to_hpa(vdev, desc->addr, desc->len, &addr_type); } else { buff_addr = gpa_to_vva(dev, desc->addr + vq->vhost_hlen); - phys_addr = gpa_to_hpa(dev, + phys_addr = gpa_to_hpa(vdev, desc->addr + vq->vhost_hlen, desc->len, &addr_type); } @@ -1830,21 +1838,21 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct rte_mbuf *m, */ vlan_tag = external_pkt_default_vlan_tag; while (dev_ll != NULL) { - if (likely(dev_ll->dev->ready == DEVICE_RX) && + if (likely(dev_ll->vdev->ready == DEVICE_RX) && ether_addr_cmp(&(pkt_hdr->d_addr), - &dev_ll->dev->mac_address)) { + &dev_ll->vdev->mac_address)) { /* * Drop the packet if the TX packet is destined * for the TX device. */ - if (unlikely(dev_ll->dev->device_fh + if (unlikely(dev_ll->vdev->dev->device_fh == dev->device_fh)) { LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: Source and destination" "MAC addresses are the same. Dropping " "packet.\n", - dev_ll->dev->device_fh); + dev_ll->vdev->dev->device_fh); MBUF_HEADROOM_UINT32(mbuf) = (uint32_t)desc_idx; __rte_mbuf_raw_free(mbuf); @@ -1858,12 +1866,12 @@ virtio_tx_route_zcp(struct virtio_net *dev, struct rte_mbuf *m, offset = 4; vlan_tag = (uint16_t) - vlan_tags[(uint16_t)dev_ll->dev->device_fh]; + vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh]; LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: pkt to local VM device id:" "(%"PRIu64") vlan tag: %d.\n", - dev->device_fh, dev_ll->dev->device_fh, + dev->device_fh, dev_ll->vdev->dev->device_fh, vlan_tag); break; @@ -1948,6 +1956,7 @@ virtio_dev_tx_zcp(struct virtio_net *dev) uint16_t avail_idx; uint8_t need_copy = 0; hpa_type addr_type; + struct vhost_dev *vdev = (struct vhost_dev *)dev->priv; vq = dev->virtqueue[VIRTIO_TXQ]; avail_idx = *((volatile uint16_t *)&vq->avail->idx); @@ -1991,7 +2000,7 @@ virtio_dev_tx_zcp(struct virtio_net *dev) /* Buffer address translation. */ buff_addr = gpa_to_vva(dev, desc->addr); - phys_addr = gpa_to_hpa(dev, desc->addr, desc->len, &addr_type); + phys_addr = gpa_to_hpa(vdev, desc->addr, desc->len, &addr_type); if (likely(packet_success < (free_entries - 1))) /* Prefetch descriptor index. */ @@ -2040,8 +2049,8 @@ virtio_dev_tx_zcp(struct virtio_net *dev) * If this is the first received packet we need to learn * the MAC and setup VMDQ */ - if (unlikely(dev->ready == DEVICE_MAC_LEARNING)) { - if (dev->remove || (link_vmdq(dev, &m) == -1)) { + if (unlikely(vdev->ready == DEVICE_MAC_LEARNING)) { + if (vdev->remove || (link_vmdq(vdev, &m) == -1)) { /* * Discard frame if device is scheduled for * removal or a duplicate MAC address is found. @@ -2066,6 +2075,7 @@ static int switch_worker_zcp(__attribute__((unused)) void *arg) { struct virtio_net *dev = NULL; + struct vhost_dev *vdev = NULL; struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; struct virtio_net_data_ll *dev_ll; struct mbuf_table *tx_q; @@ -2094,12 +2104,13 @@ switch_worker_zcp(__attribute__((unused)) void *arg) * put back into vpool.ring. */ dev_ll = lcore_ll->ll_root_used; - while ((dev_ll != NULL) && (dev_ll->dev != NULL)) { + while ((dev_ll != NULL) && (dev_ll->vdev != NULL)) { /* Get virtio device ID */ - dev = dev_ll->dev; + vdev = dev_ll->vdev; + dev = vdev->dev; - if (likely(!dev->remove)) { - tx_q = &tx_queue_zcp[(uint16_t)dev->vmdq_rx_q]; + if (likely(!vdev->remove)) { + tx_q = &tx_queue_zcp[(uint16_t)vdev->vmdq_rx_q]; if (tx_q->len) { LOG_DEBUG(VHOST_DATA, "TX queue drained after timeout" @@ -2124,7 +2135,7 @@ switch_worker_zcp(__attribute__((unused)) void *arg) tx_q->len = 0; txmbuf_clean_zcp(dev, - &vpool_array[MAX_QUEUES+dev->vmdq_rx_q]); + &vpool_array[MAX_QUEUES+vdev->vmdq_rx_q]); } } dev_ll = dev_ll->next; @@ -2144,17 +2155,18 @@ switch_worker_zcp(__attribute__((unused)) void *arg) /* Process devices */ dev_ll = lcore_ll->ll_root_used; - while ((dev_ll != NULL) && (dev_ll->dev != NULL)) { - dev = dev_ll->dev; - if (unlikely(dev->remove)) { + while ((dev_ll != NULL) && (dev_ll->vdev != NULL)) { + vdev = dev_ll->vdev; + dev = vdev->dev; + if (unlikely(vdev->remove)) { dev_ll = dev_ll->next; - unlink_vmdq(dev); - dev->ready = DEVICE_SAFE_REMOVE; + unlink_vmdq(vdev); + vdev->ready = DEVICE_SAFE_REMOVE; continue; } - if (likely(dev->ready == DEVICE_RX)) { - uint32_t index = dev->vmdq_rx_q; + if (likely(vdev->ready == DEVICE_RX)) { + uint32_t index = vdev->vmdq_rx_q; uint16_t i; count_in_ring = rte_ring_count(vpool_array[index].ring); @@ -2173,7 +2185,7 @@ switch_worker_zcp(__attribute__((unused)) void *arg) /* Handle guest RX */ rx_count = rte_eth_rx_burst(ports[0], - (uint16_t)dev->vmdq_rx_q, pkts_burst, + vdev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST); if (rx_count) { @@ -2196,7 +2208,7 @@ switch_worker_zcp(__attribute__((unused)) void *arg) } } - if (likely(!dev->remove)) + if (likely(!vdev->remove)) /* Handle guest TX */ virtio_dev_tx_zcp(dev); @@ -2309,7 +2321,7 @@ alloc_data_ll(uint32_t size) } for (i = 0; i < size - 1; i++) { - ll_new[i].dev = NULL; + ll_new[i].vdev = NULL; ll_new[i].next = &ll_new[i+1]; } ll_new[i].next = NULL; @@ -2370,21 +2382,22 @@ destroy_device (volatile struct virtio_net *dev) struct virtio_net_data_ll *ll_main_dev_cur; struct virtio_net_data_ll *ll_lcore_dev_last = NULL; struct virtio_net_data_ll *ll_main_dev_last = NULL; + struct vhost_dev *vdev; int lcore; dev->flags &= ~VIRTIO_DEV_RUNNING; + vdev = (struct vhost_dev *)dev->priv; /*set the remove flag. */ - dev->remove = 1; - - while(dev->ready != DEVICE_SAFE_REMOVE) { + vdev->remove = 1; + while(vdev->ready != DEVICE_SAFE_REMOVE) { rte_pause(); } /* Search for entry to be removed from lcore ll */ - ll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used; + ll_lcore_dev_cur = lcore_info[vdev->coreid].lcore_ll->ll_root_used; while (ll_lcore_dev_cur != NULL) { - if (ll_lcore_dev_cur->dev == dev) { + if (ll_lcore_dev_cur->vdev == vdev) { break; } else { ll_lcore_dev_last = ll_lcore_dev_cur; @@ -2403,7 +2416,7 @@ destroy_device (volatile struct virtio_net *dev) ll_main_dev_cur = ll_root_used; ll_main_dev_last = NULL; while (ll_main_dev_cur != NULL) { - if (ll_main_dev_cur->dev == dev) { + if (ll_main_dev_cur->vdev == vdev) { break; } else { ll_main_dev_last = ll_main_dev_cur; @@ -2412,7 +2425,7 @@ destroy_device (volatile struct virtio_net *dev) } /* Remove entries from the lcore and main ll. */ - rm_data_ll_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last); + rm_data_ll_entry(&lcore_info[vdev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last); rm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last); /* Set the dev_removal_flag on each lcore. */ @@ -2432,51 +2445,52 @@ destroy_device (volatile struct virtio_net *dev) } /* Add the entries back to the lcore and main free ll.*/ - put_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur); + put_data_ll_free_entry(&lcore_info[vdev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur); put_data_ll_free_entry(&ll_root_free, ll_main_dev_cur); /* Decrement number of device on the lcore. */ - lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--; + lcore_info[vdev->coreid].lcore_ll->device_num--; RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been removed from data core\n", dev->device_fh); if (zero_copy) { - struct vpool *vpool = &vpool_array[dev->vmdq_rx_q]; + struct vpool *vpool = &vpool_array[vdev->vmdq_rx_q]; /* Stop the RX queue. */ - if (rte_eth_dev_rx_queue_stop(ports[0], dev->vmdq_rx_q) != 0) { + if (rte_eth_dev_rx_queue_stop(ports[0], vdev->vmdq_rx_q) != 0) { LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") In destroy_device: Failed to stop " "rx queue:%d\n", dev->device_fh, - dev->vmdq_rx_q); + vdev->vmdq_rx_q); } LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") in destroy_device: Start put mbuf in " "mempool back to ring for RX queue: %d\n", - dev->device_fh, dev->vmdq_rx_q); + dev->device_fh, vdev->vmdq_rx_q); mbuf_destroy_zcp(vpool); /* Stop the TX queue. */ - if (rte_eth_dev_tx_queue_stop(ports[0], dev->vmdq_rx_q) != 0) { + if (rte_eth_dev_tx_queue_stop(ports[0], vdev->vmdq_rx_q) != 0) { LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") In destroy_device: Failed to " "stop tx queue:%d\n", - dev->device_fh, dev->vmdq_rx_q); + dev->device_fh, vdev->vmdq_rx_q); } - vpool = &vpool_array[dev->vmdq_rx_q + MAX_QUEUES]; + vpool = &vpool_array[vdev->vmdq_rx_q + MAX_QUEUES]; LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") destroy_device: Start put mbuf in mempool " "back to ring for TX queue: %d, dev:(%"PRIu64")\n", - dev->device_fh, (dev->vmdq_rx_q + MAX_QUEUES), + dev->device_fh, (vdev->vmdq_rx_q + MAX_QUEUES), dev->device_fh); mbuf_destroy_zcp(vpool); } + rte_free(vdev); } @@ -2637,6 +2651,17 @@ new_device (struct virtio_net *dev) struct virtio_net_data_ll *ll_dev; int lcore, core_add = 0; uint32_t device_num_min = num_devices; + struct vhost_dev *vdev; + + + vdev = rte_zmalloc("vhost device", sizeof(*vdev), CACHE_LINE_SIZE); + if (vdev == NULL) { + RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Couldn't allocate memory for vhost dev\n", + dev->device_fh); + return -1; + } + vdev->dev = dev; + dev->priv = vdev; /* Add device to main ll */ ll_dev = get_data_ll_free_entry(&ll_root_free); @@ -2644,15 +2669,16 @@ new_device (struct virtio_net *dev) RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") No free entry found in linked list. Device limit " "of %d devices per core has been reached\n", dev->device_fh, num_devices); + rte_free(vdev); return -1; } - ll_dev->dev = dev; + ll_dev->vdev = vdev; add_data_ll_entry(&ll_root_used, ll_dev); - ll_dev->dev->vmdq_rx_q - = ll_dev->dev->device_fh * (num_queues / num_devices); + vdev->vmdq_rx_q + = dev->device_fh * (num_queues / num_devices); if (zero_copy) { - uint32_t index = ll_dev->dev->vmdq_rx_q; + uint32_t index = vdev->vmdq_rx_q; uint32_t count_in_ring, i; struct mbuf_table *tx_q; @@ -2676,54 +2702,56 @@ new_device (struct virtio_net *dev) LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") in new_device: mbuf count in " "mempool after attach is: %d\n", - dev->device_fh, + dev->device_fh, rte_mempool_count(vpool_array[index].pool)); LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") in new_device: mbuf count in " "ring after attach is : %d\n", dev->device_fh, rte_ring_count(vpool_array[index].ring)); - tx_q = &tx_queue_zcp[(uint16_t)dev->vmdq_rx_q]; - tx_q->txq_id = dev->vmdq_rx_q; + tx_q = &tx_queue_zcp[(uint16_t)vdev->vmdq_rx_q]; + tx_q->txq_id = vdev->vmdq_rx_q; - if (rte_eth_dev_tx_queue_start(ports[0], dev->vmdq_rx_q) != 0) { - struct vpool *vpool = &vpool_array[dev->vmdq_rx_q]; + if (rte_eth_dev_tx_queue_start(ports[0], vdev->vmdq_rx_q) != 0) { + struct vpool *vpool = &vpool_array[vdev->vmdq_rx_q]; LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") In new_device: Failed to start " "tx queue:%d\n", - dev->device_fh, dev->vmdq_rx_q); + dev->device_fh, vdev->vmdq_rx_q); mbuf_destroy_zcp(vpool); + rte_free(vdev); return -1; } - if (rte_eth_dev_rx_queue_start(ports[0], dev->vmdq_rx_q) != 0) { - struct vpool *vpool = &vpool_array[dev->vmdq_rx_q]; + if (rte_eth_dev_rx_queue_start(ports[0], vdev->vmdq_rx_q) != 0) { + struct vpool *vpool = &vpool_array[vdev->vmdq_rx_q]; LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") In new_device: Failed to start " "rx queue:%d\n", - dev->device_fh, dev->vmdq_rx_q); + dev->device_fh, vdev->vmdq_rx_q); /* Stop the TX queue. */ if (rte_eth_dev_tx_queue_stop(ports[0], - dev->vmdq_rx_q) != 0) { + vdev->vmdq_rx_q) != 0) { LOG_DEBUG(VHOST_CONFIG, "(%"PRIu64") In new_device: Failed to " "stop tx queue:%d\n", - dev->device_fh, dev->vmdq_rx_q); + dev->device_fh, vdev->vmdq_rx_q); } mbuf_destroy_zcp(vpool); + rte_free(vdev); return -1; } } /*reset ready flag*/ - dev->ready = DEVICE_MAC_LEARNING; - dev->remove = 0; + vdev->ready = DEVICE_MAC_LEARNING; + vdev->remove = 0; /* Find a suitable lcore to add the device. */ RTE_LCORE_FOREACH_SLAVE(lcore) { @@ -2737,11 +2765,14 @@ new_device (struct virtio_net *dev) ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free); if (ll_dev == NULL) { RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh); - dev->ready = DEVICE_SAFE_REMOVE; + vdev->ready = DEVICE_SAFE_REMOVE; destroy_device(dev); + rte_free(vdev); return -1; } - ll_dev->dev = dev; + ll_dev->vdev = vdev; + vdev->coreid = core_add; + add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev); /* Initialize device stats */ @@ -2749,10 +2780,10 @@ new_device (struct virtio_net *dev) /* Disable notifications. */ set_irq_status(dev); - lcore_info[ll_dev->dev->coreid].lcore_ll->device_num++; + lcore_info[vdev->coreid].lcore_ll->device_num++; dev->flags |= VIRTIO_DEV_RUNNING; - RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, dev->coreid); + RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, vdev->coreid); return 0; } @@ -2791,7 +2822,7 @@ print_stats(void) dev_ll = ll_root_used; while (dev_ll != NULL) { - device_fh = (uint32_t)dev_ll->dev->device_fh; + device_fh = (uint32_t)dev_ll->vdev->dev->device_fh; tx_total = dev_statistics[device_fh].tx_total; tx = dev_statistics[device_fh].tx; tx_dropped = tx_total - tx; diff --git a/examples/vhost/main.h b/examples/vhost/main.h index ebb0b5b..66e2fce 100644 --- a/examples/vhost/main.h +++ b/examples/vhost/main.h @@ -72,12 +72,33 @@ struct virtio_memory_regions_hpa { uint64_t host_phys_addr_offset; }; -/* +/** * Device linked list structure for data path. */ +struct vhost_dev { + /**< Pointer to device created by vhost lib. */ + struct virtio_net *dev; + /**< Number of memory regions for gpa to hpa translation. */ + uint32_t nregions_hpa; + /**< Memory region information for gpa to hpa translation. */ + struct virtio_memory_regions_hpa *regions_hpa; + /**< Device MAC address (Obtained on first TX packet). */ + struct ether_addr mac_address; + /**< RX VMDQ queue number. */ + uint16_t vmdq_rx_q; + /**< Vlan tag assigned to the pool */ + uint32_t vlan_tag; + /**< Data core that the device is added to. */ + uint16_t coreid; + /**< A device is set as ready if the MAC address has been set. */ + volatile uint8_t ready; + /**< Device is marked for removal from the data core. */ + volatile uint8_t remove; +} __rte_cache_aligned; + struct virtio_net_data_ll { - struct virtio_net *dev; /* Pointer to device created by configuration core. */ + struct vhost_dev *vdev; /* Pointer to device created by configuration core. */ struct virtio_net_data_ll *next; /* Pointer to next device in linked list. */ }; -- 1.8.1.4