2016/10/28 19:17, Kavanagh, Mark B :
Currently, one packet is only copied to one segment
in function dpdk_do_tx_copy(),  this could be an issue
when a jumboframe comes, especially for multipile segments.
Typos - 'jumboframe', 'multipile'

This patch doesn't apply cleanly - change 'mbufs' to 'pkts' as previously 
described to address this.

I will fix the issues, and rebase to the latest code.


I haven't tested this patchset yet - will try to get to it next week.

OK, thanks.

Thanks again,
Mark

This patch calculate the segment number needed by the packet and
copy the data to different segments.

Signed-off-by: Michael Qiu <qiud...@chinac.com>
Signed-off-by: Jijiang Liu <liujiji...@chinac.com>
---
lib/netdev-dpdk.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index ad92504..abb3b53 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -1554,9 +1554,10 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct 
dp_packet_batch
*batch)
#endif
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     struct rte_mbuf *mbufs[PKT_ARRAY_SIZE];
+    struct rte_mbuf *temp, *head = NULL;
     int dropped = 0;
     int newcnt = 0;
-    int i;
+    int i, j, nb_segs;

     /* If we are on a non pmd thread we have to use the mempool mutex, because
      * every non pmd thread shares the same mempool cache */
@@ -1569,6 +1570,7 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct 
dp_packet_batch
*batch)

     for (i = 0; i < batch->count; i++) {
         int size = dp_packet_size(batch->packets[i]);
+        int max_data_len, tmp_len;

         if (OVS_UNLIKELY(size > dev->max_packet_len)) {
             VLOG_WARN_RL(&rl, "Too big size %d max_packet_len %d",
@@ -1578,7 +1580,24 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct 
dp_packet_batch
*batch)
             continue;
         }

-        mbufs[newcnt] = rte_pktmbuf_alloc(dev->dpdk_mp->mp);
+        temp = mbufs[newcnt] = rte_pktmbuf_alloc(dev->dpdk_mp->mp);
+
+        /* all new allocated mbuf's max data len is the same */
+        max_data_len = temp->buf_len - temp->data_off;
+
+        nb_segs = size/max_data_len;
+        if (size % max_data_len)
+            nb_segs = nb_segs + 1;
+
+        for (j = 1; j < nb_segs; j++) {
+            temp->next = rte_pktmbuf_alloc(dev->dpdk_mp->mp);
+            if (!temp->next) {
+                rte_pktmbuf_free(mbufs[newcnt]);
+                mbufs[newcnt] = NULL;
+                break;
+            }
+            temp = temp->next;
+        }
Need to terminate the mbuf chain here:
        + temp->next = NULL;

No need, all mbufs' next field have been set to NULL when allocated.


         if (!mbufs[newcnt]) {
             dropped += batch->count - i;
@@ -1586,15 +1605,37 @@ dpdk_do_tx_copy(struct netdev *netdev, int qid, struct
dp_packet_batch *batch)
         }

         /* We have to do a copy for now */
-        memcpy(rte_pktmbuf_mtod(mbufs[newcnt], void *),
-               dp_packet_data(batch->packets[i]), size);
+        rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;
+        temp = mbufs[newcnt];
+        tmp_len = size < max_data_len ? size: max_data_len;
+        if (batch->packets[i]->source == DPBUF_DPDK) {
+            head = &(batch->packets[i]->mbuf);
+            while (temp && head && size > 0) {
+                rte_memcpy(rte_pktmbuf_mtod(temp, void*), 
dp_packet_data((struct dp_packet
*)head),tmp_len);
+                rte_pktmbuf_data_len(temp) = tmp_len;
+                head = head->next;
+                size = size - tmp_len;
+                tmp_len =  size < max_data_len ? size: max_data_len;
+                temp = temp->next;
+            }
+        } else {
This section could use a comment or two.

OK, I will add a comment.


+            int offset = 0;
+            while (temp && size > 0) {
+                memcpy(rte_pktmbuf_mtod(temp, void *),
+                    dp_packet_at(batch->packets[i], offset,tmp_len), tmp_len);
+                rte_pktmbuf_data_len(temp) = tmp_len;
+                temp = temp->next;
+                size = size - tmp_len;
+                offset +=tmp_len;
+                tmp_len =  size < max_data_len ? size: max_data_len;
+            }
+        }
+

-        mbufs[newcnt]->nb_segs = batch->packets[i]->mbuf.nb_segs;
+        mbufs[newcnt]->nb_segs = nb_segs;
         mbufs[newcnt]->ol_flags = batch->packets[i]->mbuf.ol_flags;
         mbufs[newcnt]->packet_type = batch->packets[i]->mbuf.packet_type;
         mbufs[newcnt]->tx_offload = batch->packets[i]->mbuf.tx_offload;
-        rte_pktmbuf_data_len(mbufs[newcnt]) = size;
-        rte_pktmbuf_pkt_len(mbufs[newcnt]) = size;

         newcnt++;
     }
--
1.8.3.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to