ovs-vsctl: Support identifying Flow_Sample_Collector_Set records by id.
[cascardo/ovs.git] / lib / netdev-dpdk.c
1 /*
2  * Copyright (c) 2014, 2015, 2016 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include <string.h>
20 #include <signal.h>
21 #include <stdlib.h>
22 #include <pthread.h>
23 #include <config.h>
24 #include <errno.h>
25 #include <sched.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <stdio.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <getopt.h>
33
34 #include "dirs.h"
35 #include "dp-packet.h"
36 #include "dpif-netdev.h"
37 #include "fatal-signal.h"
38 #include "netdev-dpdk.h"
39 #include "netdev-provider.h"
40 #include "netdev-vport.h"
41 #include "odp-util.h"
42 #include "openvswitch/dynamic-string.h"
43 #include "openvswitch/list.h"
44 #include "openvswitch/ofp-print.h"
45 #include "openvswitch/vlog.h"
46 #include "ovs-numa.h"
47 #include "ovs-thread.h"
48 #include "ovs-rcu.h"
49 #include "packets.h"
50 #include "shash.h"
51 #include "smap.h"
52 #include "sset.h"
53 #include "unaligned.h"
54 #include "timeval.h"
55 #include "unixctl.h"
56
57 #include "rte_config.h"
58 #include "rte_mbuf.h"
59 #include "rte_meter.h"
60 #include "rte_virtio_net.h"
61
62 VLOG_DEFINE_THIS_MODULE(dpdk);
63 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
64
65 #define DPDK_PORT_WATCHDOG_INTERVAL 5
66
67 #define OVS_CACHE_LINE_SIZE CACHE_LINE_SIZE
68 #define OVS_VPORT_DPDK "ovs_dpdk"
69
70 /*
71  * need to reserve tons of extra space in the mbufs so we can align the
72  * DMA addresses to 4KB.
73  * The minimum mbuf size is limited to avoid scatter behaviour and drop in
74  * performance for standard Ethernet MTU.
75  */
76 #define ETHER_HDR_MAX_LEN           (ETHER_HDR_LEN + ETHER_CRC_LEN + (2 * VLAN_HEADER_LEN))
77 #define MTU_TO_FRAME_LEN(mtu)       ((mtu) + ETHER_HDR_LEN + ETHER_CRC_LEN)
78 #define MTU_TO_MAX_FRAME_LEN(mtu)   ((mtu) + ETHER_HDR_MAX_LEN)
79 #define FRAME_LEN_TO_MTU(frame_len) ((frame_len)- ETHER_HDR_LEN - ETHER_CRC_LEN)
80 #define MBUF_SIZE(mtu)              ( MTU_TO_MAX_FRAME_LEN(mtu)   \
81                                     + sizeof(struct dp_packet)    \
82                                     + RTE_PKTMBUF_HEADROOM)
83 #define NETDEV_DPDK_MBUF_ALIGN      1024
84
85 /* Max and min number of packets in the mempool.  OVS tries to allocate a
86  * mempool with MAX_NB_MBUF: if this fails (because the system doesn't have
87  * enough hugepages) we keep halving the number until the allocation succeeds
88  * or we reach MIN_NB_MBUF */
89
90 #define MAX_NB_MBUF          (4096 * 64)
91 #define MIN_NB_MBUF          (4096 * 4)
92 #define MP_CACHE_SZ          RTE_MEMPOOL_CACHE_MAX_SIZE
93
94 /* MAX_NB_MBUF can be divided by 2 many times, until MIN_NB_MBUF */
95 BUILD_ASSERT_DECL(MAX_NB_MBUF % ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF) == 0);
96
97 /* The smallest possible NB_MBUF that we're going to try should be a multiple
98  * of MP_CACHE_SZ. This is advised by DPDK documentation. */
99 BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF/MIN_NB_MBUF))
100                   % MP_CACHE_SZ == 0);
101
102 /*
103  * DPDK XSTATS Counter names definition
104  */
105 #define XSTAT_RX_64_PACKETS              "rx_size_64_packets"
106 #define XSTAT_RX_65_TO_127_PACKETS       "rx_size_65_to_127_packets"
107 #define XSTAT_RX_128_TO_255_PACKETS      "rx_size_128_to_255_packets"
108 #define XSTAT_RX_256_TO_511_PACKETS      "rx_size_256_to_511_packets"
109 #define XSTAT_RX_512_TO_1023_PACKETS     "rx_size_512_to_1023_packets"
110 #define XSTAT_RX_1024_TO_1522_PACKETS    "rx_size_1024_to_1522_packets"
111 #define XSTAT_RX_1523_TO_MAX_PACKETS     "rx_size_1523_to_max_packets"
112
113 #define XSTAT_TX_64_PACKETS              "tx_size_64_packets"
114 #define XSTAT_TX_65_TO_127_PACKETS       "tx_size_65_to_127_packets"
115 #define XSTAT_TX_128_TO_255_PACKETS      "tx_size_128_to_255_packets"
116 #define XSTAT_TX_256_TO_511_PACKETS      "tx_size_256_to_511_packets"
117 #define XSTAT_TX_512_TO_1023_PACKETS     "tx_size_512_to_1023_packets"
118 #define XSTAT_TX_1024_TO_1522_PACKETS    "tx_size_1024_to_1522_packets"
119 #define XSTAT_TX_1523_TO_MAX_PACKETS     "tx_size_1523_to_max_packets"
120
121 #define XSTAT_TX_MULTICAST_PACKETS       "tx_multicast_packets"
122 #define XSTAT_RX_BROADCAST_PACKETS       "rx_broadcast_packets"
123 #define XSTAT_TX_BROADCAST_PACKETS       "tx_broadcast_packets"
124 #define XSTAT_RX_UNDERSIZED_ERRORS       "rx_undersized_errors"
125 #define XSTAT_RX_OVERSIZE_ERRORS         "rx_oversize_errors"
126 #define XSTAT_RX_FRAGMENTED_ERRORS       "rx_fragmented_errors"
127 #define XSTAT_RX_JABBER_ERRORS           "rx_jabber_errors"
128
129 #define SOCKET0              0
130
131 #define NIC_PORT_RX_Q_SIZE 2048  /* Size of Physical NIC RX Queue, Max (n+32<=4096)*/
132 #define NIC_PORT_TX_Q_SIZE 2048  /* Size of Physical NIC TX Queue, Max (n+32<=4096)*/
133
134 #define OVS_VHOST_MAX_QUEUE_NUM 1024  /* Maximum number of vHost TX queues. */
135 #define OVS_VHOST_QUEUE_MAP_UNKNOWN (-1) /* Mapping not initialized. */
136 #define OVS_VHOST_QUEUE_DISABLED    (-2) /* Queue was disabled by guest and not
137                                           * yet mapped to another queue. */
138
139 #ifdef VHOST_CUSE
140 static char *cuse_dev_name = NULL;    /* Character device cuse_dev_name. */
141 #endif
142 static char *vhost_sock_dir = NULL;   /* Location of vhost-user sockets */
143
144 /*
145  * Maximum amount of time in micro seconds to try and enqueue to vhost.
146  */
147 #define VHOST_ENQ_RETRY_USECS 100
148
149 static const struct rte_eth_conf port_conf = {
150     .rxmode = {
151         .mq_mode = ETH_MQ_RX_RSS,
152         .split_hdr_size = 0,
153         .header_split   = 0, /* Header Split disabled */
154         .hw_ip_checksum = 0, /* IP checksum offload disabled */
155         .hw_vlan_filter = 0, /* VLAN filtering disabled */
156         .jumbo_frame    = 0, /* Jumbo Frame Support disabled */
157         .hw_strip_crc   = 0,
158     },
159     .rx_adv_conf = {
160         .rss_conf = {
161             .rss_key = NULL,
162             .rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP,
163         },
164     },
165     .txmode = {
166         .mq_mode = ETH_MQ_TX_NONE,
167     },
168 };
169
170 enum { MAX_TX_QUEUE_LEN = 384 };
171 enum { DPDK_RING_SIZE = 256 };
172 BUILD_ASSERT_DECL(IS_POW2(DPDK_RING_SIZE));
173 enum { DRAIN_TSC = 200000ULL };
174
175 enum dpdk_dev_type {
176     DPDK_DEV_ETH = 0,
177     DPDK_DEV_VHOST = 1,
178 };
179
180 static int rte_eal_init_ret = ENODEV;
181
182 static struct ovs_mutex dpdk_mutex = OVS_MUTEX_INITIALIZER;
183
184 /* Quality of Service */
185
186 /* An instance of a QoS configuration.  Always associated with a particular
187  * network device.
188  *
189  * Each QoS implementation subclasses this with whatever additional data it
190  * needs.
191  */
192 struct qos_conf {
193     const struct dpdk_qos_ops *ops;
194 };
195
196 /* A particular implementation of dpdk QoS operations.
197  *
198  * The functions below return 0 if successful or a positive errno value on
199  * failure, except where otherwise noted. All of them must be provided, except
200  * where otherwise noted.
201  */
202 struct dpdk_qos_ops {
203
204     /* Name of the QoS type */
205     const char *qos_name;
206
207     /* Called to construct the QoS implementation on 'netdev'. The
208      * implementation should make the appropriate calls to configure QoS
209      * according to 'details'. The implementation may assume that any current
210      * QoS configuration already installed should be destroyed before
211      * constructing the new configuration.
212      *
213      * The contents of 'details' should be documented as valid for 'ovs_name'
214      * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
215      * (which is built as ovs-vswitchd.conf.db(8)).
216      *
217      * This function must return 0 if and only if it sets 'netdev->qos_conf'
218      * to an initialized 'struct qos_conf'.
219      *
220      * For all QoS implementations it should always be non-null.
221      */
222     int (*qos_construct)(struct netdev *netdev, const struct smap *details);
223
224     /* Destroys the data structures allocated by the implementation as part of
225      * 'qos_conf.
226      *
227      * For all QoS implementations it should always be non-null.
228      */
229     void (*qos_destruct)(struct netdev *netdev, struct qos_conf *conf);
230
231     /* Retrieves details of 'netdev->qos_conf' configuration into 'details'.
232      *
233      * The contents of 'details' should be documented as valid for 'ovs_name'
234      * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
235      * (which is built as ovs-vswitchd.conf.db(8)).
236      */
237     int (*qos_get)(const struct netdev *netdev, struct smap *details);
238
239     /* Reconfigures 'netdev->qos_conf' according to 'details', performing any
240      * required calls to complete the reconfiguration.
241      *
242      * The contents of 'details' should be documented as valid for 'ovs_name'
243      * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
244      * (which is built as ovs-vswitchd.conf.db(8)).
245      *
246      * This function may be null if 'qos_conf' is not configurable.
247      */
248     int (*qos_set)(struct netdev *netdev, const struct smap *details);
249
250     /* Modify an array of rte_mbufs. The modification is specific to
251      * each qos implementation.
252      *
253      * The function should take and array of mbufs and an int representing
254      * the current number of mbufs present in the array.
255      *
256      * After the function has performed a qos modification to the array of
257      * mbufs it returns an int representing the number of mbufs now present in
258      * the array. This value is can then be passed to the port send function
259      * along with the modified array for transmission.
260      *
261      * For all QoS implementations it should always be non-null.
262      */
263     int (*qos_run)(struct netdev *netdev, struct rte_mbuf **pkts,
264                            int pkt_cnt);
265 };
266
267 /* dpdk_qos_ops for each type of user space QoS implementation */
268 static const struct dpdk_qos_ops egress_policer_ops;
269
270 /*
271  * Array of dpdk_qos_ops, contains pointer to all supported QoS
272  * operations.
273  */
274 static const struct dpdk_qos_ops *const qos_confs[] = {
275     &egress_policer_ops,
276     NULL
277 };
278
279 /* Contains all 'struct dpdk_dev's. */
280 static struct ovs_list dpdk_list OVS_GUARDED_BY(dpdk_mutex)
281     = OVS_LIST_INITIALIZER(&dpdk_list);
282
283 static struct ovs_list dpdk_mp_list OVS_GUARDED_BY(dpdk_mutex)
284     = OVS_LIST_INITIALIZER(&dpdk_mp_list);
285
286 /* This mutex must be used by non pmd threads when allocating or freeing
287  * mbufs through mempools. Since dpdk_queue_pkts() and dpdk_queue_flush() may
288  * use mempools, a non pmd thread should hold this mutex while calling them */
289 static struct ovs_mutex nonpmd_mempool_mutex = OVS_MUTEX_INITIALIZER;
290
291 struct dpdk_mp {
292     struct rte_mempool *mp;
293     int mtu;
294     int socket_id;
295     int refcount;
296     struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex);
297 };
298
299 /* There should be one 'struct dpdk_tx_queue' created for
300  * each cpu core. */
301 struct dpdk_tx_queue {
302     bool flush_tx;                 /* Set to true to flush queue everytime */
303                                    /* pkts are queued. */
304     int count;
305     rte_spinlock_t tx_lock;        /* Protects the members and the NIC queue
306                                     * from concurrent access.  It is used only
307                                     * if the queue is shared among different
308                                     * pmd threads (see 'txq_needs_locking'). */
309     int map;                       /* Mapping of configured vhost-user queues
310                                     * to enabled by guest. */
311     uint64_t tsc;
312     struct rte_mbuf *burst_pkts[MAX_TX_QUEUE_LEN];
313 };
314
315 /* dpdk has no way to remove dpdk ring ethernet devices
316    so we have to keep them around once they've been created
317 */
318
319 static struct ovs_list dpdk_ring_list OVS_GUARDED_BY(dpdk_mutex)
320     = OVS_LIST_INITIALIZER(&dpdk_ring_list);
321
322 struct dpdk_ring {
323     /* For the client rings */
324     struct rte_ring *cring_tx;
325     struct rte_ring *cring_rx;
326     unsigned int user_port_id; /* User given port no, parsed from port name */
327     int eth_port_id; /* ethernet device port id */
328     struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex);
329 };
330
331 struct ingress_policer {
332     struct rte_meter_srtcm_params app_srtcm_params;
333     struct rte_meter_srtcm in_policer;
334     rte_spinlock_t policer_lock;
335 };
336
337 struct netdev_dpdk {
338     struct netdev up;
339     int port_id;
340     int max_packet_len;
341     enum dpdk_dev_type type;
342
343     struct dpdk_tx_queue *tx_q;
344
345     struct ovs_mutex mutex OVS_ACQ_AFTER(dpdk_mutex);
346
347     struct dpdk_mp *dpdk_mp;
348     int mtu;
349     int socket_id;
350     int buf_size;
351     struct netdev_stats stats;
352     /* Protects stats */
353     rte_spinlock_t stats_lock;
354
355     struct eth_addr hwaddr;
356     enum netdev_flags flags;
357
358     struct rte_eth_link link;
359     int link_reset_cnt;
360
361     /* The user might request more txqs than the NIC has.  We remap those
362      * ('up.n_txq') on these ('real_n_txq').
363      * If the numbers match, 'txq_needs_locking' is false, otherwise it is
364      * true and we will take a spinlock on transmission */
365     int real_n_txq;
366     int real_n_rxq;
367     bool txq_needs_locking;
368
369     /* virtio-net structure for vhost device */
370     OVSRCU_TYPE(struct virtio_net *) virtio_dev;
371
372     /* Identifier used to distinguish vhost devices from each other */
373     char vhost_id[PATH_MAX];
374
375     /* In dpdk_list. */
376     struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex);
377
378     /* QoS configuration and lock for the device */
379     struct qos_conf *qos_conf;
380     rte_spinlock_t qos_lock;
381
382     /* The following properties cannot be changed when a device is running,
383      * so we remember the request and update them next time
384      * netdev_dpdk*_reconfigure() is called */
385     int requested_n_txq;
386     int requested_n_rxq;
387
388     /* Ingress Policer */
389     OVSRCU_TYPE(struct ingress_policer *) ingress_policer;
390     uint32_t policer_rate;
391     uint32_t policer_burst;
392 };
393
394 struct netdev_rxq_dpdk {
395     struct netdev_rxq up;
396     int port_id;
397 };
398
399 static bool dpdk_thread_is_pmd(void);
400
401 static int netdev_dpdk_construct(struct netdev *);
402
403 struct virtio_net * netdev_dpdk_get_virtio(const struct netdev_dpdk *dev);
404
405 struct ingress_policer *
406 netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev);
407
408 static bool
409 is_dpdk_class(const struct netdev_class *class)
410 {
411     return class->construct == netdev_dpdk_construct;
412 }
413
414 /* DPDK NIC drivers allocate RX buffers at a particular granularity, typically
415  * aligned at 1k or less. If a declared mbuf size is not a multiple of this
416  * value, insufficient buffers are allocated to accomodate the packet in its
417  * entirety. Furthermore, certain drivers need to ensure that there is also
418  * sufficient space in the Rx buffer to accommodate two VLAN tags (for QinQ
419  * frames). If the RX buffer is too small, then the driver enables scatter RX
420  * behaviour, which reduces performance. To prevent this, use a buffer size that
421  * is closest to 'mtu', but which satisfies the aforementioned criteria.
422  */
423 static uint32_t
424 dpdk_buf_size(int mtu)
425 {
426     return ROUND_UP((MTU_TO_MAX_FRAME_LEN(mtu) + RTE_PKTMBUF_HEADROOM),
427                      NETDEV_DPDK_MBUF_ALIGN);
428 }
429
430 /* XXX: use dpdk malloc for entire OVS. in fact huge page should be used
431  * for all other segments data, bss and text. */
432
433 static void *
434 dpdk_rte_mzalloc(size_t sz)
435 {
436     void *ptr;
437
438     ptr = rte_zmalloc(OVS_VPORT_DPDK, sz, OVS_CACHE_LINE_SIZE);
439     if (ptr == NULL) {
440         out_of_memory();
441     }
442     return ptr;
443 }
444
445 /* XXX this function should be called only by pmd threads (or by non pmd
446  * threads holding the nonpmd_mempool_mutex) */
447 void
448 free_dpdk_buf(struct dp_packet *p)
449 {
450     struct rte_mbuf *pkt = (struct rte_mbuf *) p;
451
452     rte_pktmbuf_free(pkt);
453 }
454
455 static void
456 ovs_rte_pktmbuf_init(struct rte_mempool *mp,
457                      void *opaque_arg OVS_UNUSED,
458                      void *_m,
459                      unsigned i OVS_UNUSED)
460 {
461     struct rte_mbuf *m = _m;
462
463     rte_pktmbuf_init(mp, opaque_arg, _m, i);
464
465     dp_packet_init_dpdk((struct dp_packet *) m, m->buf_len);
466 }
467
468 static struct dpdk_mp *
469 dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
470 {
471     struct dpdk_mp *dmp = NULL;
472     char mp_name[RTE_MEMPOOL_NAMESIZE];
473     unsigned mp_size;
474     struct rte_pktmbuf_pool_private mbp_priv;
475
476     LIST_FOR_EACH (dmp, list_node, &dpdk_mp_list) {
477         if (dmp->socket_id == socket_id && dmp->mtu == mtu) {
478             dmp->refcount++;
479             return dmp;
480         }
481     }
482
483     dmp = dpdk_rte_mzalloc(sizeof *dmp);
484     dmp->socket_id = socket_id;
485     dmp->mtu = mtu;
486     dmp->refcount = 1;
487     mbp_priv.mbuf_data_room_size = MBUF_SIZE(mtu) - sizeof(struct dp_packet);
488     mbp_priv.mbuf_priv_size = sizeof (struct dp_packet) - sizeof (struct rte_mbuf);
489
490     mp_size = MAX_NB_MBUF;
491     do {
492         if (snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_mp_%d_%d_%u",
493                      dmp->mtu, dmp->socket_id, mp_size) < 0) {
494             return NULL;
495         }
496
497         dmp->mp = rte_mempool_create(mp_name, mp_size, MBUF_SIZE(mtu),
498                                      MP_CACHE_SZ,
499                                      sizeof(struct rte_pktmbuf_pool_private),
500                                      rte_pktmbuf_pool_init, &mbp_priv,
501                                      ovs_rte_pktmbuf_init, NULL,
502                                      socket_id, 0);
503     } while (!dmp->mp && rte_errno == ENOMEM && (mp_size /= 2) >= MIN_NB_MBUF);
504
505     if (dmp->mp == NULL) {
506         return NULL;
507     } else {
508         VLOG_DBG("Allocated \"%s\" mempool with %u mbufs", mp_name, mp_size );
509     }
510
511     ovs_list_push_back(&dpdk_mp_list, &dmp->list_node);
512     return dmp;
513 }
514
515 static void
516 dpdk_mp_put(struct dpdk_mp *dmp)
517 {
518
519     if (!dmp) {
520         return;
521     }
522
523     dmp->refcount--;
524     ovs_assert(dmp->refcount >= 0);
525
526 #if 0
527     /* I could not find any API to destroy mp. */
528     if (dmp->refcount == 0) {
529         list_delete(dmp->list_node);
530         /* destroy mp-pool. */
531     }
532 #endif
533 }
534
535 static void
536 check_link_status(struct netdev_dpdk *dev)
537 {
538     struct rte_eth_link link;
539
540     rte_eth_link_get_nowait(dev->port_id, &link);
541
542     if (dev->link.link_status != link.link_status) {
543         netdev_change_seq_changed(&dev->up);
544
545         dev->link_reset_cnt++;
546         dev->link = link;
547         if (dev->link.link_status) {
548             VLOG_DBG_RL(&rl, "Port %d Link Up - speed %u Mbps - %s",
549                         dev->port_id, (unsigned)dev->link.link_speed,
550                         (dev->link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
551                          ("full-duplex") : ("half-duplex"));
552         } else {
553             VLOG_DBG_RL(&rl, "Port %d Link Down", dev->port_id);
554         }
555     }
556 }
557
558 static void *
559 dpdk_watchdog(void *dummy OVS_UNUSED)
560 {
561     struct netdev_dpdk *dev;
562
563     pthread_detach(pthread_self());
564
565     for (;;) {
566         ovs_mutex_lock(&dpdk_mutex);
567         LIST_FOR_EACH (dev, list_node, &dpdk_list) {
568             ovs_mutex_lock(&dev->mutex);
569             check_link_status(dev);
570             ovs_mutex_unlock(&dev->mutex);
571         }
572         ovs_mutex_unlock(&dpdk_mutex);
573         xsleep(DPDK_PORT_WATCHDOG_INTERVAL);
574     }
575
576     return NULL;
577 }
578
579 static int
580 dpdk_eth_dev_queue_setup(struct netdev_dpdk *dev, int n_rxq, int n_txq)
581 {
582     int diag = 0;
583     int i;
584
585     /* A device may report more queues than it makes available (this has
586      * been observed for Intel xl710, which reserves some of them for
587      * SRIOV):  rte_eth_*_queue_setup will fail if a queue is not
588      * available.  When this happens we can retry the configuration
589      * and request less queues */
590     while (n_rxq && n_txq) {
591         if (diag) {
592             VLOG_INFO("Retrying setup with (rxq:%d txq:%d)", n_rxq, n_txq);
593         }
594
595         diag = rte_eth_dev_configure(dev->port_id, n_rxq, n_txq, &port_conf);
596         if (diag) {
597             break;
598         }
599
600         for (i = 0; i < n_txq; i++) {
601             diag = rte_eth_tx_queue_setup(dev->port_id, i, NIC_PORT_TX_Q_SIZE,
602                                           dev->socket_id, NULL);
603             if (diag) {
604                 VLOG_INFO("Interface %s txq(%d) setup error: %s",
605                           dev->up.name, i, rte_strerror(-diag));
606                 break;
607             }
608         }
609
610         if (i != n_txq) {
611             /* Retry with less tx queues */
612             n_txq = i;
613             continue;
614         }
615
616         for (i = 0; i < n_rxq; i++) {
617             diag = rte_eth_rx_queue_setup(dev->port_id, i, NIC_PORT_RX_Q_SIZE,
618                                           dev->socket_id, NULL,
619                                           dev->dpdk_mp->mp);
620             if (diag) {
621                 VLOG_INFO("Interface %s rxq(%d) setup error: %s",
622                           dev->up.name, i, rte_strerror(-diag));
623                 break;
624             }
625         }
626
627         if (i != n_rxq) {
628             /* Retry with less rx queues */
629             n_rxq = i;
630             continue;
631         }
632
633         dev->up.n_rxq = n_rxq;
634         dev->real_n_txq = n_txq;
635
636         return 0;
637     }
638
639     return diag;
640 }
641
642
643 static int
644 dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex)
645 {
646     struct rte_pktmbuf_pool_private *mbp_priv;
647     struct rte_eth_dev_info info;
648     struct ether_addr eth_addr;
649     int diag;
650     int n_rxq, n_txq;
651
652     if (dev->port_id < 0 || dev->port_id >= rte_eth_dev_count()) {
653         return ENODEV;
654     }
655
656     rte_eth_dev_info_get(dev->port_id, &info);
657
658     n_rxq = MIN(info.max_rx_queues, dev->up.n_rxq);
659     n_txq = MIN(info.max_tx_queues, dev->up.n_txq);
660
661     diag = dpdk_eth_dev_queue_setup(dev, n_rxq, n_txq);
662     if (diag) {
663         VLOG_ERR("Interface %s(rxq:%d txq:%d) configure error: %s",
664                  dev->up.name, n_rxq, n_txq, rte_strerror(-diag));
665         return -diag;
666     }
667
668     diag = rte_eth_dev_start(dev->port_id);
669     if (diag) {
670         VLOG_ERR("Interface %s start error: %s", dev->up.name,
671                  rte_strerror(-diag));
672         return -diag;
673     }
674
675     rte_eth_promiscuous_enable(dev->port_id);
676     rte_eth_allmulticast_enable(dev->port_id);
677
678     memset(&eth_addr, 0x0, sizeof(eth_addr));
679     rte_eth_macaddr_get(dev->port_id, &eth_addr);
680     VLOG_INFO_RL(&rl, "Port %d: "ETH_ADDR_FMT"",
681                     dev->port_id, ETH_ADDR_BYTES_ARGS(eth_addr.addr_bytes));
682
683     memcpy(dev->hwaddr.ea, eth_addr.addr_bytes, ETH_ADDR_LEN);
684     rte_eth_link_get_nowait(dev->port_id, &dev->link);
685
686     mbp_priv = rte_mempool_get_priv(dev->dpdk_mp->mp);
687     dev->buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
688
689     dev->flags = NETDEV_UP | NETDEV_PROMISC;
690     return 0;
691 }
692
693 static struct netdev_dpdk *
694 netdev_dpdk_cast(const struct netdev *netdev)
695 {
696     return CONTAINER_OF(netdev, struct netdev_dpdk, up);
697 }
698
699 static struct netdev *
700 netdev_dpdk_alloc(void)
701 {
702     struct netdev_dpdk *dev;
703
704     if (!rte_eal_init_ret) { /* Only after successful initialization */
705         dev = dpdk_rte_mzalloc(sizeof *dev);
706         if (dev) {
707             return &dev->up;
708         }
709     }
710     return NULL;
711 }
712
713 static void
714 netdev_dpdk_alloc_txq(struct netdev_dpdk *dev, unsigned int n_txqs)
715 {
716     unsigned i;
717
718     dev->tx_q = dpdk_rte_mzalloc(n_txqs * sizeof *dev->tx_q);
719     for (i = 0; i < n_txqs; i++) {
720         int numa_id = ovs_numa_get_numa_id(i);
721
722         if (!dev->txq_needs_locking) {
723             /* Each index is considered as a cpu core id, since there should
724              * be one tx queue for each cpu core.  If the corresponding core
725              * is not on the same numa node as 'dev', flags the
726              * 'flush_tx'. */
727             dev->tx_q[i].flush_tx = dev->socket_id == numa_id;
728         } else {
729             /* Queues are shared among CPUs. Always flush */
730             dev->tx_q[i].flush_tx = true;
731         }
732
733         /* Initialize map for vhost devices. */
734         dev->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN;
735         rte_spinlock_init(&dev->tx_q[i].tx_lock);
736     }
737 }
738
739 static int
740 netdev_dpdk_init(struct netdev *netdev, unsigned int port_no,
741                  enum dpdk_dev_type type)
742     OVS_REQUIRES(dpdk_mutex)
743 {
744     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
745     int sid;
746     int err = 0;
747     uint32_t buf_size;
748
749     ovs_mutex_init(&dev->mutex);
750     ovs_mutex_lock(&dev->mutex);
751
752     rte_spinlock_init(&dev->stats_lock);
753
754     /* If the 'sid' is negative, it means that the kernel fails
755      * to obtain the pci numa info.  In that situation, always
756      * use 'SOCKET0'. */
757     if (type == DPDK_DEV_ETH) {
758         sid = rte_eth_dev_socket_id(port_no);
759     } else {
760         sid = rte_lcore_to_socket_id(rte_get_master_lcore());
761     }
762
763     dev->socket_id = sid < 0 ? SOCKET0 : sid;
764     dev->port_id = port_no;
765     dev->type = type;
766     dev->flags = 0;
767     dev->mtu = ETHER_MTU;
768     dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu);
769
770     buf_size = dpdk_buf_size(dev->mtu);
771     dev->dpdk_mp = dpdk_mp_get(dev->socket_id, FRAME_LEN_TO_MTU(buf_size));
772     if (!dev->dpdk_mp) {
773         err = ENOMEM;
774         goto unlock;
775     }
776
777     /* Initialise QoS configuration to NULL and qos lock to unlocked */
778     dev->qos_conf = NULL;
779     rte_spinlock_init(&dev->qos_lock);
780
781     /* Initialise rcu pointer for ingress policer to NULL */
782     ovsrcu_init(&dev->ingress_policer, NULL);
783     dev->policer_rate = 0;
784     dev->policer_burst = 0;
785
786     netdev->n_txq = NR_QUEUE;
787     netdev->n_rxq = NR_QUEUE;
788     dev->requested_n_rxq = NR_QUEUE;
789     dev->requested_n_txq = NR_QUEUE;
790     dev->real_n_txq = NR_QUEUE;
791
792     if (type == DPDK_DEV_ETH) {
793         netdev_dpdk_alloc_txq(dev, NR_QUEUE);
794         err = dpdk_eth_dev_init(dev);
795         if (err) {
796             goto unlock;
797         }
798     } else {
799         netdev_dpdk_alloc_txq(dev, OVS_VHOST_MAX_QUEUE_NUM);
800         /* Enable DPDK_DEV_VHOST device and set promiscuous mode flag. */
801         dev->flags = NETDEV_UP | NETDEV_PROMISC;
802     }
803
804     ovs_list_push_back(&dpdk_list, &dev->list_node);
805
806 unlock:
807     if (err) {
808         rte_free(dev->tx_q);
809     }
810     ovs_mutex_unlock(&dev->mutex);
811     return err;
812 }
813
814 /* dev_name must be the prefix followed by a positive decimal number.
815  * (no leading + or - signs are allowed) */
816 static int
817 dpdk_dev_parse_name(const char dev_name[], const char prefix[],
818                     unsigned int *port_no)
819 {
820     const char *cport;
821
822     if (strncmp(dev_name, prefix, strlen(prefix))) {
823         return ENODEV;
824     }
825
826     cport = dev_name + strlen(prefix);
827
828     if (str_to_uint(cport, 10, port_no)) {
829         return 0;
830     } else {
831         return ENODEV;
832     }
833 }
834
835 static int
836 vhost_construct_helper(struct netdev *netdev) OVS_REQUIRES(dpdk_mutex)
837 {
838     if (rte_eal_init_ret) {
839         return rte_eal_init_ret;
840     }
841
842     return netdev_dpdk_init(netdev, -1, DPDK_DEV_VHOST);
843 }
844
845 static int
846 netdev_dpdk_vhost_cuse_construct(struct netdev *netdev)
847 {
848     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
849     int err;
850
851     if (rte_eal_init_ret) {
852         return rte_eal_init_ret;
853     }
854
855     ovs_mutex_lock(&dpdk_mutex);
856     strncpy(dev->vhost_id, netdev->name, sizeof(dev->vhost_id));
857     err = vhost_construct_helper(netdev);
858     ovs_mutex_unlock(&dpdk_mutex);
859     return err;
860 }
861
862 static int
863 netdev_dpdk_vhost_user_construct(struct netdev *netdev)
864 {
865     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
866     const char *name = netdev->name;
867     int err;
868
869     /* 'name' is appended to 'vhost_sock_dir' and used to create a socket in
870      * the file system. '/' or '\' would traverse directories, so they're not
871      * acceptable in 'name'. */
872     if (strchr(name, '/') || strchr(name, '\\')) {
873         VLOG_ERR("\"%s\" is not a valid name for a vhost-user port. "
874                  "A valid name must not include '/' or '\\'",
875                  name);
876         return EINVAL;
877     }
878
879     if (rte_eal_init_ret) {
880         return rte_eal_init_ret;
881     }
882
883     ovs_mutex_lock(&dpdk_mutex);
884     /* Take the name of the vhost-user port and append it to the location where
885      * the socket is to be created, then register the socket.
886      */
887     snprintf(dev->vhost_id, sizeof(dev->vhost_id), "%s/%s",
888              vhost_sock_dir, name);
889
890     err = rte_vhost_driver_register(dev->vhost_id);
891     if (err) {
892         VLOG_ERR("vhost-user socket device setup failure for socket %s\n",
893                  dev->vhost_id);
894     } else {
895         fatal_signal_add_file_to_unlink(dev->vhost_id);
896         VLOG_INFO("Socket %s created for vhost-user port %s\n",
897                   dev->vhost_id, name);
898         err = vhost_construct_helper(netdev);
899     }
900
901     ovs_mutex_unlock(&dpdk_mutex);
902     return err;
903 }
904
905 static int
906 netdev_dpdk_construct(struct netdev *netdev)
907 {
908     unsigned int port_no;
909     int err;
910
911     if (rte_eal_init_ret) {
912         return rte_eal_init_ret;
913     }
914
915     /* Names always start with "dpdk" */
916     err = dpdk_dev_parse_name(netdev->name, "dpdk", &port_no);
917     if (err) {
918         return err;
919     }
920
921     ovs_mutex_lock(&dpdk_mutex);
922     err = netdev_dpdk_init(netdev, port_no, DPDK_DEV_ETH);
923     ovs_mutex_unlock(&dpdk_mutex);
924     return err;
925 }
926
927 static void
928 netdev_dpdk_destruct(struct netdev *netdev)
929 {
930     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
931
932     ovs_mutex_lock(&dev->mutex);
933     rte_eth_dev_stop(dev->port_id);
934     free(ovsrcu_get_protected(struct ingress_policer *,
935                               &dev->ingress_policer));
936     ovs_mutex_unlock(&dev->mutex);
937
938     ovs_mutex_lock(&dpdk_mutex);
939     rte_free(dev->tx_q);
940     ovs_list_remove(&dev->list_node);
941     dpdk_mp_put(dev->dpdk_mp);
942     ovs_mutex_unlock(&dpdk_mutex);
943 }
944
945 static void
946 netdev_dpdk_vhost_destruct(struct netdev *netdev)
947 {
948     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
949
950     /* Guest becomes an orphan if still attached. */
951     if (netdev_dpdk_get_virtio(dev) != NULL) {
952         VLOG_ERR("Removing port '%s' while vhost device still attached.",
953                  netdev->name);
954         VLOG_ERR("To restore connectivity after re-adding of port, VM on socket"
955                  " '%s' must be restarted.",
956                  dev->vhost_id);
957     }
958
959     if (rte_vhost_driver_unregister(dev->vhost_id)) {
960         VLOG_ERR("Unable to remove vhost-user socket %s", dev->vhost_id);
961     } else {
962         fatal_signal_remove_file_to_unlink(dev->vhost_id);
963     }
964
965     ovs_mutex_lock(&dev->mutex);
966     free(ovsrcu_get_protected(struct ingress_policer *,
967                               &dev->ingress_policer));
968     ovs_mutex_unlock(&dev->mutex);
969
970     ovs_mutex_lock(&dpdk_mutex);
971     rte_free(dev->tx_q);
972     ovs_list_remove(&dev->list_node);
973     dpdk_mp_put(dev->dpdk_mp);
974     ovs_mutex_unlock(&dpdk_mutex);
975 }
976
977 static void
978 netdev_dpdk_dealloc(struct netdev *netdev)
979 {
980     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
981
982     rte_free(dev);
983 }
984
985 static int
986 netdev_dpdk_get_config(const struct netdev *netdev, struct smap *args)
987 {
988     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
989
990     ovs_mutex_lock(&dev->mutex);
991
992     smap_add_format(args, "requested_rx_queues", "%d", dev->requested_n_rxq);
993     smap_add_format(args, "configured_rx_queues", "%d", netdev->n_rxq);
994     smap_add_format(args, "requested_tx_queues", "%d", netdev->n_txq);
995     smap_add_format(args, "configured_tx_queues", "%d", dev->real_n_txq);
996     ovs_mutex_unlock(&dev->mutex);
997
998     return 0;
999 }
1000
1001 static int
1002 netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args)
1003 {
1004     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1005     int new_n_rxq;
1006
1007     ovs_mutex_lock(&dev->mutex);
1008     new_n_rxq = MAX(smap_get_int(args, "n_rxq", dev->requested_n_rxq), 1);
1009     if (new_n_rxq != dev->requested_n_rxq) {
1010         dev->requested_n_rxq = new_n_rxq;
1011         netdev_request_reconfigure(netdev);
1012     }
1013     ovs_mutex_unlock(&dev->mutex);
1014
1015     return 0;
1016 }
1017
1018 static int
1019 netdev_dpdk_get_numa_id(const struct netdev *netdev)
1020 {
1021     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1022
1023     return dev->socket_id;
1024 }
1025
1026 /* Sets the number of tx queues for the dpdk interface. */
1027 static int
1028 netdev_dpdk_set_tx_multiq(struct netdev *netdev, unsigned int n_txq)
1029 {
1030     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1031
1032     ovs_mutex_lock(&dev->mutex);
1033
1034     if (dev->requested_n_txq == n_txq) {
1035         goto out;
1036     }
1037
1038     dev->requested_n_txq = n_txq;
1039     netdev_request_reconfigure(netdev);
1040
1041 out:
1042     ovs_mutex_unlock(&dev->mutex);
1043     return 0;
1044 }
1045
1046 static struct netdev_rxq *
1047 netdev_dpdk_rxq_alloc(void)
1048 {
1049     struct netdev_rxq_dpdk *rx = dpdk_rte_mzalloc(sizeof *rx);
1050
1051     return &rx->up;
1052 }
1053
1054 static struct netdev_rxq_dpdk *
1055 netdev_rxq_dpdk_cast(const struct netdev_rxq *rxq)
1056 {
1057     return CONTAINER_OF(rxq, struct netdev_rxq_dpdk, up);
1058 }
1059
1060 static int
1061 netdev_dpdk_rxq_construct(struct netdev_rxq *rxq)
1062 {
1063     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq);
1064     struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
1065
1066     ovs_mutex_lock(&dev->mutex);
1067     rx->port_id = dev->port_id;
1068     ovs_mutex_unlock(&dev->mutex);
1069
1070     return 0;
1071 }
1072
1073 static void
1074 netdev_dpdk_rxq_destruct(struct netdev_rxq *rxq OVS_UNUSED)
1075 {
1076 }
1077
1078 static void
1079 netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq)
1080 {
1081     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq);
1082
1083     rte_free(rx);
1084 }
1085
1086 static inline void
1087 dpdk_queue_flush__(struct netdev_dpdk *dev, int qid)
1088 {
1089     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
1090     uint32_t nb_tx = 0;
1091
1092     while (nb_tx != txq->count) {
1093         uint32_t ret;
1094
1095         ret = rte_eth_tx_burst(dev->port_id, qid, txq->burst_pkts + nb_tx,
1096                                txq->count - nb_tx);
1097         if (!ret) {
1098             break;
1099         }
1100
1101         nb_tx += ret;
1102     }
1103
1104     if (OVS_UNLIKELY(nb_tx != txq->count)) {
1105         /* free buffers, which we couldn't transmit, one at a time (each
1106          * packet could come from a different mempool) */
1107         int i;
1108
1109         for (i = nb_tx; i < txq->count; i++) {
1110             rte_pktmbuf_free(txq->burst_pkts[i]);
1111         }
1112         rte_spinlock_lock(&dev->stats_lock);
1113         dev->stats.tx_dropped += txq->count-nb_tx;
1114         rte_spinlock_unlock(&dev->stats_lock);
1115     }
1116
1117     txq->count = 0;
1118     txq->tsc = rte_get_timer_cycles();
1119 }
1120
1121 static inline void
1122 dpdk_queue_flush(struct netdev_dpdk *dev, int qid)
1123 {
1124     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
1125
1126     if (txq->count == 0) {
1127         return;
1128     }
1129     dpdk_queue_flush__(dev, qid);
1130 }
1131
1132 static inline bool
1133 netdev_dpdk_policer_pkt_handle(struct rte_meter_srtcm *meter,
1134                                struct rte_mbuf *pkt, uint64_t time)
1135 {
1136     uint32_t pkt_len = rte_pktmbuf_pkt_len(pkt) - sizeof(struct ether_hdr);
1137
1138     return rte_meter_srtcm_color_blind_check(meter, time, pkt_len) ==
1139                                                 e_RTE_METER_GREEN;
1140 }
1141
1142 static int
1143 netdev_dpdk_policer_run(struct rte_meter_srtcm *meter,
1144                         struct rte_mbuf **pkts, int pkt_cnt)
1145 {
1146     int i = 0;
1147     int cnt = 0;
1148     struct rte_mbuf *pkt = NULL;
1149     uint64_t current_time = rte_rdtsc();
1150
1151     for (i = 0; i < pkt_cnt; i++) {
1152         pkt = pkts[i];
1153         /* Handle current packet */
1154         if (netdev_dpdk_policer_pkt_handle(meter, pkt, current_time)) {
1155             if (cnt != i) {
1156                 pkts[cnt] = pkt;
1157             }
1158             cnt++;
1159         } else {
1160             rte_pktmbuf_free(pkt);
1161         }
1162     }
1163
1164     return cnt;
1165 }
1166
1167 static int
1168 ingress_policer_run(struct ingress_policer *policer, struct rte_mbuf **pkts,
1169                     int pkt_cnt)
1170 {
1171     int cnt = 0;
1172
1173     rte_spinlock_lock(&policer->policer_lock);
1174     cnt = netdev_dpdk_policer_run(&policer->in_policer, pkts, pkt_cnt);
1175     rte_spinlock_unlock(&policer->policer_lock);
1176
1177     return cnt;
1178 }
1179
1180 static bool
1181 is_vhost_running(struct virtio_net *virtio_dev)
1182 {
1183     return (virtio_dev != NULL && (virtio_dev->flags & VIRTIO_DEV_RUNNING));
1184 }
1185
1186 static inline void
1187 netdev_dpdk_vhost_update_rx_size_counters(struct netdev_stats *stats,
1188                                           unsigned int packet_size)
1189 {
1190     /* Hard-coded search for the size bucket. */
1191     if (packet_size < 256) {
1192         if (packet_size >= 128) {
1193             stats->rx_128_to_255_packets++;
1194         } else if (packet_size <= 64) {
1195             stats->rx_1_to_64_packets++;
1196         } else {
1197             stats->rx_65_to_127_packets++;
1198         }
1199     } else {
1200         if (packet_size >= 1523) {
1201             stats->rx_1523_to_max_packets++;
1202         } else if (packet_size >= 1024) {
1203             stats->rx_1024_to_1522_packets++;
1204         } else if (packet_size < 512) {
1205             stats->rx_256_to_511_packets++;
1206         } else {
1207             stats->rx_512_to_1023_packets++;
1208         }
1209     }
1210 }
1211
1212 static inline void
1213 netdev_dpdk_vhost_update_rx_counters(struct netdev_stats *stats,
1214                                      struct dp_packet **packets, int count,
1215                                      int dropped)
1216 {
1217     int i;
1218     unsigned int packet_size;
1219     struct dp_packet *packet;
1220
1221     stats->rx_packets += count;
1222     stats->rx_dropped += dropped;
1223     for (i = 0; i < count; i++) {
1224         packet = packets[i];
1225         packet_size = dp_packet_size(packet);
1226
1227         if (OVS_UNLIKELY(packet_size < ETH_HEADER_LEN)) {
1228             /* This only protects the following multicast counting from
1229              * too short packets, but it does not stop the packet from
1230              * further processing. */
1231             stats->rx_errors++;
1232             stats->rx_length_errors++;
1233             continue;
1234         }
1235
1236         netdev_dpdk_vhost_update_rx_size_counters(stats, packet_size);
1237
1238         struct eth_header *eh = (struct eth_header *) dp_packet_data(packet);
1239         if (OVS_UNLIKELY(eth_addr_is_multicast(eh->eth_dst))) {
1240             stats->multicast++;
1241         }
1242
1243         stats->rx_bytes += packet_size;
1244     }
1245 }
1246
1247 /*
1248  * The receive path for the vhost port is the TX path out from guest.
1249  */
1250 static int
1251 netdev_dpdk_vhost_rxq_recv(struct netdev_rxq *rxq,
1252                            struct dp_packet **packets, int *c)
1253 {
1254     struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
1255     struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
1256     int qid = rxq->queue_id;
1257     struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev);
1258     uint16_t nb_rx = 0;
1259     uint16_t dropped = 0;
1260
1261     if (OVS_UNLIKELY(!is_vhost_running(virtio_dev)
1262                      || !(dev->flags & NETDEV_UP))) {
1263         return EAGAIN;
1264     }
1265
1266     if (rxq->queue_id >= dev->real_n_rxq) {
1267         return EOPNOTSUPP;
1268     }
1269
1270     nb_rx = rte_vhost_dequeue_burst(virtio_dev, qid * VIRTIO_QNUM + VIRTIO_TXQ,
1271                                     dev->dpdk_mp->mp,
1272                                     (struct rte_mbuf **)packets,
1273                                     NETDEV_MAX_BURST);
1274     if (!nb_rx) {
1275         return EAGAIN;
1276     }
1277
1278     if (policer) {
1279         dropped = nb_rx;
1280         nb_rx = ingress_policer_run(policer, (struct rte_mbuf **)packets, nb_rx);
1281         dropped -= nb_rx;
1282     }
1283
1284     rte_spinlock_lock(&dev->stats_lock);
1285     netdev_dpdk_vhost_update_rx_counters(&dev->stats, packets, nb_rx, dropped);
1286     rte_spinlock_unlock(&dev->stats_lock);
1287
1288     *c = (int) nb_rx;
1289     return 0;
1290 }
1291
1292 static int
1293 netdev_dpdk_rxq_recv(struct netdev_rxq *rxq, struct dp_packet **packets,
1294                      int *c)
1295 {
1296     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq);
1297     struct netdev_dpdk *dev = netdev_dpdk_cast(rxq->netdev);
1298     struct ingress_policer *policer = netdev_dpdk_get_ingress_policer(dev);
1299     int nb_rx;
1300     int dropped = 0;
1301
1302     /* There is only one tx queue for this core.  Do not flush other
1303      * queues.
1304      * Do not flush tx queue which is shared among CPUs
1305      * since it is always flushed */
1306     if (rxq->queue_id == rte_lcore_id() &&
1307         OVS_LIKELY(!dev->txq_needs_locking)) {
1308         dpdk_queue_flush(dev, rxq->queue_id);
1309     }
1310
1311     nb_rx = rte_eth_rx_burst(rx->port_id, rxq->queue_id,
1312                              (struct rte_mbuf **) packets,
1313                              NETDEV_MAX_BURST);
1314     if (!nb_rx) {
1315         return EAGAIN;
1316     }
1317
1318     if (policer) {
1319         dropped = nb_rx;
1320         nb_rx = ingress_policer_run(policer, (struct rte_mbuf **) packets, nb_rx);
1321         dropped -= nb_rx;
1322     }
1323
1324     /* Update stats to reflect dropped packets */
1325     if (OVS_UNLIKELY(dropped)) {
1326         rte_spinlock_lock(&dev->stats_lock);
1327         dev->stats.rx_dropped += dropped;
1328         rte_spinlock_unlock(&dev->stats_lock);
1329     }
1330
1331     *c = nb_rx;
1332
1333     return 0;
1334 }
1335
1336 static inline int
1337 netdev_dpdk_qos_run__(struct netdev_dpdk *dev, struct rte_mbuf **pkts,
1338                         int cnt)
1339 {
1340     struct netdev *netdev = &dev->up;
1341
1342     if (dev->qos_conf != NULL) {
1343         rte_spinlock_lock(&dev->qos_lock);
1344         if (dev->qos_conf != NULL) {
1345             cnt = dev->qos_conf->ops->qos_run(netdev, pkts, cnt);
1346         }
1347         rte_spinlock_unlock(&dev->qos_lock);
1348     }
1349
1350     return cnt;
1351 }
1352
1353 static inline void
1354 netdev_dpdk_vhost_update_tx_counters(struct netdev_stats *stats,
1355                                      struct dp_packet **packets,
1356                                      int attempted,
1357                                      int dropped)
1358 {
1359     int i;
1360     int sent = attempted - dropped;
1361
1362     stats->tx_packets += sent;
1363     stats->tx_dropped += dropped;
1364
1365     for (i = 0; i < sent; i++) {
1366         stats->tx_bytes += dp_packet_size(packets[i]);
1367     }
1368 }
1369
1370 static void
1371 __netdev_dpdk_vhost_send(struct netdev *netdev, int qid,
1372                          struct dp_packet **pkts, int cnt,
1373                          bool may_steal)
1374 {
1375     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1376     struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
1377     struct rte_mbuf **cur_pkts = (struct rte_mbuf **) pkts;
1378     unsigned int total_pkts = cnt;
1379     unsigned int qos_pkts = cnt;
1380     uint64_t start = 0;
1381
1382     qid = dev->tx_q[qid % dev->real_n_txq].map;
1383
1384     if (OVS_UNLIKELY(!is_vhost_running(virtio_dev) || qid < 0
1385                      || !(dev->flags & NETDEV_UP))) {
1386         rte_spinlock_lock(&dev->stats_lock);
1387         dev->stats.tx_dropped+= cnt;
1388         rte_spinlock_unlock(&dev->stats_lock);
1389         goto out;
1390     }
1391
1392     rte_spinlock_lock(&dev->tx_q[qid].tx_lock);
1393
1394     /* Check has QoS has been configured for the netdev */
1395     cnt = netdev_dpdk_qos_run__(dev, cur_pkts, cnt);
1396     qos_pkts -= cnt;
1397
1398     do {
1399         int vhost_qid = qid * VIRTIO_QNUM + VIRTIO_RXQ;
1400         unsigned int tx_pkts;
1401
1402         tx_pkts = rte_vhost_enqueue_burst(virtio_dev, vhost_qid,
1403                                           cur_pkts, cnt);
1404         if (OVS_LIKELY(tx_pkts)) {
1405             /* Packets have been sent.*/
1406             cnt -= tx_pkts;
1407             /* Prepare for possible next iteration.*/
1408             cur_pkts = &cur_pkts[tx_pkts];
1409         } else {
1410             uint64_t timeout = VHOST_ENQ_RETRY_USECS * rte_get_timer_hz() / 1E6;
1411             unsigned int expired = 0;
1412
1413             if (!start) {
1414                 start = rte_get_timer_cycles();
1415             }
1416
1417             /*
1418              * Unable to enqueue packets to vhost interface.
1419              * Check available entries before retrying.
1420              */
1421             while (!rte_vring_available_entries(virtio_dev, vhost_qid)) {
1422                 if (OVS_UNLIKELY((rte_get_timer_cycles() - start) > timeout)) {
1423                     expired = 1;
1424                     break;
1425                 }
1426             }
1427             if (expired) {
1428                 /* break out of main loop. */
1429                 break;
1430             }
1431         }
1432     } while (cnt);
1433
1434     rte_spinlock_unlock(&dev->tx_q[qid].tx_lock);
1435
1436     rte_spinlock_lock(&dev->stats_lock);
1437     cnt += qos_pkts;
1438     netdev_dpdk_vhost_update_tx_counters(&dev->stats, pkts, total_pkts, cnt);
1439     rte_spinlock_unlock(&dev->stats_lock);
1440
1441 out:
1442     if (may_steal) {
1443         int i;
1444
1445         for (i = 0; i < total_pkts; i++) {
1446             dp_packet_delete(pkts[i]);
1447         }
1448     }
1449 }
1450
1451 inline static void
1452 dpdk_queue_pkts(struct netdev_dpdk *dev, int qid,
1453                struct rte_mbuf **pkts, int cnt)
1454 {
1455     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
1456     uint64_t diff_tsc;
1457
1458     int i = 0;
1459
1460     while (i < cnt) {
1461         int freeslots = MAX_TX_QUEUE_LEN - txq->count;
1462         int tocopy = MIN(freeslots, cnt-i);
1463
1464         memcpy(&txq->burst_pkts[txq->count], &pkts[i],
1465                tocopy * sizeof (struct rte_mbuf *));
1466
1467         txq->count += tocopy;
1468         i += tocopy;
1469
1470         if (txq->count == MAX_TX_QUEUE_LEN || txq->flush_tx) {
1471             dpdk_queue_flush__(dev, qid);
1472         }
1473         diff_tsc = rte_get_timer_cycles() - txq->tsc;
1474         if (diff_tsc >= DRAIN_TSC) {
1475             dpdk_queue_flush__(dev, qid);
1476         }
1477     }
1478 }
1479
1480 /* Tx function. Transmit packets indefinitely */
1481 static void
1482 dpdk_do_tx_copy(struct netdev *netdev, int qid, struct dp_packet **pkts,
1483                 int cnt)
1484     OVS_NO_THREAD_SAFETY_ANALYSIS
1485 {
1486 #if !defined(__CHECKER__) && !defined(_WIN32)
1487     const size_t PKT_ARRAY_SIZE = cnt;
1488 #else
1489     /* Sparse or MSVC doesn't like variable length array. */
1490     enum { PKT_ARRAY_SIZE = NETDEV_MAX_BURST };
1491 #endif
1492     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1493     struct rte_mbuf *mbufs[PKT_ARRAY_SIZE];
1494     int dropped = 0;
1495     int newcnt = 0;
1496     int i;
1497
1498     /* If we are on a non pmd thread we have to use the mempool mutex, because
1499      * every non pmd thread shares the same mempool cache */
1500
1501     if (!dpdk_thread_is_pmd()) {
1502         ovs_mutex_lock(&nonpmd_mempool_mutex);
1503     }
1504
1505     for (i = 0; i < cnt; i++) {
1506         int size = dp_packet_size(pkts[i]);
1507
1508         if (OVS_UNLIKELY(size > dev->max_packet_len)) {
1509             VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d",
1510                          (int)size , dev->max_packet_len);
1511
1512             dropped++;
1513             continue;
1514         }
1515
1516         mbufs[newcnt] = rte_pktmbuf_alloc(dev->dpdk_mp->mp);
1517
1518         if (!mbufs[newcnt]) {
1519             dropped += cnt - i;
1520             break;
1521         }
1522
1523         /* We have to do a copy for now */
1524         memcpy(rte_pktmbuf_mtod(mbufs[newcnt], void *), dp_packet_data(pkts[i]), size);
1525
1526         rte_pktmbuf_data_len(mbufs[newcnt]) = size;
1527         rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;
1528
1529         newcnt++;
1530     }
1531
1532     if (dev->type == DPDK_DEV_VHOST) {
1533         __netdev_dpdk_vhost_send(netdev, qid, (struct dp_packet **) mbufs, newcnt, true);
1534     } else {
1535         unsigned int qos_pkts = newcnt;
1536
1537         /* Check if QoS has been configured for this netdev. */
1538         newcnt = netdev_dpdk_qos_run__(dev, mbufs, newcnt);
1539
1540         dropped += qos_pkts - newcnt;
1541         dpdk_queue_pkts(dev, qid, mbufs, newcnt);
1542         dpdk_queue_flush(dev, qid);
1543     }
1544
1545     if (OVS_UNLIKELY(dropped)) {
1546         rte_spinlock_lock(&dev->stats_lock);
1547         dev->stats.tx_dropped += dropped;
1548         rte_spinlock_unlock(&dev->stats_lock);
1549     }
1550
1551     if (!dpdk_thread_is_pmd()) {
1552         ovs_mutex_unlock(&nonpmd_mempool_mutex);
1553     }
1554 }
1555
1556 static int
1557 netdev_dpdk_vhost_send(struct netdev *netdev, int qid, struct dp_packet **pkts,
1558                  int cnt, bool may_steal)
1559 {
1560     if (OVS_UNLIKELY(pkts[0]->source != DPBUF_DPDK)) {
1561         int i;
1562
1563         dpdk_do_tx_copy(netdev, qid, pkts, cnt);
1564         if (may_steal) {
1565             for (i = 0; i < cnt; i++) {
1566                 dp_packet_delete(pkts[i]);
1567             }
1568         }
1569     } else {
1570         __netdev_dpdk_vhost_send(netdev, qid, pkts, cnt, may_steal);
1571     }
1572     return 0;
1573 }
1574
1575 static inline void
1576 netdev_dpdk_send__(struct netdev_dpdk *dev, int qid,
1577                    struct dp_packet **pkts, int cnt, bool may_steal)
1578 {
1579     int i;
1580
1581     if (OVS_UNLIKELY(dev->txq_needs_locking)) {
1582         qid = qid % dev->real_n_txq;
1583         rte_spinlock_lock(&dev->tx_q[qid].tx_lock);
1584     }
1585
1586     if (OVS_UNLIKELY(!may_steal ||
1587                      pkts[0]->source != DPBUF_DPDK)) {
1588         struct netdev *netdev = &dev->up;
1589
1590         dpdk_do_tx_copy(netdev, qid, pkts, cnt);
1591
1592         if (may_steal) {
1593             for (i = 0; i < cnt; i++) {
1594                 dp_packet_delete(pkts[i]);
1595             }
1596         }
1597     } else {
1598         int next_tx_idx = 0;
1599         int dropped = 0;
1600         unsigned int qos_pkts = 0;
1601         unsigned int temp_cnt = 0;
1602
1603         for (i = 0; i < cnt; i++) {
1604             int size = dp_packet_size(pkts[i]);
1605
1606             if (OVS_UNLIKELY(size > dev->max_packet_len)) {
1607                 if (next_tx_idx != i) {
1608                     temp_cnt = i - next_tx_idx;
1609                     qos_pkts = temp_cnt;
1610
1611                     temp_cnt = netdev_dpdk_qos_run__(dev, (struct rte_mbuf**)pkts,
1612                                                 temp_cnt);
1613                     dropped += qos_pkts - temp_cnt;
1614                     dpdk_queue_pkts(dev, qid,
1615                                     (struct rte_mbuf **)&pkts[next_tx_idx],
1616                                     temp_cnt);
1617
1618                 }
1619
1620                 VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d",
1621                              (int)size , dev->max_packet_len);
1622
1623                 dp_packet_delete(pkts[i]);
1624                 dropped++;
1625                 next_tx_idx = i + 1;
1626             }
1627         }
1628         if (next_tx_idx != cnt) {
1629             cnt -= next_tx_idx;
1630             qos_pkts = cnt;
1631
1632             cnt = netdev_dpdk_qos_run__(dev, (struct rte_mbuf**)pkts, cnt);
1633             dropped += qos_pkts - cnt;
1634             dpdk_queue_pkts(dev, qid, (struct rte_mbuf **)&pkts[next_tx_idx],
1635                             cnt);
1636         }
1637
1638         if (OVS_UNLIKELY(dropped)) {
1639             rte_spinlock_lock(&dev->stats_lock);
1640             dev->stats.tx_dropped += dropped;
1641             rte_spinlock_unlock(&dev->stats_lock);
1642         }
1643     }
1644
1645     if (OVS_UNLIKELY(dev->txq_needs_locking)) {
1646         rte_spinlock_unlock(&dev->tx_q[qid].tx_lock);
1647     }
1648 }
1649
1650 static int
1651 netdev_dpdk_eth_send(struct netdev *netdev, int qid,
1652                      struct dp_packet **pkts, int cnt, bool may_steal)
1653 {
1654     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1655
1656     netdev_dpdk_send__(dev, qid, pkts, cnt, may_steal);
1657     return 0;
1658 }
1659
1660 static int
1661 netdev_dpdk_set_etheraddr(struct netdev *netdev, const struct eth_addr mac)
1662 {
1663     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1664
1665     ovs_mutex_lock(&dev->mutex);
1666     if (!eth_addr_equals(dev->hwaddr, mac)) {
1667         dev->hwaddr = mac;
1668         netdev_change_seq_changed(netdev);
1669     }
1670     ovs_mutex_unlock(&dev->mutex);
1671
1672     return 0;
1673 }
1674
1675 static int
1676 netdev_dpdk_get_etheraddr(const struct netdev *netdev, struct eth_addr *mac)
1677 {
1678     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1679
1680     ovs_mutex_lock(&dev->mutex);
1681     *mac = dev->hwaddr;
1682     ovs_mutex_unlock(&dev->mutex);
1683
1684     return 0;
1685 }
1686
1687 static int
1688 netdev_dpdk_get_mtu(const struct netdev *netdev, int *mtup)
1689 {
1690     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1691
1692     ovs_mutex_lock(&dev->mutex);
1693     *mtup = dev->mtu;
1694     ovs_mutex_unlock(&dev->mutex);
1695
1696     return 0;
1697 }
1698
1699 static int
1700 netdev_dpdk_set_mtu(const struct netdev *netdev, int mtu)
1701 {
1702     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1703     int old_mtu, err, dpdk_mtu;
1704     struct dpdk_mp *old_mp;
1705     struct dpdk_mp *mp;
1706     uint32_t buf_size;
1707
1708     ovs_mutex_lock(&dpdk_mutex);
1709     ovs_mutex_lock(&dev->mutex);
1710     if (dev->mtu == mtu) {
1711         err = 0;
1712         goto out;
1713     }
1714
1715     buf_size = dpdk_buf_size(mtu);
1716     dpdk_mtu = FRAME_LEN_TO_MTU(buf_size);
1717
1718     mp = dpdk_mp_get(dev->socket_id, dpdk_mtu);
1719     if (!mp) {
1720         err = ENOMEM;
1721         goto out;
1722     }
1723
1724     rte_eth_dev_stop(dev->port_id);
1725
1726     old_mtu = dev->mtu;
1727     old_mp = dev->dpdk_mp;
1728     dev->dpdk_mp = mp;
1729     dev->mtu = mtu;
1730     dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu);
1731
1732     err = dpdk_eth_dev_init(dev);
1733     if (err) {
1734         dpdk_mp_put(mp);
1735         dev->mtu = old_mtu;
1736         dev->dpdk_mp = old_mp;
1737         dev->max_packet_len = MTU_TO_FRAME_LEN(dev->mtu);
1738         dpdk_eth_dev_init(dev);
1739         goto out;
1740     }
1741
1742     dpdk_mp_put(old_mp);
1743     netdev_change_seq_changed(netdev);
1744 out:
1745     ovs_mutex_unlock(&dev->mutex);
1746     ovs_mutex_unlock(&dpdk_mutex);
1747     return err;
1748 }
1749
1750 static int
1751 netdev_dpdk_get_carrier(const struct netdev *netdev, bool *carrier);
1752
1753 static int
1754 netdev_dpdk_vhost_get_stats(const struct netdev *netdev,
1755                             struct netdev_stats *stats)
1756 {
1757     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1758
1759     ovs_mutex_lock(&dev->mutex);
1760
1761     rte_spinlock_lock(&dev->stats_lock);
1762     /* Supported Stats */
1763     stats->rx_packets += dev->stats.rx_packets;
1764     stats->tx_packets += dev->stats.tx_packets;
1765     stats->rx_dropped = dev->stats.rx_dropped;
1766     stats->tx_dropped += dev->stats.tx_dropped;
1767     stats->multicast = dev->stats.multicast;
1768     stats->rx_bytes = dev->stats.rx_bytes;
1769     stats->tx_bytes = dev->stats.tx_bytes;
1770     stats->rx_errors = dev->stats.rx_errors;
1771     stats->rx_length_errors = dev->stats.rx_length_errors;
1772
1773     stats->rx_1_to_64_packets = dev->stats.rx_1_to_64_packets;
1774     stats->rx_65_to_127_packets = dev->stats.rx_65_to_127_packets;
1775     stats->rx_128_to_255_packets = dev->stats.rx_128_to_255_packets;
1776     stats->rx_256_to_511_packets = dev->stats.rx_256_to_511_packets;
1777     stats->rx_512_to_1023_packets = dev->stats.rx_512_to_1023_packets;
1778     stats->rx_1024_to_1522_packets = dev->stats.rx_1024_to_1522_packets;
1779     stats->rx_1523_to_max_packets = dev->stats.rx_1523_to_max_packets;
1780
1781     rte_spinlock_unlock(&dev->stats_lock);
1782
1783     ovs_mutex_unlock(&dev->mutex);
1784
1785     return 0;
1786 }
1787
1788 static void
1789 netdev_dpdk_convert_xstats(struct netdev_stats *stats,
1790                            const struct rte_eth_xstats *xstats,
1791                            const unsigned int size)
1792 {
1793     /* XXX Current implementation is simple search through an array
1794      * to find hardcoded counter names. In future DPDK release (TBD)
1795      * XSTATS API will change so each counter will be represented by
1796      * unique ID instead of String. */
1797
1798     for (unsigned int i = 0; i < size; i++) {
1799         if (strcmp(XSTAT_RX_64_PACKETS, xstats[i].name) == 0) {
1800             stats->rx_1_to_64_packets = xstats[i].value;
1801         } else if (strcmp(XSTAT_RX_65_TO_127_PACKETS, xstats[i].name) == 0) {
1802             stats->rx_65_to_127_packets = xstats[i].value;
1803         } else if (strcmp(XSTAT_RX_128_TO_255_PACKETS, xstats[i].name) == 0) {
1804             stats->rx_128_to_255_packets = xstats[i].value;
1805         } else if (strcmp(XSTAT_RX_256_TO_511_PACKETS, xstats[i].name) == 0) {
1806             stats->rx_256_to_511_packets = xstats[i].value;
1807         } else if (strcmp(XSTAT_RX_512_TO_1023_PACKETS,
1808                           xstats[i].name) == 0) {
1809             stats->rx_512_to_1023_packets = xstats[i].value;
1810         } else if (strcmp(XSTAT_RX_1024_TO_1522_PACKETS,
1811                           xstats[i].name) == 0) {
1812             stats->rx_1024_to_1522_packets = xstats[i].value;
1813         } else if (strcmp(XSTAT_RX_1523_TO_MAX_PACKETS,
1814                           xstats[i].name) == 0) {
1815             stats->rx_1523_to_max_packets = xstats[i].value;
1816         } else if (strcmp(XSTAT_TX_64_PACKETS, xstats[i].name) == 0) {
1817             stats->tx_1_to_64_packets = xstats[i].value;
1818         } else if (strcmp(XSTAT_TX_65_TO_127_PACKETS, xstats[i].name) == 0) {
1819             stats->tx_65_to_127_packets = xstats[i].value;
1820         } else if (strcmp(XSTAT_TX_128_TO_255_PACKETS, xstats[i].name) == 0) {
1821             stats->tx_128_to_255_packets = xstats[i].value;
1822         } else if (strcmp(XSTAT_TX_256_TO_511_PACKETS, xstats[i].name) == 0) {
1823             stats->tx_256_to_511_packets = xstats[i].value;
1824         } else if (strcmp(XSTAT_TX_512_TO_1023_PACKETS,
1825                           xstats[i].name) == 0) {
1826             stats->tx_512_to_1023_packets = xstats[i].value;
1827         } else if (strcmp(XSTAT_TX_1024_TO_1522_PACKETS,
1828                           xstats[i].name) == 0) {
1829             stats->tx_1024_to_1522_packets = xstats[i].value;
1830         } else if (strcmp(XSTAT_TX_1523_TO_MAX_PACKETS,
1831                           xstats[i].name) == 0) {
1832             stats->tx_1523_to_max_packets = xstats[i].value;
1833         } else if (strcmp(XSTAT_TX_MULTICAST_PACKETS, xstats[i].name) == 0) {
1834             stats->tx_multicast_packets = xstats[i].value;
1835         } else if (strcmp(XSTAT_RX_BROADCAST_PACKETS, xstats[i].name) == 0) {
1836             stats->rx_broadcast_packets = xstats[i].value;
1837         } else if (strcmp(XSTAT_TX_BROADCAST_PACKETS, xstats[i].name) == 0) {
1838             stats->tx_broadcast_packets = xstats[i].value;
1839         } else if (strcmp(XSTAT_RX_UNDERSIZED_ERRORS, xstats[i].name) == 0) {
1840             stats->rx_undersized_errors = xstats[i].value;
1841         } else if (strcmp(XSTAT_RX_FRAGMENTED_ERRORS, xstats[i].name) == 0) {
1842             stats->rx_fragmented_errors = xstats[i].value;
1843         } else if (strcmp(XSTAT_RX_JABBER_ERRORS, xstats[i].name) == 0) {
1844             stats->rx_jabber_errors = xstats[i].value;
1845         }
1846     }
1847 }
1848
1849 static int
1850 netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
1851 {
1852     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1853     struct rte_eth_stats rte_stats;
1854     bool gg;
1855
1856     netdev_dpdk_get_carrier(netdev, &gg);
1857     ovs_mutex_lock(&dev->mutex);
1858
1859     struct rte_eth_xstats *rte_xstats;
1860     int rte_xstats_len, rte_xstats_ret;
1861
1862     if (rte_eth_stats_get(dev->port_id, &rte_stats)) {
1863         VLOG_ERR("Can't get ETH statistics for port: %i.", dev->port_id);
1864         ovs_mutex_unlock(&dev->mutex);
1865         return EPROTO;
1866     }
1867
1868     rte_xstats_len = rte_eth_xstats_get(dev->port_id, NULL, 0);
1869     if (rte_xstats_len > 0) {
1870         rte_xstats = dpdk_rte_mzalloc(sizeof(*rte_xstats) * rte_xstats_len);
1871         memset(rte_xstats, 0xff, sizeof(*rte_xstats) * rte_xstats_len);
1872         rte_xstats_ret = rte_eth_xstats_get(dev->port_id, rte_xstats,
1873                                             rte_xstats_len);
1874         if (rte_xstats_ret > 0 && rte_xstats_ret <= rte_xstats_len) {
1875             netdev_dpdk_convert_xstats(stats, rte_xstats, rte_xstats_ret);
1876         }
1877         rte_free(rte_xstats);
1878     } else {
1879         VLOG_WARN("Can't get XSTATS counters for port: %i.", dev->port_id);
1880     }
1881
1882     stats->rx_packets = rte_stats.ipackets;
1883     stats->tx_packets = rte_stats.opackets;
1884     stats->rx_bytes = rte_stats.ibytes;
1885     stats->tx_bytes = rte_stats.obytes;
1886     /* DPDK counts imissed as errors, but count them here as dropped instead */
1887     stats->rx_errors = rte_stats.ierrors - rte_stats.imissed;
1888     stats->tx_errors = rte_stats.oerrors;
1889     stats->multicast = rte_stats.imcasts;
1890
1891     rte_spinlock_lock(&dev->stats_lock);
1892     stats->tx_dropped = dev->stats.tx_dropped;
1893     stats->rx_dropped = dev->stats.rx_dropped;
1894     rte_spinlock_unlock(&dev->stats_lock);
1895
1896     /* These are the available DPDK counters for packets not received due to
1897      * local resource constraints in DPDK and NIC respectively. */
1898     stats->rx_dropped += rte_stats.rx_nombuf + rte_stats.imissed;
1899     stats->rx_missed_errors = rte_stats.imissed;
1900
1901     ovs_mutex_unlock(&dev->mutex);
1902
1903     return 0;
1904 }
1905
1906 static int
1907 netdev_dpdk_get_features(const struct netdev *netdev,
1908                          enum netdev_features *current,
1909                          enum netdev_features *advertised OVS_UNUSED,
1910                          enum netdev_features *supported OVS_UNUSED,
1911                          enum netdev_features *peer OVS_UNUSED)
1912 {
1913     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1914     struct rte_eth_link link;
1915
1916     ovs_mutex_lock(&dev->mutex);
1917     link = dev->link;
1918     ovs_mutex_unlock(&dev->mutex);
1919
1920     if (link.link_duplex == ETH_LINK_HALF_DUPLEX) {
1921         if (link.link_speed == ETH_SPEED_NUM_10M) {
1922             *current = NETDEV_F_10MB_HD;
1923         }
1924         if (link.link_speed == ETH_SPEED_NUM_100M) {
1925             *current = NETDEV_F_100MB_HD;
1926         }
1927         if (link.link_speed == ETH_SPEED_NUM_1G) {
1928             *current = NETDEV_F_1GB_HD;
1929         }
1930     } else if (link.link_duplex == ETH_LINK_FULL_DUPLEX) {
1931         if (link.link_speed == ETH_SPEED_NUM_10M) {
1932             *current = NETDEV_F_10MB_FD;
1933         }
1934         if (link.link_speed == ETH_SPEED_NUM_100M) {
1935             *current = NETDEV_F_100MB_FD;
1936         }
1937         if (link.link_speed == ETH_SPEED_NUM_1G) {
1938             *current = NETDEV_F_1GB_FD;
1939         }
1940         if (link.link_speed == ETH_SPEED_NUM_10G) {
1941             *current = NETDEV_F_10GB_FD;
1942         }
1943     }
1944
1945     if (link.link_autoneg) {
1946         *current |= NETDEV_F_AUTONEG;
1947     }
1948
1949     return 0;
1950 }
1951
1952 static struct ingress_policer *
1953 netdev_dpdk_policer_construct(uint32_t rate, uint32_t burst)
1954 {
1955     struct ingress_policer *policer = NULL;
1956     uint64_t rate_bytes;
1957     uint64_t burst_bytes;
1958     int err = 0;
1959
1960     policer = xmalloc(sizeof *policer);
1961     rte_spinlock_init(&policer->policer_lock);
1962
1963     /* rte_meter requires bytes so convert kbits rate and burst to bytes. */
1964     rate_bytes = rate * 1000/8;
1965     burst_bytes = burst * 1000/8;
1966
1967     policer->app_srtcm_params.cir = rate_bytes;
1968     policer->app_srtcm_params.cbs = burst_bytes;
1969     policer->app_srtcm_params.ebs = 0;
1970     err = rte_meter_srtcm_config(&policer->in_policer,
1971                                     &policer->app_srtcm_params);
1972     if(err) {
1973         VLOG_ERR("Could not create rte meter for ingress policer");
1974         return NULL;
1975     }
1976
1977     return policer;
1978 }
1979
1980 static int
1981 netdev_dpdk_set_policing(struct netdev* netdev, uint32_t policer_rate,
1982                          uint32_t policer_burst)
1983 {
1984     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
1985     struct ingress_policer *policer;
1986
1987     /* Force to 0 if no rate specified,
1988      * default to 8000 kbits if burst is 0,
1989      * else stick with user-specified value.
1990      */
1991     policer_burst = (!policer_rate ? 0
1992                      : !policer_burst ? 8000
1993                      : policer_burst);
1994
1995     ovs_mutex_lock(&dev->mutex);
1996
1997     policer = ovsrcu_get_protected(struct ingress_policer *,
1998                                     &dev->ingress_policer);
1999
2000     if (dev->policer_rate == policer_rate &&
2001         dev->policer_burst == policer_burst) {
2002         /* Assume that settings haven't changed since we last set them. */
2003         ovs_mutex_unlock(&dev->mutex);
2004         return 0;
2005     }
2006
2007     /* Destroy any existing ingress policer for the device if one exists */
2008     if (policer) {
2009         ovsrcu_postpone(free, policer);
2010     }
2011
2012     if (policer_rate != 0) {
2013         policer = netdev_dpdk_policer_construct(policer_rate, policer_burst);
2014     } else {
2015         policer = NULL;
2016     }
2017     ovsrcu_set(&dev->ingress_policer, policer);
2018     dev->policer_rate = policer_rate;
2019     dev->policer_burst = policer_burst;
2020     ovs_mutex_unlock(&dev->mutex);
2021
2022     return 0;
2023 }
2024
2025 static int
2026 netdev_dpdk_get_ifindex(const struct netdev *netdev)
2027 {
2028     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2029     int ifindex;
2030
2031     ovs_mutex_lock(&dev->mutex);
2032     ifindex = dev->port_id;
2033     ovs_mutex_unlock(&dev->mutex);
2034
2035     return ifindex;
2036 }
2037
2038 static int
2039 netdev_dpdk_get_carrier(const struct netdev *netdev, bool *carrier)
2040 {
2041     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2042
2043     ovs_mutex_lock(&dev->mutex);
2044     check_link_status(dev);
2045     *carrier = dev->link.link_status;
2046
2047     ovs_mutex_unlock(&dev->mutex);
2048
2049     return 0;
2050 }
2051
2052 static int
2053 netdev_dpdk_vhost_get_carrier(const struct netdev *netdev, bool *carrier)
2054 {
2055     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2056     struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
2057
2058     ovs_mutex_lock(&dev->mutex);
2059
2060     if (is_vhost_running(virtio_dev)) {
2061         *carrier = 1;
2062     } else {
2063         *carrier = 0;
2064     }
2065
2066     ovs_mutex_unlock(&dev->mutex);
2067
2068     return 0;
2069 }
2070
2071 static long long int
2072 netdev_dpdk_get_carrier_resets(const struct netdev *netdev)
2073 {
2074     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2075     long long int carrier_resets;
2076
2077     ovs_mutex_lock(&dev->mutex);
2078     carrier_resets = dev->link_reset_cnt;
2079     ovs_mutex_unlock(&dev->mutex);
2080
2081     return carrier_resets;
2082 }
2083
2084 static int
2085 netdev_dpdk_set_miimon(struct netdev *netdev OVS_UNUSED,
2086                        long long int interval OVS_UNUSED)
2087 {
2088     return EOPNOTSUPP;
2089 }
2090
2091 static int
2092 netdev_dpdk_update_flags__(struct netdev_dpdk *dev,
2093                            enum netdev_flags off, enum netdev_flags on,
2094                            enum netdev_flags *old_flagsp) OVS_REQUIRES(dev->mutex)
2095 {
2096     int err;
2097
2098     if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) {
2099         return EINVAL;
2100     }
2101
2102     *old_flagsp = dev->flags;
2103     dev->flags |= on;
2104     dev->flags &= ~off;
2105
2106     if (dev->flags == *old_flagsp) {
2107         return 0;
2108     }
2109
2110     if (dev->type == DPDK_DEV_ETH) {
2111         if (dev->flags & NETDEV_UP) {
2112             err = rte_eth_dev_start(dev->port_id);
2113             if (err)
2114                 return -err;
2115         }
2116
2117         if (dev->flags & NETDEV_PROMISC) {
2118             rte_eth_promiscuous_enable(dev->port_id);
2119         }
2120
2121         if (!(dev->flags & NETDEV_UP)) {
2122             rte_eth_dev_stop(dev->port_id);
2123         }
2124     } else {
2125         /* If DPDK_DEV_VHOST device's NETDEV_UP flag was changed and vhost is
2126          * running then change netdev's change_seq to trigger link state
2127          * update. */
2128         struct virtio_net *virtio_dev = netdev_dpdk_get_virtio(dev);
2129
2130         if ((NETDEV_UP & ((*old_flagsp ^ on) | (*old_flagsp ^ off)))
2131             && is_vhost_running(virtio_dev)) {
2132             netdev_change_seq_changed(&dev->up);
2133
2134             /* Clear statistics if device is getting up. */
2135             if (NETDEV_UP & on) {
2136                 rte_spinlock_lock(&dev->stats_lock);
2137                 memset(&dev->stats, 0, sizeof(dev->stats));
2138                 rte_spinlock_unlock(&dev->stats_lock);
2139             }
2140         }
2141     }
2142
2143     return 0;
2144 }
2145
2146 static int
2147 netdev_dpdk_update_flags(struct netdev *netdev,
2148                          enum netdev_flags off, enum netdev_flags on,
2149                          enum netdev_flags *old_flagsp)
2150 {
2151     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2152     int error;
2153
2154     ovs_mutex_lock(&dev->mutex);
2155     error = netdev_dpdk_update_flags__(dev, off, on, old_flagsp);
2156     ovs_mutex_unlock(&dev->mutex);
2157
2158     return error;
2159 }
2160
2161 static int
2162 netdev_dpdk_get_status(const struct netdev *netdev, struct smap *args)
2163 {
2164     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2165     struct rte_eth_dev_info dev_info;
2166
2167     if (dev->port_id < 0)
2168         return ENODEV;
2169
2170     ovs_mutex_lock(&dev->mutex);
2171     rte_eth_dev_info_get(dev->port_id, &dev_info);
2172     ovs_mutex_unlock(&dev->mutex);
2173
2174     smap_add_format(args, "driver_name", "%s", dev_info.driver_name);
2175
2176     smap_add_format(args, "port_no", "%d", dev->port_id);
2177     smap_add_format(args, "numa_id", "%d", rte_eth_dev_socket_id(dev->port_id));
2178     smap_add_format(args, "driver_name", "%s", dev_info.driver_name);
2179     smap_add_format(args, "min_rx_bufsize", "%u", dev_info.min_rx_bufsize);
2180     smap_add_format(args, "max_rx_pktlen", "%u", dev->max_packet_len);
2181     smap_add_format(args, "max_rx_queues", "%u", dev_info.max_rx_queues);
2182     smap_add_format(args, "max_tx_queues", "%u", dev_info.max_tx_queues);
2183     smap_add_format(args, "max_mac_addrs", "%u", dev_info.max_mac_addrs);
2184     smap_add_format(args, "max_hash_mac_addrs", "%u", dev_info.max_hash_mac_addrs);
2185     smap_add_format(args, "max_vfs", "%u", dev_info.max_vfs);
2186     smap_add_format(args, "max_vmdq_pools", "%u", dev_info.max_vmdq_pools);
2187
2188     if (dev_info.pci_dev) {
2189         smap_add_format(args, "pci-vendor_id", "0x%u",
2190                         dev_info.pci_dev->id.vendor_id);
2191         smap_add_format(args, "pci-device_id", "0x%x",
2192                         dev_info.pci_dev->id.device_id);
2193     }
2194
2195     return 0;
2196 }
2197
2198 static void
2199 netdev_dpdk_set_admin_state__(struct netdev_dpdk *dev, bool admin_state)
2200     OVS_REQUIRES(dev->mutex)
2201 {
2202     enum netdev_flags old_flags;
2203
2204     if (admin_state) {
2205         netdev_dpdk_update_flags__(dev, 0, NETDEV_UP, &old_flags);
2206     } else {
2207         netdev_dpdk_update_flags__(dev, NETDEV_UP, 0, &old_flags);
2208     }
2209 }
2210
2211 static void
2212 netdev_dpdk_set_admin_state(struct unixctl_conn *conn, int argc,
2213                             const char *argv[], void *aux OVS_UNUSED)
2214 {
2215     bool up;
2216
2217     if (!strcasecmp(argv[argc - 1], "up")) {
2218         up = true;
2219     } else if ( !strcasecmp(argv[argc - 1], "down")) {
2220         up = false;
2221     } else {
2222         unixctl_command_reply_error(conn, "Invalid Admin State");
2223         return;
2224     }
2225
2226     if (argc > 2) {
2227         struct netdev *netdev = netdev_from_name(argv[1]);
2228         if (netdev && is_dpdk_class(netdev->netdev_class)) {
2229             struct netdev_dpdk *dpdk_dev = netdev_dpdk_cast(netdev);
2230
2231             ovs_mutex_lock(&dpdk_dev->mutex);
2232             netdev_dpdk_set_admin_state__(dpdk_dev, up);
2233             ovs_mutex_unlock(&dpdk_dev->mutex);
2234
2235             netdev_close(netdev);
2236         } else {
2237             unixctl_command_reply_error(conn, "Not a DPDK Interface");
2238             netdev_close(netdev);
2239             return;
2240         }
2241     } else {
2242         struct netdev_dpdk *netdev;
2243
2244         ovs_mutex_lock(&dpdk_mutex);
2245         LIST_FOR_EACH (netdev, list_node, &dpdk_list) {
2246             ovs_mutex_lock(&netdev->mutex);
2247             netdev_dpdk_set_admin_state__(netdev, up);
2248             ovs_mutex_unlock(&netdev->mutex);
2249         }
2250         ovs_mutex_unlock(&dpdk_mutex);
2251     }
2252     unixctl_command_reply(conn, "OK");
2253 }
2254
2255 /*
2256  * Set virtqueue flags so that we do not receive interrupts.
2257  */
2258 static void
2259 set_irq_status(struct virtio_net *virtio_dev)
2260 {
2261     uint32_t i;
2262     uint64_t idx;
2263
2264     for (i = 0; i < virtio_dev->virt_qp_nb; i++) {
2265         idx = i * VIRTIO_QNUM;
2266         rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_RXQ, 0);
2267         rte_vhost_enable_guest_notification(virtio_dev, idx + VIRTIO_TXQ, 0);
2268     }
2269 }
2270
2271 /*
2272  * Fixes mapping for vhost-user tx queues. Must be called after each
2273  * enabling/disabling of queues and real_n_txq modifications.
2274  */
2275 static void
2276 netdev_dpdk_remap_txqs(struct netdev_dpdk *dev)
2277     OVS_REQUIRES(dev->mutex)
2278 {
2279     int *enabled_queues, n_enabled = 0;
2280     int i, k, total_txqs = dev->real_n_txq;
2281
2282     enabled_queues = dpdk_rte_mzalloc(total_txqs * sizeof *enabled_queues);
2283
2284     for (i = 0; i < total_txqs; i++) {
2285         /* Enabled queues always mapped to themselves. */
2286         if (dev->tx_q[i].map == i) {
2287             enabled_queues[n_enabled++] = i;
2288         }
2289     }
2290
2291     if (n_enabled == 0 && total_txqs != 0) {
2292         enabled_queues[0] = OVS_VHOST_QUEUE_DISABLED;
2293         n_enabled = 1;
2294     }
2295
2296     k = 0;
2297     for (i = 0; i < total_txqs; i++) {
2298         if (dev->tx_q[i].map != i) {
2299             dev->tx_q[i].map = enabled_queues[k];
2300             k = (k + 1) % n_enabled;
2301         }
2302     }
2303
2304     VLOG_DBG("TX queue mapping for %s\n", dev->vhost_id);
2305     for (i = 0; i < total_txqs; i++) {
2306         VLOG_DBG("%2d --> %2d", i, dev->tx_q[i].map);
2307     }
2308
2309     rte_free(enabled_queues);
2310 }
2311
2312 static int
2313 netdev_dpdk_vhost_set_queues(struct netdev_dpdk *dev, struct virtio_net *virtio_dev)
2314     OVS_REQUIRES(dev->mutex)
2315 {
2316     uint32_t qp_num;
2317
2318     qp_num = virtio_dev->virt_qp_nb;
2319     if (qp_num > dev->up.n_rxq) {
2320         VLOG_ERR("vHost Device '%s' %"PRIu64" can't be added - "
2321                  "too many queues %d > %d", virtio_dev->ifname, virtio_dev->device_fh,
2322                  qp_num, dev->up.n_rxq);
2323         return -1;
2324     }
2325
2326     dev->real_n_rxq = qp_num;
2327     dev->real_n_txq = qp_num;
2328     dev->txq_needs_locking = true;
2329     /* Enable TX queue 0 by default if it wasn't disabled. */
2330     if (dev->tx_q[0].map == OVS_VHOST_QUEUE_MAP_UNKNOWN) {
2331         dev->tx_q[0].map = 0;
2332     }
2333
2334     netdev_dpdk_remap_txqs(dev);
2335
2336     return 0;
2337 }
2338
2339 /*
2340  * A new virtio-net device is added to a vhost port.
2341  */
2342 static int
2343 new_device(struct virtio_net *virtio_dev)
2344 {
2345     struct netdev_dpdk *dev;
2346     bool exists = false;
2347
2348     ovs_mutex_lock(&dpdk_mutex);
2349     /* Add device to the vhost port with the same name as that passed down. */
2350     LIST_FOR_EACH(dev, list_node, &dpdk_list) {
2351         if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) {
2352             ovs_mutex_lock(&dev->mutex);
2353             if (netdev_dpdk_vhost_set_queues(dev, virtio_dev)) {
2354                 ovs_mutex_unlock(&dev->mutex);
2355                 ovs_mutex_unlock(&dpdk_mutex);
2356                 return -1;
2357             }
2358             ovsrcu_set(&dev->virtio_dev, virtio_dev);
2359             exists = true;
2360             virtio_dev->flags |= VIRTIO_DEV_RUNNING;
2361             /* Disable notifications. */
2362             set_irq_status(virtio_dev);
2363             netdev_change_seq_changed(&dev->up);
2364             ovs_mutex_unlock(&dev->mutex);
2365             break;
2366         }
2367     }
2368     ovs_mutex_unlock(&dpdk_mutex);
2369
2370     if (!exists) {
2371         VLOG_INFO("vHost Device '%s' %"PRIu64" can't be added - name not "
2372                   "found", virtio_dev->ifname, virtio_dev->device_fh);
2373
2374         return -1;
2375     }
2376
2377     VLOG_INFO("vHost Device '%s' %"PRIu64" has been added", virtio_dev->ifname,
2378               virtio_dev->device_fh);
2379     return 0;
2380 }
2381
2382 /* Clears mapping for all available queues of vhost interface. */
2383 static void
2384 netdev_dpdk_txq_map_clear(struct netdev_dpdk *dev)
2385     OVS_REQUIRES(dev->mutex)
2386 {
2387     int i;
2388
2389     for (i = 0; i < dev->real_n_txq; i++) {
2390         dev->tx_q[i].map = OVS_VHOST_QUEUE_MAP_UNKNOWN;
2391     }
2392 }
2393
2394 /*
2395  * Remove a virtio-net device from the specific vhost port.  Use dev->remove
2396  * flag to stop any more packets from being sent or received to/from a VM and
2397  * ensure all currently queued packets have been sent/received before removing
2398  *  the device.
2399  */
2400 static void
2401 destroy_device(volatile struct virtio_net *virtio_dev)
2402 {
2403     struct netdev_dpdk *dev;
2404     bool exists = false;
2405
2406     ovs_mutex_lock(&dpdk_mutex);
2407     LIST_FOR_EACH (dev, list_node, &dpdk_list) {
2408         if (netdev_dpdk_get_virtio(dev) == virtio_dev) {
2409
2410             ovs_mutex_lock(&dev->mutex);
2411             virtio_dev->flags &= ~VIRTIO_DEV_RUNNING;
2412             ovsrcu_set(&dev->virtio_dev, NULL);
2413             netdev_dpdk_txq_map_clear(dev);
2414             exists = true;
2415             netdev_change_seq_changed(&dev->up);
2416             ovs_mutex_unlock(&dev->mutex);
2417             break;
2418         }
2419     }
2420
2421     ovs_mutex_unlock(&dpdk_mutex);
2422
2423     if (exists == true) {
2424         /*
2425          * Wait for other threads to quiesce after setting the 'virtio_dev'
2426          * to NULL, before returning.
2427          */
2428         ovsrcu_synchronize();
2429         /*
2430          * As call to ovsrcu_synchronize() will end the quiescent state,
2431          * put thread back into quiescent state before returning.
2432          */
2433         ovsrcu_quiesce_start();
2434         VLOG_INFO("vHost Device '%s' %"PRIu64" has been removed",
2435                   virtio_dev->ifname, virtio_dev->device_fh);
2436     } else {
2437         VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname,
2438                   virtio_dev->device_fh);
2439     }
2440 }
2441
2442 static int
2443 vring_state_changed(struct virtio_net *virtio_dev, uint16_t queue_id,
2444                     int enable)
2445 {
2446     struct netdev_dpdk *dev;
2447     bool exists = false;
2448     int qid = queue_id / VIRTIO_QNUM;
2449
2450     if (queue_id % VIRTIO_QNUM == VIRTIO_TXQ) {
2451         return 0;
2452     }
2453
2454     ovs_mutex_lock(&dpdk_mutex);
2455     LIST_FOR_EACH (dev, list_node, &dpdk_list) {
2456         if (strncmp(virtio_dev->ifname, dev->vhost_id, IF_NAME_SZ) == 0) {
2457             ovs_mutex_lock(&dev->mutex);
2458             if (enable) {
2459                 dev->tx_q[qid].map = qid;
2460             } else {
2461                 dev->tx_q[qid].map = OVS_VHOST_QUEUE_DISABLED;
2462             }
2463             netdev_dpdk_remap_txqs(dev);
2464             exists = true;
2465             ovs_mutex_unlock(&dev->mutex);
2466             break;
2467         }
2468     }
2469     ovs_mutex_unlock(&dpdk_mutex);
2470
2471     if (exists) {
2472         VLOG_INFO("State of queue %d ( tx_qid %d ) of vhost device '%s' %"
2473                   PRIu64" changed to \'%s\'", queue_id, qid,
2474                   virtio_dev->ifname, virtio_dev->device_fh,
2475                   (enable == 1) ? "enabled" : "disabled");
2476     } else {
2477         VLOG_INFO("vHost Device '%s' %"PRIu64" not found", virtio_dev->ifname,
2478                   virtio_dev->device_fh);
2479         return -1;
2480     }
2481
2482     return 0;
2483 }
2484
2485 struct virtio_net *
2486 netdev_dpdk_get_virtio(const struct netdev_dpdk *dev)
2487 {
2488     return ovsrcu_get(struct virtio_net *, &dev->virtio_dev);
2489 }
2490
2491 struct ingress_policer *
2492 netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev)
2493 {
2494     return ovsrcu_get(struct ingress_policer *, &dev->ingress_policer);
2495 }
2496
2497 /*
2498  * These callbacks allow virtio-net devices to be added to vhost ports when
2499  * configuration has been fully complete.
2500  */
2501 static const struct virtio_net_device_ops virtio_net_device_ops =
2502 {
2503     .new_device =  new_device,
2504     .destroy_device = destroy_device,
2505     .vring_state_changed = vring_state_changed
2506 };
2507
2508 static void *
2509 start_vhost_loop(void *dummy OVS_UNUSED)
2510 {
2511      pthread_detach(pthread_self());
2512      /* Put the cuse thread into quiescent state. */
2513      ovsrcu_quiesce_start();
2514      rte_vhost_driver_session_start();
2515      return NULL;
2516 }
2517
2518 static int
2519 dpdk_vhost_class_init(void)
2520 {
2521     rte_vhost_driver_callback_register(&virtio_net_device_ops);
2522     rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4
2523                             | 1ULL << VIRTIO_NET_F_HOST_TSO6
2524                             | 1ULL << VIRTIO_NET_F_CSUM);
2525
2526     ovs_thread_create("vhost_thread", start_vhost_loop, NULL);
2527     return 0;
2528 }
2529
2530 static int
2531 dpdk_vhost_cuse_class_init(void)
2532 {
2533     return 0;
2534 }
2535
2536 static int
2537 dpdk_vhost_user_class_init(void)
2538 {
2539     return 0;
2540 }
2541
2542 static void
2543 dpdk_common_init(void)
2544 {
2545     unixctl_command_register("netdev-dpdk/set-admin-state",
2546                              "[netdev] up|down", 1, 2,
2547                              netdev_dpdk_set_admin_state, NULL);
2548
2549 }
2550
2551 /* Client Rings */
2552
2553 static int
2554 dpdk_ring_create(const char dev_name[], unsigned int port_no,
2555                  unsigned int *eth_port_id)
2556 {
2557     struct dpdk_ring *ivshmem;
2558     char ring_name[RTE_RING_NAMESIZE];
2559     int err;
2560
2561     ivshmem = dpdk_rte_mzalloc(sizeof *ivshmem);
2562     if (ivshmem == NULL) {
2563         return ENOMEM;
2564     }
2565
2566     /* XXX: Add support for multiquque ring. */
2567     err = snprintf(ring_name, sizeof(ring_name), "%s_tx", dev_name);
2568     if (err < 0) {
2569         return -err;
2570     }
2571
2572     /* Create single producer tx ring, netdev does explicit locking. */
2573     ivshmem->cring_tx = rte_ring_create(ring_name, DPDK_RING_SIZE, SOCKET0,
2574                                         RING_F_SP_ENQ);
2575     if (ivshmem->cring_tx == NULL) {
2576         rte_free(ivshmem);
2577         return ENOMEM;
2578     }
2579
2580     err = snprintf(ring_name, sizeof(ring_name), "%s_rx", dev_name);
2581     if (err < 0) {
2582         return -err;
2583     }
2584
2585     /* Create single consumer rx ring, netdev does explicit locking. */
2586     ivshmem->cring_rx = rte_ring_create(ring_name, DPDK_RING_SIZE, SOCKET0,
2587                                         RING_F_SC_DEQ);
2588     if (ivshmem->cring_rx == NULL) {
2589         rte_free(ivshmem);
2590         return ENOMEM;
2591     }
2592
2593     err = rte_eth_from_rings(dev_name, &ivshmem->cring_rx, 1,
2594                              &ivshmem->cring_tx, 1, SOCKET0);
2595
2596     if (err < 0) {
2597         rte_free(ivshmem);
2598         return ENODEV;
2599     }
2600
2601     ivshmem->user_port_id = port_no;
2602     ivshmem->eth_port_id = rte_eth_dev_count() - 1;
2603     ovs_list_push_back(&dpdk_ring_list, &ivshmem->list_node);
2604
2605     *eth_port_id = ivshmem->eth_port_id;
2606     return 0;
2607 }
2608
2609 static int
2610 dpdk_ring_open(const char dev_name[], unsigned int *eth_port_id) OVS_REQUIRES(dpdk_mutex)
2611 {
2612     struct dpdk_ring *ivshmem;
2613     unsigned int port_no;
2614     int err = 0;
2615
2616     /* Names always start with "dpdkr" */
2617     err = dpdk_dev_parse_name(dev_name, "dpdkr", &port_no);
2618     if (err) {
2619         return err;
2620     }
2621
2622     /* look through our list to find the device */
2623     LIST_FOR_EACH (ivshmem, list_node, &dpdk_ring_list) {
2624          if (ivshmem->user_port_id == port_no) {
2625             VLOG_INFO("Found dpdk ring device %s:", dev_name);
2626             *eth_port_id = ivshmem->eth_port_id; /* really all that is needed */
2627             return 0;
2628          }
2629     }
2630     /* Need to create the device rings */
2631     return dpdk_ring_create(dev_name, port_no, eth_port_id);
2632 }
2633
2634 static int
2635 netdev_dpdk_ring_send(struct netdev *netdev, int qid,
2636                       struct dp_packet **pkts, int cnt, bool may_steal)
2637 {
2638     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2639     unsigned i;
2640
2641     /* When using 'dpdkr' and sending to a DPDK ring, we want to ensure that the
2642      * rss hash field is clear. This is because the same mbuf may be modified by
2643      * the consumer of the ring and return into the datapath without recalculating
2644      * the RSS hash. */
2645     for (i = 0; i < cnt; i++) {
2646         dp_packet_rss_invalidate(pkts[i]);
2647     }
2648
2649     netdev_dpdk_send__(dev, qid, pkts, cnt, may_steal);
2650     return 0;
2651 }
2652
2653 static int
2654 netdev_dpdk_ring_construct(struct netdev *netdev)
2655 {
2656     unsigned int port_no = 0;
2657     int err = 0;
2658
2659     if (rte_eal_init_ret) {
2660         return rte_eal_init_ret;
2661     }
2662
2663     ovs_mutex_lock(&dpdk_mutex);
2664
2665     err = dpdk_ring_open(netdev->name, &port_no);
2666     if (err) {
2667         goto unlock_dpdk;
2668     }
2669
2670     err = netdev_dpdk_init(netdev, port_no, DPDK_DEV_ETH);
2671
2672 unlock_dpdk:
2673     ovs_mutex_unlock(&dpdk_mutex);
2674     return err;
2675 }
2676
2677 /* QoS Functions */
2678
2679 /*
2680  * Initialize QoS configuration operations.
2681  */
2682 static void
2683 qos_conf_init(struct qos_conf *conf, const struct dpdk_qos_ops *ops)
2684 {
2685     conf->ops = ops;
2686 }
2687
2688 /*
2689  * Search existing QoS operations in qos_ops and compare each set of
2690  * operations qos_name to name. Return a dpdk_qos_ops pointer to a match,
2691  * else return NULL
2692  */
2693 static const struct dpdk_qos_ops *
2694 qos_lookup_name(const char *name)
2695 {
2696     const struct dpdk_qos_ops *const *opsp;
2697
2698     for (opsp = qos_confs; *opsp != NULL; opsp++) {
2699         const struct dpdk_qos_ops *ops = *opsp;
2700         if (!strcmp(name, ops->qos_name)) {
2701             return ops;
2702         }
2703     }
2704     return NULL;
2705 }
2706
2707 /*
2708  * Call qos_destruct to clean up items associated with the netdevs
2709  * qos_conf. Set netdevs qos_conf to NULL.
2710  */
2711 static void
2712 qos_delete_conf(struct netdev *netdev)
2713 {
2714     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2715
2716     rte_spinlock_lock(&dev->qos_lock);
2717     if (dev->qos_conf) {
2718         if (dev->qos_conf->ops->qos_destruct) {
2719             dev->qos_conf->ops->qos_destruct(netdev, dev->qos_conf);
2720         }
2721         dev->qos_conf = NULL;
2722     }
2723     rte_spinlock_unlock(&dev->qos_lock);
2724 }
2725
2726 static int
2727 netdev_dpdk_get_qos_types(const struct netdev *netdev OVS_UNUSED,
2728                            struct sset *types)
2729 {
2730     const struct dpdk_qos_ops *const *opsp;
2731
2732     for (opsp = qos_confs; *opsp != NULL; opsp++) {
2733         const struct dpdk_qos_ops *ops = *opsp;
2734         if (ops->qos_construct && ops->qos_name[0] != '\0') {
2735             sset_add(types, ops->qos_name);
2736         }
2737     }
2738     return 0;
2739 }
2740
2741 static int
2742 netdev_dpdk_get_qos(const struct netdev *netdev,
2743                     const char **typep, struct smap *details)
2744 {
2745     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2746     int error = 0;
2747
2748     ovs_mutex_lock(&dev->mutex);
2749     if(dev->qos_conf) {
2750         *typep = dev->qos_conf->ops->qos_name;
2751         error = (dev->qos_conf->ops->qos_get
2752                  ? dev->qos_conf->ops->qos_get(netdev, details): 0);
2753     }
2754     ovs_mutex_unlock(&dev->mutex);
2755
2756     return error;
2757 }
2758
2759 static int
2760 netdev_dpdk_set_qos(struct netdev *netdev,
2761                     const char *type, const struct smap *details)
2762 {
2763     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2764     const struct dpdk_qos_ops *new_ops = NULL;
2765     int error = 0;
2766
2767     /* If type is empty or unsupported then the current QoS configuration
2768      * for the dpdk-netdev can be destroyed */
2769     new_ops = qos_lookup_name(type);
2770
2771     if (type[0] == '\0' || !new_ops || !new_ops->qos_construct) {
2772         qos_delete_conf(netdev);
2773         return EOPNOTSUPP;
2774     }
2775
2776     ovs_mutex_lock(&dev->mutex);
2777
2778     if (dev->qos_conf) {
2779         if (new_ops == dev->qos_conf->ops) {
2780             error = new_ops->qos_set ? new_ops->qos_set(netdev, details) : 0;
2781         } else {
2782             /* Delete existing QoS configuration. */
2783             qos_delete_conf(netdev);
2784             ovs_assert(dev->qos_conf == NULL);
2785
2786             /* Install new QoS configuration. */
2787             error = new_ops->qos_construct(netdev, details);
2788             ovs_assert((error == 0) == (dev->qos_conf != NULL));
2789         }
2790     } else {
2791         error = new_ops->qos_construct(netdev, details);
2792         ovs_assert((error == 0) == (dev->qos_conf != NULL));
2793     }
2794
2795     ovs_mutex_unlock(&dev->mutex);
2796     return error;
2797 }
2798
2799 /* egress-policer details */
2800
2801 struct egress_policer {
2802     struct qos_conf qos_conf;
2803     struct rte_meter_srtcm_params app_srtcm_params;
2804     struct rte_meter_srtcm egress_meter;
2805 };
2806
2807 static struct egress_policer *
2808 egress_policer_get__(const struct netdev *netdev)
2809 {
2810     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2811     return CONTAINER_OF(dev->qos_conf, struct egress_policer, qos_conf);
2812 }
2813
2814 static int
2815 egress_policer_qos_construct(struct netdev *netdev,
2816                              const struct smap *details)
2817 {
2818     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2819     struct egress_policer *policer;
2820     const char *cir_s;
2821     const char *cbs_s;
2822     int err = 0;
2823
2824     rte_spinlock_lock(&dev->qos_lock);
2825     policer = xmalloc(sizeof *policer);
2826     qos_conf_init(&policer->qos_conf, &egress_policer_ops);
2827     dev->qos_conf = &policer->qos_conf;
2828     cir_s = smap_get(details, "cir");
2829     cbs_s = smap_get(details, "cbs");
2830     policer->app_srtcm_params.cir = cir_s ? strtoull(cir_s, NULL, 10) : 0;
2831     policer->app_srtcm_params.cbs = cbs_s ? strtoull(cbs_s, NULL, 10) : 0;
2832     policer->app_srtcm_params.ebs = 0;
2833     err = rte_meter_srtcm_config(&policer->egress_meter,
2834                                     &policer->app_srtcm_params);
2835     rte_spinlock_unlock(&dev->qos_lock);
2836
2837     return err;
2838 }
2839
2840 static void
2841 egress_policer_qos_destruct(struct netdev *netdev OVS_UNUSED,
2842                         struct qos_conf *conf)
2843 {
2844     struct egress_policer *policer = CONTAINER_OF(conf, struct egress_policer,
2845                                                 qos_conf);
2846     free(policer);
2847 }
2848
2849 static int
2850 egress_policer_qos_get(const struct netdev *netdev, struct smap *details)
2851 {
2852     struct egress_policer *policer = egress_policer_get__(netdev);
2853     smap_add_format(details, "cir", "%llu",
2854                     1ULL * policer->app_srtcm_params.cir);
2855     smap_add_format(details, "cbs", "%llu",
2856                     1ULL * policer->app_srtcm_params.cbs);
2857
2858     return 0;
2859 }
2860
2861 static int
2862 egress_policer_qos_set(struct netdev *netdev, const struct smap *details)
2863 {
2864     struct egress_policer *policer;
2865     const char *cir_s;
2866     const char *cbs_s;
2867     int err = 0;
2868
2869     policer = egress_policer_get__(netdev);
2870     cir_s = smap_get(details, "cir");
2871     cbs_s = smap_get(details, "cbs");
2872     policer->app_srtcm_params.cir = cir_s ? strtoull(cir_s, NULL, 10) : 0;
2873     policer->app_srtcm_params.cbs = cbs_s ? strtoull(cbs_s, NULL, 10) : 0;
2874     policer->app_srtcm_params.ebs = 0;
2875     err = rte_meter_srtcm_config(&policer->egress_meter,
2876                                     &policer->app_srtcm_params);
2877
2878     return err;
2879 }
2880
2881 static int
2882 egress_policer_run(struct netdev *netdev, struct rte_mbuf **pkts, int pkt_cnt)
2883 {
2884     int cnt = 0;
2885     struct egress_policer *policer = egress_policer_get__(netdev);
2886
2887     cnt = netdev_dpdk_policer_run(&policer->egress_meter, pkts, pkt_cnt);
2888
2889     return cnt;
2890 }
2891
2892 static const struct dpdk_qos_ops egress_policer_ops = {
2893     "egress-policer",    /* qos_name */
2894     egress_policer_qos_construct,
2895     egress_policer_qos_destruct,
2896     egress_policer_qos_get,
2897     egress_policer_qos_set,
2898     egress_policer_run
2899 };
2900
2901 static int
2902 netdev_dpdk_reconfigure(struct netdev *netdev)
2903 {
2904     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2905     int err = 0;
2906
2907     ovs_mutex_lock(&dpdk_mutex);
2908     ovs_mutex_lock(&dev->mutex);
2909
2910     if (netdev->n_txq == dev->requested_n_txq
2911         && netdev->n_rxq == dev->requested_n_rxq) {
2912         /* Reconfiguration is unnecessary */
2913
2914         goto out;
2915     }
2916
2917     rte_eth_dev_stop(dev->port_id);
2918
2919     netdev->n_txq = dev->requested_n_txq;
2920     netdev->n_rxq = dev->requested_n_rxq;
2921
2922     rte_free(dev->tx_q);
2923     err = dpdk_eth_dev_init(dev);
2924     netdev_dpdk_alloc_txq(dev, dev->real_n_txq);
2925
2926     dev->txq_needs_locking = dev->real_n_txq != netdev->n_txq;
2927
2928 out:
2929
2930     ovs_mutex_unlock(&dev->mutex);
2931     ovs_mutex_unlock(&dpdk_mutex);
2932
2933     return err;
2934 }
2935
2936 static int
2937 netdev_dpdk_vhost_user_reconfigure(struct netdev *netdev)
2938 {
2939     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2940
2941     ovs_mutex_lock(&dpdk_mutex);
2942     ovs_mutex_lock(&dev->mutex);
2943
2944     netdev->n_txq = dev->requested_n_txq;
2945     netdev->n_rxq = dev->requested_n_rxq;
2946
2947     ovs_mutex_unlock(&dev->mutex);
2948     ovs_mutex_unlock(&dpdk_mutex);
2949
2950     return 0;
2951 }
2952
2953 static int
2954 netdev_dpdk_vhost_cuse_reconfigure(struct netdev *netdev)
2955 {
2956     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
2957
2958     ovs_mutex_lock(&dpdk_mutex);
2959     ovs_mutex_lock(&dev->mutex);
2960
2961     netdev->n_txq = dev->requested_n_txq;
2962     dev->real_n_txq = 1;
2963     netdev->n_rxq = 1;
2964     dev->txq_needs_locking = dev->real_n_txq != netdev->n_txq;
2965
2966     ovs_mutex_unlock(&dev->mutex);
2967     ovs_mutex_unlock(&dpdk_mutex);
2968
2969     return 0;
2970 }
2971
2972 #define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT, SEND, \
2973                           GET_CARRIER, GET_STATS, GET_FEATURES,  \
2974                           GET_STATUS, RECONFIGURE, RXQ_RECV)     \
2975 {                                                             \
2976     NAME,                                                     \
2977     true,                       /* is_pmd */                  \
2978     INIT,                       /* init */                    \
2979     NULL,                       /* netdev_dpdk_run */         \
2980     NULL,                       /* netdev_dpdk_wait */        \
2981                                                               \
2982     netdev_dpdk_alloc,                                        \
2983     CONSTRUCT,                                                \
2984     DESTRUCT,                                                 \
2985     netdev_dpdk_dealloc,                                      \
2986     netdev_dpdk_get_config,                                   \
2987     netdev_dpdk_set_config,                                   \
2988     NULL,                       /* get_tunnel_config */       \
2989     NULL,                       /* build header */            \
2990     NULL,                       /* push header */             \
2991     NULL,                       /* pop header */              \
2992     netdev_dpdk_get_numa_id,    /* get_numa_id */             \
2993     netdev_dpdk_set_tx_multiq,                                \
2994                                                               \
2995     SEND,                       /* send */                    \
2996     NULL,                       /* send_wait */               \
2997                                                               \
2998     netdev_dpdk_set_etheraddr,                                \
2999     netdev_dpdk_get_etheraddr,                                \
3000     netdev_dpdk_get_mtu,                                      \
3001     netdev_dpdk_set_mtu,                                      \
3002     netdev_dpdk_get_ifindex,                                  \
3003     GET_CARRIER,                                              \
3004     netdev_dpdk_get_carrier_resets,                           \
3005     netdev_dpdk_set_miimon,                                   \
3006     GET_STATS,                                                \
3007     GET_FEATURES,                                             \
3008     NULL,                       /* set_advertisements */      \
3009                                                               \
3010     netdev_dpdk_set_policing,                                 \
3011     netdev_dpdk_get_qos_types,                                \
3012     NULL,                       /* get_qos_capabilities */    \
3013     netdev_dpdk_get_qos,                                      \
3014     netdev_dpdk_set_qos,                                      \
3015     NULL,                       /* get_queue */               \
3016     NULL,                       /* set_queue */               \
3017     NULL,                       /* delete_queue */            \
3018     NULL,                       /* get_queue_stats */         \
3019     NULL,                       /* queue_dump_start */        \
3020     NULL,                       /* queue_dump_next */         \
3021     NULL,                       /* queue_dump_done */         \
3022     NULL,                       /* dump_queue_stats */        \
3023                                                               \
3024     NULL,                       /* set_in4 */                 \
3025     NULL,                       /* get_addr_list */           \
3026     NULL,                       /* add_router */              \
3027     NULL,                       /* get_next_hop */            \
3028     GET_STATUS,                                               \
3029     NULL,                       /* arp_lookup */              \
3030                                                               \
3031     netdev_dpdk_update_flags,                                 \
3032     RECONFIGURE,                                              \
3033                                                               \
3034     netdev_dpdk_rxq_alloc,                                    \
3035     netdev_dpdk_rxq_construct,                                \
3036     netdev_dpdk_rxq_destruct,                                 \
3037     netdev_dpdk_rxq_dealloc,                                  \
3038     RXQ_RECV,                                                 \
3039     NULL,                       /* rx_wait */                 \
3040     NULL,                       /* rxq_drain */               \
3041 }
3042
3043 static int
3044 process_vhost_flags(char *flag, char *default_val, int size,
3045                     const struct smap *ovs_other_config,
3046                     char **new_val)
3047 {
3048     const char *val;
3049     int changed = 0;
3050
3051     val = smap_get(ovs_other_config, flag);
3052
3053     /* Depending on which version of vhost is in use, process the vhost-specific
3054      * flag if it is provided, otherwise resort to default value.
3055      */
3056     if (val && (strlen(val) <= size)) {
3057         changed = 1;
3058         *new_val = xstrdup(val);
3059         VLOG_INFO("User-provided %s in use: %s", flag, *new_val);
3060     } else {
3061         VLOG_INFO("No %s provided - defaulting to %s", flag, default_val);
3062         *new_val = default_val;
3063     }
3064
3065     return changed;
3066 }
3067
3068 static char **
3069 grow_argv(char ***argv, size_t cur_siz, size_t grow_by)
3070 {
3071     return xrealloc(*argv, sizeof(char *) * (cur_siz + grow_by));
3072 }
3073
3074 static void
3075 dpdk_option_extend(char ***argv, int argc, const char *option,
3076                    const char *value)
3077 {
3078     char **newargv = grow_argv(argv, argc, 2);
3079     *argv = newargv;
3080     newargv[argc] = xstrdup(option);
3081     newargv[argc+1] = xstrdup(value);
3082 }
3083
3084 static char **
3085 move_argv(char ***argv, size_t cur_size, char **src_argv, size_t src_argc)
3086 {
3087     char **newargv = grow_argv(argv, cur_size, src_argc);
3088     while (src_argc--) {
3089         newargv[cur_size+src_argc] = src_argv[src_argc];
3090         src_argv[src_argc] = NULL;
3091     }
3092     return newargv;
3093 }
3094
3095 static int
3096 extra_dpdk_args(const char *ovs_extra_config, char ***argv, int argc)
3097 {
3098     int ret = argc;
3099     char *release_tok = xstrdup(ovs_extra_config);
3100     char *tok = release_tok, *endptr = NULL;
3101
3102     for (tok = strtok_r(release_tok, " ", &endptr); tok != NULL;
3103          tok = strtok_r(NULL, " ", &endptr)) {
3104         char **newarg = grow_argv(argv, ret, 1);
3105         *argv = newarg;
3106         newarg[ret++] = xstrdup(tok);
3107     }
3108     free(release_tok);
3109     return ret;
3110 }
3111
3112 static bool
3113 argv_contains(char **argv_haystack, const size_t argc_haystack,
3114               const char *needle)
3115 {
3116     for (size_t i = 0; i < argc_haystack; ++i) {
3117         if (!strcmp(argv_haystack[i], needle))
3118             return true;
3119     }
3120     return false;
3121 }
3122
3123 static int
3124 construct_dpdk_options(const struct smap *ovs_other_config,
3125                        char ***argv, const int initial_size,
3126                        char **extra_args, const size_t extra_argc)
3127 {
3128     struct dpdk_options_map {
3129         const char *ovs_configuration;
3130         const char *dpdk_option;
3131         bool default_enabled;
3132         const char *default_value;
3133     } opts[] = {
3134         {"dpdk-lcore-mask", "-c", false, NULL},
3135         {"dpdk-hugepage-dir", "--huge-dir", false, NULL},
3136     };
3137
3138     int i, ret = initial_size;
3139
3140     /*First, construct from the flat-options (non-mutex)*/
3141     for (i = 0; i < ARRAY_SIZE(opts); ++i) {
3142         const char *lookup = smap_get(ovs_other_config,
3143                                       opts[i].ovs_configuration);
3144         if (!lookup && opts[i].default_enabled) {
3145             lookup = opts[i].default_value;
3146         }
3147
3148         if (lookup) {
3149             if (!argv_contains(extra_args, extra_argc, opts[i].dpdk_option)) {
3150                 dpdk_option_extend(argv, ret, opts[i].dpdk_option, lookup);
3151                 ret += 2;
3152             } else {
3153                 VLOG_WARN("Ignoring database defined option '%s' due to "
3154                           "dpdk_extras config", opts[i].dpdk_option);
3155             }
3156         }
3157     }
3158
3159     return ret;
3160 }
3161
3162 #define MAX_DPDK_EXCL_OPTS 10
3163
3164 static int
3165 construct_dpdk_mutex_options(const struct smap *ovs_other_config,
3166                              char ***argv, const int initial_size,
3167                              char **extra_args, const size_t extra_argc)
3168 {
3169     struct dpdk_exclusive_options_map {
3170         const char *category;
3171         const char *ovs_dpdk_options[MAX_DPDK_EXCL_OPTS];
3172         const char *eal_dpdk_options[MAX_DPDK_EXCL_OPTS];
3173         const char *default_value;
3174         int default_option;
3175     } excl_opts[] = {
3176         {"memory type",
3177          {"dpdk-alloc-mem", "dpdk-socket-mem", NULL,},
3178          {"-m",             "--socket-mem",    NULL,},
3179          "1024,0", 1
3180         },
3181     };
3182
3183     int i, ret = initial_size;
3184     for (i = 0; i < ARRAY_SIZE(excl_opts); ++i) {
3185         int found_opts = 0, scan, found_pos = -1;
3186         const char *found_value;
3187         struct dpdk_exclusive_options_map *popt = &excl_opts[i];
3188
3189         for (scan = 0; scan < MAX_DPDK_EXCL_OPTS
3190                  && popt->ovs_dpdk_options[scan]; ++scan) {
3191             const char *lookup = smap_get(ovs_other_config,
3192                                           popt->ovs_dpdk_options[scan]);
3193             if (lookup && strlen(lookup)) {
3194                 found_opts++;
3195                 found_pos = scan;
3196                 found_value = lookup;
3197             }
3198         }
3199
3200         if (!found_opts) {
3201             if (popt->default_option) {
3202                 found_pos = popt->default_option;
3203                 found_value = popt->default_value;
3204             } else {
3205                 continue;
3206             }
3207         }
3208
3209         if (found_opts > 1) {
3210             VLOG_ERR("Multiple defined options for %s. Please check your"
3211                      " database settings and reconfigure if necessary.",
3212                      popt->category);
3213         }
3214
3215         if (!argv_contains(extra_args, extra_argc,
3216                            popt->eal_dpdk_options[found_pos])) {
3217             dpdk_option_extend(argv, ret, popt->eal_dpdk_options[found_pos],
3218                                found_value);
3219             ret += 2;
3220         } else {
3221             VLOG_WARN("Ignoring database defined option '%s' due to "
3222                       "dpdk_extras config", popt->eal_dpdk_options[found_pos]);
3223         }
3224     }
3225
3226     return ret;
3227 }
3228
3229 static int
3230 get_dpdk_args(const struct smap *ovs_other_config, char ***argv,
3231               int argc)
3232 {
3233     const char *extra_configuration;
3234     char **extra_args = NULL;
3235     int i;
3236     size_t extra_argc = 0;
3237
3238     extra_configuration = smap_get(ovs_other_config, "dpdk-extra");
3239     if (extra_configuration) {
3240         extra_argc = extra_dpdk_args(extra_configuration, &extra_args, 0);
3241     }
3242
3243     i = construct_dpdk_options(ovs_other_config, argv, argc, extra_args,
3244                                extra_argc);
3245     i = construct_dpdk_mutex_options(ovs_other_config, argv, i, extra_args,
3246                                      extra_argc);
3247
3248     if (extra_configuration) {
3249         *argv = move_argv(argv, i, extra_args, extra_argc);
3250     }
3251
3252     return i + extra_argc;
3253 }
3254
3255 static char **dpdk_argv;
3256 static int dpdk_argc;
3257
3258 static void
3259 deferred_argv_release(void)
3260 {
3261     int result;
3262     for (result = 0; result < dpdk_argc; ++result) {
3263         free(dpdk_argv[result]);
3264     }
3265
3266     free(dpdk_argv);
3267 }
3268
3269 static void
3270 dpdk_init__(const struct smap *ovs_other_config)
3271 {
3272     char **argv = NULL;
3273     int result;
3274     int argc, argc_tmp;
3275     bool auto_determine = true;
3276     int err = 0;
3277     cpu_set_t cpuset;
3278 #ifndef VHOST_CUSE
3279     char *sock_dir_subcomponent;
3280 #endif
3281
3282     if (!smap_get_bool(ovs_other_config, "dpdk-init", false)) {
3283         VLOG_INFO("DPDK Disabled - to change this requires a restart.\n");
3284         return;
3285     }
3286
3287     VLOG_INFO("DPDK Enabled, initializing");
3288
3289 #ifdef VHOST_CUSE
3290     if (process_vhost_flags("cuse-dev-name", xstrdup("vhost-net"),
3291                             PATH_MAX, ovs_other_config, &cuse_dev_name)) {
3292 #else
3293     if (process_vhost_flags("vhost-sock-dir", xstrdup(ovs_rundir()),
3294                             NAME_MAX, ovs_other_config,
3295                             &sock_dir_subcomponent)) {
3296         struct stat s;
3297         if (!strstr(sock_dir_subcomponent, "..")) {
3298             vhost_sock_dir = xasprintf("%s/%s", ovs_rundir(),
3299                                        sock_dir_subcomponent);
3300
3301             err = stat(vhost_sock_dir, &s);
3302             if (err) {
3303                 VLOG_ERR("vhost-user sock directory '%s' does not exist.",
3304                          vhost_sock_dir);
3305             }
3306         } else {
3307             vhost_sock_dir = xstrdup(ovs_rundir());
3308             VLOG_ERR("vhost-user sock directory request '%s/%s' has invalid"
3309                      "characters '..' - using %s instead.",
3310                      ovs_rundir(), sock_dir_subcomponent, ovs_rundir());
3311         }
3312         free(sock_dir_subcomponent);
3313     } else {
3314         vhost_sock_dir = sock_dir_subcomponent;
3315 #endif
3316     }
3317
3318     argv = grow_argv(&argv, 0, 1);
3319     argc = 1;
3320     argv[0] = xstrdup(ovs_get_program_name());
3321     argc_tmp = get_dpdk_args(ovs_other_config, &argv, argc);
3322
3323     while (argc_tmp != argc) {
3324         if (!strcmp("-c", argv[argc]) || !strcmp("-l", argv[argc])) {
3325             auto_determine = false;
3326             break;
3327         }
3328         argc++;
3329     }
3330     argc = argc_tmp;
3331
3332     /**
3333      * NOTE: This is an unsophisticated mechanism for determining the DPDK
3334      * lcore for the DPDK Master.
3335      */
3336     if (auto_determine) {
3337         int i;
3338         /* Get the main thread affinity */
3339         CPU_ZERO(&cpuset);
3340         err = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t),
3341                                      &cpuset);
3342         if (!err) {
3343             for (i = 0; i < CPU_SETSIZE; i++) {
3344                 if (CPU_ISSET(i, &cpuset)) {
3345                     argv = grow_argv(&argv, argc, 2);
3346                     argv[argc++] = xstrdup("-c");
3347                     argv[argc++] = xasprintf("0x%08llX", (1ULL<<i));
3348                     i = CPU_SETSIZE;
3349                 }
3350             }
3351         } else {
3352             VLOG_ERR("Thread getaffinity error %d. Using core 0x1", err);
3353             /* User did not set dpdk-lcore-mask and unable to get current
3354              * thread affintity - default to core 0x1 */
3355             argv = grow_argv(&argv, argc, 2);
3356             argv[argc++] = xstrdup("-c");
3357             argv[argc++] = xasprintf("0x%X", 1);
3358         }
3359     }
3360
3361     argv = grow_argv(&argv, argc, 1);
3362     argv[argc] = NULL;
3363
3364     optind = 1;
3365
3366     if (VLOG_IS_INFO_ENABLED()) {
3367         struct ds eal_args;
3368         int opt;
3369         ds_init(&eal_args);
3370         ds_put_cstr(&eal_args, "EAL ARGS:");
3371         for (opt = 0; opt < argc; ++opt) {
3372             ds_put_cstr(&eal_args, " ");
3373             ds_put_cstr(&eal_args, argv[opt]);
3374         }
3375         VLOG_INFO("%s", ds_cstr_ro(&eal_args));
3376         ds_destroy(&eal_args);
3377     }
3378
3379     /* Make sure things are initialized ... */
3380     result = rte_eal_init(argc, argv);
3381     if (result < 0) {
3382         ovs_abort(result, "Cannot init EAL");
3383     }
3384
3385     /* Set the main thread affinity back to pre rte_eal_init() value */
3386     if (auto_determine && !err) {
3387         err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t),
3388                                      &cpuset);
3389         if (err) {
3390             VLOG_ERR("Thread setaffinity error %d", err);
3391         }
3392     }
3393
3394     dpdk_argv = argv;
3395     dpdk_argc = argc;
3396
3397     atexit(deferred_argv_release);
3398
3399     rte_memzone_dump(stdout);
3400     rte_eal_init_ret = 0;
3401
3402     /* We are called from the main thread here */
3403     RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID;
3404
3405     ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
3406
3407 #ifdef VHOST_CUSE
3408     /* Register CUSE device to handle IOCTLs.
3409      * Unless otherwise specified, cuse_dev_name is set to vhost-net.
3410      */
3411     err = rte_vhost_driver_register(cuse_dev_name);
3412
3413     if (err != 0) {
3414         VLOG_ERR("CUSE device setup failure.");
3415         return;
3416     }
3417 #endif
3418
3419     dpdk_vhost_class_init();
3420
3421     /* Finally, register the dpdk classes */
3422     netdev_dpdk_register();
3423 }
3424
3425 void
3426 dpdk_init(const struct smap *ovs_other_config)
3427 {
3428     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
3429
3430     if (ovs_other_config && ovsthread_once_start(&once)) {
3431         dpdk_init__(ovs_other_config);
3432         ovsthread_once_done(&once);
3433     }
3434 }
3435
3436 static const struct netdev_class dpdk_class =
3437     NETDEV_DPDK_CLASS(
3438         "dpdk",
3439         NULL,
3440         netdev_dpdk_construct,
3441         netdev_dpdk_destruct,
3442         netdev_dpdk_eth_send,
3443         netdev_dpdk_get_carrier,
3444         netdev_dpdk_get_stats,
3445         netdev_dpdk_get_features,
3446         netdev_dpdk_get_status,
3447         netdev_dpdk_reconfigure,
3448         netdev_dpdk_rxq_recv);
3449
3450 static const struct netdev_class dpdk_ring_class =
3451     NETDEV_DPDK_CLASS(
3452         "dpdkr",
3453         NULL,
3454         netdev_dpdk_ring_construct,
3455         netdev_dpdk_destruct,
3456         netdev_dpdk_ring_send,
3457         netdev_dpdk_get_carrier,
3458         netdev_dpdk_get_stats,
3459         netdev_dpdk_get_features,
3460         netdev_dpdk_get_status,
3461         netdev_dpdk_reconfigure,
3462         netdev_dpdk_rxq_recv);
3463
3464 static const struct netdev_class OVS_UNUSED dpdk_vhost_cuse_class =
3465     NETDEV_DPDK_CLASS(
3466         "dpdkvhostcuse",
3467         dpdk_vhost_cuse_class_init,
3468         netdev_dpdk_vhost_cuse_construct,
3469         netdev_dpdk_vhost_destruct,
3470         netdev_dpdk_vhost_send,
3471         netdev_dpdk_vhost_get_carrier,
3472         netdev_dpdk_vhost_get_stats,
3473         NULL,
3474         NULL,
3475         netdev_dpdk_vhost_cuse_reconfigure,
3476         netdev_dpdk_vhost_rxq_recv);
3477
3478 static const struct netdev_class OVS_UNUSED dpdk_vhost_user_class =
3479     NETDEV_DPDK_CLASS(
3480         "dpdkvhostuser",
3481         dpdk_vhost_user_class_init,
3482         netdev_dpdk_vhost_user_construct,
3483         netdev_dpdk_vhost_destruct,
3484         netdev_dpdk_vhost_send,
3485         netdev_dpdk_vhost_get_carrier,
3486         netdev_dpdk_vhost_get_stats,
3487         NULL,
3488         NULL,
3489         netdev_dpdk_vhost_user_reconfigure,
3490         netdev_dpdk_vhost_rxq_recv);
3491
3492 void
3493 netdev_dpdk_register(void)
3494 {
3495     dpdk_common_init();
3496     netdev_register_provider(&dpdk_class);
3497     netdev_register_provider(&dpdk_ring_class);
3498 #ifdef VHOST_CUSE
3499     netdev_register_provider(&dpdk_vhost_cuse_class);
3500 #else
3501     netdev_register_provider(&dpdk_vhost_user_class);
3502 #endif
3503 }
3504
3505 void
3506 dpdk_set_lcore_id(unsigned cpu)
3507 {
3508     /* NON_PMD_CORE_ID is reserved for use by non pmd threads. */
3509     ovs_assert(cpu != NON_PMD_CORE_ID);
3510     RTE_PER_LCORE(_lcore_id) = cpu;
3511 }
3512
3513 static bool
3514 dpdk_thread_is_pmd(void)
3515 {
3516     return rte_lcore_id() != NON_PMD_CORE_ID;
3517 }