In preparation for batches larger than NETDEV_MAX_BURST,
refactor metering code so that it does not need to track
per packet exceeded band.

Suggested-by: Ilya Maximets <[email protected]>
Signed-off-by: David Marchand <[email protected]>
---
 lib/dpif-netdev.c | 50 ++++++++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 27 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 1065fd7cc2..2dc1dd5d4c 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -6276,16 +6276,14 @@ static void
 dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
                     uint32_t meter_id, long long int now_ms)
 {
+    unsigned long failed_bands[BITMAP_N_LONGS(MAX_BANDS)];
     const size_t cnt = dp_packet_batch_size(packets_);
-    uint32_t exceeded_rate[NETDEV_MAX_BURST];
-    uint32_t exceeded_band[NETDEV_MAX_BURST];
     uint64_t bytes, volume, meter_used, old;
     uint64_t band_packets[MAX_BANDS];
     uint64_t band_bytes[MAX_BANDS];
     struct dp_meter_band *band;
     struct dp_packet *packet;
     struct dp_meter *meter;
-    bool exceeded = false;
 
     if (meter_id >= MAX_METERS) {
         return;
@@ -6296,11 +6294,6 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct 
dp_packet_batch *packets_,
         return;
     }
 
-    /* Initialize as negative values. */
-    memset(exceeded_band, 0xff, cnt * sizeof *exceeded_band);
-    /* Initialize as zeroes. */
-    memset(exceeded_rate, 0, cnt * sizeof *exceeded_rate);
-
     atomic_read_relaxed(&meter->used, &meter_used);
     do {
         if (meter_used >= now_ms) {
@@ -6351,6 +6344,7 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct 
dp_packet_batch *packets_,
     }
 
     /* Find the band hit with the highest rate for each packet (if any). */
+    memset(failed_bands, 0, sizeof failed_bands);
     for (int m = 0; m < meter->n_bands; m++) {
         band = &meter->bands[m];
 
@@ -6359,26 +6353,11 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct 
dp_packet_batch *packets_,
             continue;
         }
 
-        /* Band limit hit, must process packet-by-packet. */
-        DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
-            uint64_t packet_volume = (meter->flags & OFPMF13_PKTPS)
-                                     ? 1000 : (dp_packet_size(packet) * 8);
-
-            if (!atomic_bound_sub(&band->bucket, packet_volume, 0)) {
-                /* Update the exceeding band for the exceeding packet.
-                 * Only one band will be fired by a packet, and that can
-                 * be different for each packet. */
-                if (band->rate > exceeded_rate[i]) {
-                    exceeded_rate[i] = band->rate;
-                    exceeded_band[i] = m;
-                    exceeded = true;
-                }
-            }
-        }
+        bitmap_set1(failed_bands, m);
     }
 
     /* No need to iterate over packets if there are no drops. */
-    if (!exceeded) {
+    if (bitmap_is_all_zeros(failed_bands, meter->n_bands)) {
         return;
     }
 
@@ -6390,9 +6369,26 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct 
dp_packet_batch *packets_,
 
     size_t j;
     DP_PACKET_BATCH_REFILL_FOR_EACH (j, cnt, packet, packets_) {
-        uint32_t m = exceeded_band[j];
+        uint64_t packet_volume = (meter->flags & OFPMF13_PKTPS)
+                                 ? 1000 : (dp_packet_size(packet) * 8);
+        uint32_t exceeded_rate = 0;
+        int m = -1;
+        int b;
+
+        BITMAP_FOR_EACH_1 (b, meter->n_bands, failed_bands) {
+            band = &meter->bands[b];
+            if (!atomic_bound_sub(&band->bucket, packet_volume, 0)) {
+                /* Update the exceeding band for the exceeding packet.
+                 * Only one band will be fired by a packet, and that can
+                 * be different for each packet. */
+                if (band->rate > exceeded_rate) {
+                    exceeded_rate = band->rate;
+                    m = b;
+                }
+            }
+        }
 
-        if (m != UINT32_MAX) {
+        if (m >= 0) {
             /* Meter drop packet. */
             band_packets[m]++;
             band_bytes[m] += dp_packet_size(packet);
-- 
2.54.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to