From: Vlad Yasevich <vyasevic@redhat.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Thomas Huth <thuth@linux.vnet.ibm.com>,
David Miller <davem@davemloft.net>,
netdev@vger.kernel.org
Subject: Re: [PATCH] macvtap: fix two races
Date: Fri, 09 Aug 2013 13:16:10 -0400 [thread overview]
Message-ID: <520523DA.1000400@redhat.com> (raw)
In-Reply-To: <1375974374.4004.103.camel@edumazet-glaptop>
On 08/08/2013 11:06 AM, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Since commit ac4e4af1e59e1 ("macvtap: Consistently use rcu functions"),
> Thomas gets two different warnings :
>
> BUG: using smp_processor_id() in preemptible [00000000] code: vhost-45891/45892
> caller is macvtap_do_read+0x45c/0x600 [macvtap]
> CPU: 1 PID: 45892 Comm: vhost-45891 Not tainted 3.11.0-bisecttest #13
> Call Trace:
> ([<00000000001126ee>] show_trace+0x126/0x144)
> [<00000000001127d2>] show_stack+0xc6/0xd4
> [<000000000068bcec>] dump_stack+0x74/0xd8
> [<0000000000481066>] debug_smp_processor_id+0xf6/0x114
> [<000003ff802e9a18>] macvtap_do_read+0x45c/0x600 [macvtap]
> [<000003ff802e9c1c>] macvtap_recvmsg+0x60/0x88 [macvtap]
> [<000003ff80318c5e>] handle_rx+0x5b2/0x800 [vhost_net]
> [<000003ff8028f77c>] vhost_worker+0x15c/0x1c4 [vhost]
> [<000000000015f3ac>] kthread+0xd8/0xe4
> [<00000000006934a6>] kernel_thread_starter+0x6/0xc
> [<00000000006934a0>] kernel_thread_starter+0x0/0xc
>
> And
>
> BUG: using smp_processor_id() in preemptible [00000000] code: vhost-45897/45898
> caller is macvlan_start_xmit+0x10a/0x1b4 [macvlan]
> CPU: 1 PID: 45898 Comm: vhost-45897 Not tainted 3.11.0-bisecttest #16
> Call Trace:
> ([<00000000001126ee>] show_trace+0x126/0x144)
> [<00000000001127d2>] show_stack+0xc6/0xd4
> [<000000000068bdb8>] dump_stack+0x74/0xd4
> [<0000000000481132>] debug_smp_processor_id+0xf6/0x114
> [<000003ff802b72ca>] macvlan_start_xmit+0x10a/0x1b4 [macvlan]
> [<000003ff802ea69a>] macvtap_get_user+0x982/0xbc4 [macvtap]
> [<000003ff802ea92a>] macvtap_sendmsg+0x4e/0x60 [macvtap]
> [<000003ff8031947c>] handle_tx+0x494/0x5ec [vhost_net]
> [<000003ff8028f77c>] vhost_worker+0x15c/0x1c4 [vhost]
> [<000000000015f3ac>] kthread+0xd8/0xe4
> [<000000000069356e>] kernel_thread_starter+0x6/0xc
> [<0000000000693568>] kernel_thread_starter+0x0/0xc
> 2 locks held by vhost-45897/45898:
> #0: (&vq->mutex){+.+.+.}, at: [<000003ff8031903c>] handle_tx+0x54/0x5ec [vhost_net]
> #1: (rcu_read_lock){.+.+..}, at: [<000003ff802ea53c>] macvtap_get_user+0x824/0xbc4 [macvtap]
>
>
> In the first case, macvtap_put_user() calls macvlan_count_rx()
> in a preempt-able context, and this is not allowed.
>
> In the second case, macvtap_get_user() calls
> macvlan_start_xmit() with BH enabled, and this is not allowed.
>
> Reported-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Bisected-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Tested-by: Thomas Huth <thuth@linux.vnet.ibm.com>
> Cc: Vlad Yasevich <vyasevic@redhat.com>
> ---
> drivers/net/macvtap.c | 12 +++++++++---
> 1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
> index a98fb0e..b51db2a 100644
> --- a/drivers/net/macvtap.c
> +++ b/drivers/net/macvtap.c
> @@ -818,10 +818,13 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
> skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
> skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
> }
> - if (vlan)
> + if (vlan) {
> + local_bh_disable();
> macvlan_start_xmit(skb, vlan->dev);
> - else
> + local_bh_enable();
> + } else {
> kfree_skb(skb);
> + }
> rcu_read_unlock();
>
> return total_len;
> @@ -912,8 +915,11 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
> done:
> rcu_read_lock();
> vlan = rcu_dereference(q->vlan);
> - if (vlan)
> + if (vlan) {
> + preempt_disable();
> macvlan_count_rx(vlan, copied - vnet_hdr_len, ret == 0, 0);
> + preempt_enable();
> + }
I was looking at this a bit more and I think this call to
macvlan_count_rx() is double counting the packets.
In macvlan_handle_frame(), we call macvlan_count_rx() after we call
vlan->receive(). For macvtap, receive() function is essentially
macvtap_forward() which just tacks the data onto the queue.
Then, the above code counts the data again as we pull it off the queue
socket queue to give to the user.
-vlad
> rcu_read_unlock();
>
> return ret ? ret : copied;
>
>
next prev parent reply other threads:[~2013-08-09 17:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-07 14:43 macvtap bug: using smp_processor_id() in preemptible code Thomas Huth
2013-08-07 15:26 ` Eric Dumazet
2013-08-08 8:25 ` Thomas Huth
2013-08-08 13:21 ` Eric Dumazet
2013-08-08 13:56 ` Thomas Huth
2013-08-08 14:04 ` Eric Dumazet
2013-08-08 15:06 ` [PATCH] macvtap: fix two races Eric Dumazet
2013-08-09 17:16 ` Vlad Yasevich [this message]
2013-08-09 17:41 ` Eric Dumazet
2013-08-09 18:01 ` Vlad Yasevich
2013-08-12 4:50 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=520523DA.1000400@redhat.com \
--to=vyasevic@redhat.com \
--cc=davem@davemloft.net \
--cc=eric.dumazet@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=thuth@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.