remove extra parentheses in return statement
[dpdk.git] / examples / vhost_xen / main.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <arpa/inet.h>
35 #include <getopt.h>
36 #include <linux/if_ether.h>
37 #include <linux/if_vlan.h>
38 #include <linux/virtio_net.h>
39 #include <linux/virtio_ring.h>
40 #include <signal.h>
41 #include <stdint.h>
42 #include <sys/eventfd.h>
43 #include <sys/param.h>
44 #include <unistd.h>
45
46 #include <rte_atomic.h>
47 #include <rte_cycles.h>
48 #include <rte_ethdev.h>
49 #include <rte_log.h>
50 #include <rte_string_fns.h>
51
52 #include "main.h"
53 #include "virtio-net.h"
54 #include "xen_vhost.h"
55
56 #define MAX_QUEUES 128
57
58 /* the maximum number of external ports supported */
59 #define MAX_SUP_PORTS 1
60
61 /*
62  * Calculate the number of buffers needed per port
63  */
64 #define NUM_MBUFS_PER_PORT ((MAX_QUEUES*RTE_TEST_RX_DESC_DEFAULT) +             \
65                                                         (num_switching_cores*MAX_PKT_BURST) +                   \
66                                                         (num_switching_cores*RTE_TEST_TX_DESC_DEFAULT) +\
67                                                         (num_switching_cores*MBUF_CACHE_SIZE))
68
69 #define MBUF_CACHE_SIZE 64
70
71 /*
72  * RX and TX Prefetch, Host, and Write-back threshold values should be
73  * carefully set for optimal performance. Consult the network
74  * controller's datasheet and supporting DPDK documentation for guidance
75  * on how these parameters should be set.
76  */
77 #define RX_PTHRESH 8 /* Default values of RX prefetch threshold reg. */
78 #define RX_HTHRESH 8 /* Default values of RX host threshold reg. */
79 #define RX_WTHRESH 4 /* Default values of RX write-back threshold reg. */
80
81 /*
82  * These default values are optimized for use with the Intel(R) 82599 10 GbE
83  * Controller and the DPDK ixgbe PMD. Consider using other values for other
84  * network controllers and/or network drivers.
85  */
86 #define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */
87 #define TX_HTHRESH 0  /* Default values of TX host threshold reg. */
88 #define TX_WTHRESH 0  /* Default values of TX write-back threshold reg. */
89
90 #define MAX_PKT_BURST 32                /* Max burst size for RX/TX */
91 #define MAX_MRG_PKT_BURST 16    /* Max burst for merge buffers. Set to 1 due to performance issue. */
92 #define BURST_TX_DRAIN_US 100   /* TX drain every ~100us */
93
94 /* State of virtio device. */
95 #define DEVICE_NOT_READY     0
96 #define DEVICE_READY         1
97 #define DEVICE_SAFE_REMOVE   2
98
99 /* Config_core_flag status definitions. */
100 #define REQUEST_DEV_REMOVAL 1
101 #define ACK_DEV_REMOVAL 0
102
103 /* Configurable number of RX/TX ring descriptors */
104 #define RTE_TEST_RX_DESC_DEFAULT 128
105 #define RTE_TEST_TX_DESC_DEFAULT 512
106
107 #define INVALID_PORT_ID 0xFF
108
109 /* Max number of devices. Limited by vmdq. */
110 #define MAX_DEVICES 64
111
112 /* Size of buffers used for snprintfs. */
113 #define MAX_PRINT_BUFF 6072
114
115
116 /* Maximum long option length for option parsing. */
117 #define MAX_LONG_OPT_SZ 64
118
119 /* Used to compare MAC addresses. */
120 #define MAC_ADDR_CMP 0xFFFFFFFFFFFF
121
122 /* mask of enabled ports */
123 static uint32_t enabled_port_mask = 0;
124
125 /*Number of switching cores enabled*/
126 static uint32_t num_switching_cores = 0;
127
128 /* number of devices/queues to support*/
129 static uint32_t num_queues = 0;
130 uint32_t num_devices = 0;
131
132 /* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */
133 static uint32_t enable_vm2vm = 1;
134 /* Enable stats. */
135 static uint32_t enable_stats = 0;
136
137 /* empty vmdq configuration structure. Filled in programatically */
138 static const struct rte_eth_conf vmdq_conf_default = {
139         .rxmode = {
140                 .mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
141                 .split_hdr_size = 0,
142                 .header_split   = 0, /**< Header Split disabled */
143                 .hw_ip_checksum = 0, /**< IP checksum offload disabled */
144                 .hw_vlan_filter = 0, /**< VLAN filtering disabled */
145                 /*
146                  * It is necessary for 1G NIC such as I350,
147                  * this fixes bug of ipv4 forwarding in guest can't
148                  * forward pakets from one virtio dev to another virtio dev.
149                  */
150                 .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
151                 .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
152                 .hw_strip_crc   = 0, /**< CRC stripped by hardware */
153         },
154
155         .txmode = {
156                 .mq_mode = ETH_MQ_TX_NONE,
157         },
158         .rx_adv_conf = {
159                 /*
160                  * should be overridden separately in code with
161                  * appropriate values
162                  */
163                 .vmdq_rx_conf = {
164                         .nb_queue_pools = ETH_8_POOLS,
165                         .enable_default_pool = 0,
166                         .default_pool = 0,
167                         .nb_pool_maps = 0,
168                         .pool_map = {{0, 0},},
169                 },
170         },
171 };
172
173 static unsigned lcore_ids[RTE_MAX_LCORE];
174 static uint8_t ports[RTE_MAX_ETHPORTS];
175 static unsigned num_ports = 0; /**< The number of ports specified in command line */
176
177 const uint16_t vlan_tags[] = {
178         1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
179         1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015,
180         1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
181         1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031,
182         1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
183         1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
184         1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
185         1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
186 };
187
188 /* ethernet addresses of ports */
189 static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
190
191 /* heads for the main used and free linked lists for the data path. */
192 static struct virtio_net_data_ll *ll_root_used = NULL;
193 static struct virtio_net_data_ll *ll_root_free = NULL;
194
195 /* Array of data core structures containing information on individual core linked lists. */
196 static struct lcore_info lcore_info[RTE_MAX_LCORE];
197
198 /* Used for queueing bursts of TX packets. */
199 struct mbuf_table {
200         unsigned len;
201         unsigned txq_id;
202         struct rte_mbuf *m_table[MAX_PKT_BURST];
203 };
204
205 /* TX queue for each data core. */
206 struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
207
208 /* Vlan header struct used to insert vlan tags on TX. */
209 struct vlan_ethhdr {
210         unsigned char   h_dest[ETH_ALEN];
211         unsigned char   h_source[ETH_ALEN];
212         __be16          h_vlan_proto;
213         __be16          h_vlan_TCI;
214         __be16          h_vlan_encapsulated_proto;
215 };
216
217 /* Header lengths. */
218 #define VLAN_HLEN       4
219 #define VLAN_ETH_HLEN   18
220
221 /* Per-device statistics struct */
222 struct device_statistics {
223         uint64_t tx_total;
224         rte_atomic64_t rx_total;
225         uint64_t tx;
226         rte_atomic64_t rx;
227 } __rte_cache_aligned;
228 struct device_statistics dev_statistics[MAX_DEVICES];
229
230 /*
231  * Builds up the correct configuration for VMDQ VLAN pool map
232  * according to the pool & queue limits.
233  */
234 static inline int
235 get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
236 {
237         struct rte_eth_vmdq_rx_conf conf;
238         unsigned i;
239
240         memset(&conf, 0, sizeof(conf));
241         conf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;
242         conf.nb_pool_maps = num_devices;
243
244         for (i = 0; i < conf.nb_pool_maps; i++) {
245                 conf.pool_map[i].vlan_id = vlan_tags[ i ];
246                 conf.pool_map[i].pools = (1UL << i);
247         }
248
249         (void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
250         (void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
251                    sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
252         return 0;
253 }
254
255 /*
256  * Validate the device number according to the max pool number gotten form dev_info
257  * If the device number is invalid, give the error message and return -1.
258  * Each device must have its own pool.
259  */
260 static inline int
261 validate_num_devices(uint32_t max_nb_devices)
262 {
263         if (num_devices > max_nb_devices) {
264                 RTE_LOG(ERR, VHOST_PORT, "invalid number of devices\n");
265                 return -1;
266         }
267         return 0;
268 }
269
270 /*
271  * Initialises a given port using global settings and with the rx buffers
272  * coming from the mbuf_pool passed as parameter
273  */
274 static inline int
275 port_init(uint8_t port, struct rte_mempool *mbuf_pool)
276 {
277         struct rte_eth_dev_info dev_info;
278         struct rte_eth_rxconf *rxconf;
279         struct rte_eth_conf port_conf;
280         uint16_t rx_rings, tx_rings = (uint16_t)rte_lcore_count();
281         const uint16_t rx_ring_size = RTE_TEST_RX_DESC_DEFAULT, tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;
282         int retval;
283         uint16_t q;
284
285         /* The max pool number from dev_info will be used to validate the pool number specified in cmd line */
286         rte_eth_dev_info_get (port, &dev_info);
287
288         /*configure the number of supported virtio devices based on VMDQ limits */
289         num_devices = dev_info.max_vmdq_pools;
290         num_queues = dev_info.max_rx_queues;
291
292         retval = validate_num_devices(MAX_DEVICES);
293         if (retval < 0)
294                 return retval;
295
296         /* Get port configuration. */
297         retval = get_eth_conf(&port_conf, num_devices);
298         if (retval < 0)
299                 return retval;
300
301         if (port >= rte_eth_dev_count()) return -1;
302
303         rx_rings = (uint16_t)num_queues,
304         /* Configure ethernet device. */
305         retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
306         if (retval != 0)
307                 return retval;
308
309         rte_eth_dev_info_get(port, &dev_info);
310         rxconf = &dev_info.default_rxconf;
311         rxconf->rx_drop_en = 1;
312         /* Setup the queues. */
313         for (q = 0; q < rx_rings; q ++) {
314                 retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
315                                                 rte_eth_dev_socket_id(port), rxconf,
316                                                 mbuf_pool);
317                 if (retval < 0)
318                         return retval;
319         }
320         for (q = 0; q < tx_rings; q ++) {
321                 retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
322                                                 rte_eth_dev_socket_id(port),
323                                                 NULL);
324                 if (retval < 0)
325                         return retval;
326         }
327
328         /* Start the device. */
329         retval  = rte_eth_dev_start(port);
330         if (retval < 0)
331                 return retval;
332
333         rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
334         RTE_LOG(INFO, VHOST_PORT, "Max virtio devices supported: %u\n", num_devices);
335         RTE_LOG(INFO, VHOST_PORT, "Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
336                         " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
337                         (unsigned)port,
338                         vmdq_ports_eth_addr[port].addr_bytes[0],
339                         vmdq_ports_eth_addr[port].addr_bytes[1],
340                         vmdq_ports_eth_addr[port].addr_bytes[2],
341                         vmdq_ports_eth_addr[port].addr_bytes[3],
342                         vmdq_ports_eth_addr[port].addr_bytes[4],
343                         vmdq_ports_eth_addr[port].addr_bytes[5]);
344
345         return 0;
346 }
347
348 /*
349  * Parse the portmask provided at run time.
350  */
351 static int
352 parse_portmask(const char *portmask)
353 {
354         char *end = NULL;
355         unsigned long pm;
356
357         errno = 0;
358
359         /* parse hexadecimal string */
360         pm = strtoul(portmask, &end, 16);
361         if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
362                 return -1;
363
364         if (pm == 0)
365                 return -1;
366
367         return pm;
368
369 }
370
371 /*
372  * Parse num options at run time.
373  */
374 static int
375 parse_num_opt(const char *q_arg, uint32_t max_valid_value)
376 {
377         char *end = NULL;
378         unsigned long num;
379
380         errno = 0;
381
382         /* parse unsigned int string */
383         num = strtoul(q_arg, &end, 10);
384         if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
385                 return -1;
386
387         if (num > max_valid_value)
388                 return -1;
389
390         return num;
391
392 }
393
394 /*
395  * Display usage
396  */
397 static void
398 us_vhost_usage(const char *prgname)
399 {
400         RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK --vm2vm [0|1] --stats [0-N] --nb-devices ND\n"
401         "               -p PORTMASK: Set mask for ports to be used by application\n"
402         "               --vm2vm [0|1]: disable/enable(default) vm2vm comms\n"
403         "               --stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\n",
404                prgname);
405 }
406
407 /*
408  * Parse the arguments given in the command line of the application.
409  */
410 static int
411 us_vhost_parse_args(int argc, char **argv)
412 {
413         int opt, ret;
414         int option_index;
415         unsigned i;
416         const char *prgname = argv[0];
417         static struct option long_option[] = {
418                 {"vm2vm", required_argument, NULL, 0},
419                 {"stats", required_argument, NULL, 0},
420                 {NULL, 0, 0, 0}
421         };
422
423         /* Parse command line */
424         while ((opt = getopt_long(argc, argv, "p:",long_option, &option_index)) != EOF) {
425                 switch (opt) {
426                 /* Portmask */
427                 case 'p':
428                         enabled_port_mask = parse_portmask(optarg);
429                         if (enabled_port_mask == 0) {
430                                 RTE_LOG(INFO, VHOST_CONFIG, "Invalid portmask\n");
431                                 us_vhost_usage(prgname);
432                                 return -1;
433                         }
434                         break;
435
436                 case 0:
437                         /* Enable/disable vm2vm comms. */
438                         if (!strncmp(long_option[option_index].name, "vm2vm", MAX_LONG_OPT_SZ)) {
439                                 ret = parse_num_opt(optarg, 1);
440                                 if (ret == -1) {
441                                         RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for vm2vm [0|1]\n");
442                                         us_vhost_usage(prgname);
443                                         return -1;
444                                 } else {
445                                         enable_vm2vm = ret;
446                                 }
447                         }
448
449                         /* Enable/disable stats. */
450                         if (!strncmp(long_option[option_index].name, "stats", MAX_LONG_OPT_SZ)) {
451                                 ret = parse_num_opt(optarg, INT32_MAX);
452                                 if (ret == -1) {
453                                         RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for stats [0..N]\n");
454                                         us_vhost_usage(prgname);
455                                         return -1;
456                                 } else {
457                                         enable_stats = ret;
458                                 }
459                         }
460                         break;
461
462                         /* Invalid option - print options. */
463                 default:
464                         us_vhost_usage(prgname);
465                         return -1;
466                 }
467         }
468
469         for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
470                 if (enabled_port_mask & (1 << i))
471                         ports[num_ports++] = (uint8_t)i;
472         }
473
474         if ((num_ports ==  0) || (num_ports > MAX_SUP_PORTS)) {
475                 RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
476                         "but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
477                 return -1;
478         }
479
480         return 0;
481 }
482
483 /*
484  * Update the global var NUM_PORTS and array PORTS according to system ports number
485  * and return valid ports number
486  */
487 static unsigned check_ports_num(unsigned nb_ports)
488 {
489         unsigned valid_num_ports = num_ports;
490         unsigned portid;
491
492         if (num_ports > nb_ports) {
493                 RTE_LOG(INFO, VHOST_PORT, "\nSpecified port number(%u) exceeds total system port number(%u)\n",
494                         num_ports, nb_ports);
495                 num_ports = nb_ports;
496         }
497
498         for (portid = 0; portid < num_ports; portid ++) {
499                 if (ports[portid] >= nb_ports) {
500                         RTE_LOG(INFO, VHOST_PORT, "\nSpecified port ID(%u) exceeds max system port ID(%u)\n",
501                                 ports[portid], (nb_ports - 1));
502                         ports[portid] = INVALID_PORT_ID;
503                         valid_num_ports--;
504                 }
505         }
506         return valid_num_ports;
507 }
508
509 /*
510  * Macro to print out packet contents. Wrapped in debug define so that the
511  * data path is not effected when debug is disabled.
512  */
513 #ifdef DEBUG
514 #define PRINT_PACKET(device, addr, size, header) do {                                                                                                                           \
515         char *pkt_addr = (char*)(addr);                                                                                                                                                                 \
516         unsigned int index;                                                                                                                                                                                             \
517         char packet[MAX_PRINT_BUFF];                                                                                                                                                                    \
518                                                                                                                                                                                                                                         \
519         if ((header))                                                                                                                                                                                                   \
520                 snprintf(packet, MAX_PRINT_BUFF, "(%"PRIu64") Header size %d: ", (device->device_fh), (size));                          \
521         else                                                                                                                                                                                                                    \
522                 snprintf(packet, MAX_PRINT_BUFF, "(%"PRIu64") Packet size %d: ", (device->device_fh), (size));                          \
523         for (index = 0; index < (size); index++) {                                                                                                                                              \
524                 snprintf(packet + strnlen(packet, MAX_PRINT_BUFF), MAX_PRINT_BUFF - strnlen(packet, MAX_PRINT_BUFF),    \
525                         "%02hhx ", pkt_addr[index]);                                                                                                                                                    \
526         }                                                                                                                                                                                                                               \
527         snprintf(packet + strnlen(packet, MAX_PRINT_BUFF), MAX_PRINT_BUFF - strnlen(packet, MAX_PRINT_BUFF), "\n");     \
528                                                                                                                                                                                                                                         \
529         LOG_DEBUG(VHOST_DATA, "%s", packet);                                                                                                                                                                    \
530 } while(0)
531 #else
532 #define PRINT_PACKET(device, addr, size, header) do{} while(0)
533 #endif
534
535 /*
536  * Function to convert guest physical addresses to vhost virtual addresses. This
537  * is used to convert virtio buffer addresses.
538  */
539 static inline uint64_t __attribute__((always_inline))
540 gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa)
541 {
542         struct virtio_memory_regions *region;
543         uint32_t regionidx;
544         uint64_t vhost_va = 0;
545
546         for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
547                 region = &dev->mem->regions[regionidx];
548                 if ((guest_pa >= region->guest_phys_address) &&
549                         (guest_pa <= region->guest_phys_address_end)) {
550                         vhost_va = region->address_offset + guest_pa;
551                         break;
552                 }
553         }
554         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") GPA %p| VVA %p\n",
555                 dev->device_fh, (void*)(uintptr_t)guest_pa, (void*)(uintptr_t)vhost_va);
556
557         return vhost_va;
558 }
559
560 /*
561  * This function adds buffers to the virtio devices RX virtqueue. Buffers can
562  * be received from the physical port or from another virtio device. A packet
563  * count is returned to indicate the number of packets that were succesfully
564  * added to the RX queue.
565  */
566 static inline uint32_t __attribute__((always_inline))
567 virtio_dev_rx(struct virtio_net *dev, struct rte_mbuf **pkts, uint32_t count)
568 {
569         struct vhost_virtqueue *vq;
570         struct vring_desc *desc;
571         struct rte_mbuf *buff;
572         /* The virtio_hdr is initialised to 0. */
573         struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0,0,0,0,0,0},0};
574         uint64_t buff_addr = 0;
575         uint64_t buff_hdr_addr = 0;
576         uint32_t head[MAX_PKT_BURST], packet_len = 0;
577         uint32_t head_idx, packet_success = 0;
578         uint16_t avail_idx, res_cur_idx;
579         uint16_t res_base_idx, res_end_idx;
580         uint16_t free_entries;
581         uint8_t success = 0;
582         void *userdata;
583
584         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") virtio_dev_rx()\n", dev->device_fh);
585         vq = dev->virtqueue_rx;
586         count = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count;
587         /* As many data cores may want access to available buffers, they need to be reserved. */
588         do {
589
590                 res_base_idx = vq->last_used_idx_res;
591
592                 avail_idx = *((volatile uint16_t *)&vq->avail->idx);
593
594                 free_entries = (avail_idx - res_base_idx);
595
596                 /*check that we have enough buffers*/
597                 if (unlikely(count > free_entries))
598                         count = free_entries;
599
600                 if (count == 0)
601                         return 0;
602
603                 res_end_idx = res_base_idx + count;
604                 /* vq->last_used_idx_res is atomically updated. */
605                 success = rte_atomic16_cmpset(&vq->last_used_idx_res, res_base_idx,
606                                                                         res_end_idx);
607         } while (unlikely(success == 0));
608         res_cur_idx = res_base_idx;
609         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") Current Index %d| End Index %d\n", dev->device_fh, res_cur_idx, res_end_idx);
610
611         /* Prefetch available ring to retrieve indexes. */
612         rte_prefetch0(&vq->avail->ring[res_cur_idx & (vq->size - 1)]);
613
614         /* Retrieve all of the head indexes first to avoid caching issues. */
615         for (head_idx = 0; head_idx < count; head_idx++)
616                 head[head_idx] = vq->avail->ring[(res_cur_idx + head_idx) & (vq->size - 1)];
617
618         /*Prefetch descriptor index. */
619         rte_prefetch0(&vq->desc[head[packet_success]]);
620
621         while (res_cur_idx != res_end_idx) {
622                 /* Get descriptor from available ring */
623                 desc = &vq->desc[head[packet_success]];
624                 /* Prefetch descriptor address. */
625                 rte_prefetch0(desc);
626
627                 buff = pkts[packet_success];
628
629                 /* Convert from gpa to vva (guest physical addr -> vhost virtual addr) */
630                 buff_addr = gpa_to_vva(dev, desc->addr);
631                 /* Prefetch buffer address. */
632                 rte_prefetch0((void*)(uintptr_t)buff_addr);
633
634                 {
635                         /* Copy virtio_hdr to packet and increment buffer address */
636                         buff_hdr_addr = buff_addr;
637                         packet_len = rte_pktmbuf_data_len(buff) + vq->vhost_hlen;
638
639                         /*
640                          * If the descriptors are chained the header and data are placed in
641                          * separate buffers.
642                          */
643                         if (desc->flags & VRING_DESC_F_NEXT) {
644                                 desc->len = vq->vhost_hlen;
645                                 desc = &vq->desc[desc->next];
646                                 /* Buffer address translation. */
647                                 buff_addr = gpa_to_vva(dev, desc->addr);
648                                 desc->len = rte_pktmbuf_data_len(buff);
649                         } else {
650                                 buff_addr += vq->vhost_hlen;
651                                 desc->len = packet_len;
652                         }
653                 }
654
655                 /* Update used ring with desc information */
656                 vq->used->ring[res_cur_idx & (vq->size - 1)].id = head[packet_success];
657                 vq->used->ring[res_cur_idx & (vq->size - 1)].len = packet_len;
658
659                 /* Copy mbuf data to buffer */
660                 userdata = rte_pktmbuf_mtod(buff, void *);
661                 rte_memcpy((void *)(uintptr_t)buff_addr, userdata, rte_pktmbuf_data_len(buff));
662
663                 res_cur_idx++;
664                 packet_success++;
665
666                 /* mergeable is disabled then a header is required per buffer. */
667                 rte_memcpy((void *)(uintptr_t)buff_hdr_addr, (const void *)&virtio_hdr, vq->vhost_hlen);
668                 if (res_cur_idx < res_end_idx) {
669                         /* Prefetch descriptor index. */
670                         rte_prefetch0(&vq->desc[head[packet_success]]);
671                 }
672         }
673
674         rte_compiler_barrier();
675
676         /* Wait until it's our turn to add our buffer to the used ring. */
677         while (unlikely(vq->last_used_idx != res_base_idx))
678                 rte_pause();
679
680         *(volatile uint16_t *)&vq->used->idx += count;
681
682         vq->last_used_idx = res_end_idx;
683
684         return count;
685 }
686
687 /*
688  * Compares a packet destination MAC address to a device MAC address.
689  */
690 static inline int __attribute__((always_inline))
691 ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb)
692 {
693         return ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0;
694 }
695
696 /*
697  * This function registers mac along with a
698  * vlan tag to a VMDQ.
699  */
700 static int
701 link_vmdq(struct virtio_net *dev)
702 {
703         int ret;
704         struct virtio_net_data_ll *dev_ll;
705
706         dev_ll = ll_root_used;
707
708         while (dev_ll != NULL) {
709                 if ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) {
710                         RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh);
711                         return -1;
712                 }
713                 dev_ll = dev_ll->next;
714         }
715
716         /* vlan_tag currently uses the device_id. */
717         dev->vlan_tag = vlan_tags[dev->device_fh];
718         dev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices);
719
720         /* Print out VMDQ registration info. */
721         RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n",
722                 dev->device_fh,
723                 dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1],
724                 dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3],
725                 dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5],
726                 dev->vlan_tag);
727
728         /* Register the MAC address. */
729         ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh);
730         if (ret) {
731                 RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n",
732                                                                                 dev->device_fh);
733                 return -1;
734         }
735
736         /* Enable stripping of the vlan tag as we handle routing. */
737         rte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1);
738
739         rte_compiler_barrier();
740         /* Set device as ready for RX. */
741         dev->ready = DEVICE_READY;
742
743         return 0;
744 }
745
746 /*
747  * Removes MAC address and vlan tag from VMDQ. Ensures that nothing is adding buffers to the RX
748  * queue before disabling RX on the device.
749  */
750 static inline void
751 unlink_vmdq(struct virtio_net *dev)
752 {
753         unsigned i = 0;
754         unsigned rx_count;
755         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
756
757         if (dev->ready == DEVICE_READY) {
758                 /*clear MAC and VLAN settings*/
759                 rte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address);
760                 for (i = 0; i < 6; i++)
761                         dev->mac_address.addr_bytes[i] = 0;
762
763                 dev->vlan_tag = 0;
764
765                 /*Clear out the receive buffers*/
766                 rx_count = rte_eth_rx_burst(ports[0],
767                                         (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
768
769                 while (rx_count) {
770                         for (i = 0; i < rx_count; i++)
771                                 rte_pktmbuf_free(pkts_burst[i]);
772
773                         rx_count = rte_eth_rx_burst(ports[0],
774                                         (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
775                 }
776
777                 dev->ready = DEVICE_NOT_READY;
778         }
779 }
780
781 /*
782  * Check if the packet destination MAC address is for a local device. If so then put
783  * the packet on that devices RX queue. If not then return.
784  */
785 static inline unsigned __attribute__((always_inline))
786 virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m)
787 {
788         struct virtio_net_data_ll *dev_ll;
789         struct ether_hdr *pkt_hdr;
790         uint64_t ret = 0;
791
792         pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
793
794         /*get the used devices list*/
795         dev_ll = ll_root_used;
796
797         while (dev_ll != NULL) {
798                 if (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr),
799                                           &dev_ll->dev->mac_address)) {
800
801                         /* Drop the packet if the TX packet is destined for the TX device. */
802                         if (dev_ll->dev->device_fh == dev->device_fh) {
803                                 LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: Source and destination MAC addresses are the same. Dropping packet.\n",
804                                                         dev_ll->dev->device_fh);
805                                 return 0;
806                         }
807
808
809                         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: MAC address is local\n", dev_ll->dev->device_fh);
810
811                         if (dev_ll->dev->remove) {
812                                 /*drop the packet if the device is marked for removal*/
813                                 LOG_DEBUG(VHOST_DATA, "(%"PRIu64") Device is marked for removal\n", dev_ll->dev->device_fh);
814                         } else {
815                                 /*send the packet to the local virtio device*/
816                                 ret = virtio_dev_rx(dev_ll->dev, &m, 1);
817                                 if (enable_stats) {
818                                         rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1);
819                                         rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret);
820                                         dev_statistics[dev->device_fh].tx_total++;
821                                         dev_statistics[dev->device_fh].tx += ret;
822                                 }
823                         }
824
825                         return 0;
826                 }
827                 dev_ll = dev_ll->next;
828         }
829
830         return -1;
831 }
832
833 /*
834  * This function routes the TX packet to the correct interface. This may be a local device
835  * or the physical port.
836  */
837 static inline void __attribute__((always_inline))
838 virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag)
839 {
840         struct mbuf_table *tx_q;
841         struct vlan_ethhdr *vlan_hdr;
842         struct rte_mbuf **m_table;
843         struct rte_mbuf *mbuf;
844         unsigned len, ret;
845         const uint16_t lcore_id = rte_lcore_id();
846
847         /*check if destination is local VM*/
848         if (enable_vm2vm && (virtio_tx_local(dev, m) == 0)) {
849                 return;
850         }
851
852         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") TX: MAC address is external\n", dev->device_fh);
853
854         /*Add packet to the port tx queue*/
855         tx_q = &lcore_tx_queue[lcore_id];
856         len = tx_q->len;
857
858         /* Allocate an mbuf and populate the structure. */
859         mbuf = rte_pktmbuf_alloc(mbuf_pool);
860         if(!mbuf)
861                 return;
862
863         mbuf->data_len = m->data_len + VLAN_HLEN;
864         mbuf->pkt_len = mbuf->data_len;
865
866         /* Copy ethernet header to mbuf. */
867         rte_memcpy(rte_pktmbuf_mtod(mbuf, void*),
868                         rte_pktmbuf_mtod(m, const void*), ETH_HLEN);
869
870
871         /* Setup vlan header. Bytes need to be re-ordered for network with htons()*/
872         vlan_hdr = rte_pktmbuf_mtod(mbuf, struct vlan_ethhdr *);
873         vlan_hdr->h_vlan_encapsulated_proto = vlan_hdr->h_vlan_proto;
874         vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
875         vlan_hdr->h_vlan_TCI = htons(vlan_tag);
876
877         /* Copy the remaining packet contents to the mbuf. */
878         rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),
879                 rte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),
880                 (m->data_len - ETH_HLEN));
881         tx_q->m_table[len] = mbuf;
882         len++;
883         if (enable_stats) {
884                 dev_statistics[dev->device_fh].tx_total++;
885                 dev_statistics[dev->device_fh].tx++;
886         }
887
888         if (unlikely(len == MAX_PKT_BURST)) {
889                 m_table = (struct rte_mbuf **)tx_q->m_table;
890                 ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id, m_table, (uint16_t) len);
891                 /* Free any buffers not handled by TX and update the port stats. */
892                 if (unlikely(ret < len)) {
893                         do {
894                                 rte_pktmbuf_free(m_table[ret]);
895                         } while (++ret < len);
896                 }
897
898                 len = 0;
899         }
900
901         tx_q->len = len;
902         return;
903 }
904
905 static inline void __attribute__((always_inline))
906 virtio_dev_tx(struct virtio_net* dev, struct rte_mempool *mbuf_pool)
907 {
908         struct rte_mbuf m;
909         struct vhost_virtqueue *vq;
910         struct vring_desc *desc;
911         uint64_t buff_addr = 0;
912         uint32_t head[MAX_PKT_BURST];
913         uint32_t used_idx;
914         uint32_t i;
915         uint16_t free_entries, packet_success = 0;
916         uint16_t avail_idx;
917
918         vq = dev->virtqueue_tx;
919         avail_idx = *((volatile uint16_t *)&vq->avail->idx);
920
921         /* If there are no available buffers then return. */
922         if (vq->last_used_idx == avail_idx)
923                 return;
924
925         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") virtio_dev_tx()\n", dev->device_fh);
926
927         /* Prefetch available ring to retrieve head indexes. */
928         rte_prefetch0(&vq->avail->ring[vq->last_used_idx & (vq->size - 1)]);
929
930         /*get the number of free entries in the ring*/
931         free_entries = avail_idx - vq->last_used_idx;
932         free_entries = unlikely(free_entries < MAX_PKT_BURST) ? free_entries : MAX_PKT_BURST;
933
934         LOG_DEBUG(VHOST_DATA, "(%"PRIu64") Buffers available %d\n", dev->device_fh, free_entries);
935         /* Retrieve all of the head indexes first to avoid caching issues. */
936         for (i = 0; i < free_entries; i++)
937                 head[i] = vq->avail->ring[(vq->last_used_idx + i) & (vq->size - 1)];
938
939         /* Prefetch descriptor index. */
940         rte_prefetch0(&vq->desc[head[packet_success]]);
941
942         while (packet_success < free_entries) {
943                 desc = &vq->desc[head[packet_success]];
944                 /* Prefetch descriptor address. */
945                 rte_prefetch0(desc);
946
947                 if (packet_success < (free_entries - 1)) {
948                         /* Prefetch descriptor index. */
949                         rte_prefetch0(&vq->desc[head[packet_success+1]]);
950                 }
951
952                 /* Update used index buffer information. */
953                 used_idx = vq->last_used_idx & (vq->size - 1);
954                 vq->used->ring[used_idx].id = head[packet_success];
955                 vq->used->ring[used_idx].len = 0;
956
957                 /* Discard first buffer as it is the virtio header */
958                 desc = &vq->desc[desc->next];
959
960                 /* Buffer address translation. */
961                 buff_addr = gpa_to_vva(dev, desc->addr);
962                 /* Prefetch buffer address. */
963                 rte_prefetch0((void*)(uintptr_t)buff_addr);
964
965                 /* Setup dummy mbuf. This is copied to a real mbuf if transmitted out the physical port. */
966                 m.data_len = desc->len;
967                 m.data_off = 0;
968                 m.nb_segs = 1;
969
970                 virtio_tx_route(dev, &m, mbuf_pool, 0);
971
972                 vq->last_used_idx++;
973                 packet_success++;
974         }
975
976         rte_compiler_barrier();
977         vq->used->idx += packet_success;
978         /* Kick guest if required. */
979 }
980
981 /*
982  * This function is called by each data core. It handles all RX/TX registered with the
983  * core. For TX the specific lcore linked list is used. For RX, MAC addresses are compared
984  * with all devices in the main linked list.
985  */
986 static int
987 switch_worker(__attribute__((unused)) void *arg)
988 {
989         struct rte_mempool *mbuf_pool = arg;
990         struct virtio_net *dev = NULL;
991         struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
992         struct virtio_net_data_ll *dev_ll;
993         struct mbuf_table *tx_q;
994         volatile struct lcore_ll_info *lcore_ll;
995         const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
996         uint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0;
997         unsigned ret, i;
998         const uint16_t lcore_id = rte_lcore_id();
999         const uint16_t num_cores = (uint16_t)rte_lcore_count();
1000         uint16_t rx_count = 0;
1001
1002         RTE_LOG(INFO, VHOST_DATA, "Procesing on Core %u started \n", lcore_id);
1003         lcore_ll = lcore_info[lcore_id].lcore_ll;
1004         prev_tsc = 0;
1005
1006         tx_q = &lcore_tx_queue[lcore_id];
1007         for (i = 0; i < num_cores; i ++) {
1008                 if (lcore_ids[i] == lcore_id) {
1009                         tx_q->txq_id = i;
1010                         break;
1011                 }
1012         }
1013
1014         while(1) {
1015                 cur_tsc = rte_rdtsc();
1016                 /*
1017                  * TX burst queue drain
1018                  */
1019                 diff_tsc = cur_tsc - prev_tsc;
1020                 if (unlikely(diff_tsc > drain_tsc)) {
1021
1022                         if (tx_q->len) {
1023                                 LOG_DEBUG(VHOST_DATA, "TX queue drained after timeout with burst size %u \n", tx_q->len);
1024
1025                                 /*Tx any packets in the queue*/
1026                                 ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id,
1027                                                                            (struct rte_mbuf **)tx_q->m_table,
1028                                                                            (uint16_t)tx_q->len);
1029                                 if (unlikely(ret < tx_q->len)) {
1030                                         do {
1031                                                 rte_pktmbuf_free(tx_q->m_table[ret]);
1032                                         } while (++ret < tx_q->len);
1033                                 }
1034
1035                                 tx_q->len = 0;
1036                         }
1037
1038                         prev_tsc = cur_tsc;
1039
1040                 }
1041
1042                 /*
1043                  * Inform the configuration core that we have exited the linked list and that no devices are
1044                  * in use if requested.
1045                  */
1046                 if (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL)
1047                         lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
1048
1049                 /*
1050                  * Process devices
1051                  */
1052                 dev_ll = lcore_ll->ll_root_used;
1053
1054                 while (dev_ll != NULL) {
1055                         /*get virtio device ID*/
1056                         dev = dev_ll->dev;
1057
1058                         if (unlikely(dev->remove)) {
1059                                 dev_ll = dev_ll->next;
1060                                 unlink_vmdq(dev);
1061                                 dev->ready = DEVICE_SAFE_REMOVE;
1062                                 continue;
1063                         }
1064                         if (likely(dev->ready == DEVICE_READY)) {
1065                                 /*Handle guest RX*/
1066                                 rx_count = rte_eth_rx_burst(ports[0],
1067                                         (uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
1068
1069                                 if (rx_count) {
1070                                         ret_count = virtio_dev_rx(dev, pkts_burst, rx_count);
1071                                         if (enable_stats) {
1072                                                 rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, rx_count);
1073                                                 rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret_count);
1074                                         }
1075                                         while (likely(rx_count)) {
1076                                                 rx_count--;
1077                                                 rte_pktmbuf_free_seg(pkts_burst[rx_count]);
1078                                         }
1079
1080                                 }
1081                         }
1082
1083                         if (likely(!dev->remove))
1084                                 /*Handle guest TX*/
1085                                 virtio_dev_tx(dev, mbuf_pool);
1086
1087                         /*move to the next device in the list*/
1088                         dev_ll = dev_ll->next;
1089                 }
1090         }
1091
1092         return 0;
1093 }
1094
1095 /*
1096  * Add an entry to a used linked list. A free entry must first be found in the free linked list
1097  * using get_data_ll_free_entry();
1098  */
1099 static void
1100 add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
1101 {
1102         struct virtio_net_data_ll *ll = *ll_root_addr;
1103
1104         /* Set next as NULL and use a compiler barrier to avoid reordering. */
1105         ll_dev->next = NULL;
1106         rte_compiler_barrier();
1107
1108         /* If ll == NULL then this is the first device. */
1109         if (ll) {
1110                 /* Increment to the tail of the linked list. */
1111                 while ((ll->next != NULL) )
1112                         ll = ll->next;
1113
1114                 ll->next = ll_dev;
1115         } else {
1116                 *ll_root_addr = ll_dev;
1117         }
1118 }
1119
1120 /*
1121  * Remove an entry from a used linked list. The entry must then be added to the free linked list
1122  * using put_data_ll_free_entry().
1123  */
1124 static void
1125 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)
1126 {
1127         struct virtio_net_data_ll *ll = *ll_root_addr;
1128
1129         if (ll_dev == ll)
1130                 *ll_root_addr = ll_dev->next;
1131         else
1132                 ll_dev_last->next = ll_dev->next;
1133 }
1134
1135 /*
1136  * Find and return an entry from the free linked list.
1137  */
1138 static struct virtio_net_data_ll *
1139 get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr)
1140 {
1141         struct virtio_net_data_ll *ll_free = *ll_root_addr;
1142         struct virtio_net_data_ll *ll_dev;
1143
1144         if (ll_free == NULL)
1145                 return NULL;
1146
1147         ll_dev = ll_free;
1148         *ll_root_addr = ll_free->next;
1149
1150         return ll_dev;
1151 }
1152
1153 /*
1154  * Place an entry back on to the free linked list.
1155  */
1156 static void
1157 put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
1158 {
1159         struct virtio_net_data_ll *ll_free = *ll_root_addr;
1160
1161         ll_dev->next = ll_free;
1162         *ll_root_addr = ll_dev;
1163 }
1164
1165 /*
1166  * Creates a linked list of a given size.
1167  */
1168 static struct virtio_net_data_ll *
1169 alloc_data_ll(uint32_t size)
1170 {
1171         struct virtio_net_data_ll *ll_new;
1172         uint32_t i;
1173
1174         /* Malloc and then chain the linked list. */
1175         ll_new = malloc(size * sizeof(struct virtio_net_data_ll));
1176         if (ll_new == NULL) {
1177                 RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for ll_new.\n");
1178                 return NULL;
1179         }
1180
1181         for (i = 0; i < size - 1; i++) {
1182                 ll_new[i].dev = NULL;
1183                 ll_new[i].next = &ll_new[i+1];
1184         }
1185         ll_new[i].next = NULL;
1186
1187         return ll_new;
1188 }
1189
1190 /*
1191  * Create the main linked list along with each individual cores linked list. A used and a free list
1192  * are created to manage entries.
1193  */
1194 static int
1195 init_data_ll (void)
1196 {
1197         int lcore;
1198
1199         RTE_LCORE_FOREACH_SLAVE(lcore) {
1200                 lcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info));
1201                 if (lcore_info[lcore].lcore_ll == NULL) {
1202                         RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for lcore_ll.\n");
1203                         return -1;
1204                 }
1205
1206                 lcore_info[lcore].lcore_ll->device_num = 0;
1207                 lcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
1208                 lcore_info[lcore].lcore_ll->ll_root_used = NULL;
1209                 if (num_devices % num_switching_cores)
1210                         lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1);
1211                 else
1212                         lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores);
1213         }
1214
1215         /* Allocate devices up to a maximum of MAX_DEVICES. */
1216         ll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES));
1217
1218         return 0;
1219 }
1220 /*
1221  * Remove a device from the specific data core linked list and from the main linked list. The
1222  * rx/tx thread must be set the flag to indicate that it is safe to remove the device.
1223  * used.
1224  */
1225 static void
1226 destroy_device (volatile struct virtio_net *dev)
1227 {
1228         struct virtio_net_data_ll *ll_lcore_dev_cur;
1229         struct virtio_net_data_ll *ll_main_dev_cur;
1230         struct virtio_net_data_ll *ll_lcore_dev_last = NULL;
1231         struct virtio_net_data_ll *ll_main_dev_last = NULL;
1232         int lcore;
1233
1234         dev->flags &= ~VIRTIO_DEV_RUNNING;
1235
1236         /*set the remove flag. */
1237         dev->remove = 1;
1238
1239         while(dev->ready != DEVICE_SAFE_REMOVE) {
1240                 rte_pause();
1241         }
1242
1243         /* Search for entry to be removed from lcore ll */
1244         ll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used;
1245         while (ll_lcore_dev_cur != NULL) {
1246                 if (ll_lcore_dev_cur->dev == dev) {
1247                         break;
1248                 } else {
1249                         ll_lcore_dev_last = ll_lcore_dev_cur;
1250                         ll_lcore_dev_cur = ll_lcore_dev_cur->next;
1251                 }
1252         }
1253
1254         /* Search for entry to be removed from main ll */
1255         ll_main_dev_cur = ll_root_used;
1256         ll_main_dev_last = NULL;
1257         while (ll_main_dev_cur != NULL) {
1258                 if (ll_main_dev_cur->dev == dev) {
1259                         break;
1260                 } else {
1261                         ll_main_dev_last = ll_main_dev_cur;
1262                         ll_main_dev_cur = ll_main_dev_cur->next;
1263                 }
1264         }
1265
1266         if (ll_lcore_dev_cur == NULL || ll_main_dev_cur == NULL) {
1267                 RTE_LOG(ERR, XENHOST, "%s: could find device in per_cpu list or main_list\n", __func__);
1268                 return;
1269         }
1270
1271         /* Remove entries from the lcore and main ll. */
1272         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);
1273         rm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last);
1274
1275         /* Set the dev_removal_flag on each lcore. */
1276         RTE_LCORE_FOREACH_SLAVE(lcore) {
1277                 lcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL;
1278         }
1279
1280         /*
1281          * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that
1282          * they can no longer access the device removed from the linked lists and that the devices
1283          * are no longer in use.
1284          */
1285         RTE_LCORE_FOREACH_SLAVE(lcore) {
1286                 while (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) {
1287                         rte_pause();
1288                 }
1289         }
1290
1291         /* Add the entries back to the lcore and main free ll.*/
1292         put_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur);
1293         put_data_ll_free_entry(&ll_root_free, ll_main_dev_cur);
1294
1295         /* Decrement number of device on the lcore. */
1296         lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--;
1297
1298         RTE_LOG(INFO, VHOST_DATA, "  #####(%"PRIu64") Device has been removed from data core\n", dev->device_fh);
1299 }
1300
1301 /*
1302  * A new device is added to a data core. First the device is added to the main linked list
1303  * and the allocated to a specific data core.
1304  */
1305 static int
1306 new_device (struct virtio_net *dev)
1307 {
1308         struct virtio_net_data_ll *ll_dev;
1309         int lcore, core_add = 0;
1310         uint32_t device_num_min = num_devices;
1311
1312         /* Add device to main ll */
1313         ll_dev = get_data_ll_free_entry(&ll_root_free);
1314         if (ll_dev == NULL) {
1315                 RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") No free entry found in linked list. Device limit "
1316                         "of %d devices per core has been reached\n",
1317                         dev->device_fh, num_devices);
1318                 return -1;
1319         }
1320         ll_dev->dev = dev;
1321         add_data_ll_entry(&ll_root_used, ll_dev);
1322
1323         /*reset ready flag*/
1324         dev->ready = DEVICE_NOT_READY;
1325         dev->remove = 0;
1326
1327         /* Find a suitable lcore to add the device. */
1328         RTE_LCORE_FOREACH_SLAVE(lcore) {
1329                 if (lcore_info[lcore].lcore_ll->device_num < device_num_min) {
1330                         device_num_min = lcore_info[lcore].lcore_ll->device_num;
1331                         core_add = lcore;
1332                 }
1333         }
1334         /* Add device to lcore ll */
1335         ll_dev->dev->coreid = core_add;
1336         ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);
1337         if (ll_dev == NULL) {
1338                 RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh);
1339                 destroy_device(dev);
1340                 return -1;
1341         }
1342         ll_dev->dev = dev;
1343         add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);
1344
1345         /* Initialize device stats */
1346         memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));
1347
1348         lcore_info[ll_dev->dev->coreid].lcore_ll->device_num++;
1349         dev->flags |= VIRTIO_DEV_RUNNING;
1350
1351         RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, dev->coreid);
1352
1353         link_vmdq(dev);
1354
1355         return 0;
1356 }
1357
1358 /*
1359  * These callback allow devices to be added to the data core when configuration
1360  * has been fully complete.
1361  */
1362 static const struct virtio_net_device_ops virtio_net_device_ops =
1363 {
1364         .new_device =  new_device,
1365         .destroy_device = destroy_device,
1366 };
1367
1368 /*
1369  * This is a thread will wake up after a period to print stats if the user has
1370  * enabled them.
1371  */
1372 static void
1373 print_stats(void)
1374 {
1375         struct virtio_net_data_ll *dev_ll;
1376         uint64_t tx_dropped, rx_dropped;
1377         uint64_t tx, tx_total, rx, rx_total;
1378         uint32_t device_fh;
1379         const char clr[] = { 27, '[', '2', 'J', '\0' };
1380         const char top_left[] = { 27, '[', '1', ';', '1', 'H','\0' };
1381
1382         while(1) {
1383                 sleep(enable_stats);
1384
1385                 /* Clear screen and move to top left */
1386                 printf("%s%s", clr, top_left);
1387
1388                 printf("\nDevice statistics ====================================");
1389
1390                 dev_ll = ll_root_used;
1391                 while (dev_ll != NULL) {
1392                         device_fh = (uint32_t)dev_ll->dev->device_fh;
1393                         tx_total = dev_statistics[device_fh].tx_total;
1394                         tx = dev_statistics[device_fh].tx;
1395                         tx_dropped = tx_total - tx;
1396                         rx_total = rte_atomic64_read(&dev_statistics[device_fh].rx_total);
1397                         rx = rte_atomic64_read(&dev_statistics[device_fh].rx);
1398                         rx_dropped = rx_total - rx;
1399
1400                         printf("\nStatistics for device %"PRIu32" ------------------------------"
1401                                         "\nTX total:            %"PRIu64""
1402                                         "\nTX dropped:          %"PRIu64""
1403                                         "\nTX successful:               %"PRIu64""
1404                                         "\nRX total:            %"PRIu64""
1405                                         "\nRX dropped:          %"PRIu64""
1406                                         "\nRX successful:               %"PRIu64"",
1407                                         device_fh,
1408                                         tx_total,
1409                                         tx_dropped,
1410                                         tx,
1411                                         rx_total,
1412                                         rx_dropped,
1413                                         rx);
1414
1415                         dev_ll = dev_ll->next;
1416                 }
1417                 printf("\n======================================================\n");
1418         }
1419 }
1420
1421
1422 int init_virtio_net(struct virtio_net_device_ops const * const ops);
1423
1424 /*
1425  * Main function, does initialisation and calls the per-lcore functions. The CUSE
1426  * device is also registered here to handle the IOCTLs.
1427  */
1428 int
1429 main(int argc, char *argv[])
1430 {
1431         struct rte_mempool *mbuf_pool;
1432         unsigned lcore_id, core_id = 0;
1433         unsigned nb_ports, valid_num_ports;
1434         int ret;
1435         uint8_t portid;
1436         static pthread_t tid;
1437         char thread_name[RTE_MAX_THREAD_NAME_LEN];
1438
1439         /* init EAL */
1440         ret = rte_eal_init(argc, argv);
1441         if (ret < 0)
1442                 rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
1443         argc -= ret;
1444         argv += ret;
1445
1446         /* parse app arguments */
1447         ret = us_vhost_parse_args(argc, argv);
1448         if (ret < 0)
1449                 rte_exit(EXIT_FAILURE, "Invalid argument\n");
1450
1451         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)
1452                 if (rte_lcore_is_enabled(lcore_id))
1453                         lcore_ids[core_id ++] = lcore_id;
1454
1455         if (rte_lcore_count() > RTE_MAX_LCORE)
1456                 rte_exit(EXIT_FAILURE,"Not enough cores\n");
1457
1458         /*set the number of swithcing cores available*/
1459         num_switching_cores = rte_lcore_count()-1;
1460
1461         /* Get the number of physical ports. */
1462         nb_ports = rte_eth_dev_count();
1463         if (nb_ports > RTE_MAX_ETHPORTS)
1464                 nb_ports = RTE_MAX_ETHPORTS;
1465
1466         /*
1467          * Update the global var NUM_PORTS and global array PORTS
1468          * and get value of var VALID_NUM_PORTS according to system ports number
1469          */
1470         valid_num_ports = check_ports_num(nb_ports);
1471
1472         if ((valid_num_ports ==  0) || (valid_num_ports > MAX_SUP_PORTS)) {
1473                 RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
1474                         "but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
1475                 return -1;
1476         }
1477
1478         /* Create the mbuf pool. */
1479         mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
1480                 NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
1481                 RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
1482         if (mbuf_pool == NULL)
1483                 rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
1484
1485         /* Set log level. */
1486         rte_set_log_level(LOG_LEVEL);
1487
1488         /* initialize all ports */
1489         for (portid = 0; portid < nb_ports; portid++) {
1490                 /* skip ports that are not enabled */
1491                 if ((enabled_port_mask & (1 << portid)) == 0) {
1492                         RTE_LOG(INFO, VHOST_PORT, "Skipping disabled port %d\n", portid);
1493                         continue;
1494                 }
1495                 if (port_init(portid, mbuf_pool) != 0)
1496                         rte_exit(EXIT_FAILURE, "Cannot initialize network ports\n");
1497         }
1498
1499         /* Initialise all linked lists. */
1500         if (init_data_ll() == -1)
1501                 rte_exit(EXIT_FAILURE, "Failed to initialize linked list\n");
1502
1503         /* Initialize device stats */
1504         memset(&dev_statistics, 0, sizeof(dev_statistics));
1505
1506         /* Enable stats if the user option is set. */
1507         if (enable_stats) {
1508                 ret = pthread_create(&tid, NULL, (void *)print_stats, NULL);
1509                 if (ret != 0)
1510                         rte_exit(EXIT_FAILURE,
1511                                 "Cannot create print-stats thread\n");
1512
1513                 /* Set thread_name for aid in debugging. */
1514                 snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-xen-stats");
1515                 ret = rte_thread_setname(tid, thread_name);
1516                 if (ret != 0)
1517                         RTE_LOG(ERR, VHOST_CONFIG,
1518                                 "Cannot set print-stats name\n");
1519         }
1520
1521         /* Launch all data cores. */
1522         RTE_LCORE_FOREACH_SLAVE(lcore_id) {
1523                 rte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id);
1524         }
1525
1526         init_virtio_xen(&virtio_net_device_ops);
1527
1528         virtio_monitor_loop();
1529         return 0;
1530 }