diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2013-10-29 20:22:21 -0400 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2014-01-06 18:52:24 -0500 |
commit | e298e505700604c97e6a9edb21cebb080bdb91f6 (patch) | |
tree | d2f4452ed7a4ec42a212690ac2633b006c1e10c0 /net/openvswitch/flow.h | |
parent | 795449d8b846a42d11d47d6ff2f51ab2967411c3 (diff) |
openvswitch: Per cpu flow stats.
With mega flow implementation ovs flow can be shared between
multiple CPUs which makes stats updates highly contended
operation. This patch uses per-CPU stats in cases where a flow
is likely to be shared (if there is a wildcard in the 5-tuple
and therefore likely to be spread by RSS). In other situations,
it uses the current strategy, saving memory and allocation time.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch/flow.h')
-rw-r--r-- | net/openvswitch/flow.h | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 176406d9b779..2d770e28a3a3 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #ifndef FLOW_H | 19 | #ifndef FLOW_H |
20 | #define FLOW_H 1 | 20 | #define FLOW_H 1 |
21 | 21 | ||
22 | #include <linux/cache.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/netlink.h> | 24 | #include <linux/netlink.h> |
24 | #include <linux/openvswitch.h> | 25 | #include <linux/openvswitch.h> |
@@ -146,6 +147,22 @@ struct sw_flow_actions { | |||
146 | struct nlattr actions[]; | 147 | struct nlattr actions[]; |
147 | }; | 148 | }; |
148 | 149 | ||
150 | struct flow_stats { | ||
151 | u64 packet_count; /* Number of packets matched. */ | ||
152 | u64 byte_count; /* Number of bytes matched. */ | ||
153 | unsigned long used; /* Last used time (in jiffies). */ | ||
154 | spinlock_t lock; /* Lock for atomic stats update. */ | ||
155 | __be16 tcp_flags; /* Union of seen TCP flags. */ | ||
156 | }; | ||
157 | |||
158 | struct sw_flow_stats { | ||
159 | bool is_percpu; | ||
160 | union { | ||
161 | struct flow_stats *stat; | ||
162 | struct flow_stats __percpu *cpu_stats; | ||
163 | }; | ||
164 | }; | ||
165 | |||
149 | struct sw_flow { | 166 | struct sw_flow { |
150 | struct rcu_head rcu; | 167 | struct rcu_head rcu; |
151 | struct hlist_node hash_node[2]; | 168 | struct hlist_node hash_node[2]; |
@@ -155,12 +172,7 @@ struct sw_flow { | |||
155 | struct sw_flow_key unmasked_key; | 172 | struct sw_flow_key unmasked_key; |
156 | struct sw_flow_mask *mask; | 173 | struct sw_flow_mask *mask; |
157 | struct sw_flow_actions __rcu *sf_acts; | 174 | struct sw_flow_actions __rcu *sf_acts; |
158 | 175 | struct sw_flow_stats stats; | |
159 | spinlock_t lock; /* Lock for values below. */ | ||
160 | unsigned long used; /* Last used time (in jiffies). */ | ||
161 | u64 packet_count; /* Number of packets matched. */ | ||
162 | u64 byte_count; /* Number of bytes matched. */ | ||
163 | __be16 tcp_flags; /* Union of seen TCP flags. */ | ||
164 | }; | 176 | }; |
165 | 177 | ||
166 | struct arp_eth_header { | 178 | struct arp_eth_header { |
@@ -177,7 +189,10 @@ struct arp_eth_header { | |||
177 | unsigned char ar_tip[4]; /* target IP address */ | 189 | unsigned char ar_tip[4]; /* target IP address */ |
178 | } __packed; | 190 | } __packed; |
179 | 191 | ||
180 | void ovs_flow_used(struct sw_flow *, struct sk_buff *); | 192 | void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb); |
193 | void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *stats, | ||
194 | unsigned long *used, __be16 *tcp_flags); | ||
195 | void ovs_flow_stats_clear(struct sw_flow *flow); | ||
181 | u64 ovs_flow_used_time(unsigned long flow_jiffies); | 196 | u64 ovs_flow_used_time(unsigned long flow_jiffies); |
182 | 197 | ||
183 | int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *); | 198 | int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *); |