diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2013-04-15 16:23:03 -0400 |
---|---|---|
committer | Jesse Gross <jesse@nicira.com> | 2013-04-15 17:38:40 -0400 |
commit | 8e4e1713e4978447c5f799aa668dcc6d2cb0dee9 (patch) | |
tree | dc0c2e05b677183d617d74020fa9d1ed28691102 /net/openvswitch/vport.c | |
parent | b4f9e8cdc82e4a07c3ca50395af5800a6229363e (diff) |
openvswitch: Simplify datapath locking.
Currently OVS uses combination of genl and rtnl lock to protect
datapath state. This was done due to networking stack locking.
But this has complicated locking and there are few lock ordering
issues with new tunneling protocols.
Following patch simplifies locking by introducing new ovs mutex
and now this lock is used to protect entire ovs state.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'net/openvswitch/vport.c')
-rw-r--r-- | net/openvswitch/vport.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 71a2de8726cb..c90d856d441c 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -40,7 +40,7 @@ static const struct vport_ops *vport_ops_list[] = { | |||
40 | &ovs_internal_vport_ops, | 40 | &ovs_internal_vport_ops, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /* Protected by RCU read lock for reading, RTNL lock for writing. */ | 43 | /* Protected by RCU read lock for reading, ovs_mutex for writing. */ |
44 | static struct hlist_head *dev_table; | 44 | static struct hlist_head *dev_table; |
45 | #define VPORT_HASH_BUCKETS 1024 | 45 | #define VPORT_HASH_BUCKETS 1024 |
46 | 46 | ||
@@ -80,7 +80,7 @@ static struct hlist_head *hash_bucket(struct net *net, const char *name) | |||
80 | * | 80 | * |
81 | * @name: name of port to find | 81 | * @name: name of port to find |
82 | * | 82 | * |
83 | * Must be called with RTNL or RCU read lock. | 83 | * Must be called with ovs or RCU read lock. |
84 | */ | 84 | */ |
85 | struct vport *ovs_vport_locate(struct net *net, const char *name) | 85 | struct vport *ovs_vport_locate(struct net *net, const char *name) |
86 | { | 86 | { |
@@ -161,7 +161,7 @@ void ovs_vport_free(struct vport *vport) | |||
161 | * @parms: Information about new vport. | 161 | * @parms: Information about new vport. |
162 | * | 162 | * |
163 | * Creates a new vport with the specified configuration (which is dependent on | 163 | * Creates a new vport with the specified configuration (which is dependent on |
164 | * device type). RTNL lock must be held. | 164 | * device type). ovs_mutex must be held. |
165 | */ | 165 | */ |
166 | struct vport *ovs_vport_add(const struct vport_parms *parms) | 166 | struct vport *ovs_vport_add(const struct vport_parms *parms) |
167 | { | 167 | { |
@@ -169,8 +169,6 @@ struct vport *ovs_vport_add(const struct vport_parms *parms) | |||
169 | int err = 0; | 169 | int err = 0; |
170 | int i; | 170 | int i; |
171 | 171 | ||
172 | ASSERT_RTNL(); | ||
173 | |||
174 | for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) { | 172 | for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) { |
175 | if (vport_ops_list[i]->type == parms->type) { | 173 | if (vport_ops_list[i]->type == parms->type) { |
176 | struct hlist_head *bucket; | 174 | struct hlist_head *bucket; |
@@ -201,12 +199,10 @@ out: | |||
201 | * @port: New configuration. | 199 | * @port: New configuration. |
202 | * | 200 | * |
203 | * Modifies an existing device with the specified configuration (which is | 201 | * Modifies an existing device with the specified configuration (which is |
204 | * dependent on device type). RTNL lock must be held. | 202 | * dependent on device type). ovs_mutex must be held. |
205 | */ | 203 | */ |
206 | int ovs_vport_set_options(struct vport *vport, struct nlattr *options) | 204 | int ovs_vport_set_options(struct vport *vport, struct nlattr *options) |
207 | { | 205 | { |
208 | ASSERT_RTNL(); | ||
209 | |||
210 | if (!vport->ops->set_options) | 206 | if (!vport->ops->set_options) |
211 | return -EOPNOTSUPP; | 207 | return -EOPNOTSUPP; |
212 | return vport->ops->set_options(vport, options); | 208 | return vport->ops->set_options(vport, options); |
@@ -218,11 +214,11 @@ int ovs_vport_set_options(struct vport *vport, struct nlattr *options) | |||
218 | * @vport: vport to delete. | 214 | * @vport: vport to delete. |
219 | * | 215 | * |
220 | * Detaches @vport from its datapath and destroys it. It is possible to fail | 216 | * Detaches @vport from its datapath and destroys it. It is possible to fail |
221 | * for reasons such as lack of memory. RTNL lock must be held. | 217 | * for reasons such as lack of memory. ovs_mutex must be held. |
222 | */ | 218 | */ |
223 | void ovs_vport_del(struct vport *vport) | 219 | void ovs_vport_del(struct vport *vport) |
224 | { | 220 | { |
225 | ASSERT_RTNL(); | 221 | ASSERT_OVSL(); |
226 | 222 | ||
227 | hlist_del_rcu(&vport->hash_node); | 223 | hlist_del_rcu(&vport->hash_node); |
228 | 224 | ||
@@ -237,7 +233,7 @@ void ovs_vport_del(struct vport *vport) | |||
237 | * | 233 | * |
238 | * Retrieves transmit, receive, and error stats for the given device. | 234 | * Retrieves transmit, receive, and error stats for the given device. |
239 | * | 235 | * |
240 | * Must be called with RTNL lock or rcu_read_lock. | 236 | * Must be called with ovs_mutex or rcu_read_lock. |
241 | */ | 237 | */ |
242 | void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats) | 238 | void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats) |
243 | { | 239 | { |
@@ -296,7 +292,7 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats) | |||
296 | * negative error code if a real error occurred. If an error occurs, @skb is | 292 | * negative error code if a real error occurred. If an error occurs, @skb is |
297 | * left unmodified. | 293 | * left unmodified. |
298 | * | 294 | * |
299 | * Must be called with RTNL lock or rcu_read_lock. | 295 | * Must be called with ovs_mutex or rcu_read_lock. |
300 | */ | 296 | */ |
301 | int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb) | 297 | int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb) |
302 | { | 298 | { |
@@ -348,7 +344,7 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb) | |||
348 | * @vport: vport on which to send the packet | 344 | * @vport: vport on which to send the packet |
349 | * @skb: skb to send | 345 | * @skb: skb to send |
350 | * | 346 | * |
351 | * Sends the given packet and returns the length of data sent. Either RTNL | 347 | * Sends the given packet and returns the length of data sent. Either ovs |
352 | * lock or rcu_read_lock must be held. | 348 | * lock or rcu_read_lock must be held. |
353 | */ | 349 | */ |
354 | int ovs_vport_send(struct vport *vport, struct sk_buff *skb) | 350 | int ovs_vport_send(struct vport *vport, struct sk_buff *skb) |