netdev-dpdk: Refactor dpdk_class_init()
[cascardo/ovs.git] / lib / netdev-dpdk.c
1 /*
2  * Copyright (c) 2014 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 <stdio.h>
20 #include <string.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <pthread.h>
24 #include <config.h>
25 #include <errno.h>
26 #include <sched.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <stdio.h>
30
31 #include "dpif-netdev.h"
32 #include "list.h"
33 #include "netdev-dpdk.h"
34 #include "netdev-provider.h"
35 #include "netdev-vport.h"
36 #include "odp-util.h"
37 #include "ofp-print.h"
38 #include "ofpbuf.h"
39 #include "ovs-thread.h"
40 #include "ovs-rcu.h"
41 #include "packet-dpif.h"
42 #include "packets.h"
43 #include "shash.h"
44 #include "sset.h"
45 #include "unaligned.h"
46 #include "timeval.h"
47 #include "unixctl.h"
48 #include "vlog.h"
49
50 VLOG_DEFINE_THIS_MODULE(dpdk);
51 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
52
53 #define DPDK_PORT_WATCHDOG_INTERVAL 5
54
55 #define OVS_CACHE_LINE_SIZE CACHE_LINE_SIZE
56 #define OVS_VPORT_DPDK "ovs_dpdk"
57
58 /*
59  * need to reserve tons of extra space in the mbufs so we can align the
60  * DMA addresses to 4KB.
61  */
62
63 #define MTU_TO_MAX_LEN(mtu)  ((mtu) + ETHER_HDR_LEN + ETHER_CRC_LEN)
64 #define MBUF_SIZE(mtu)       (MTU_TO_MAX_LEN(mtu) + (512) + \
65                              sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
66
67 /* TODO: mempool size should be based on system resources. */
68 #define NB_MBUF              (4096 * 64)
69 #define MP_CACHE_SZ          (256 * 2)
70 #define SOCKET0              0
71
72 #define NON_PMD_THREAD_TX_QUEUE 0
73
74 #define NIC_PORT_RX_Q_SIZE 2048  /* Size of Physical NIC RX Queue, Max (n+32<=4096)*/
75 #define NIC_PORT_TX_Q_SIZE 2048  /* Size of Physical NIC TX Queue, Max (n+32<=4096)*/
76
77 /* TODO: Needs per NIC value for these constants. */
78 #define RX_PTHRESH 32 /* Default values of RX prefetch threshold reg. */
79 #define RX_HTHRESH 32 /* Default values of RX host threshold reg. */
80 #define RX_WTHRESH 16 /* Default values of RX write-back threshold reg. */
81
82 #define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */
83 #define TX_HTHRESH 0  /* Default values of TX host threshold reg. */
84 #define TX_WTHRESH 0  /* Default values of TX write-back threshold reg. */
85
86 static const struct rte_eth_conf port_conf = {
87     .rxmode = {
88         .mq_mode = ETH_MQ_RX_RSS,
89         .split_hdr_size = 0,
90         .header_split   = 0, /* Header Split disabled */
91         .hw_ip_checksum = 0, /* IP checksum offload disabled */
92         .hw_vlan_filter = 0, /* VLAN filtering disabled */
93         .jumbo_frame    = 0, /* Jumbo Frame Support disabled */
94         .hw_strip_crc   = 0,
95     },
96     .rx_adv_conf = {
97         .rss_conf = {
98             .rss_key = NULL,
99             .rss_hf = ETH_RSS_IPV4_TCP | ETH_RSS_IPV4 | ETH_RSS_IPV6,
100         },
101     },
102     .txmode = {
103         .mq_mode = ETH_MQ_TX_NONE,
104     },
105 };
106
107 static const struct rte_eth_rxconf rx_conf = {
108     .rx_thresh = {
109         .pthresh = RX_PTHRESH,
110         .hthresh = RX_HTHRESH,
111         .wthresh = RX_WTHRESH,
112     },
113 };
114
115 static const struct rte_eth_txconf tx_conf = {
116     .tx_thresh = {
117         .pthresh = TX_PTHRESH,
118         .hthresh = TX_HTHRESH,
119         .wthresh = TX_WTHRESH,
120     },
121     .tx_free_thresh = 0,
122     .tx_rs_thresh = 0,
123     .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS|ETH_TXQ_FLAGS_NOOFFLOADS,
124 };
125
126 enum { MAX_RX_QUEUE_LEN = 64 };
127 enum { MAX_TX_QUEUE_LEN = 64 };
128 enum { DRAIN_TSC = 200000ULL };
129
130 static int rte_eal_init_ret = ENODEV;
131
132 static struct ovs_mutex dpdk_mutex = OVS_MUTEX_INITIALIZER;
133
134 /* Contains all 'struct dpdk_dev's. */
135 static struct list dpdk_list OVS_GUARDED_BY(dpdk_mutex)
136     = LIST_INITIALIZER(&dpdk_list);
137
138 static struct list dpdk_mp_list OVS_GUARDED_BY(dpdk_mutex)
139     = LIST_INITIALIZER(&dpdk_mp_list);
140
141 struct dpdk_mp {
142     struct rte_mempool *mp;
143     int mtu;
144     int socket_id;
145     int refcount;
146     struct list list_node OVS_GUARDED_BY(dpdk_mutex);
147 };
148
149 struct dpdk_tx_queue {
150     rte_spinlock_t tx_lock;
151     int count;
152     uint64_t tsc;
153     struct rte_mbuf *burst_pkts[MAX_TX_QUEUE_LEN];
154 };
155
156 /* dpdk has no way to remove dpdk ring ethernet devices
157    so we have to keep them around once they've been created
158 */
159
160 static struct list dpdk_ring_list OVS_GUARDED_BY(dpdk_mutex)
161     = LIST_INITIALIZER(&dpdk_ring_list);
162
163 struct dpdk_ring {
164     /* For the client rings */
165     struct rte_ring *cring_tx;
166     struct rte_ring *cring_rx;
167     int user_port_id; /* User given port no, parsed from port name */
168     int eth_port_id; /* ethernet device port id */
169     struct list list_node OVS_GUARDED_BY(dpdk_mutex);
170 };
171
172 struct netdev_dpdk {
173     struct netdev up;
174     int port_id;
175     int max_packet_len;
176
177     struct dpdk_tx_queue tx_q[NR_QUEUE];
178
179     struct ovs_mutex mutex OVS_ACQ_AFTER(dpdk_mutex);
180
181     struct dpdk_mp *dpdk_mp;
182     int mtu;
183     int socket_id;
184     int buf_size;
185     struct netdev_stats stats_offset;
186     struct netdev_stats stats;
187
188     uint8_t hwaddr[ETH_ADDR_LEN];
189     enum netdev_flags flags;
190
191     struct rte_eth_link link;
192     int link_reset_cnt;
193
194     /* In dpdk_list. */
195     struct list list_node OVS_GUARDED_BY(dpdk_mutex);
196 };
197
198 struct netdev_rxq_dpdk {
199     struct netdev_rxq up;
200     int port_id;
201 };
202
203 static int netdev_dpdk_construct(struct netdev *);
204
205 static bool
206 is_dpdk_class(const struct netdev_class *class)
207 {
208     return class->construct == netdev_dpdk_construct;
209 }
210
211 /* TODO: use dpdk malloc for entire OVS. infact huge page shld be used
212  * for all other sengments data, bss and text. */
213
214 static void *
215 dpdk_rte_mzalloc(size_t sz)
216 {
217     void *ptr;
218
219     ptr = rte_zmalloc(OVS_VPORT_DPDK, sz, OVS_CACHE_LINE_SIZE);
220     if (ptr == NULL) {
221         out_of_memory();
222     }
223     return ptr;
224 }
225
226 void
227 free_dpdk_buf(struct dpif_packet *p)
228 {
229     struct ofpbuf *buf = &p->ofpbuf;
230     struct rte_mbuf *pkt = (struct rte_mbuf *) buf->dpdk_buf;
231
232     rte_mempool_put(pkt->pool, pkt);
233 }
234
235 static void
236 __rte_pktmbuf_init(struct rte_mempool *mp,
237                    void *opaque_arg OVS_UNUSED,
238                    void *_m,
239                    unsigned i OVS_UNUSED)
240 {
241     struct rte_mbuf *m = _m;
242     uint32_t buf_len = mp->elt_size - sizeof(struct dpif_packet);
243
244     RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct dpif_packet));
245
246     memset(m, 0, mp->elt_size);
247
248     /* start of buffer is just after mbuf structure */
249     m->buf_addr = (char *)m + sizeof(struct dpif_packet);
250     m->buf_physaddr = rte_mempool_virt2phy(mp, m) +
251                     sizeof(struct dpif_packet);
252     m->buf_len = (uint16_t)buf_len;
253
254     /* keep some headroom between start of buffer and data */
255     m->pkt.data = (char*) m->buf_addr + RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len);
256
257     /* init some constant fields */
258     m->type = RTE_MBUF_PKT;
259     m->pool = mp;
260     m->pkt.nb_segs = 1;
261     m->pkt.in_port = 0xff;
262 }
263
264 static void
265 ovs_rte_pktmbuf_init(struct rte_mempool *mp,
266                      void *opaque_arg OVS_UNUSED,
267                      void *_m,
268                      unsigned i OVS_UNUSED)
269 {
270     struct rte_mbuf *m = _m;
271
272     __rte_pktmbuf_init(mp, opaque_arg, _m, i);
273
274     ofpbuf_init_dpdk((struct ofpbuf *) m, m->buf_len);
275 }
276
277 static struct dpdk_mp *
278 dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
279 {
280     struct dpdk_mp *dmp = NULL;
281     char mp_name[RTE_MEMPOOL_NAMESIZE];
282
283     LIST_FOR_EACH (dmp, list_node, &dpdk_mp_list) {
284         if (dmp->socket_id == socket_id && dmp->mtu == mtu) {
285             dmp->refcount++;
286             return dmp;
287         }
288     }
289
290     dmp = dpdk_rte_mzalloc(sizeof *dmp);
291     dmp->socket_id = socket_id;
292     dmp->mtu = mtu;
293     dmp->refcount = 1;
294
295     if (snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_mp_%d", dmp->mtu) < 0) {
296         return NULL;
297     }
298
299     dmp->mp = rte_mempool_create(mp_name, NB_MBUF, MBUF_SIZE(mtu),
300                                  MP_CACHE_SZ,
301                                  sizeof(struct rte_pktmbuf_pool_private),
302                                  rte_pktmbuf_pool_init, NULL,
303                                  ovs_rte_pktmbuf_init, NULL,
304                                  socket_id, 0);
305
306     if (dmp->mp == NULL) {
307         return NULL;
308     }
309
310     list_push_back(&dpdk_mp_list, &dmp->list_node);
311     return dmp;
312 }
313
314 static void
315 dpdk_mp_put(struct dpdk_mp *dmp)
316 {
317
318     if (!dmp) {
319         return;
320     }
321
322     dmp->refcount--;
323     ovs_assert(dmp->refcount >= 0);
324
325 #if 0
326     /* I could not find any API to destroy mp. */
327     if (dmp->refcount == 0) {
328         list_delete(dmp->list_node);
329         /* destroy mp-pool. */
330     }
331 #endif
332 }
333
334 static void
335 check_link_status(struct netdev_dpdk *dev)
336 {
337     struct rte_eth_link link;
338
339     rte_eth_link_get_nowait(dev->port_id, &link);
340
341     if (dev->link.link_status != link.link_status) {
342         netdev_change_seq_changed(&dev->up);
343
344         dev->link_reset_cnt++;
345         dev->link = link;
346         if (dev->link.link_status) {
347             VLOG_DBG_RL(&rl, "Port %d Link Up - speed %u Mbps - %s",
348                         dev->port_id, (unsigned)dev->link.link_speed,
349                         (dev->link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
350                          ("full-duplex") : ("half-duplex"));
351         } else {
352             VLOG_DBG_RL(&rl, "Port %d Link Down", dev->port_id);
353         }
354     }
355 }
356
357 static void *
358 dpdk_watchdog(void *dummy OVS_UNUSED)
359 {
360     struct netdev_dpdk *dev;
361
362     pthread_detach(pthread_self());
363
364     for (;;) {
365         ovs_mutex_lock(&dpdk_mutex);
366         LIST_FOR_EACH (dev, list_node, &dpdk_list) {
367             ovs_mutex_lock(&dev->mutex);
368             check_link_status(dev);
369             ovs_mutex_unlock(&dev->mutex);
370         }
371         ovs_mutex_unlock(&dpdk_mutex);
372         xsleep(DPDK_PORT_WATCHDOG_INTERVAL);
373     }
374
375     return NULL;
376 }
377
378 static int
379 dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex)
380 {
381     struct rte_pktmbuf_pool_private *mbp_priv;
382     struct ether_addr eth_addr;
383     int diag;
384     int i;
385
386     if (dev->port_id < 0 || dev->port_id >= rte_eth_dev_count()) {
387         return ENODEV;
388     }
389
390     diag = rte_eth_dev_configure(dev->port_id, NR_QUEUE, NR_QUEUE,  &port_conf);
391     if (diag) {
392         VLOG_ERR("eth dev config error %d",diag);
393         return -diag;
394     }
395
396     for (i = 0; i < NR_QUEUE; i++) {
397         diag = rte_eth_tx_queue_setup(dev->port_id, i, NIC_PORT_TX_Q_SIZE,
398                                       dev->socket_id, &tx_conf);
399         if (diag) {
400             VLOG_ERR("eth dev tx queue setup error %d",diag);
401             return -diag;
402         }
403     }
404
405     for (i = 0; i < NR_QUEUE; i++) {
406         diag = rte_eth_rx_queue_setup(dev->port_id, i, NIC_PORT_RX_Q_SIZE,
407                                       dev->socket_id,
408                                       &rx_conf, dev->dpdk_mp->mp);
409         if (diag) {
410             VLOG_ERR("eth dev rx queue setup error %d",diag);
411             return -diag;
412         }
413     }
414
415     diag = rte_eth_dev_start(dev->port_id);
416     if (diag) {
417         VLOG_ERR("eth dev start error %d",diag);
418         return -diag;
419     }
420
421     rte_eth_promiscuous_enable(dev->port_id);
422     rte_eth_allmulticast_enable(dev->port_id);
423
424     memset(&eth_addr, 0x0, sizeof(eth_addr));
425     rte_eth_macaddr_get(dev->port_id, &eth_addr);
426     VLOG_INFO_RL(&rl, "Port %d: "ETH_ADDR_FMT"",
427                     dev->port_id, ETH_ADDR_ARGS(eth_addr.addr_bytes));
428
429     memcpy(dev->hwaddr, eth_addr.addr_bytes, ETH_ADDR_LEN);
430     rte_eth_link_get_nowait(dev->port_id, &dev->link);
431
432     mbp_priv = rte_mempool_get_priv(dev->dpdk_mp->mp);
433     dev->buf_size = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
434
435     dev->flags = NETDEV_UP | NETDEV_PROMISC;
436     return 0;
437 }
438
439 static struct netdev_dpdk *
440 netdev_dpdk_cast(const struct netdev *netdev)
441 {
442     return CONTAINER_OF(netdev, struct netdev_dpdk, up);
443 }
444
445 static struct netdev *
446 netdev_dpdk_alloc(void)
447 {
448     struct netdev_dpdk *netdev = dpdk_rte_mzalloc(sizeof *netdev);
449     return &netdev->up;
450 }
451
452 static int
453 netdev_dpdk_init(struct netdev *netdev_, unsigned int port_no) OVS_REQUIRES(dpdk_mutex)
454 {
455     struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
456     int err = 0;
457     int i;
458
459     ovs_mutex_init(&netdev->mutex);
460
461     ovs_mutex_lock(&netdev->mutex);
462
463     for (i = 0; i < NR_QUEUE; i++) {
464         rte_spinlock_init(&netdev->tx_q[i].tx_lock);
465     }
466
467     netdev->port_id = port_no;
468
469     netdev->flags = 0;
470     netdev->mtu = ETHER_MTU;
471     netdev->max_packet_len = MTU_TO_MAX_LEN(netdev->mtu);
472
473     /* TODO: need to discover device node at run time. */
474     netdev->socket_id = SOCKET0;
475
476     netdev->dpdk_mp = dpdk_mp_get(netdev->socket_id, netdev->mtu);
477     if (!netdev->dpdk_mp) {
478         err = ENOMEM;
479         goto unlock;
480     }
481
482     err = dpdk_eth_dev_init(netdev);
483     if (err) {
484         goto unlock;
485     }
486     netdev_->n_rxq = NR_QUEUE;
487
488     list_push_back(&dpdk_list, &netdev->list_node);
489
490 unlock:
491     ovs_mutex_unlock(&netdev->mutex);
492     return err;
493 }
494
495 static int
496 dpdk_dev_parse_name(const char dev_name[], const char prefix[],
497                     unsigned int *port_no)
498 {
499     const char *cport;
500
501     if (strncmp(dev_name, prefix, strlen(prefix))) {
502         return ENODEV;
503     }
504
505     cport = dev_name + strlen(prefix);
506     *port_no = strtol(cport, 0, 0); /* string must be null terminated */
507     return 0;
508 }
509
510 static int
511 netdev_dpdk_construct(struct netdev *netdev)
512 {
513     unsigned int port_no;
514     int err;
515
516     if (rte_eal_init_ret) {
517         return rte_eal_init_ret;
518     }
519
520     /* Names always start with "dpdk" */
521     err = dpdk_dev_parse_name(netdev->name, "dpdk", &port_no);
522     if (err) {
523         return err;
524     }
525
526     ovs_mutex_lock(&dpdk_mutex);
527     err = netdev_dpdk_init(netdev, port_no);
528     ovs_mutex_unlock(&dpdk_mutex);
529     return err;
530 }
531
532 static void
533 netdev_dpdk_destruct(struct netdev *netdev_)
534 {
535     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
536
537     ovs_mutex_lock(&dev->mutex);
538     rte_eth_dev_stop(dev->port_id);
539     ovs_mutex_unlock(&dev->mutex);
540
541     ovs_mutex_lock(&dpdk_mutex);
542     list_remove(&dev->list_node);
543     dpdk_mp_put(dev->dpdk_mp);
544     ovs_mutex_unlock(&dpdk_mutex);
545
546     ovs_mutex_destroy(&dev->mutex);
547 }
548
549 static void
550 netdev_dpdk_dealloc(struct netdev *netdev_)
551 {
552     struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
553
554     rte_free(netdev);
555 }
556
557 static int
558 netdev_dpdk_get_config(const struct netdev *netdev_, struct smap *args)
559 {
560     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
561
562     ovs_mutex_lock(&dev->mutex);
563
564     /* TODO: Allow to configure number of queues. */
565     smap_add_format(args, "configured_rx_queues", "%u", netdev_->n_rxq);
566     smap_add_format(args, "configured_tx_queues", "%u", netdev_->n_rxq);
567     ovs_mutex_unlock(&dev->mutex);
568
569     return 0;
570 }
571
572 static struct netdev_rxq *
573 netdev_dpdk_rxq_alloc(void)
574 {
575     struct netdev_rxq_dpdk *rx = dpdk_rte_mzalloc(sizeof *rx);
576
577     return &rx->up;
578 }
579
580 static struct netdev_rxq_dpdk *
581 netdev_rxq_dpdk_cast(const struct netdev_rxq *rx)
582 {
583     return CONTAINER_OF(rx, struct netdev_rxq_dpdk, up);
584 }
585
586 static int
587 netdev_dpdk_rxq_construct(struct netdev_rxq *rxq_)
588 {
589     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq_);
590     struct netdev_dpdk *netdev = netdev_dpdk_cast(rx->up.netdev);
591
592     ovs_mutex_lock(&netdev->mutex);
593     rx->port_id = netdev->port_id;
594     ovs_mutex_unlock(&netdev->mutex);
595
596     return 0;
597 }
598
599 static void
600 netdev_dpdk_rxq_destruct(struct netdev_rxq *rxq_ OVS_UNUSED)
601 {
602 }
603
604 static void
605 netdev_dpdk_rxq_dealloc(struct netdev_rxq *rxq_)
606 {
607     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq_);
608
609     rte_free(rx);
610 }
611
612 static inline void
613 dpdk_queue_flush__(struct netdev_dpdk *dev, int qid)
614 {
615     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
616     uint32_t nb_tx;
617
618     nb_tx = rte_eth_tx_burst(dev->port_id, qid, txq->burst_pkts, txq->count);
619     if (OVS_UNLIKELY(nb_tx != txq->count)) {
620         /* free buffers if we couldn't transmit packets */
621         rte_mempool_put_bulk(dev->dpdk_mp->mp,
622                              (void **) &txq->burst_pkts[nb_tx],
623                              (txq->count - nb_tx));
624     }
625     txq->count = 0;
626     txq->tsc = rte_get_timer_cycles();
627 }
628
629 static inline void
630 dpdk_queue_flush(struct netdev_dpdk *dev, int qid)
631 {
632     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
633
634     if (txq->count == 0) {
635         return;
636     }
637     rte_spinlock_lock(&txq->tx_lock);
638     dpdk_queue_flush__(dev, qid);
639     rte_spinlock_unlock(&txq->tx_lock);
640 }
641
642 static int
643 netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct dpif_packet **packets,
644                      int *c)
645 {
646     struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq_);
647     struct netdev *netdev = rx->up.netdev;
648     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
649     int nb_rx;
650
651     dpdk_queue_flush(dev, rxq_->queue_id);
652
653     nb_rx = rte_eth_rx_burst(rx->port_id, rxq_->queue_id,
654                              (struct rte_mbuf **) packets,
655                              MIN((int)NETDEV_MAX_RX_BATCH,
656                                  (int)MAX_RX_QUEUE_LEN));
657     if (!nb_rx) {
658         return EAGAIN;
659     }
660
661     *c = nb_rx;
662
663     return 0;
664 }
665
666 inline static void
667 dpdk_queue_pkts(struct netdev_dpdk *dev, int qid,
668                struct rte_mbuf **pkts, int cnt)
669 {
670     struct dpdk_tx_queue *txq = &dev->tx_q[qid];
671     uint64_t diff_tsc;
672
673     int i = 0;
674
675     rte_spinlock_lock(&txq->tx_lock);
676     while (i < cnt) {
677         int freeslots = MAX_TX_QUEUE_LEN - txq->count;
678         int tocopy = MIN(freeslots, cnt-i);
679
680         memcpy(&txq->burst_pkts[txq->count], &pkts[i],
681                tocopy * sizeof (struct rte_mbuf *));
682
683         txq->count += tocopy;
684         i += tocopy;
685
686         if (txq->count == MAX_TX_QUEUE_LEN) {
687             dpdk_queue_flush__(dev, qid);
688         }
689         diff_tsc = rte_get_timer_cycles() - txq->tsc;
690         if (diff_tsc >= DRAIN_TSC) {
691             dpdk_queue_flush__(dev, qid);
692         }
693     }
694     rte_spinlock_unlock(&txq->tx_lock);
695 }
696
697 /* Tx function. Transmit packets indefinitely */
698 static void
699 dpdk_do_tx_copy(struct netdev *netdev, struct dpif_packet ** pkts, int cnt)
700 {
701     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
702     struct rte_mbuf *mbufs[cnt];
703     int dropped = 0;
704     int newcnt = 0;
705     int i;
706
707     for (i = 0; i < cnt; i++) {
708         int size = ofpbuf_size(&pkts[i]->ofpbuf);
709
710         if (OVS_UNLIKELY(size > dev->max_packet_len)) {
711             VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d",
712                          (int)size , dev->max_packet_len);
713
714             dropped++;
715             continue;
716         }
717
718         mbufs[newcnt] = rte_pktmbuf_alloc(dev->dpdk_mp->mp);
719
720         if (!mbufs[newcnt]) {
721             dropped += cnt - i;
722             break;
723         }
724
725         /* We have to do a copy for now */
726         memcpy(mbufs[newcnt]->pkt.data, ofpbuf_data(&pkts[i]->ofpbuf), size);
727
728         rte_pktmbuf_data_len(mbufs[newcnt]) = size;
729         rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;
730
731         newcnt++;
732     }
733
734     if (OVS_UNLIKELY(dropped)) {
735         ovs_mutex_lock(&dev->mutex);
736         dev->stats.tx_dropped += dropped;
737         ovs_mutex_unlock(&dev->mutex);
738     }
739
740     dpdk_queue_pkts(dev, NON_PMD_THREAD_TX_QUEUE, mbufs, newcnt);
741     dpdk_queue_flush(dev, NON_PMD_THREAD_TX_QUEUE);
742 }
743
744 static int
745 netdev_dpdk_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
746                  bool may_steal)
747 {
748     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
749     int ret;
750     int i;
751
752     if (!may_steal || pkts[0]->ofpbuf.source != OFPBUF_DPDK) {
753         dpdk_do_tx_copy(netdev, pkts, cnt);
754
755         if (may_steal) {
756             for (i = 0; i < cnt; i++) {
757                 dpif_packet_delete(pkts[i]);
758             }
759         }
760     } else {
761         int qid;
762         int next_tx_idx = 0;
763         int dropped = 0;
764
765         qid = rte_lcore_id() % NR_QUEUE;
766
767         for (i = 0; i < cnt; i++) {
768             int size = ofpbuf_size(&pkts[i]->ofpbuf);
769             if (OVS_UNLIKELY(size > dev->max_packet_len)) {
770                 if (next_tx_idx != i) {
771                     dpdk_queue_pkts(dev, qid,
772                                     (struct rte_mbuf **)&pkts[next_tx_idx],
773                                     i-next_tx_idx);
774                 }
775
776                 VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d",
777                              (int)size , dev->max_packet_len);
778
779                 dpif_packet_delete(pkts[i]);
780                 dropped++;
781                 next_tx_idx = i + 1;
782             }
783         }
784         if (next_tx_idx != cnt) {
785            dpdk_queue_pkts(dev, qid,
786                             (struct rte_mbuf **)&pkts[next_tx_idx],
787                             cnt-next_tx_idx);
788         }
789
790         if (OVS_UNLIKELY(dropped)) {
791             ovs_mutex_lock(&dev->mutex);
792             dev->stats.tx_dropped += dropped;
793             ovs_mutex_unlock(&dev->mutex);
794         }
795     }
796     ret = 0;
797
798     return ret;
799 }
800
801 static int
802 netdev_dpdk_set_etheraddr(struct netdev *netdev,
803                           const uint8_t mac[ETH_ADDR_LEN])
804 {
805     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
806
807     ovs_mutex_lock(&dev->mutex);
808     if (!eth_addr_equals(dev->hwaddr, mac)) {
809         memcpy(dev->hwaddr, mac, ETH_ADDR_LEN);
810         netdev_change_seq_changed(netdev);
811     }
812     ovs_mutex_unlock(&dev->mutex);
813
814     return 0;
815 }
816
817 static int
818 netdev_dpdk_get_etheraddr(const struct netdev *netdev,
819                           uint8_t mac[ETH_ADDR_LEN])
820 {
821     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
822
823     ovs_mutex_lock(&dev->mutex);
824     memcpy(mac, dev->hwaddr, ETH_ADDR_LEN);
825     ovs_mutex_unlock(&dev->mutex);
826
827     return 0;
828 }
829
830 static int
831 netdev_dpdk_get_mtu(const struct netdev *netdev, int *mtup)
832 {
833     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
834
835     ovs_mutex_lock(&dev->mutex);
836     *mtup = dev->mtu;
837     ovs_mutex_unlock(&dev->mutex);
838
839     return 0;
840 }
841
842 static int
843 netdev_dpdk_set_mtu(const struct netdev *netdev, int mtu)
844 {
845     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
846     int old_mtu, err;
847     struct dpdk_mp *old_mp;
848     struct dpdk_mp *mp;
849
850     ovs_mutex_lock(&dpdk_mutex);
851     ovs_mutex_lock(&dev->mutex);
852     if (dev->mtu == mtu) {
853         err = 0;
854         goto out;
855     }
856
857     mp = dpdk_mp_get(dev->socket_id, dev->mtu);
858     if (!mp) {
859         err = ENOMEM;
860         goto out;
861     }
862
863     rte_eth_dev_stop(dev->port_id);
864
865     old_mtu = dev->mtu;
866     old_mp = dev->dpdk_mp;
867     dev->dpdk_mp = mp;
868     dev->mtu = mtu;
869     dev->max_packet_len = MTU_TO_MAX_LEN(dev->mtu);
870
871     err = dpdk_eth_dev_init(dev);
872     if (err) {
873         dpdk_mp_put(mp);
874         dev->mtu = old_mtu;
875         dev->dpdk_mp = old_mp;
876         dev->max_packet_len = MTU_TO_MAX_LEN(dev->mtu);
877         dpdk_eth_dev_init(dev);
878         goto out;
879     }
880
881     dpdk_mp_put(old_mp);
882     netdev_change_seq_changed(netdev);
883 out:
884     ovs_mutex_unlock(&dev->mutex);
885     ovs_mutex_unlock(&dpdk_mutex);
886     return err;
887 }
888
889 static int
890 netdev_dpdk_get_carrier(const struct netdev *netdev_, bool *carrier);
891
892 static int
893 netdev_dpdk_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
894 {
895     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
896     struct rte_eth_stats rte_stats;
897     bool gg;
898
899     netdev_dpdk_get_carrier(netdev, &gg);
900     ovs_mutex_lock(&dev->mutex);
901     rte_eth_stats_get(dev->port_id, &rte_stats);
902
903     *stats = dev->stats_offset;
904
905     stats->rx_packets += rte_stats.ipackets;
906     stats->tx_packets += rte_stats.opackets;
907     stats->rx_bytes += rte_stats.ibytes;
908     stats->tx_bytes += rte_stats.obytes;
909     stats->rx_errors += rte_stats.ierrors;
910     stats->tx_errors += rte_stats.oerrors;
911     stats->multicast += rte_stats.imcasts;
912
913     stats->tx_dropped += dev->stats.tx_dropped;
914     ovs_mutex_unlock(&dev->mutex);
915
916     return 0;
917 }
918
919 static int
920 netdev_dpdk_set_stats(struct netdev *netdev, const struct netdev_stats *stats)
921 {
922     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
923
924     ovs_mutex_lock(&dev->mutex);
925     dev->stats_offset = *stats;
926     ovs_mutex_unlock(&dev->mutex);
927
928     return 0;
929 }
930
931 static int
932 netdev_dpdk_get_features(const struct netdev *netdev_,
933                          enum netdev_features *current,
934                          enum netdev_features *advertised OVS_UNUSED,
935                          enum netdev_features *supported OVS_UNUSED,
936                          enum netdev_features *peer OVS_UNUSED)
937 {
938     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
939     struct rte_eth_link link;
940
941     ovs_mutex_lock(&dev->mutex);
942     link = dev->link;
943     ovs_mutex_unlock(&dev->mutex);
944
945     if (link.link_duplex == ETH_LINK_AUTONEG_DUPLEX) {
946         if (link.link_speed == ETH_LINK_SPEED_AUTONEG) {
947             *current = NETDEV_F_AUTONEG;
948         }
949     } else if (link.link_duplex == ETH_LINK_HALF_DUPLEX) {
950         if (link.link_speed == ETH_LINK_SPEED_10) {
951             *current = NETDEV_F_10MB_HD;
952         }
953         if (link.link_speed == ETH_LINK_SPEED_100) {
954             *current = NETDEV_F_100MB_HD;
955         }
956         if (link.link_speed == ETH_LINK_SPEED_1000) {
957             *current = NETDEV_F_1GB_HD;
958         }
959     } else if (link.link_duplex == ETH_LINK_FULL_DUPLEX) {
960         if (link.link_speed == ETH_LINK_SPEED_10) {
961             *current = NETDEV_F_10MB_FD;
962         }
963         if (link.link_speed == ETH_LINK_SPEED_100) {
964             *current = NETDEV_F_100MB_FD;
965         }
966         if (link.link_speed == ETH_LINK_SPEED_1000) {
967             *current = NETDEV_F_1GB_FD;
968         }
969         if (link.link_speed == ETH_LINK_SPEED_10000) {
970             *current = NETDEV_F_10GB_FD;
971         }
972     }
973
974     return 0;
975 }
976
977 static int
978 netdev_dpdk_get_ifindex(const struct netdev *netdev)
979 {
980     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
981     int ifindex;
982
983     ovs_mutex_lock(&dev->mutex);
984     ifindex = dev->port_id;
985     ovs_mutex_unlock(&dev->mutex);
986
987     return ifindex;
988 }
989
990 static int
991 netdev_dpdk_get_carrier(const struct netdev *netdev_, bool *carrier)
992 {
993     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
994
995     ovs_mutex_lock(&dev->mutex);
996     check_link_status(dev);
997     *carrier = dev->link.link_status;
998     ovs_mutex_unlock(&dev->mutex);
999
1000     return 0;
1001 }
1002
1003 static long long int
1004 netdev_dpdk_get_carrier_resets(const struct netdev *netdev_)
1005 {
1006     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
1007     long long int carrier_resets;
1008
1009     ovs_mutex_lock(&dev->mutex);
1010     carrier_resets = dev->link_reset_cnt;
1011     ovs_mutex_unlock(&dev->mutex);
1012
1013     return carrier_resets;
1014 }
1015
1016 static int
1017 netdev_dpdk_set_miimon(struct netdev *netdev_ OVS_UNUSED,
1018                        long long int interval OVS_UNUSED)
1019 {
1020     return 0;
1021 }
1022
1023 static int
1024 netdev_dpdk_update_flags__(struct netdev_dpdk *dev,
1025                            enum netdev_flags off, enum netdev_flags on,
1026                            enum netdev_flags *old_flagsp) OVS_REQUIRES(dev->mutex)
1027 {
1028     int err;
1029
1030     if ((off | on) & ~(NETDEV_UP | NETDEV_PROMISC)) {
1031         return EINVAL;
1032     }
1033
1034     *old_flagsp = dev->flags;
1035     dev->flags |= on;
1036     dev->flags &= ~off;
1037
1038     if (dev->flags == *old_flagsp) {
1039         return 0;
1040     }
1041
1042     if (dev->flags & NETDEV_UP) {
1043         err = rte_eth_dev_start(dev->port_id);
1044         if (err)
1045             return -err;
1046     }
1047
1048     if (dev->flags & NETDEV_PROMISC) {
1049         rte_eth_promiscuous_enable(dev->port_id);
1050     }
1051
1052     if (!(dev->flags & NETDEV_UP)) {
1053         rte_eth_dev_stop(dev->port_id);
1054     }
1055
1056     return 0;
1057 }
1058
1059 static int
1060 netdev_dpdk_update_flags(struct netdev *netdev_,
1061                          enum netdev_flags off, enum netdev_flags on,
1062                          enum netdev_flags *old_flagsp)
1063 {
1064     struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
1065     int error;
1066
1067     ovs_mutex_lock(&netdev->mutex);
1068     error = netdev_dpdk_update_flags__(netdev, off, on, old_flagsp);
1069     ovs_mutex_unlock(&netdev->mutex);
1070
1071     return error;
1072 }
1073
1074 static int
1075 netdev_dpdk_get_status(const struct netdev *netdev_, struct smap *args)
1076 {
1077     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev_);
1078     struct rte_eth_dev_info dev_info;
1079
1080     if (dev->port_id <= 0)
1081         return ENODEV;
1082
1083     ovs_mutex_lock(&dev->mutex);
1084     rte_eth_dev_info_get(dev->port_id, &dev_info);
1085     ovs_mutex_unlock(&dev->mutex);
1086
1087     smap_add_format(args, "driver_name", "%s", dev_info.driver_name);
1088
1089     smap_add_format(args, "port_no", "%d", dev->port_id);
1090     smap_add_format(args, "numa_id", "%d", rte_eth_dev_socket_id(dev->port_id));
1091     smap_add_format(args, "driver_name", "%s", dev_info.driver_name);
1092     smap_add_format(args, "min_rx_bufsize", "%u", dev_info.min_rx_bufsize);
1093     smap_add_format(args, "max_rx_pktlen", "%u", dev_info.max_rx_pktlen);
1094     smap_add_format(args, "max_rx_queues", "%u", dev_info.max_rx_queues);
1095     smap_add_format(args, "max_tx_queues", "%u", dev_info.max_tx_queues);
1096     smap_add_format(args, "max_mac_addrs", "%u", dev_info.max_mac_addrs);
1097     smap_add_format(args, "max_hash_mac_addrs", "%u", dev_info.max_hash_mac_addrs);
1098     smap_add_format(args, "max_vfs", "%u", dev_info.max_vfs);
1099     smap_add_format(args, "max_vmdq_pools", "%u", dev_info.max_vmdq_pools);
1100
1101     smap_add_format(args, "pci-vendor_id", "0x%u", dev_info.pci_dev->id.vendor_id);
1102     smap_add_format(args, "pci-device_id", "0x%x", dev_info.pci_dev->id.device_id);
1103
1104     return 0;
1105 }
1106
1107 static void
1108 netdev_dpdk_set_admin_state__(struct netdev_dpdk *dev, bool admin_state)
1109     OVS_REQUIRES(dev->mutex)
1110 {
1111     enum netdev_flags old_flags;
1112
1113     if (admin_state) {
1114         netdev_dpdk_update_flags__(dev, 0, NETDEV_UP, &old_flags);
1115     } else {
1116         netdev_dpdk_update_flags__(dev, NETDEV_UP, 0, &old_flags);
1117     }
1118 }
1119
1120 static void
1121 netdev_dpdk_set_admin_state(struct unixctl_conn *conn, int argc,
1122                             const char *argv[], void *aux OVS_UNUSED)
1123 {
1124     bool up;
1125
1126     if (!strcasecmp(argv[argc - 1], "up")) {
1127         up = true;
1128     } else if ( !strcasecmp(argv[argc - 1], "down")) {
1129         up = false;
1130     } else {
1131         unixctl_command_reply_error(conn, "Invalid Admin State");
1132         return;
1133     }
1134
1135     if (argc > 2) {
1136         struct netdev *netdev = netdev_from_name(argv[1]);
1137         if (netdev && is_dpdk_class(netdev->netdev_class)) {
1138             struct netdev_dpdk *dpdk_dev = netdev_dpdk_cast(netdev);
1139
1140             ovs_mutex_lock(&dpdk_dev->mutex);
1141             netdev_dpdk_set_admin_state__(dpdk_dev, up);
1142             ovs_mutex_unlock(&dpdk_dev->mutex);
1143
1144             netdev_close(netdev);
1145         } else {
1146             unixctl_command_reply_error(conn, "Not a DPDK Interface");
1147             netdev_close(netdev);
1148             return;
1149         }
1150     } else {
1151         struct netdev_dpdk *netdev;
1152
1153         ovs_mutex_lock(&dpdk_mutex);
1154         LIST_FOR_EACH (netdev, list_node, &dpdk_list) {
1155             ovs_mutex_lock(&netdev->mutex);
1156             netdev_dpdk_set_admin_state__(netdev, up);
1157             ovs_mutex_unlock(&netdev->mutex);
1158         }
1159         ovs_mutex_unlock(&dpdk_mutex);
1160     }
1161     unixctl_command_reply(conn, "OK");
1162 }
1163
1164 static void
1165 dpdk_common_init(void)
1166 {
1167     unixctl_command_register("netdev-dpdk/set-admin-state",
1168                              "[netdev] up|down", 1, 2,
1169                              netdev_dpdk_set_admin_state, NULL);
1170
1171     ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
1172 }
1173
1174 static int
1175 dpdk_class_init(void)
1176 {
1177     int result;
1178
1179     result = rte_pmd_init_all();
1180     if (result) {
1181         VLOG_ERR("Cannot init PMD");
1182         return -result;
1183     }
1184
1185     result = rte_eal_pci_probe();
1186     if (result) {
1187         VLOG_ERR("Cannot probe PCI");
1188         return -result;
1189     }
1190
1191     VLOG_INFO("Ethernet Device Count: %d", (int)rte_eth_dev_count());
1192
1193     return 0;
1194 }
1195
1196 /* Client Rings */
1197
1198 static int
1199 dpdk_ring_create(const char dev_name[], unsigned int port_no,
1200                  unsigned int *eth_port_id)
1201 {
1202     struct dpdk_ring *ivshmem;
1203     char ring_name[10];
1204     int err;
1205
1206     ivshmem = dpdk_rte_mzalloc(sizeof *ivshmem);
1207     if (ivshmem == NULL) {
1208         return ENOMEM;
1209     }
1210
1211     err = snprintf(ring_name, 10, "%s_tx", dev_name);
1212     if (err < 0) {
1213         return -err;
1214     }
1215
1216     ivshmem->cring_tx = rte_ring_create(ring_name, MAX_RX_QUEUE_LEN, SOCKET0, 0);
1217     if (ivshmem->cring_tx == NULL) {
1218         rte_free(ivshmem);
1219         return ENOMEM;
1220     }
1221
1222     err = snprintf(ring_name, 10, "%s_rx", dev_name);
1223     if (err < 0) {
1224         return -err;
1225     }
1226
1227     ivshmem->cring_rx = rte_ring_create(ring_name, MAX_RX_QUEUE_LEN, SOCKET0, 0);
1228     if (ivshmem->cring_rx == NULL) {
1229         rte_free(ivshmem);
1230         return ENOMEM;
1231     }
1232
1233     err = rte_eth_from_rings(&ivshmem->cring_rx, 1, &ivshmem->cring_tx, 1, SOCKET0);
1234     if (err < 0) {
1235         rte_free(ivshmem);
1236         return ENODEV;
1237     }
1238
1239     ivshmem->user_port_id = port_no;
1240     ivshmem->eth_port_id = rte_eth_dev_count() - 1;
1241     list_push_back(&dpdk_ring_list, &ivshmem->list_node);
1242
1243     *eth_port_id = ivshmem->eth_port_id;
1244     return 0;
1245 }
1246
1247 static int
1248 dpdk_ring_open(const char dev_name[], unsigned int *eth_port_id) OVS_REQUIRES(dpdk_mutex)
1249 {
1250     struct dpdk_ring *ivshmem;
1251     unsigned int port_no;
1252     int err = 0;
1253
1254     /* Names always start with "dpdkr" */
1255     err = dpdk_dev_parse_name(dev_name, "dpdkr", &port_no);
1256     if (err) {
1257         return err;
1258     }
1259
1260     /* look through our list to find the device */
1261     LIST_FOR_EACH (ivshmem, list_node, &dpdk_ring_list) {
1262          if (ivshmem->user_port_id == port_no) {
1263             VLOG_INFO("Found dpdk ring device %s:\n", dev_name);
1264             *eth_port_id = ivshmem->eth_port_id; /* really all that is needed */
1265             return 0;
1266          }
1267     }
1268     /* Need to create the device rings */
1269     return dpdk_ring_create(dev_name, port_no, eth_port_id);
1270 }
1271
1272 static int
1273 netdev_dpdk_ring_construct(struct netdev *netdev)
1274 {
1275     unsigned int port_no = 0;
1276     int err = 0;
1277
1278     if (rte_eal_init_ret) {
1279         return rte_eal_init_ret;
1280     }
1281
1282     ovs_mutex_lock(&dpdk_mutex);
1283
1284     err = dpdk_ring_open(netdev->name, &port_no);
1285     if (err) {
1286         goto unlock_dpdk;
1287     }
1288
1289     err = netdev_dpdk_init(netdev, port_no);
1290
1291 unlock_dpdk:
1292     ovs_mutex_unlock(&dpdk_mutex);
1293     return err;
1294 }
1295
1296 #define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT)              \
1297 {                                                             \
1298     NAME,                                                     \
1299     INIT,                       /* init */                    \
1300     NULL,                       /* netdev_dpdk_run */         \
1301     NULL,                       /* netdev_dpdk_wait */        \
1302                                                               \
1303     netdev_dpdk_alloc,                                        \
1304     CONSTRUCT,                                                \
1305     netdev_dpdk_destruct,                                     \
1306     netdev_dpdk_dealloc,                                      \
1307     netdev_dpdk_get_config,                                   \
1308     NULL,                       /* netdev_dpdk_set_config */  \
1309     NULL,                       /* get_tunnel_config */       \
1310                                                               \
1311     netdev_dpdk_send,           /* send */                    \
1312     NULL,                       /* send_wait */               \
1313                                                               \
1314     netdev_dpdk_set_etheraddr,                                \
1315     netdev_dpdk_get_etheraddr,                                \
1316     netdev_dpdk_get_mtu,                                      \
1317     netdev_dpdk_set_mtu,                                      \
1318     netdev_dpdk_get_ifindex,                                  \
1319     netdev_dpdk_get_carrier,                                  \
1320     netdev_dpdk_get_carrier_resets,                           \
1321     netdev_dpdk_set_miimon,                                   \
1322     netdev_dpdk_get_stats,                                    \
1323     netdev_dpdk_set_stats,                                    \
1324     netdev_dpdk_get_features,                                 \
1325     NULL,                       /* set_advertisements */      \
1326                                                               \
1327     NULL,                       /* set_policing */            \
1328     NULL,                       /* get_qos_types */           \
1329     NULL,                       /* get_qos_capabilities */    \
1330     NULL,                       /* get_qos */                 \
1331     NULL,                       /* set_qos */                 \
1332     NULL,                       /* get_queue */               \
1333     NULL,                       /* set_queue */               \
1334     NULL,                       /* delete_queue */            \
1335     NULL,                       /* get_queue_stats */         \
1336     NULL,                       /* queue_dump_start */        \
1337     NULL,                       /* queue_dump_next */         \
1338     NULL,                       /* queue_dump_done */         \
1339     NULL,                       /* dump_queue_stats */        \
1340                                                               \
1341     NULL,                       /* get_in4 */                 \
1342     NULL,                       /* set_in4 */                 \
1343     NULL,                       /* get_in6 */                 \
1344     NULL,                       /* add_router */              \
1345     NULL,                       /* get_next_hop */            \
1346     netdev_dpdk_get_status,                                   \
1347     NULL,                       /* arp_lookup */              \
1348                                                               \
1349     netdev_dpdk_update_flags,                                 \
1350                                                               \
1351     netdev_dpdk_rxq_alloc,                                    \
1352     netdev_dpdk_rxq_construct,                                \
1353     netdev_dpdk_rxq_destruct,                                 \
1354     netdev_dpdk_rxq_dealloc,                                  \
1355     netdev_dpdk_rxq_recv,                                     \
1356     NULL,                       /* rx_wait */                 \
1357     NULL,                       /* rxq_drain */               \
1358 }
1359
1360 int
1361 dpdk_init(int argc, char **argv)
1362 {
1363     int result;
1364
1365     if (argc < 2 || strcmp(argv[1], "--dpdk"))
1366         return 0;
1367
1368     /* Make sure program name passed to rte_eal_init() is vswitchd. */
1369     argv[1] = argv[0];
1370
1371     argc--;
1372     argv++;
1373
1374     /* Make sure things are initialized ... */
1375     result = rte_eal_init(argc, argv);
1376     if (result < 0) {
1377         ovs_abort(result, "Cannot init EAL\n");
1378     }
1379
1380     rte_memzone_dump();
1381     rte_eal_init_ret = 0;
1382
1383     if (argc > result) {
1384         argv[result] = argv[0];
1385     }
1386
1387     return result + 1;
1388 }
1389
1390 const struct netdev_class dpdk_class =
1391     NETDEV_DPDK_CLASS(
1392         "dpdk",
1393         dpdk_class_init,
1394         netdev_dpdk_construct);
1395
1396 const struct netdev_class dpdk_ring_class =
1397     NETDEV_DPDK_CLASS(
1398         "dpdkr",
1399         NULL,
1400         netdev_dpdk_ring_construct);
1401
1402 void
1403 netdev_dpdk_register(void)
1404 {
1405     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
1406
1407     if (rte_eal_init_ret) {
1408         return;
1409     }
1410
1411     if (ovsthread_once_start(&once)) {
1412         dpdk_common_init();
1413         netdev_register_provider(&dpdk_class);
1414         netdev_register_provider(&dpdk_ring_class);
1415         ovsthread_once_done(&once);
1416     }
1417 }
1418
1419 int
1420 pmd_thread_setaffinity_cpu(int cpu)
1421 {
1422     cpu_set_t cpuset;
1423     int err;
1424
1425     CPU_ZERO(&cpuset);
1426     CPU_SET(cpu, &cpuset);
1427     err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
1428     if (err) {
1429         VLOG_ERR("Thread affinity error %d",err);
1430         return err;
1431     }
1432     RTE_PER_LCORE(_lcore_id) = cpu;
1433
1434     return 0;
1435 }