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
