From a499a2e9d9c03fd35bd9920b629e4d5b1d6cc1f0 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 9 Nov 2015 09:14:17 -0500 Subject: [PATCH] macvtap: Resolve possible __might_sleep warning in macvtap_do_read() macvtap_do_read code calls macvtap_put_user while it might be set up to wait for the user. This results in the following warning: Jun 23 16:25:26 galen kernel: ------------[ cut here ]------------ Jun 23 16:25:26 galen kernel: WARNING: CPU: 0 PID: 30433 at kernel/sched/core.c: 7286 __might_sleep+0x7f/0x90() Jun 23 16:25:26 galen kernel: do not call blocking ops when !TASK_RUNNING; state =1 set at [] prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: CPU: 0 PID: 30433 Comm: cat Not tainted 4.1.0-rc6+ #11 Jun 23 16:25:26 galen kernel: Call Trace: Jun 23 16:25:26 galen kernel: [] dump_stack+0x4c/0x65 Jun 23 16:25:26 galen kernel: [] warn_slowpath_common+0x8a/0xc 0 Jun 23 16:25:26 galen kernel: [] warn_slowpath_fmt+0x46/0x50 Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait+0x2f/0x90 Jun 23 16:25:26 galen kernel: [] __might_sleep+0x7f/0x90 Jun 23 16:25:26 galen kernel: [] might_fault+0x55/0xb0 Jun 23 16:25:26 galen kernel: [] ? trace_hardirqs_on_caller+0x fd/0x1c0 Jun 23 16:25:26 galen kernel: [] copy_to_iter+0x7c/0x360 Jun 23 16:25:26 galen kernel: [] macvtap_do_read+0x256/0x3d0 [macvtap] Jun 23 16:25:26 galen kernel: [] ? prepare_to_wait_event+0x110/0x110 Jun 23 16:25:26 galen kernel: [] macvtap_read_iter+0x2b/0x50 [macvtap] Jun 23 16:25:26 galen kernel: [] __vfs_read+0xae/0xe0 Jun 23 16:25:26 galen kernel: [] vfs_read+0x86/0x140 Jun 23 16:25:26 galen kernel: [] SyS_read+0x49/0xb0 Jun 23 16:25:26 galen kernel: [] system_call_fastpath+0x12/0x76 Jun 23 16:25:26 galen kernel: ---[ end trace 22e33f67e70c0c2a ]--- Make sure thet we call finish_wait() if we have the skb to process before trying to actually process it. Signed-off-by: Vladislav Yasevich Signed-off-by: David S. Miller --- drivers/net/macvtap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 197c93937c2d..54036ae0a388 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -935,6 +935,9 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, /* Nothing to read, let's sleep */ schedule(); } + if (!noblock) + finish_wait(sk_sleep(&q->sk), &wait); + if (skb) { ret = macvtap_put_user(q, skb, to); if (unlikely(ret < 0)) @@ -942,8 +945,6 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q, else consume_skb(skb); } - if (!noblock) - finish_wait(sk_sleep(&q->sk), &wait); return ret; }