diff mbox series

[ovs-dev,v1,1/6] netdev: avoid unnecessary packet batch refilling in netdev feature check

Message ID 20200602071005.29925-2-Yanqin.Wei@arm.com
State Changes Requested
Headers show
Series Memory access optimization for flow scalability of userspace datapath. | expand

Commit Message

Yanqin Wei June 2, 2020, 7:10 a.m. UTC
Before sending packets on netdev, feature compatibility is always checked
and incompatible traffic should be dropped. But, packet batch is refilled
even when no packet needs to be dropped. This patch improves it by keeping
the original batch if no packet should be dropped.

Reviewed-by: Lijian Zhang <Lijian.Zhang@arm.com>
Reviewed-by: Malvika Gupta <Malvika.Gupta@arm.com>
Signed-off-by: Yanqin Wei <Yanqin.Wei@arm.com>
---
 lib/dp-packet.h | 12 ++++++++----
 lib/netdev.c    | 13 ++++++++++---
 2 files changed, 18 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index 0430cca8e..1345f46e7 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -762,12 +762,12 @@  dp_packet_batch_size(const struct dp_packet_batch *batch)
     return batch->count;
 }
 
-/* Clear 'batch' for refill. Use dp_packet_batch_refill() to add
+/* Clear 'batch' from 'offset' for refill. Use dp_packet_batch_refill() to add
  * packets back into the 'batch'. */
 static inline void
-dp_packet_batch_refill_init(struct dp_packet_batch *batch)
+dp_packet_batch_refill_prepare(struct dp_packet_batch *batch, size_t offset)
 {
-    batch->count = 0;
+    batch->count = offset;
 };
 
 static inline void
@@ -801,6 +801,10 @@  dp_packet_batch_is_full(const struct dp_packet_batch *batch)
     for (size_t IDX = 0; IDX < dp_packet_batch_size(BATCH); IDX++)  \
         if (PACKET = BATCH->packets[IDX], true)
 
+#define DP_PACKET_BATCH_FOR_EACH_WITH_SIZE(IDX, SIZE, PACKET, BATCH) \
+     for (size_t IDX = 0; IDX < SIZE; IDX++)                         \
+        if (PACKET = BATCH->packets[IDX], true)
+
 /* Use this macro for cases where some packets in the 'BATCH' may be
  * dropped after going through each packet in the 'BATCH'.
  *
@@ -813,7 +817,7 @@  dp_packet_batch_is_full(const struct dp_packet_batch *batch)
  * the 'const' modifier since it should not be modified by
  * the iterator.  */
 #define DP_PACKET_BATCH_REFILL_FOR_EACH(IDX, SIZE, PACKET, BATCH)       \
-    for (dp_packet_batch_refill_init(BATCH), IDX=0; IDX < SIZE; IDX++)  \
+    for (dp_packet_batch_refill_prepare(BATCH, 0), IDX=0; IDX < SIZE; IDX++)  \
          if (PACKET = BATCH->packets[IDX], true)
 
 static inline void
diff --git a/lib/netdev.c b/lib/netdev.c
index 90962eec6..7934a00d4 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -838,15 +838,22 @@  netdev_send_prepare_batch(const struct netdev *netdev,
                           struct dp_packet_batch *batch)
 {
     struct dp_packet *packet;
-    size_t i, size = dp_packet_batch_size(batch);
+    size_t batch_cnt = dp_packet_batch_size(batch);;
+    bool refill = false;
 
-    DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) {
+    DP_PACKET_BATCH_FOR_EACH_WITH_SIZE (i, batch_cnt, packet, batch) {
         char *errormsg = NULL;
 
         if (netdev_send_prepare_packet(netdev->ol_flags, packet, &errormsg)) {
-            dp_packet_batch_refill(batch, packet, i);
+            if ( OVS_UNLIKELY(refill) ) {
+                dp_packet_batch_refill(batch, packet, i);
+            }
         } else {
             dp_packet_delete(packet);
+            if( !refill ) {
+                dp_packet_batch_refill_prepare(batch, i);
+                refill = true;
+            }
             COVERAGE_INC(netdev_send_prepare_drops);
             VLOG_WARN_RL(&rl, "%s: Packet dropped: %s",
                          netdev_get_name(netdev), errormsg);