atm: remove an unnecessary loop
authorFrancois Romieu <romieu@fr.zoreil.com>
Sun, 12 Mar 2017 00:41:36 +0000 (19:41 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 13 Mar 2017 22:37:29 +0000 (15:37 -0700)
commitc55fa3cccbc2c672e7f118be8f7484e53a8e9e77
tree06147d1603162f9c84a5f2970db5884c2090aba8
parentbe086e7c53f1fac51eed14523b28f2214b548dd2
atm: remove an unnecessary loop

Andrey reported this kernel warning:

WARNING: CPU: 0 PID: 4114 at kernel/sched/core.c:7737 __might_sleep+0x149/0x1a0
do not call blocking ops when !TASK_RUNNING; state=1 set at
[<ffffffff813fcb22>] prepare_to_wait+0x182/0x530

The deeply nested alloc_skb is a problem.

Diagnosis: nesting is wrong. It makes zero sense. Fix it and the
implicit task state change problem automagically goes away.

alloc_skb() does not need to be in the "while" loop.

alloc_skb() does not need to be in the {prepare_to_wait/add_wait_queue ...
finish_wait/remove_wait_queue} block.

I claim that:
- alloc_tx() should only perform the "wait_for_decent_tx_drain" part
- alloc_skb() ought to be done directly in vcc_sendmsg
- alloc_skb() failure can be handled gracefully in vcc_sendmsg
- alloc_skb() may use a (m->msg_flags & MSG_DONTWAIT) dependent
  GFP_{KERNEL / ATOMIC} flag

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Reviewed-and-Tested-by: Chas Williams <3chas3@gmail.com>
Signed-off-by: Chas Williams <3chas3@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/atm/common.c