diff mbox

[ovs-dev,4/5] lib/dp-packet: copy multi-segments data from DPDK mbuf

Message ID 1477548924-26376-5-git-send-email-qiudayu@chinac.com
State Changes Requested
Delegated to: Daniele Di Proietto
Headers show

Commit Message

Michael Qiu Oct. 27, 2016, 6:15 a.m. UTC
When doing packet clone, if packet source is from DPDK driver,
multi-segment must be considered, and copy the segment's
data one by one.

Signed-off-by: Michael Qiu <qiudayu@chinac.com>
Signed-off-by: Jijiang Liu <liujijiang@chinac.com>
---
 lib/dp-packet.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

Comments

Mark Kavanagh Oct. 28, 2016, 10:50 a.m. UTC | #1
>When doing packet clone, if packet source is from DPDK driver,
>multi-segment must be considered, and copy the segment's
>data one by one.
>
>Signed-off-by: Michael Qiu <qiudayu@chinac.com>
>Signed-off-by: Jijiang Liu <liujijiang@chinac.com>
>---
> lib/dp-packet.c | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
>
>diff --git a/lib/dp-packet.c b/lib/dp-packet.c
>index 619f651..3ca1fde 100644
>--- a/lib/dp-packet.c
>+++ b/lib/dp-packet.c
>@@ -164,9 +164,28 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t
>headroom)
> {
>     struct dp_packet *new_buffer;
>
>-    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
>-                                                 dp_packet_size(buffer),
>-                                                 headroom);
>+    uint32_t size = dp_packet_size(buffer);
>+
>+    /* copy multi-seg data */
>+    #ifdef DPDK_NETDEV
Align compiler guard to far left margin

>+    if (buffer->source == DPBUF_DPDK && buffer->mbuf.nb_segs > 1) {
>+        struct rte_mbuf *tmbuf = &(buffer->mbuf);
This assignment introduces a compiler warning:
	lib/dp-packet.c:173:34: warning: initialization discards 'const' qualifier from pointer target type [enabled by default]
This removes the warning:
+        struct rte_mbuf *tmbuf = CONST_CAST(struct rte_mbuf *, &(buffer->mbuf));

>+        new_buffer = dp_packet_new_with_headroom(size, headroom);
>+        void *dst = dp_packet_put_uninit(new_buffer, size);

Why do you need to call dp_packet_put_uninit? This adds an additional (and unneccesary) 'size' bytes to the tail of the dp_packet.

>+        uint32_t off_set = 0;
>+
>+        while (tmbuf) {
>+            rte_memcpy((char *)dst + off_set,
>+                       rte_pktmbuf_mtod(tmbuf, void *), tmbuf->data_len);
>+            off_set += tmbuf->data_len;
>+            tmbuf = tmbuf->next;
>+        }
>+    }
>+    else
>+    #endif
>+        new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
>+                                                        size, headroom);
>+
>     new_buffer->l2_pad_size = buffer->l2_pad_size;
>     new_buffer->l2_5_ofs = buffer->l2_5_ofs;
>     new_buffer->l3_ofs = buffer->l3_ofs;
>--
>1.8.3.1
Michael Qiu Nov. 1, 2016, 3:54 a.m. UTC | #2
2016/10/28 18:50, Kavanagh, Mark B :
>> When doing packet clone, if packet source is from DPDK driver,
>> multi-segment must be considered, and copy the segment's
>> data one by one.
>>
>> Signed-off-by: Michael Qiu <qiudayu@chinac.com>
>> Signed-off-by: Jijiang Liu <liujijiang@chinac.com>
>> ---
>> lib/dp-packet.c | 25 ++++++++++++++++++++++---
>> 1 file changed, 22 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/dp-packet.c b/lib/dp-packet.c
>> index 619f651..3ca1fde 100644
>> --- a/lib/dp-packet.c
>> +++ b/lib/dp-packet.c
>> @@ -164,9 +164,28 @@ dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t
>> headroom)
>> {
>>      struct dp_packet *new_buffer;
>>
>> -    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
>> -                                                 dp_packet_size(buffer),
>> -                                                 headroom);
>> +    uint32_t size = dp_packet_size(buffer);
>> +
>> +    /* copy multi-seg data */
>> +    #ifdef DPDK_NETDEV
> Align compiler guard to far left margin

