[PATCHv2,4/5] linux-generic: netmap: support segmented packets

Message ID 1453488486-12176-5-git-send-email-stuart.haslam@linaro.org
State New
Headers show

Commit Message

Stuart Haslam Jan. 22, 2016, 6:48 p.m.
Replace the nm_inject() helper with our own version so that
odp_packet_copydata_out() can be used as this understands segmented
packets.

Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
---
 platform/linux-generic/pktio/netmap.c | 57 ++++++++++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 5 deletions(-)

Comments

Stuart Haslam Jan. 28, 2016, 10:40 a.m. | #1
On Mon, Jan 25, 2016 at 03:15:49PM +0000, Elo, Matias (Nokia - FI/Espoo) wrote:
> The same functionality is already implemented in API-NEXT branch. Is this patch mandatory for the whole set?
> 
> -Matias
> 

Without this the validation test in 5/5 fails so I can't just drop it
from this series without also dropping 5/5, and that would partly negate
the purpose of the series.

I'll merge the series to API-NEXT and resend without this patch.

> > -----Original Message-----
> > From: lng-odp [mailto:lng-odp-bounces@lists.linaro.org] On Behalf Of EXT Stuart
> > Haslam
> > Sent: Friday, January 22, 2016 8:48 PM
> > To: lng-odp@lists.linaro.org
> > Subject: [lng-odp] [PATCHv2 4/5] linux-generic: netmap: support segmented
> > packets
> > 
> > Replace the nm_inject() helper with our own version so that
> > odp_packet_copydata_out() can be used as this understands segmented
> > packets.
> > 
> > Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
> > ---
> >  platform/linux-generic/pktio/netmap.c | 57
> > ++++++++++++++++++++++++++++++++---
> >  1 file changed, 52 insertions(+), 5 deletions(-)
> > 
> > diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-
> > generic/pktio/netmap.c
> > index 639afa8..b7547e1 100644
> > --- a/platform/linux-generic/pktio/netmap.c
> > +++ b/platform/linux-generic/pktio/netmap.c
> > @@ -308,23 +308,70 @@ static int netmap_recv(pktio_entry_t *pktio_entry,
> > odp_packet_t pkt_table[],
> >  	return num_rx;
> >  }
> > 
> > +static struct netmap_ring *netmap_tx_ring(struct nm_desc *d)
> > +{
> > +	unsigned c, n = d->last_tx_ring - d->first_tx_ring + 1;
> > +
> > +	for (c = 0; c < n ; c++) {
> > +		struct netmap_ring *ring;
> > +		unsigned ri = d->cur_tx_ring + c;
> > +
> > +		if (ri > d->last_tx_ring)
> > +			ri = d->first_tx_ring;
> > +		ring = NETMAP_TXRING(d->nifp, ri);
> > +		if (nm_ring_empty(ring))
> > +			continue;
> > +
> > +		return ring;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> > +static int netmap_inject(struct nm_desc *d, odp_packet_t pkt)
> > +{
> > +	struct netmap_ring *ring;
> > +	unsigned i;
> > +	uint32_t pkt_len = odp_packet_len(pkt);
> > +	uint32_t offset = 0;
> > +	char *buf;
> > +
> > +	ring = netmap_tx_ring(d);
> > +	if (!ring)
> > +		return 0;
> > +
> > +	if (pkt_len > ring->nr_buf_size) {
> > +		__odp_errno = -EMSGSIZE;
> > +		return 0;
> > +	}
> > +
> > +	i = ring->cur;
> > +	ring->slot[i].flags = 0;
> > +	ring->slot[i].len = pkt_len;
> > +	buf = NETMAP_BUF(ring, ring->slot[i].buf_idx);
> > +
> > +	if (odp_packet_copydata_out(pkt, offset, pkt_len, buf))
> > +		return 0;
> > +
> > +	ring->cur = nm_ring_next(ring, i);
> > +	ring->head = ring->cur;
> > +
> > +	return 1;
> > +}
> > +
> >  static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
> >  		       unsigned num)
> >  {
> >  	struct pollfd polld;
> >  	struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.tx_desc;
> >  	unsigned i, nb_tx;
> > -	uint8_t *frame;
> > -	uint32_t frame_len;
> > 
> >  	polld.fd = nm_desc->fd;
> >  	polld.events = POLLOUT;
> > 
> >  	for (nb_tx = 0; nb_tx < num; nb_tx++) {
> > -		frame_len = 0;
> > -		frame = odp_packet_l2_ptr(pkt_table[nb_tx], &frame_len);
> >  		for (i = 0; i < NM_INJECT_RETRIES; i++) {
> > -			if (nm_inject(nm_desc, frame, frame_len) == 0)
> > +			if (netmap_inject(nm_desc, pkt_table[nb_tx]) == 0)
> >  				poll(&polld, 1, 0);
> >  			else
> >  				break;
> > --
> > 2.1.1
> >

Patch

diff --git a/platform/linux-generic/pktio/netmap.c b/platform/linux-generic/pktio/netmap.c
index 639afa8..b7547e1 100644
--- a/platform/linux-generic/pktio/netmap.c
+++ b/platform/linux-generic/pktio/netmap.c
@@ -308,23 +308,70 @@  static int netmap_recv(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
 	return num_rx;
 }
 
+static struct netmap_ring *netmap_tx_ring(struct nm_desc *d)
+{
+	unsigned c, n = d->last_tx_ring - d->first_tx_ring + 1;
+
+	for (c = 0; c < n ; c++) {
+		struct netmap_ring *ring;
+		unsigned ri = d->cur_tx_ring + c;
+
+		if (ri > d->last_tx_ring)
+			ri = d->first_tx_ring;
+		ring = NETMAP_TXRING(d->nifp, ri);
+		if (nm_ring_empty(ring))
+			continue;
+
+		return ring;
+	}
+
+	return NULL;
+}
+
+static int netmap_inject(struct nm_desc *d, odp_packet_t pkt)
+{
+	struct netmap_ring *ring;
+	unsigned i;
+	uint32_t pkt_len = odp_packet_len(pkt);
+	uint32_t offset = 0;
+	char *buf;
+
+	ring = netmap_tx_ring(d);
+	if (!ring)
+		return 0;
+
+	if (pkt_len > ring->nr_buf_size) {
+		__odp_errno = -EMSGSIZE;
+		return 0;
+	}
+
+	i = ring->cur;
+	ring->slot[i].flags = 0;
+	ring->slot[i].len = pkt_len;
+	buf = NETMAP_BUF(ring, ring->slot[i].buf_idx);
+
+	if (odp_packet_copydata_out(pkt, offset, pkt_len, buf))
+		return 0;
+
+	ring->cur = nm_ring_next(ring, i);
+	ring->head = ring->cur;
+
+	return 1;
+}
+
 static int netmap_send(pktio_entry_t *pktio_entry, odp_packet_t pkt_table[],
 		       unsigned num)
 {
 	struct pollfd polld;
 	struct nm_desc *nm_desc = pktio_entry->s.pkt_nm.tx_desc;
 	unsigned i, nb_tx;
-	uint8_t *frame;
-	uint32_t frame_len;
 
 	polld.fd = nm_desc->fd;
 	polld.events = POLLOUT;
 
 	for (nb_tx = 0; nb_tx < num; nb_tx++) {
-		frame_len = 0;
-		frame = odp_packet_l2_ptr(pkt_table[nb_tx], &frame_len);
 		for (i = 0; i < NM_INJECT_RETRIES; i++) {
-			if (nm_inject(nm_desc, frame, frame_len) == 0)
+			if (netmap_inject(nm_desc, pkt_table[nb_tx]) == 0)
 				poll(&polld, 1, 0);
 			else
 				break;