On Wed, Apr 2, 2014 at 1:00 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote: > > On Mar 31, 2014, at 9:43 PM, Pravin <pshe...@nicira.com> wrote: > >> From: Pravin Shelar <pshe...@nicira.com> >> >> On DPDK packet recv, ovs is given pointer to mbuf which has >> information about a packet, for example pointer to data and size. >> By moving mbuf to ofpbuf we can let dpdk allocate ofpbuf and >> pass that to ovs for processing the packet. >> >> Signed-off-by: Pravin B Shelar <pshe...@nicira.com> >> --- >> lib/netdev-dpdk.c | 99 >> +++++++++++++++++++++++++++-------------------------- >> lib/ofpbuf.c | 4 +-- >> lib/ofpbuf.h | 6 +++- >> 3 files changed, 57 insertions(+), 52 deletions(-) >> >> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c >> index 5db4b49..facf220 100644 >> --- a/lib/netdev-dpdk.c >> +++ b/lib/netdev-dpdk.c >> @@ -209,16 +209,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, >> + __attribute__((unused)) void *opaque_arg, >> + void *_m, >> + __attribute__((unused)) unsigned i) > > Can use OVS_UNUSED here. > ok.
>> +{ >> + 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 */ > > Are these fields constant though the lifetime of 'm'? > Yes, they are constant for dpdk packet. >> + 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, >> + __attribute__((unused)) void *opaque_arg, >> + void *_m, >> + __attribute__((unused)) unsigned i) >> +{ >> + 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 +279,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) { >> @@ -550,47 +587,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_get_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) >> { >> 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 **) packet, MAX_RX_QUEUE_LEN); > > > The parameter 'packet' should be called 'packets' instead. > ok. >> 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 +689,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_get_data(ofpbuf), >> ofpbuf_get_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_get_size(ofpbuf); >> - rte_pktmbuf_pkt_len(pkt) = ofpbuf_get_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; >> } >> >> diff --git a/lib/ofpbuf.c b/lib/ofpbuf.c >> index f616b1c..749f7ff 100644 >> --- a/lib/ofpbuf.c >> +++ b/lib/ofpbuf.c >> @@ -134,9 +134,7 @@ ofpbuf_uninit(struct ofpbuf *b) >> if (b->source == OFPBUF_MALLOC) { >> free(ofpbuf_get_base(b)); >> } >> - if (b->source == OFPBUF_DPDK) { >> - free_dpdk_buf(b); >> - } >> + ovs_assert(b->source != OFPBUF_DPDK); >> } >> } >> >> diff --git a/lib/ofpbuf.h b/lib/ofpbuf.h >> index 94651e4..ec3429a 100644 >> --- a/lib/ofpbuf.h >> +++ b/lib/ofpbuf.h >> @@ -41,7 +41,6 @@ enum OVS_PACKED_ENUM ofpbuf_source { >> struct ofpbuf { >> #ifdef DPDK_NETDEV >> struct rte_mbuf mbuf; /* DPDK mbuf */ >> - void *private_p; /* private pointer for use by dpdk */ >> #else >> void *base; /* First byte of allocated space. */ >> void *data; /* First byte actually in use. */ >> @@ -155,6 +154,11 @@ static inline void *ofpbuf_get_uninit_pointer(struct >> ofpbuf *b) >> static inline void ofpbuf_delete(struct ofpbuf *b) >> { >> if (b) { >> + if (b->source == OFPBUF_DPDK) { >> + free_dpdk_buf(b); >> + return; >> + } >> + > > There is a comment in ofpbuf_get_uninit_pointer() that you may want to > address in context of this patch. > > Otherwise: > > Acked-by: Jarno Rajahalme <jrajaha...@nicira.com> > > Thanks for review. I pushed patches to master. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev