Fetching the number of flows in the datapath has been causing
unnecessary contention on the kernel ovs_lock in recent TCP CRR tests.
This patch caches this number for up to 100ms in the userspace to reduce
such kernel calls.

Signed-off-by: Joe Stringer <[email protected]>
Co-authored-by: Jarno Rajahalme <[email protected]>
Signed-off--by: Jarno Rajahalme <[email protected]>
---
 ofproto/ofproto-dpif-upcall.c |   22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index dd24f5c..d8a05ec 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -470,10 +470,24 @@ upcall_destroy(struct upcall *upcall)
 static uint64_t
 udpif_get_n_flows(const struct udpif *udpif)
 {
-    struct dpif_dp_stats stats;
-
-    dpif_get_dp_stats(udpif->dpif, &stats);
-    return stats.n_flows;
+    static atomic_llong last_updated = ATOMIC_VAR_INIT(LLONG_MIN);
+    static atomic_uint64_t flow_count = ATOMIC_VAR_INIT(UINT64_C(0));
+    long long int time, now;
+    uint64_t n_flows;
+
+    now = time_msec();
+    atomic_read(&last_updated, &time);
+    if (time < now - 100) {
+        struct dpif_dp_stats stats;
+
+        atomic_store(&last_updated, now);
+        dpif_get_dp_stats(udpif->dpif, &stats);
+        n_flows = stats.n_flows;
+        atomic_store(&flow_count, n_flows);
+    } else {
+        atomic_read(&flow_count, &n_flows);
+    }
+    return n_flows;
 }
 
 /* The dispatcher thread is responsible for receiving upcalls from the kernel,
-- 
1.7.9.5

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to