From: Jesse Gross Date: Wed, 12 May 2010 20:45:49 +0000 (-0700) Subject: datapath: Hold rcu_read_lock where we claim to. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9dca7bd50a93eeb26fb7e47ddb896de22f782e7b;p=openvswitch datapath: Hold rcu_read_lock where we claim to. Many of the vport operations require that either RTNL lock or rcu_read_lock be held. However, operations from userspace often hold a different lock so grab rcu_read_lock as well. --- diff --git a/datapath/datapath.c b/datapath/datapath.c index 67c422ad..a083274b 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1305,8 +1305,12 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute) skb->protocol = htons(ETH_P_802_2); flow_extract(skb, execute->in_port, &key); + + rcu_read_lock(); err = execute_actions(dp, skb, &key, actions->actions, actions->n_actions, GFP_KERNEL); + rcu_read_unlock(); + kfree(actions); return err; diff --git a/datapath/vport.c b/datapath/vport.c index cc209593..691ab84b 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -400,9 +400,12 @@ vport_stats_get(struct odp_vport_stats_req __user *ustats_req) goto out; } - if (vport->ops->get_stats) + if (vport->ops->get_stats) { + rcu_read_lock(); err = vport->ops->get_stats(vport, &stats_req.stats); - else if (vport->ops->flags & VPORT_F_GEN_STATS) { + rcu_read_unlock(); + + } else if (vport->ops->flags & VPORT_F_GEN_STATS) { int i; memset(&stats_req.stats, 0, sizeof(struct odp_vport_stats)); @@ -475,7 +478,9 @@ vport_ether_get(struct odp_vport_ether __user *uvport_ether) goto out; } + rcu_read_lock(); memcpy(vport_ether.ether_addr, vport_get_addr(vport), ETH_ALEN); + rcu_read_unlock(); out: vport_unlock(); @@ -632,11 +637,17 @@ vport_locate(const char *name) dump_stack(); } + rcu_read_lock(); + hlist_for_each_entry(vport, node, bucket, hash_node) if (!strcmp(name, vport_get_name(vport))) - return vport; + goto out; - return NULL; + vport = NULL; + +out: + rcu_read_unlock(); + return vport; } static void