openvswitch: Fix ovs_flow_stats_get/clear RCU dereference.
For ovs_flow_stats_get() using ovsl_dereference() was wrong, since flow dumps call this with RCU read lock. ovs_flow_stats_clear() is always called with ovs_mutex, so can use ovsl_dereference(). Also, make the ovs_flow_stats_get() 'flow' argument const to make later patches cleaner. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
This commit is contained in:
parent
eb07265904
commit
86ec8dbae2
@ -122,8 +122,9 @@ unlock:
|
||||
spin_unlock(&stats->lock);
|
||||
}
|
||||
|
||||
/* Called with ovs_mutex. */
|
||||
void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats,
|
||||
/* Must be called with rcu_read_lock or ovs_mutex. */
|
||||
void ovs_flow_stats_get(const struct sw_flow *flow,
|
||||
struct ovs_flow_stats *ovs_stats,
|
||||
unsigned long *used, __be16 *tcp_flags)
|
||||
{
|
||||
int node;
|
||||
@ -133,7 +134,7 @@ void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats,
|
||||
memset(ovs_stats, 0, sizeof(*ovs_stats));
|
||||
|
||||
for_each_node(node) {
|
||||
struct flow_stats *stats = ovsl_dereference(flow->stats[node]);
|
||||
struct flow_stats *stats = rcu_dereference_ovsl(flow->stats[node]);
|
||||
|
||||
if (stats) {
|
||||
/* Local CPU may write on non-local stats, so we must
|
||||
@ -150,12 +151,13 @@ void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats,
|
||||
}
|
||||
}
|
||||
|
||||
/* Called with ovs_mutex. */
|
||||
void ovs_flow_stats_clear(struct sw_flow *flow)
|
||||
{
|
||||
int node;
|
||||
|
||||
for_each_node(node) {
|
||||
struct flow_stats *stats = rcu_dereference(flow->stats[node]);
|
||||
struct flow_stats *stats = ovsl_dereference(flow->stats[node]);
|
||||
|
||||
if (stats) {
|
||||
spin_lock_bh(&stats->lock);
|
||||
|
@ -180,10 +180,10 @@ struct arp_eth_header {
|
||||
unsigned char ar_tip[4]; /* target IP address */
|
||||
} __packed;
|
||||
|
||||
void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb);
|
||||
void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *stats,
|
||||
void ovs_flow_stats_update(struct sw_flow *, struct sk_buff *);
|
||||
void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
|
||||
unsigned long *used, __be16 *tcp_flags);
|
||||
void ovs_flow_stats_clear(struct sw_flow *flow);
|
||||
void ovs_flow_stats_clear(struct sw_flow *);
|
||||
u64 ovs_flow_used_time(unsigned long flow_jiffies);
|
||||
|
||||
int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *);
|
||||
|
Loading…
Reference in New Issue
Block a user