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

Yanqin Wei Yanqin.Wei at arm.com
Tue Jun 2 07:10:00 UTC 2020


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 at arm.com>
Reviewed-by: Malvika Gupta <Malvika.Gupta at arm.com>
Signed-off-by: Yanqin Wei <Yanqin.Wei at arm.com>
---
 lib/dp-packet.h | 12 ++++++++----
 lib/netdev.c    | 13 ++++++++++---
 2 files changed, 18 insertions(+), 7 deletions(-)

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);
-- 
2.17.1



More information about the dev mailing list