Skip to content

Commit

Permalink
datapath/flow: Fix ovs_flow_stats_get/clear RCU dereference.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Pravin B Shelar <[email protected]>
  • Loading branch information
Jarno Rajahalme committed Apr 2, 2014
1 parent 87e6ccf commit 4bb90be
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
10 changes: 6 additions & 4 deletions datapath/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
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;
Expand All @@ -134,7 +135,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
Expand All @@ -151,12 +152,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);
Expand Down
6 changes: 3 additions & 3 deletions datapath/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,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 *);
Expand Down

0 comments on commit 4bb90be

Please sign in to comment.