[ovs-dev] [PATCH] datapath: Don't query time for every packet.

Jesse Gross jesse at nicira.com
Thu Jul 22 02:36:15 UTC 2010


Rather than actually query the time every time a packet comes through,
just store the current jiffies and convert it to actual time when
requested.  GRE is the primary beneficiary of this because the traffic
travels through the datapath twice.  This change reduces CPU utilization
3-4% with GRE.
---
 datapath/datapath.c |   23 +++++++++++++++++++----
 datapath/flow.c     |    2 +-
 datapath/flow.h     |    3 ++-
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index eb260e3..0c39871 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -905,13 +905,28 @@ error:
 
 static void get_stats(struct sw_flow *flow, struct odp_flow_stats *stats)
 {
-	if (flow->used.tv_sec) {
-		stats->used_sec = flow->used.tv_sec;
-		stats->used_nsec = flow->used.tv_nsec;
+	if (flow->used) {
+		struct timespec now, delta, used;
+
+		ktime_get_ts(&now);
+
+		/* Deal with jiffie roll over.  Jiffies is always greater than
+		 * flow->used so if it isn't that means that it has rolled
+		 * over but flow->used hasn't. */
+		if (jiffies > flow->used)
+			jiffies_to_timespec(jiffies - flow->used, &delta);
+		else
+			jiffies_to_timespec(ULONG_MAX - flow->used + jiffies, &delta);
+
+		used = timespec_sub(now, delta);
+
+		stats->used_sec = used.tv_sec;
+		stats->used_nsec = used.tv_nsec;
 	} else {
 		stats->used_sec = 0;
 		stats->used_nsec = 0;
 	}
+
 	stats->n_packets = flow->packet_count;
 	stats->n_bytes = flow->byte_count;
 	stats->ip_tos = flow->ip_tos;
@@ -921,7 +936,7 @@ static void get_stats(struct sw_flow *flow, struct odp_flow_stats *stats)
 
 static void clear_stats(struct sw_flow *flow)
 {
-	flow->used.tv_sec = flow->used.tv_nsec = 0;
+	flow->used = 0;
 	flow->tcp_flags = 0;
 	flow->ip_tos = 0;
 	flow->packet_count = 0;
diff --git a/datapath/flow.c b/datapath/flow.c
index bf50e94..95cc042 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -111,7 +111,7 @@ void flow_used(struct sw_flow *flow, struct sk_buff *skb)
 	}
 
 	spin_lock_bh(&flow->lock);
-	ktime_get_ts(&flow->used);
+	flow->used = jiffies;
 	flow->packet_count++;
 	flow->byte_count += skb->len;
 	flow->tcp_flags |= tcp_flags;
diff --git a/datapath/flow.h b/datapath/flow.h
index 9704489..082f5be 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/rcupdate.h>
 #include <linux/gfp.h>
+#include <linux/jiffies.h>
 #include <linux/time.h>
 
 #include "openvswitch/datapath-protocol.h"
@@ -34,7 +35,7 @@ struct sw_flow {
 	struct odp_flow_key key;
 	struct sw_flow_actions *sf_acts;
 
-	struct timespec used;	/* Last used time. */
+	unsigned long used;	/* Last used time (in jiffies). */
 
 	u8 ip_tos;		/* IP TOS value. */
 
-- 
1.7.0.4





More information about the dev mailing list