OK, I've got your point, will fix it.

>
>> +    if (buffer->source == DPBUF_DPDK && buffer->mbuf.nb_segs > 1) {
>> +        struct rte_mbuf *tmbuf = &(buffer->mbuf);
> This assignment introduces a compiler warning:
> 	lib/dp-packet.c:173:34: warning: initialization discards 'const' qualifier from pointer target type [enabled by default]
> This removes the warning:
> +        struct rte_mbuf *tmbuf = CONST_CAST(struct rte_mbuf *, &(buffer->mbuf));

Thanks, you are right, and I will fix it.

>> +        new_buffer = dp_packet_new_with_headroom(size, headroom);
>> +        void *dst = dp_packet_put_uninit(new_buffer, size);
> Why do you need to call dp_packet_put_uninit? This adds an additional (and unneccesary) 'size' bytes to the tail of the dp_packet.

First, dp_packet_put_uninit() will finally be called in before, see call 
path:
dp_packet_clone() ---> dp_packet_clone_with_headroom() ---> 
dp_packet_clone_data_with_headroom() --->
         dp_packet_put() ---> dp_packet_put_uninit()

Second, dp_packet_put_uninit() does not add an additional 'size' bytes 
in this case, because dp_packet_prealloc_tailroom() will check if it has 
'size' bytes in its tailroom, and we have already allocated enought size 
here.

Third, the new allocated buffer hasn't set the pkt_len(packet size).

I use it only becasue it return the data start address here, and we also 
set the packet size here.

>
>> +        uint32_t off_set = 0;
>> +
>> +        while (tmbuf) {
>> +            rte_memcpy((char *)dst + off_set,
>> +                       rte_pktmbuf_mtod(tmbuf, void *), tmbuf->data_len);
>> +            off_set += tmbuf->data_len;
>> +            tmbuf = tmbuf->next;
>> +        }
>> +    }
>> +    else
>> +    #endif
>> +        new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
>> +                                                        size, headroom);
>> +
>>      new_buffer->l2_pad_size = buffer->l2_pad_size;
>>      new_buffer->l2_5_ofs = buffer->l2_5_ofs;
>>      new_buffer->l3_ofs = buffer->l3_ofs;
>> --
>> 1.8.3.1
>
diff mbox

Patch

diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 619f651..3ca1fde 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -164,9 +164,28 @@  dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
 {
     struct dp_packet *new_buffer;
 
-    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
-                                                 dp_packet_size(buffer),
-                                                 headroom);
+    uint32_t size = dp_packet_size(buffer);
+
+    /* copy multi-seg data */
+    #ifdef DPDK_NETDEV
+    if (buffer->source == DPBUF_DPDK && buffer->mbuf.nb_segs > 1) {
+        struct rte_mbuf *tmbuf = &(buffer->mbuf);
+        new_buffer = dp_packet_new_with_headroom(size, headroom);
+        void *dst = dp_packet_put_uninit(new_buffer, size);
+        uint32_t off_set = 0;
+
+        while (tmbuf) {
+            rte_memcpy((char *)dst + off_set,
+                       rte_pktmbuf_mtod(tmbuf, void *), tmbuf->data_len);
+            off_set += tmbuf->data_len;
+            tmbuf = tmbuf->next;
+        }
+    }
+    else
+    #endif
+        new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
+                                                        size, headroom);
+
     new_buffer->l2_pad_size = buffer->l2_pad_size;
     new_buffer->l2_5_ofs = buffer->l2_5_ofs;
     new_buffer->l3_ofs = buffer->l3_ofs;