From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id B875B2A5D for ; Tue, 26 Apr 2016 06:43:41 +0200 (CEST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP; 25 Apr 2016 21:43:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,535,1455004800"; d="scan'208";a="940170651" Received: from yliu-dev.sh.intel.com ([10.239.67.162]) by orsmga001.jf.intel.com with ESMTP; 25 Apr 2016 21:43:41 -0700 From: Yuanhan Liu To: dev@dpdk.org Cc: huawei.xie@intel.com, Yuanhan Liu Date: Mon, 25 Apr 2016 21:45:47 -0700 Message-Id: <1461645951-14603-4-git-send-email-yuanhan.liu@linux.intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1461645951-14603-1-git-send-email-yuanhan.liu@linux.intel.com> References: <1461645951-14603-1-git-send-email-yuanhan.liu@linux.intel.com> Subject: [dpdk-dev] [PATCH 3/7] examples/vhost: use tailq to link vhost devices 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: Tue, 26 Apr 2016 04:43:42 -0000 To simplify code and logic. Signed-off-by: Yuanhan Liu --- examples/vhost/main.c | 457 +++++++++++++------------------------------------- examples/vhost/main.h | 32 ++-- 2 files changed, 128 insertions(+), 361 deletions(-) diff --git a/examples/vhost/main.c b/examples/vhost/main.c index b5dd677..092bb13 100644 --- a/examples/vhost/main.c +++ b/examples/vhost/main.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -86,10 +86,6 @@ #define DEVICE_RX 1 #define DEVICE_SAFE_REMOVE 2 -/* Config_core_flag status definitions. */ -#define REQUEST_DEV_REMOVAL 1 -#define ACK_DEV_REMOVAL 0 - /* Configurable number of RX/TX ring descriptors */ #define RTE_TEST_RX_DESC_DEFAULT 1024 #define RTE_TEST_TX_DESC_DEFAULT 512 @@ -216,11 +212,9 @@ const uint16_t vlan_tags[] = { /* ethernet addresses of ports */ static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS]; -/* heads for the main used and free linked lists for the data path. */ -static struct virtio_net_data_ll *ll_root_used = NULL; -static struct virtio_net_data_ll *ll_root_free = NULL; +static struct vhost_dev_tailq_list vhost_dev_list = + TAILQ_HEAD_INITIALIZER(vhost_dev_list); -/* Array of data core structures containing information on individual core linked lists. */ static struct lcore_info lcore_info[RTE_MAX_LCORE]; /* Used for queueing bursts of TX packets. */ @@ -749,6 +743,20 @@ ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb) return ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0; } +static inline struct vhost_dev * __attribute__((always_inline)) +find_vhost_dev(struct ether_addr *mac) +{ + struct vhost_dev *vdev; + + TAILQ_FOREACH(vdev, &vhost_dev_list, next) { + if (vdev->ready == DEVICE_RX && + ether_addr_cmp(mac, &vdev->mac_address)) + return vdev; + } + + return NULL; +} + /* * This function learns the MAC address of the device and registers this along with a * vlan tag to a VMDQ. @@ -757,21 +765,17 @@ static int 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 */ pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); - dev_ll = ll_root_used; - - while (dev_ll != NULL) { - 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; - } - dev_ll = dev_ll->next; + if (find_vhost_dev(&pkt_hdr->s_addr)) { + RTE_LOG(ERR, VHOST_DATA, + "Device (%" PRIu64 ") is using a registered MAC!\n", + dev->device_fh); + return -1; } for (i = 0; i < ETHER_ADDR_LEN; i++) @@ -848,60 +852,48 @@ unlink_vmdq(struct vhost_dev *vdev) static inline int __attribute__((always_inline)) 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 */ + struct vhost_dev *vdev2; + uint64_t fh; pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); - /*get the used devices list*/ - dev_ll = ll_root_used; + vdev2 = find_vhost_dev(&pkt_hdr->d_addr); + if (!vdev2) + return -1; - while (dev_ll != NULL) { - if ((dev_ll->vdev->ready == DEVICE_RX) && ether_addr_cmp(&(pkt_hdr->d_addr), - &dev_ll->vdev->mac_address)) { + tdev = vdev2->dev; + fh = tdev->device_fh; - /* Drop the packet if the TX packet is destined for the TX device. */ - if (dev_ll->vdev->dev->device_fh == dev->device_fh) { - RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: " - "Source and destination MAC addresses are the same. " - "Dropping packet.\n", - dev->device_fh); - return 0; - } - tdev = dev_ll->vdev->dev; - - - RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: " - "MAC address is local\n", tdev->device_fh); - - if (unlikely(dev_ll->vdev->remove)) { - /*drop the packet if the device is marked for removal*/ - RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") " - "Device is marked for removal\n", tdev->device_fh); - } else { - /*send the packet to the local virtio device*/ - ret = rte_vhost_enqueue_burst(tdev, VIRTIO_RXQ, &m, 1); - if (enable_stats) { - rte_atomic64_add( - &dev_statistics[tdev->device_fh].rx_total_atomic, - 1); - rte_atomic64_add( - &dev_statistics[tdev->device_fh].rx_atomic, - ret); - dev_statistics[dev->device_fh].tx_total++; - dev_statistics[dev->device_fh].tx += ret; - } - } + if (fh == dev->device_fh) { + RTE_LOG(DEBUG, VHOST_DATA, + "(%" PRIu64 ") TX: src and dst MAC is same. " + "Dropping packet.\n", fh); + return 0; + } - return 0; - } - dev_ll = dev_ll->next; + RTE_LOG(DEBUG, VHOST_DATA, + "(%" PRIu64 ") TX: MAC address is local\n", fh); + + if (unlikely(vdev2->remove)) { + RTE_LOG(DEBUG, VHOST_DATA, "(%" PRIu64 ") " + "Device is marked for removal\n", fh); + return 0; + } + + /* send the packet to the local virtio device */ + ret = rte_vhost_enqueue_burst(tdev, VIRTIO_RXQ, &m, 1); + if (enable_stats) { + rte_atomic64_inc(&dev_statistics[fh].rx_total_atomic); + rte_atomic64_add(&dev_statistics[fh].rx_atomic, ret); + dev_statistics[vdev->dev->device_fh].tx_total++; + dev_statistics[vdev->dev->device_fh].tx += ret; } - return -1; + return 0; } /* @@ -912,46 +904,33 @@ static inline int __attribute__((always_inline)) find_local_dest(struct virtio_net *dev, struct rte_mbuf *m, uint32_t *offset, uint16_t *vlan_tag) { - struct virtio_net_data_ll *dev_ll = ll_root_used; + struct vhost_dev *vdev; struct ether_hdr *pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *); - while (dev_ll != NULL) { - 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->vdev->dev->device_fh == dev->device_fh) { - RTE_LOG(DEBUG, VHOST_DATA, - "(%"PRIu64") TX: Source and destination" - " MAC addresses are the same. Dropping " - "packet.\n", - dev_ll->vdev->dev->device_fh); - return -1; - } - - /* - * HW vlan strip will reduce the packet length - * by minus length of vlan tag, so need restore - * the packet length by plus it. - */ - *offset = VLAN_HLEN; - *vlan_tag = - (uint16_t) - vlan_tags[(uint16_t)dev_ll->vdev->dev->device_fh]; - - RTE_LOG(DEBUG, VHOST_DATA, - "(%"PRIu64") TX: pkt to local VM device id:" - "(%"PRIu64") vlan tag: %d.\n", - dev->device_fh, dev_ll->vdev->dev->device_fh, - (int)*vlan_tag); + vdev = find_vhost_dev(&pkt_hdr->d_addr); + if (!vdev) + return 0; - break; - } - dev_ll = dev_ll->next; + if (vdev->dev->device_fh == dev->device_fh) { + RTE_LOG(DEBUG, VHOST_DATA, + "(%" PRIu64 ") TX: src and dst MAC is same. " + " Dropping packet.\n", vdev->dev->device_fh); + return -1; } + + /* + * HW vlan strip will reduce the packet length + * by minus length of vlan tag, so need restore + * the packet length by plus it. + */ + *offset = VLAN_HLEN; + *vlan_tag = vlan_tags[(uint16_t)vdev->dev->device_fh]; + + RTE_LOG(DEBUG, VHOST_DATA, + "(%" PRIu64 ") TX: pkt to local VM device id: (%" PRIu64 ") " + "vlan tag: %u.\n", + dev->device_fh, vdev->dev->device_fh, *vlan_tag); + return 0; } @@ -1087,9 +1066,7 @@ switch_worker(__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; - volatile struct lcore_ll_info *lcore_ll; const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US; uint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0; unsigned ret, i; @@ -1100,7 +1077,6 @@ switch_worker(__attribute__((unused)) void *arg) uint32_t retry = 0; RTE_LOG(INFO, VHOST_DATA, "Procesing on Core %u started\n", lcore_id); - lcore_ll = lcore_info[lcore_id].lcore_ll; prev_tsc = 0; tx_q = &lcore_tx_queue[lcore_id]; @@ -1141,30 +1117,28 @@ switch_worker(__attribute__((unused)) void *arg) } - rte_prefetch0(lcore_ll->ll_root_used); /* - * Inform the configuration core that we have exited the linked list and that no devices are - * in use if requested. + * Inform the configuration core that we have exited the + * linked list and that no devices are in use if requested. */ - if (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL) - lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL; + if (lcore_info[lcore_id].dev_removal_flag == REQUEST_DEV_REMOVAL) + lcore_info[lcore_id].dev_removal_flag = ACK_DEV_REMOVAL; /* * Process devices */ - dev_ll = lcore_ll->ll_root_used; + TAILQ_FOREACH(vdev, &lcore_info[lcore_id].vdev_list, next) { + uint64_t fh; - while (dev_ll != NULL) { - /*get virtio device ID*/ - vdev = dev_ll->vdev; dev = vdev->dev; + fh = dev->device_fh; if (unlikely(vdev->remove)) { - dev_ll = dev_ll->next; unlink_vmdq(vdev); vdev->ready = DEVICE_SAFE_REMOVE; continue; } + if (likely(vdev->ready == DEVICE_RX)) { /*Handle guest RX*/ rx_count = rte_eth_rx_burst(ports[0], @@ -1185,10 +1159,11 @@ switch_worker(__attribute__((unused)) void *arg) ret_count = rte_vhost_enqueue_burst(dev, VIRTIO_RXQ, pkts_burst, rx_count); if (enable_stats) { rte_atomic64_add( - &dev_statistics[dev_ll->vdev->dev->device_fh].rx_total_atomic, - rx_count); + &dev_statistics[fh].rx_total_atomic, + rx_count); rte_atomic64_add( - &dev_statistics[dev_ll->vdev->dev->device_fh].rx_atomic, ret_count); + &dev_statistics[fh].rx_atomic, + ret_count); } while (likely(rx_count)) { rx_count--; @@ -1213,166 +1188,21 @@ switch_worker(__attribute__((unused)) void *arg) vlan_tags[(uint16_t)dev->device_fh]); } } - - /*move to the next device in the list*/ - dev_ll = dev_ll->next; - } - } - - return 0; -} - -/* - * Add an entry to a used linked list. A free entry must first be found - * in the free linked list using get_data_ll_free_entry(); - */ -static void -add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, - struct virtio_net_data_ll *ll_dev) -{ - struct virtio_net_data_ll *ll = *ll_root_addr; - - /* Set next as NULL and use a compiler barrier to avoid reordering. */ - ll_dev->next = NULL; - rte_compiler_barrier(); - - /* If ll == NULL then this is the first device. */ - if (ll) { - /* Increment to the tail of the linked list. */ - while ((ll->next != NULL) ) - ll = ll->next; - - ll->next = ll_dev; - } else { - *ll_root_addr = ll_dev; - } -} - -/* - * Remove an entry from a used linked list. The entry must then be added to - * the free linked list using put_data_ll_free_entry(). - */ -static void -rm_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, - struct virtio_net_data_ll *ll_dev, - struct virtio_net_data_ll *ll_dev_last) -{ - struct virtio_net_data_ll *ll = *ll_root_addr; - - if (unlikely((ll == NULL) || (ll_dev == NULL))) - return; - - if (ll_dev == ll) - *ll_root_addr = ll_dev->next; - else - if (likely(ll_dev_last != NULL)) - ll_dev_last->next = ll_dev->next; - else - RTE_LOG(ERR, VHOST_CONFIG, "Remove entry form ll failed.\n"); -} - -/* - * Find and return an entry from the free linked list. - */ -static struct virtio_net_data_ll * -get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr) -{ - struct virtio_net_data_ll *ll_free = *ll_root_addr; - struct virtio_net_data_ll *ll_dev; - - if (ll_free == NULL) - return NULL; - - ll_dev = ll_free; - *ll_root_addr = ll_free->next; - - return ll_dev; -} - -/* - * Place an entry back on to the free linked list. - */ -static void -put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, - struct virtio_net_data_ll *ll_dev) -{ - struct virtio_net_data_ll *ll_free = *ll_root_addr; - - if (ll_dev == NULL) - return; - - ll_dev->next = ll_free; - *ll_root_addr = ll_dev; -} - -/* - * Creates a linked list of a given size. - */ -static struct virtio_net_data_ll * -alloc_data_ll(uint32_t size) -{ - struct virtio_net_data_ll *ll_new; - uint32_t i; - - /* Malloc and then chain the linked list. */ - ll_new = malloc(size * sizeof(struct virtio_net_data_ll)); - if (ll_new == NULL) { - RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for ll_new.\n"); - return NULL; - } - - for (i = 0; i < size - 1; i++) { - ll_new[i].vdev = NULL; - ll_new[i].next = &ll_new[i+1]; - } - ll_new[i].next = NULL; - - return ll_new; -} - -/* - * Create the main linked list along with each individual cores linked list. A used and a free list - * are created to manage entries. - */ -static int -init_data_ll (void) -{ - int lcore; - - RTE_LCORE_FOREACH_SLAVE(lcore) { - lcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info)); - if (lcore_info[lcore].lcore_ll == NULL) { - RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for lcore_ll.\n"); - return -1; } - - lcore_info[lcore].lcore_ll->device_num = 0; - lcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL; - lcore_info[lcore].lcore_ll->ll_root_used = NULL; - if (num_devices % num_switching_cores) - lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1); - else - lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores); } - /* Allocate devices up to a maximum of MAX_DEVICES. */ - ll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES)); - return 0; } /* - * Remove a device from the specific data core linked list and from the main linked list. Synchonization - * occurs through the use of the lcore dev_removal_flag. Device is made volatile here to avoid re-ordering + * Remove a device from the specific data core linked list and from the + * main linked list. Synchonization occurs through the use of the + * lcore dev_removal_flag. Device is made volatile here to avoid re-ordering * of dev->remove=1 which can cause an infinite loop in the rte_pause loop. */ static void destroy_device (volatile struct virtio_net *dev) { - struct virtio_net_data_ll *ll_lcore_dev_cur; - 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; @@ -1385,67 +1215,30 @@ destroy_device (volatile struct virtio_net *dev) rte_pause(); } - /* Search for entry to be removed from lcore ll */ - ll_lcore_dev_cur = lcore_info[vdev->coreid].lcore_ll->ll_root_used; - while (ll_lcore_dev_cur != NULL) { - if (ll_lcore_dev_cur->vdev == vdev) { - break; - } else { - ll_lcore_dev_last = ll_lcore_dev_cur; - ll_lcore_dev_cur = ll_lcore_dev_cur->next; - } - } - - if (ll_lcore_dev_cur == NULL) { - RTE_LOG(ERR, VHOST_CONFIG, - "(%"PRIu64") Failed to find the dev to be destroy.\n", - dev->device_fh); - return; - } - - /* Search for entry to be removed from main ll */ - ll_main_dev_cur = ll_root_used; - ll_main_dev_last = NULL; - while (ll_main_dev_cur != NULL) { - if (ll_main_dev_cur->vdev == vdev) { - break; - } else { - ll_main_dev_last = ll_main_dev_cur; - ll_main_dev_cur = ll_main_dev_cur->next; - } - } - - /* Remove entries from the lcore and main ll. */ - 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); + TAILQ_REMOVE(&lcore_info[vdev->coreid].vdev_list, vdev, next); + TAILQ_REMOVE(&vhost_dev_list, vdev, next); /* Set the dev_removal_flag on each lcore. */ - RTE_LCORE_FOREACH_SLAVE(lcore) { - lcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL; - } + RTE_LCORE_FOREACH_SLAVE(lcore) + lcore_info[lcore].dev_removal_flag = REQUEST_DEV_REMOVAL; /* - * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that - * they can no longer access the device removed from the linked lists and that the devices - * are no longer in use. + * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL + * we can be sure that they can no longer access the device removed + * from the linked lists and that the devices are no longer in use. */ RTE_LCORE_FOREACH_SLAVE(lcore) { - while (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) { + while (lcore_info[lcore].dev_removal_flag != ACK_DEV_REMOVAL) rte_pause(); - } } - /* Add the entries back to the lcore and main free ll.*/ - 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); + lcore_info[vdev->coreid].device_num--; - /* Decrement number of device on the lcore. */ - 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); + RTE_LOG(INFO, VHOST_DATA, + "(%" PRIu64 ") Device has been removed from data core\n", + dev->device_fh); rte_free(vdev); - } /* @@ -1455,7 +1248,6 @@ destroy_device (volatile struct virtio_net *dev) static int 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; @@ -1469,17 +1261,7 @@ new_device (struct virtio_net *dev) vdev->dev = dev; dev->priv = vdev; - /* Add device to main ll */ - ll_dev = get_data_ll_free_entry(&ll_root_free); - if (ll_dev == NULL) { - 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->vdev = vdev; - add_data_ll_entry(&ll_root_used, ll_dev); + TAILQ_INSERT_TAIL(&vhost_dev_list, vdev, next); vdev->vmdq_rx_q = dev->device_fh * queues_per_pool + vmdq_queue_base; @@ -1489,24 +1271,15 @@ new_device (struct virtio_net *dev) /* Find a suitable lcore to add the device. */ RTE_LCORE_FOREACH_SLAVE(lcore) { - if (lcore_info[lcore].lcore_ll->device_num < device_num_min) { - device_num_min = lcore_info[lcore].lcore_ll->device_num; + if (lcore_info[lcore].device_num < device_num_min) { + device_num_min = lcore_info[lcore].device_num; core_add = lcore; } } - /* Add device to lcore ll */ - ll_dev = get_data_ll_free_entry(&lcore_info[core_add].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); - vdev->ready = DEVICE_SAFE_REMOVE; - destroy_device(dev); - rte_free(vdev); - return -1; - } - ll_dev->vdev = vdev; vdev->coreid = core_add; - add_data_ll_entry(&lcore_info[vdev->coreid].lcore_ll->ll_root_used, ll_dev); + TAILQ_INSERT_TAIL(&lcore_info[vdev->coreid].vdev_list, vdev, next); + lcore_info[vdev->coreid].device_num++; /* Initialize device stats */ memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics)); @@ -1514,7 +1287,6 @@ new_device (struct virtio_net *dev) /* Disable notifications. */ rte_vhost_enable_guest_notification(dev, VIRTIO_RXQ, 0); rte_vhost_enable_guest_notification(dev, VIRTIO_TXQ, 0); - 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, vdev->coreid); @@ -1539,7 +1311,7 @@ static const struct virtio_net_device_ops virtio_net_device_ops = static void print_stats(void) { - struct virtio_net_data_ll *dev_ll; + struct vhost_dev *vdev; uint64_t tx_dropped, rx_dropped; uint64_t tx, tx_total, rx, rx_total; uint32_t device_fh; @@ -1554,9 +1326,8 @@ print_stats(void) printf("\nDevice statistics ===================================="); - dev_ll = ll_root_used; - while (dev_ll != NULL) { - device_fh = (uint32_t)dev_ll->vdev->dev->device_fh; + TAILQ_FOREACH(vdev, &vhost_dev_list, next) { + device_fh = vdev->dev->device_fh; tx_total = dev_statistics[device_fh].tx_total; tx = dev_statistics[device_fh].tx; tx_dropped = tx_total - tx; @@ -1580,8 +1351,6 @@ print_stats(void) rx_total, rx_dropped, rx); - - dev_ll = dev_ll->next; } printf("\n======================================================\n"); } @@ -1627,6 +1396,8 @@ main(int argc, char *argv[]) rte_exit(EXIT_FAILURE, "Invalid argument\n"); for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) + TAILQ_INIT(&lcore_info[lcore_id].vdev_list); + if (rte_lcore_is_enabled(lcore_id)) lcore_ids[core_id ++] = lcore_id; @@ -1680,10 +1451,6 @@ main(int argc, char *argv[]) "Cannot initialize network ports\n"); } - /* Initialise all linked lists. */ - if (init_data_ll() == -1) - rte_exit(EXIT_FAILURE, "Failed to initialize linked list\n"); - /* Initialize device stats */ memset(&dev_statistics, 0, sizeof(dev_statistics)); diff --git a/examples/vhost/main.h b/examples/vhost/main.h index 222bf41..76e7fdf 100644 --- a/examples/vhost/main.h +++ b/examples/vhost/main.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,6 +34,8 @@ #ifndef _MAIN_H_ #define _MAIN_H_ +#include + /* Macros for printing using RTE_LOG */ #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1 #define RTE_LOGTYPE_VHOST_DATA RTE_LOGTYPE_USER2 @@ -59,28 +61,26 @@ struct vhost_dev { volatile uint8_t ready; /**< Device is marked for removal from the data core. */ volatile uint8_t remove; + + TAILQ_ENTRY(vhost_dev) next; } __rte_cache_aligned; -struct virtio_net_data_ll -{ - struct vhost_dev *vdev; /* Pointer to device created by configuration core. */ - struct virtio_net_data_ll *next; /* Pointer to next device in linked list. */ -}; +TAILQ_HEAD(vhost_dev_tailq_list, vhost_dev); + + +#define REQUEST_DEV_REMOVAL 1 +#define ACK_DEV_REMOVAL 0 /* * Structure containing data core specific information. */ -struct lcore_ll_info -{ - struct virtio_net_data_ll *ll_root_free; /* Pointer to head in free linked list. */ - struct virtio_net_data_ll *ll_root_used; /* Pointer to head of used linked list. */ - uint32_t device_num; /* Number of devices on lcore. */ - volatile uint8_t dev_removal_flag; /* Flag to synchronize device removal. */ -}; +struct lcore_info { + uint32_t device_num; + + /* Flag to synchronize device removal. */ + volatile uint8_t dev_removal_flag; -struct lcore_info -{ - struct lcore_ll_info *lcore_ll; /* Pointer to data core specific lcore_ll_info struct */ + struct vhost_dev_tailq_list vdev_list; }; #endif /* _MAIN_H_ */ -- 1.9.0