X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetdev-dpdk.c;h=fd991abd6f2d664aae0cbcd0f69459e80c48f7e4;hb=8ba0a5227f6e6b50838c157bd303c2d5bf6f4e59;hp=6bf19c1123904ae3ba64bdb4c0eccb2997f26f50;hpb=1f317cb5c2aa446c4b0252634a4a70dcc3682f93;p=sliver-openvswitch.git diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 6bf19c112..fd991abd6 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -28,7 +28,6 @@ #include #include -#include "connectivity.h" #include "dpif-netdev.h" #include "list.h" #include "netdev-dpdk.h" @@ -41,7 +40,6 @@ #include "ovs-rcu.h" #include "packets.h" #include "shash.h" -#include "seq.h" #include "sset.h" #include "unaligned.h" #include "timeval.h" @@ -135,8 +133,6 @@ static struct list dpdk_list OVS_GUARDED_BY(dpdk_mutex) static struct list dpdk_mp_list OVS_GUARDED_BY(dpdk_mutex) = LIST_INITIALIZER(&dpdk_mp_list); -static pthread_t watchdog_thread; - struct dpdk_mp { struct rte_mempool *mp; int mtu; @@ -209,16 +205,53 @@ dpdk_rte_mzalloc(size_t sz) void free_dpdk_buf(struct ofpbuf *b) { - struct rte_mbuf *pkt; - - pkt = b->private_p; - if (!pkt) { - return; - } + struct rte_mbuf *pkt = (struct rte_mbuf *) b; rte_mempool_put(pkt->pool, pkt); } +static void +__rte_pktmbuf_init(struct rte_mempool *mp, + void *opaque_arg OVS_UNUSED, + void *_m, + unsigned i OVS_UNUSED) +{ + struct rte_mbuf *m = _m; + uint32_t buf_len = mp->elt_size - sizeof(struct ofpbuf); + + RTE_MBUF_ASSERT(mp->elt_size >= sizeof(struct ofpbuf)); + + memset(m, 0, mp->elt_size); + + /* start of buffer is just after mbuf structure */ + m->buf_addr = (char *)m + sizeof(struct ofpbuf); + m->buf_physaddr = rte_mempool_virt2phy(mp, m) + + sizeof(struct ofpbuf); + m->buf_len = (uint16_t)buf_len; + + /* keep some headroom between start of buffer and data */ + m->pkt.data = (char*) m->buf_addr + RTE_MIN(RTE_PKTMBUF_HEADROOM, m->buf_len); + + /* init some constant fields */ + m->type = RTE_MBUF_PKT; + m->pool = mp; + m->pkt.nb_segs = 1; + m->pkt.in_port = 0xff; +} + +static void +ovs_rte_pktmbuf_init(struct rte_mempool *mp, + void *opaque_arg OVS_UNUSED, + void *_m, + unsigned i OVS_UNUSED) +{ + struct rte_mbuf *m = _m; + + __rte_pktmbuf_init(mp, opaque_arg, _m, i); + + ofpbuf_init_dpdk((struct ofpbuf *) m, m->buf_len); +} + static struct dpdk_mp * dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex) { @@ -242,7 +275,7 @@ dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex) MP_CACHE_SZ, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, NULL, - rte_pktmbuf_init, NULL, + ovs_rte_pktmbuf_init, NULL, socket_id, 0); if (dmp->mp == NULL) { @@ -281,7 +314,7 @@ check_link_status(struct netdev_dpdk *dev) rte_eth_link_get_nowait(dev->port_id, &link); if (dev->link.link_status != link.link_status) { - seq_change(connectivity_seq_get()); + netdev_change_seq_changed(&dev->up); dev->link_reset_cnt++; dev->link = link; @@ -550,47 +583,22 @@ dpdk_queue_flush(struct netdev_dpdk *dev, int qid) rte_spinlock_unlock(&txq->tx_lock); } -inline static struct ofpbuf * -build_ofpbuf(struct rte_mbuf *pkt) -{ - struct ofpbuf *b; - - b = ofpbuf_new(0); - b->private_p = pkt; - - ofpbuf_set_data(b, pkt->pkt.data); - ofpbuf_set_base(b, (char *)ofpbuf_data(b) - DP_NETDEV_HEADROOM - VLAN_ETH_HEADER_LEN); - b->allocated = pkt->buf_len; - ofpbuf_set_size(b, rte_pktmbuf_data_len(pkt)); - b->source = OFPBUF_DPDK; - - dp_packet_pad(b); - - return b; -} - static int -netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct ofpbuf **packet, int *c) +netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct ofpbuf **packets, int *c) { struct netdev_rxq_dpdk *rx = netdev_rxq_dpdk_cast(rxq_); struct netdev *netdev = rx->up.netdev; struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - struct rte_mbuf *burst_pkts[MAX_RX_QUEUE_LEN]; int nb_rx; - int i; dpdk_queue_flush(dev, rxq_->queue_id); nb_rx = rte_eth_rx_burst(rx->port_id, rxq_->queue_id, - burst_pkts, MAX_RX_QUEUE_LEN); + (struct rte_mbuf **) packets, MAX_RX_QUEUE_LEN); if (!nb_rx) { return EAGAIN; } - for (i = 0; i < nb_rx; i++) { - packet[i] = build_ofpbuf(burst_pkts[i]); - } - *c = nb_rx; return 0; @@ -677,32 +685,23 @@ netdev_dpdk_send(struct netdev *netdev, goto out; } - rte_prefetch0(&ofpbuf->private_p); - if (!may_steal || - !ofpbuf->private_p || ofpbuf->source != OFPBUF_DPDK) { + if (!may_steal || ofpbuf->source != OFPBUF_DPDK) { dpdk_do_tx_copy(netdev, (char *) ofpbuf_data(ofpbuf), ofpbuf_size(ofpbuf)); + + if (may_steal) { + ofpbuf_delete(ofpbuf); + } } else { - struct rte_mbuf *pkt; int qid; - pkt = ofpbuf->private_p; - ofpbuf->private_p = NULL; - rte_pktmbuf_data_len(pkt) = ofpbuf_size(ofpbuf); - rte_pktmbuf_pkt_len(pkt) = ofpbuf_size(ofpbuf); - qid = rte_lcore_id() % NR_QUEUE; - dpdk_queue_pkt(dev, qid, pkt); + dpdk_queue_pkt(dev, qid, (struct rte_mbuf *)ofpbuf); - ofpbuf->private_p = NULL; } ret = 0; out: - if (may_steal) { - ofpbuf_delete(ofpbuf); - } - return ret; } @@ -715,6 +714,7 @@ netdev_dpdk_set_etheraddr(struct netdev *netdev, ovs_mutex_lock(&dev->mutex); if (!eth_addr_equals(dev->hwaddr, mac)) { memcpy(dev->hwaddr, mac, ETH_ADDR_LEN); + netdev_change_seq_changed(netdev); } ovs_mutex_unlock(&dev->mutex); @@ -787,6 +787,7 @@ netdev_dpdk_set_mtu(const struct netdev *netdev, int mtu) } dpdk_mp_put(old_mp); + netdev_change_seq_changed(netdev); out: ovs_mutex_unlock(&dev->mutex); ovs_mutex_unlock(&dpdk_mutex); @@ -1102,7 +1103,7 @@ dpdk_class_init(void) "[netdev] up|down", 1, 2, netdev_dpdk_set_admin_state, NULL); - xpthread_create(&watchdog_thread, NULL, dpdk_watchdog, NULL); + ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL); return 0; }