[ovs-dev,RFC,v3,5/8] lib/dp-packet: fix dp_packet_put_uninit for multi-seg mbufs

Message ID 1511288957-68599-6-git-send-email-mark.b.kavanagh@intel.com
State New
Delegated to: Ian Stokes
Headers show
Series
  • netdev-dpdk: support multi-segment mbufs
Related show

Commit Message

Kavanagh, Mark B Nov. 21, 2017, 6:29 p.m.
dp_packet_put_uninit(dp_packet, size) appends 'size' bytes to the tail
of a dp_packet. In the case of multi-segment mbufs, it is the data
length of the last mbuf in the mbuf chain that should be adjusted by
'size' bytes.

In its current implementation, dp_packet_put_uninit() adjusts the
dp_packet's size via a call to dp_packet_set_size(); however, this
adjusts the data length of the first mbuf in the chain, which is
incorrect in the case of multi-segment mbufs. Instead, traverse the
mbuf chain to locate the final mbuf of said chain, and update its
data_len [1]. To finish, increase the packet length of the entire
mbuf [2] by 'size'.

[1] In the case of a single-segment mbuf, this is the mbuf itself.
[2] This is stored in the first mbuf of an mbuf chain.

Signed-off-by: Mark Kavanagh <mark.b.kavanagh@intel.com>
---
 lib/dp-packet.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Patch

diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 5078211..5c590e5 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -325,6 +325,22 @@  dp_packet_put_uninit(struct dp_packet *b, size_t size)
     void *p;
     dp_packet_prealloc_tailroom(b, size);
     p = dp_packet_tail(b);
+#ifdef DPDK_NETDEV
+    if (b->source == DPBUF_DPDK)  {
+        struct rte_mbuf *buf = &(b->mbuf);
+        /* In the case of multi-segment mbufs, the data length of the last mbuf
+         * should be adjusted by 'size' bytes. A call to dp_packet_size() would
+         * adjust the data length of the first mbuf in the segment, so we avoid
+         * invoking same; as a result, the packet length of the entire mbuf
+         * chain (stored in the first mbuf of said chain) must be adjusted here
+         * instead.
+         */
+        while (buf->next)
+            buf = buf->next;
+        buf->data_len += size;
+        b->mbuf.pkt_len += size;
+    } else
+#endif
     dp_packet_set_size(b, dp_packet_size(b) + size);
     return p;
 }