diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-06 23:12:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-08 00:25:21 -0400 |
commit | 66018506e15bea62de4eefc3298f170b4bfcf5ef (patch) | |
tree | d2dbf5c06e317b85f75b946a1b63ed0917d0382a /net/ipv4/ip_sockglue.c | |
parent | 8b37ef0a1f6c2401fea3536facfa21191936bd6c (diff) |
ip: Router Alert RCU conversion
Straightforward conversion to RCU.
One rwlock becomes a spinlock, and is static.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_sockglue.c')
-rw-r--r-- | net/ipv4/ip_sockglue.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ce231780a2b1..08b9519a24f4 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -239,7 +239,12 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc) | |||
239 | sent to multicast group to reach destination designated router. | 239 | sent to multicast group to reach destination designated router. |
240 | */ | 240 | */ |
241 | struct ip_ra_chain *ip_ra_chain; | 241 | struct ip_ra_chain *ip_ra_chain; |
242 | DEFINE_RWLOCK(ip_ra_lock); | 242 | static DEFINE_SPINLOCK(ip_ra_lock); |
243 | |||
244 | static void ip_ra_free_rcu(struct rcu_head *head) | ||
245 | { | ||
246 | kfree(container_of(head, struct ip_ra_chain, rcu)); | ||
247 | } | ||
243 | 248 | ||
244 | int ip_ra_control(struct sock *sk, unsigned char on, | 249 | int ip_ra_control(struct sock *sk, unsigned char on, |
245 | void (*destructor)(struct sock *)) | 250 | void (*destructor)(struct sock *)) |
@@ -251,35 +256,35 @@ int ip_ra_control(struct sock *sk, unsigned char on, | |||
251 | 256 | ||
252 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; | 257 | new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; |
253 | 258 | ||
254 | write_lock_bh(&ip_ra_lock); | 259 | spin_lock_bh(&ip_ra_lock); |
255 | for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) { | 260 | for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) { |
256 | if (ra->sk == sk) { | 261 | if (ra->sk == sk) { |
257 | if (on) { | 262 | if (on) { |
258 | write_unlock_bh(&ip_ra_lock); | 263 | spin_unlock_bh(&ip_ra_lock); |
259 | kfree(new_ra); | 264 | kfree(new_ra); |
260 | return -EADDRINUSE; | 265 | return -EADDRINUSE; |
261 | } | 266 | } |
262 | *rap = ra->next; | 267 | rcu_assign_pointer(*rap, ra->next); |
263 | write_unlock_bh(&ip_ra_lock); | 268 | spin_unlock_bh(&ip_ra_lock); |
264 | 269 | ||
265 | if (ra->destructor) | 270 | if (ra->destructor) |
266 | ra->destructor(sk); | 271 | ra->destructor(sk); |
267 | sock_put(sk); | 272 | sock_put(sk); |
268 | kfree(ra); | 273 | call_rcu(&ra->rcu, ip_ra_free_rcu); |
269 | return 0; | 274 | return 0; |
270 | } | 275 | } |
271 | } | 276 | } |
272 | if (new_ra == NULL) { | 277 | if (new_ra == NULL) { |
273 | write_unlock_bh(&ip_ra_lock); | 278 | spin_unlock_bh(&ip_ra_lock); |
274 | return -ENOBUFS; | 279 | return -ENOBUFS; |
275 | } | 280 | } |
276 | new_ra->sk = sk; | 281 | new_ra->sk = sk; |
277 | new_ra->destructor = destructor; | 282 | new_ra->destructor = destructor; |
278 | 283 | ||
279 | new_ra->next = ra; | 284 | new_ra->next = ra; |
280 | *rap = new_ra; | 285 | rcu_assign_pointer(*rap, new_ra); |
281 | sock_hold(sk); | 286 | sock_hold(sk); |
282 | write_unlock_bh(&ip_ra_lock); | 287 | spin_unlock_bh(&ip_ra_lock); |
283 | 288 | ||
284 | return 0; | 289 | return 0; |
285 | } | 290 | } |