diff options
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 62bea4591054..602e5ebe9db3 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -322,14 +322,11 @@ static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) | |||
322 | sk_mem_charge(sk, skb->truesize); | 322 | sk_mem_charge(sk, skb->truesize); |
323 | } | 323 | } |
324 | 324 | ||
325 | static void netlink_sock_destruct(struct sock *sk) | 325 | static void __netlink_sock_destruct(struct sock *sk) |
326 | { | 326 | { |
327 | struct netlink_sock *nlk = nlk_sk(sk); | 327 | struct netlink_sock *nlk = nlk_sk(sk); |
328 | 328 | ||
329 | if (nlk->cb_running) { | 329 | if (nlk->cb_running) { |
330 | if (nlk->cb.done) | ||
331 | nlk->cb.done(&nlk->cb); | ||
332 | |||
333 | module_put(nlk->cb.module); | 330 | module_put(nlk->cb.module); |
334 | kfree_skb(nlk->cb.skb); | 331 | kfree_skb(nlk->cb.skb); |
335 | } | 332 | } |
@@ -346,6 +343,28 @@ static void netlink_sock_destruct(struct sock *sk) | |||
346 | WARN_ON(nlk_sk(sk)->groups); | 343 | WARN_ON(nlk_sk(sk)->groups); |
347 | } | 344 | } |
348 | 345 | ||
346 | static void netlink_sock_destruct_work(struct work_struct *work) | ||
347 | { | ||
348 | struct netlink_sock *nlk = container_of(work, struct netlink_sock, | ||
349 | work); | ||
350 | |||
351 | nlk->cb.done(&nlk->cb); | ||
352 | __netlink_sock_destruct(&nlk->sk); | ||
353 | } | ||
354 | |||
355 | static void netlink_sock_destruct(struct sock *sk) | ||
356 | { | ||
357 | struct netlink_sock *nlk = nlk_sk(sk); | ||
358 | |||
359 | if (nlk->cb_running && nlk->cb.done) { | ||
360 | INIT_WORK(&nlk->work, netlink_sock_destruct_work); | ||
361 | schedule_work(&nlk->work); | ||
362 | return; | ||
363 | } | ||
364 | |||
365 | __netlink_sock_destruct(sk); | ||
366 | } | ||
367 | |||
349 | /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on | 368 | /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on |
350 | * SMP. Look, when several writers sleep and reader wakes them up, all but one | 369 | * SMP. Look, when several writers sleep and reader wakes them up, all but one |
351 | * immediately hit write lock and grab all the cpus. Exclusive sleep solves | 370 | * immediately hit write lock and grab all the cpus. Exclusive sleep solves |