* [BUG] Inconsistent lock state in virtnet poll
@ 2020-05-05 12:08 Thomas Gleixner
2020-05-05 16:10 ` Michael S. Tsirkin
0 siblings, 1 reply; 12+ messages in thread
From: Thomas Gleixner @ 2020-05-05 12:08 UTC (permalink / raw)
To: netdev; +Cc: Michael S. Tsirkin
The following lockdep splat happens reproducibly on 5.7-rc4
Thanks,
tglx
================================
WARNING: inconsistent lock state
5.7.0-rc4+ #79 Not tainted
--------------------------------
inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
{SOFTIRQ-ON-W} state was registered at:
lock_acquire+0x82/0x300
try_fill_recv+0x39f/0x590
virtnet_open+0xe0/0x180
__dev_open+0xbe/0x160
__dev_change_flags+0x152/0x1b0
dev_change_flags+0x23/0x60
do_setlink+0x814/0xa30
__rtnl_newlink+0x583/0x8e0
rtnl_newlink+0x36/0x60
rtnetlink_rcv_msg+0x139/0x470
netlink_rcv_skb+0x6a/0xe0
rtnetlink_rcv+0xd/0x10
netlink_unicast+0x175/0x250
netlink_sendmsg+0x263/0x440
sock_sendmsg+0x5c/0x60
____sys_sendmsg+0x182/0x1d0
___sys_sendmsg+0x59/0x90
__sys_sendmsg+0x39/0x80
__ia32_sys_socketcall+0x2d2/0x330
do_fast_syscall_32+0x82/0x340
entry_SYSENTER_32+0xaa/0x102
irq event stamp: 2276
hardirqs last enabled at (2276): [<c18e419e>] net_rx_action+0x7e/0x390
hardirqs last disabled at (2275): [<c18e4178>] net_rx_action+0x58/0x390
softirqs last enabled at (2272): [<c16f87ee>] virtnet_napi_enable+0xe/0x50
softirqs last disabled at (2273): [<c101fb10>] call_on_stack+0x40/0x50
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock(&syncp->seq#2);
<Interrupt>
lock(&syncp->seq#2);
*** DEADLOCK ***
1 lock held by ip/356:
#0: c20a4a38 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x118/0x470
stack backtrace:
CPU: 2 PID: 356 Comm: ip Not tainted 5.7.0-rc4+ #79
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Call Trace:
<SOFTIRQ>
dump_stack+0x6e/0x9e
print_usage_bug.cold+0x15a/0x162
mark_lock+0x58d/0x6e0
? check_usage_backwards+0x180/0x180
__lock_acquire+0xdd7/0x24f0
? select_task_rq_fair+0xbb/0xfe0
? __lock_acquire+0x35f/0x24f0
? __lock_acquire+0x35f/0x24f0
? __lock_acquire+0x35f/0x24f0
lock_acquire+0x82/0x300
? net_rx_action+0xfb/0x390
? find_held_lock+0x24/0x80
? lock_release+0x8a/0x260
? virtnet_poll+0xd0/0x3d9
virtnet_poll+0x1d3/0x3d9
? net_rx_action+0xfb/0x390
? trace_hardirqs_on+0x4a/0xf0
net_rx_action+0xfb/0x390
? __do_softirq+0x84/0x3ca
? virtnet_napi_enable+0xe/0x50
__do_softirq+0xb1/0x3ca
? virtnet_napi_enable+0xe/0x50
? __irqentry_text_end+0x8/0x8
call_on_stack+0x40/0x50
</SOFTIRQ>
? do_softirq.part.0+0x4e/0x50
? __local_bh_enable_ip+0xd1/0xe0
? virtnet_napi_enable+0x41/0x50
? virtnet_open+0x7f/0x180
? __dev_open+0xbe/0x160
? __dev_change_flags+0x152/0x1b0
? dev_change_flags+0x23/0x60
? do_setlink+0x814/0xa30
? __lock_acquire+0x35f/0x24f0
? __nla_parse+0x1c/0x30
? __rtnl_newlink+0x583/0x8e0
? lock_acquire+0x82/0x300
? handle_mm_fault+0x6e6/0xa10
? find_held_lock+0x24/0x80
? __lock_acquire+0x35f/0x24f0
? lock_acquire+0x82/0x300
? __lock_acquire+0x35f/0x24f0
? rtnl_newlink+0x23/0x60
? rcu_read_lock_sched_held+0x3f/0x70
? kmem_cache_alloc_trace+0x235/0x260
? rtnl_newlink+0x36/0x60
? __rtnl_newlink+0x8e0/0x8e0
? rtnetlink_rcv_msg+0x139/0x470
? netlink_deliver_tap+0x81/0x3a0
? find_held_lock+0x24/0x80
? rtnl_bridge_getlink+0x240/0x240
? netlink_rcv_skb+0x6a/0xe0
? rtnl_bridge_getlink+0x240/0x240
? rtnetlink_rcv+0xd/0x10
? netlink_unicast+0x175/0x250
? netlink_sendmsg+0x263/0x440
? netlink_unicast+0x250/0x250
? sock_sendmsg+0x5c/0x60
? ____sys_sendmsg+0x182/0x1d0
? ___sys_sendmsg+0x59/0x90
? lock_acquire+0x82/0x300
? __might_fault+0x39/0x80
? __sys_sendmsg+0x39/0x80
? __ia32_sys_socketcall+0x2d2/0x330
? do_fast_syscall_32+0x82/0x340
? entry_SYSENTER_32+0xaa/0x102
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 12:08 [BUG] Inconsistent lock state in virtnet poll Thomas Gleixner
@ 2020-05-05 16:10 ` Michael S. Tsirkin
2020-05-05 22:30 ` Thomas Gleixner
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-05 16:10 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: netdev, Jason Wang
On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>
> The following lockdep splat happens reproducibly on 5.7-rc4
>
> Thanks,
>
> tglx
>
> ================================
> WARNING: inconsistent lock state
> 5.7.0-rc4+ #79 Not tainted
> --------------------------------
> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> {SOFTIRQ-ON-W} state was registered at:
> lock_acquire+0x82/0x300
> try_fill_recv+0x39f/0x590
Weird. Where does try_fill_recv acquire any locks?
> virtnet_open+0xe0/0x180
> __dev_open+0xbe/0x160
> __dev_change_flags+0x152/0x1b0
> dev_change_flags+0x23/0x60
> do_setlink+0x814/0xa30
> __rtnl_newlink+0x583/0x8e0
> rtnl_newlink+0x36/0x60
> rtnetlink_rcv_msg+0x139/0x470
> netlink_rcv_skb+0x6a/0xe0
> rtnetlink_rcv+0xd/0x10
> netlink_unicast+0x175/0x250
> netlink_sendmsg+0x263/0x440
> sock_sendmsg+0x5c/0x60
> ____sys_sendmsg+0x182/0x1d0
> ___sys_sendmsg+0x59/0x90
> __sys_sendmsg+0x39/0x80
> __ia32_sys_socketcall+0x2d2/0x330
> do_fast_syscall_32+0x82/0x340
> entry_SYSENTER_32+0xaa/0x102
> irq event stamp: 2276
> hardirqs last enabled at (2276): [<c18e419e>] net_rx_action+0x7e/0x390
> hardirqs last disabled at (2275): [<c18e4178>] net_rx_action+0x58/0x390
> softirqs last enabled at (2272): [<c16f87ee>] virtnet_napi_enable+0xe/0x50
> softirqs last disabled at (2273): [<c101fb10>] call_on_stack+0x40/0x50
>
> other info that might help us debug this:
> Possible unsafe locking scenario:
>
> CPU0
> ----
> lock(&syncp->seq#2);
> <Interrupt>
> lock(&syncp->seq#2);
>
> *** DEADLOCK ***
>
> 1 lock held by ip/356:
> #0: c20a4a38 (rtnl_mutex){+.+.}-{3:3}, at: rtnetlink_rcv_msg+0x118/0x470
>
> stack backtrace:
> CPU: 2 PID: 356 Comm: ip Not tainted 5.7.0-rc4+ #79
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
> Call Trace:
> <SOFTIRQ>
> dump_stack+0x6e/0x9e
> print_usage_bug.cold+0x15a/0x162
> mark_lock+0x58d/0x6e0
> ? check_usage_backwards+0x180/0x180
> __lock_acquire+0xdd7/0x24f0
> ? select_task_rq_fair+0xbb/0xfe0
> ? __lock_acquire+0x35f/0x24f0
> ? __lock_acquire+0x35f/0x24f0
> ? __lock_acquire+0x35f/0x24f0
> lock_acquire+0x82/0x300
> ? net_rx_action+0xfb/0x390
> ? find_held_lock+0x24/0x80
> ? lock_release+0x8a/0x260
> ? virtnet_poll+0xd0/0x3d9
> virtnet_poll+0x1d3/0x3d9
> ? net_rx_action+0xfb/0x390
> ? trace_hardirqs_on+0x4a/0xf0
> net_rx_action+0xfb/0x390
> ? __do_softirq+0x84/0x3ca
> ? virtnet_napi_enable+0xe/0x50
> __do_softirq+0xb1/0x3ca
> ? virtnet_napi_enable+0xe/0x50
> ? __irqentry_text_end+0x8/0x8
> call_on_stack+0x40/0x50
> </SOFTIRQ>
> ? do_softirq.part.0+0x4e/0x50
> ? __local_bh_enable_ip+0xd1/0xe0
> ? virtnet_napi_enable+0x41/0x50
> ? virtnet_open+0x7f/0x180
> ? __dev_open+0xbe/0x160
> ? __dev_change_flags+0x152/0x1b0
> ? dev_change_flags+0x23/0x60
> ? do_setlink+0x814/0xa30
> ? __lock_acquire+0x35f/0x24f0
> ? __nla_parse+0x1c/0x30
> ? __rtnl_newlink+0x583/0x8e0
> ? lock_acquire+0x82/0x300
> ? handle_mm_fault+0x6e6/0xa10
> ? find_held_lock+0x24/0x80
> ? __lock_acquire+0x35f/0x24f0
> ? lock_acquire+0x82/0x300
> ? __lock_acquire+0x35f/0x24f0
> ? rtnl_newlink+0x23/0x60
> ? rcu_read_lock_sched_held+0x3f/0x70
> ? kmem_cache_alloc_trace+0x235/0x260
> ? rtnl_newlink+0x36/0x60
> ? __rtnl_newlink+0x8e0/0x8e0
> ? rtnetlink_rcv_msg+0x139/0x470
> ? netlink_deliver_tap+0x81/0x3a0
> ? find_held_lock+0x24/0x80
> ? rtnl_bridge_getlink+0x240/0x240
> ? netlink_rcv_skb+0x6a/0xe0
> ? rtnl_bridge_getlink+0x240/0x240
> ? rtnetlink_rcv+0xd/0x10
> ? netlink_unicast+0x175/0x250
> ? netlink_sendmsg+0x263/0x440
> ? netlink_unicast+0x250/0x250
> ? sock_sendmsg+0x5c/0x60
> ? ____sys_sendmsg+0x182/0x1d0
> ? ___sys_sendmsg+0x59/0x90
> ? lock_acquire+0x82/0x300
> ? __might_fault+0x39/0x80
> ? __sys_sendmsg+0x39/0x80
> ? __ia32_sys_socketcall+0x2d2/0x330
> ? do_fast_syscall_32+0x82/0x340
> ? entry_SYSENTER_32+0xaa/0x102
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 16:10 ` Michael S. Tsirkin
@ 2020-05-05 22:30 ` Thomas Gleixner
2020-05-05 22:40 ` Eric Dumazet
2020-05-05 23:54 ` Michael S. Tsirkin
0 siblings, 2 replies; 12+ messages in thread
From: Thomas Gleixner @ 2020-05-05 22:30 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: netdev, Jason Wang, Peter Zijlstra
"Michael S. Tsirkin" <mst@redhat.com> writes:
> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>>
>> The following lockdep splat happens reproducibly on 5.7-rc4
>
>> ================================
>> WARNING: inconsistent lock state
>> 5.7.0-rc4+ #79 Not tainted
>> --------------------------------
>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
>> {SOFTIRQ-ON-W} state was registered at:
>> lock_acquire+0x82/0x300
>> try_fill_recv+0x39f/0x590
>
> Weird. Where does try_fill_recv acquire any locks?
u64_stats_update_begin(&rq->stats.syncp);
That's a 32bit kernel which uses a seqcount for this. sequence counts
are "lock" constructs where you need to make sure that writers are
serialized.
Actually the problem at hand is that try_fill_recv() is called from
fully preemptible context initialy and then from softirq context.
Obviously that's for the open() path a non issue, but lockdep does not
know about that. OTOH, there is other code which calls that from
non-softirq context.
The hack below made it shut up. It's obvioulsy not ideal, but at least
it let me look at the actual problem I was chasing down :)
Thanks,
tglx
8<-----------
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
break;
} while (rq->vq->num_free);
if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
+ local_bh_disable();
u64_stats_update_begin(&rq->stats.syncp);
rq->stats.kicks++;
u64_stats_update_end(&rq->stats.syncp);
+ local_bh_enable();
}
return !oom;
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 22:30 ` Thomas Gleixner
@ 2020-05-05 22:40 ` Eric Dumazet
2020-05-05 23:49 ` Michael S. Tsirkin
2020-05-06 0:43 ` Michael S. Tsirkin
2020-05-05 23:54 ` Michael S. Tsirkin
1 sibling, 2 replies; 12+ messages in thread
From: Eric Dumazet @ 2020-05-05 22:40 UTC (permalink / raw)
To: Thomas Gleixner, Michael S. Tsirkin; +Cc: netdev, Jason Wang, Peter Zijlstra
On 5/5/20 3:30 PM, Thomas Gleixner wrote:
> "Michael S. Tsirkin" <mst@redhat.com> writes:
>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>>>
>>> The following lockdep splat happens reproducibly on 5.7-rc4
>>
>>> ================================
>>> WARNING: inconsistent lock state
>>> 5.7.0-rc4+ #79 Not tainted
>>> --------------------------------
>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
>>> {SOFTIRQ-ON-W} state was registered at:
>>> lock_acquire+0x82/0x300
>>> try_fill_recv+0x39f/0x590
>>
>> Weird. Where does try_fill_recv acquire any locks?
>
> u64_stats_update_begin(&rq->stats.syncp);
>
> That's a 32bit kernel which uses a seqcount for this. sequence counts
> are "lock" constructs where you need to make sure that writers are
> serialized.
>
> Actually the problem at hand is that try_fill_recv() is called from
> fully preemptible context initialy and then from softirq context.
>
> Obviously that's for the open() path a non issue, but lockdep does not
> know about that. OTOH, there is other code which calls that from
> non-softirq context.
>
> The hack below made it shut up. It's obvioulsy not ideal, but at least
> it let me look at the actual problem I was chasing down :)
>
> Thanks,
>
> tglx
>
> 8<-----------
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> break;
> } while (rq->vq->num_free);
> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> + local_bh_disable();
Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
> u64_stats_update_begin(&rq->stats.syncp);
> rq->stats.kicks++;
> u64_stats_update_end(&rq->stats.syncp);
> + local_bh_enable();
> }
>
> return !oom;
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 22:40 ` Eric Dumazet
@ 2020-05-05 23:49 ` Michael S. Tsirkin
2020-05-06 0:43 ` Michael S. Tsirkin
1 sibling, 0 replies; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-05 23:49 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
>
>
> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
> > "Michael S. Tsirkin" <mst@redhat.com> writes:
> >> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
> >>>
> >>> The following lockdep splat happens reproducibly on 5.7-rc4
> >>
> >>> ================================
> >>> WARNING: inconsistent lock state
> >>> 5.7.0-rc4+ #79 Not tainted
> >>> --------------------------------
> >>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> >>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> >>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> >>> {SOFTIRQ-ON-W} state was registered at:
> >>> lock_acquire+0x82/0x300
> >>> try_fill_recv+0x39f/0x590
> >>
> >> Weird. Where does try_fill_recv acquire any locks?
> >
> > u64_stats_update_begin(&rq->stats.syncp);
> >
> > That's a 32bit kernel which uses a seqcount for this. sequence counts
> > are "lock" constructs where you need to make sure that writers are
> > serialized.
> >
> > Actually the problem at hand is that try_fill_recv() is called from
> > fully preemptible context initialy and then from softirq context.
> >
> > Obviously that's for the open() path a non issue, but lockdep does not
> > know about that. OTOH, there is other code which calls that from
> > non-softirq context.
> >
> > The hack below made it shut up. It's obvioulsy not ideal, but at least
> > it let me look at the actual problem I was chasing down :)
> >
> > Thanks,
> >
> > tglx
> >
> > 8<-----------
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> > break;
> > } while (rq->vq->num_free);
> > if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> > + local_bh_disable();
>
> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
I like this better I think.
Will send a patch now.
--
MST
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 22:30 ` Thomas Gleixner
2020-05-05 22:40 ` Eric Dumazet
@ 2020-05-05 23:54 ` Michael S. Tsirkin
1 sibling, 0 replies; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-05 23:54 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: netdev, Jason Wang, Peter Zijlstra
On Wed, May 06, 2020 at 12:30:52AM +0200, Thomas Gleixner wrote:
> "Michael S. Tsirkin" <mst@redhat.com> writes:
> > On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
> >>
> >> The following lockdep splat happens reproducibly on 5.7-rc4
> >
> >> ================================
> >> WARNING: inconsistent lock state
> >> 5.7.0-rc4+ #79 Not tainted
> >> --------------------------------
> >> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> >> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> >> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> >> {SOFTIRQ-ON-W} state was registered at:
> >> lock_acquire+0x82/0x300
> >> try_fill_recv+0x39f/0x590
> >
> > Weird. Where does try_fill_recv acquire any locks?
>
> u64_stats_update_begin(&rq->stats.syncp);
>
> That's a 32bit kernel which uses a seqcount for this. sequence counts
> are "lock" constructs where you need to make sure that writers are
> serialized.
>
> Actually the problem at hand is that try_fill_recv() is called from
> fully preemptible context initialy and then from softirq context.
>
> Obviously that's for the open() path a non issue, but lockdep does not
> know about that. OTOH, there is other code which calls that from
> non-softirq context.
Well to be more specific, try_fill_recv is either called from napi,
or from preemptible contexts with napi disabled and rtnl lock taken.
Two try_fill_recv calls in parallel would cause ring corruption
and no end of mischief, we certainly don't want that even on 64 bit
kernels.
> The hack below made it shut up. It's obvioulsy not ideal, but at least
> it let me look at the actual problem I was chasing down :)
>
> Thanks,
>
> tglx
I'll post a hack based on Eric's suggestion since that is at least
0-overhead on 64 bit. It would be nice if we could teach
lockdep that it's about napi...
> 8<-----------
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> break;
> } while (rq->vq->num_free);
> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> + local_bh_disable();
> u64_stats_update_begin(&rq->stats.syncp);
> rq->stats.kicks++;
> u64_stats_update_end(&rq->stats.syncp);
> + local_bh_enable();
> }
>
> return !oom;
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-05 22:40 ` Eric Dumazet
2020-05-05 23:49 ` Michael S. Tsirkin
@ 2020-05-06 0:43 ` Michael S. Tsirkin
2020-05-06 1:19 ` Eric Dumazet
1 sibling, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-06 0:43 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
>
>
> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
> > "Michael S. Tsirkin" <mst@redhat.com> writes:
> >> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
> >>>
> >>> The following lockdep splat happens reproducibly on 5.7-rc4
> >>
> >>> ================================
> >>> WARNING: inconsistent lock state
> >>> 5.7.0-rc4+ #79 Not tainted
> >>> --------------------------------
> >>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> >>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> >>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> >>> {SOFTIRQ-ON-W} state was registered at:
> >>> lock_acquire+0x82/0x300
> >>> try_fill_recv+0x39f/0x590
> >>
> >> Weird. Where does try_fill_recv acquire any locks?
> >
> > u64_stats_update_begin(&rq->stats.syncp);
> >
> > That's a 32bit kernel which uses a seqcount for this. sequence counts
> > are "lock" constructs where you need to make sure that writers are
> > serialized.
> >
> > Actually the problem at hand is that try_fill_recv() is called from
> > fully preemptible context initialy and then from softirq context.
> >
> > Obviously that's for the open() path a non issue, but lockdep does not
> > know about that. OTOH, there is other code which calls that from
> > non-softirq context.
> >
> > The hack below made it shut up. It's obvioulsy not ideal, but at least
> > it let me look at the actual problem I was chasing down :)
> >
> > Thanks,
> >
> > tglx
> >
> > 8<-----------
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> > break;
> > } while (rq->vq->num_free);
> > if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> > + local_bh_disable();
>
> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
I applied this, but am still trying to think of something that
is 0 overhead for all configs.
Maybe we can select a lockdep class depending on whether napi
is enabled?
> > u64_stats_update_begin(&rq->stats.syncp);
> > rq->stats.kicks++;
> > u64_stats_update_end(&rq->stats.syncp);
> > + local_bh_enable();
> > }
> >
> > return !oom;
> >
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-06 0:43 ` Michael S. Tsirkin
@ 2020-05-06 1:19 ` Eric Dumazet
2020-05-06 1:25 ` Michael S. Tsirkin
0 siblings, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2020-05-06 1:19 UTC (permalink / raw)
To: Michael S. Tsirkin, Eric Dumazet
Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On 5/5/20 5:43 PM, Michael S. Tsirkin wrote:
> On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
>>
>>
>> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
>>> "Michael S. Tsirkin" <mst@redhat.com> writes:
>>>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>>>>>
>>>>> The following lockdep splat happens reproducibly on 5.7-rc4
>>>>
>>>>> ================================
>>>>> WARNING: inconsistent lock state
>>>>> 5.7.0-rc4+ #79 Not tainted
>>>>> --------------------------------
>>>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
>>>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
>>>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
>>>>> {SOFTIRQ-ON-W} state was registered at:
>>>>> lock_acquire+0x82/0x300
>>>>> try_fill_recv+0x39f/0x590
>>>>
>>>> Weird. Where does try_fill_recv acquire any locks?
>>>
>>> u64_stats_update_begin(&rq->stats.syncp);
>>>
>>> That's a 32bit kernel which uses a seqcount for this. sequence counts
>>> are "lock" constructs where you need to make sure that writers are
>>> serialized.
>>>
>>> Actually the problem at hand is that try_fill_recv() is called from
>>> fully preemptible context initialy and then from softirq context.
>>>
>>> Obviously that's for the open() path a non issue, but lockdep does not
>>> know about that. OTOH, there is other code which calls that from
>>> non-softirq context.
>>>
>>> The hack below made it shut up. It's obvioulsy not ideal, but at least
>>> it let me look at the actual problem I was chasing down :)
>>>
>>> Thanks,
>>>
>>> tglx
>>>
>>> 8<-----------
>>> --- a/drivers/net/virtio_net.c
>>> +++ b/drivers/net/virtio_net.c
>>> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
>>> break;
>>> } while (rq->vq->num_free);
>>> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
>>> + local_bh_disable();
>>
>> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
>
> I applied this, but am still trying to think of something that
> is 0 overhead for all configs.
> Maybe we can select a lockdep class depending on whether napi
> is enabled?
Do you _really_ need 64bit counter for stats.kicks on 32bit kernels ?
Adding 64bit counters just because we can might be overhead anyway.
>
>
>>> u64_stats_update_begin(&rq->stats.syncp);
>>> rq->stats.kicks++;
>>> u64_stats_update_end(&rq->stats.syncp);
>>> + local_bh_enable();
>>> }
>>>
>>> return !oom;
>>>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-06 1:19 ` Eric Dumazet
@ 2020-05-06 1:25 ` Michael S. Tsirkin
2020-05-06 2:24 ` Eric Dumazet
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-06 1:25 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On Tue, May 05, 2020 at 06:19:09PM -0700, Eric Dumazet wrote:
>
>
> On 5/5/20 5:43 PM, Michael S. Tsirkin wrote:
> > On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
> >>
> >>
> >> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
> >>> "Michael S. Tsirkin" <mst@redhat.com> writes:
> >>>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
> >>>>>
> >>>>> The following lockdep splat happens reproducibly on 5.7-rc4
> >>>>
> >>>>> ================================
> >>>>> WARNING: inconsistent lock state
> >>>>> 5.7.0-rc4+ #79 Not tainted
> >>>>> --------------------------------
> >>>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> >>>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> >>>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> >>>>> {SOFTIRQ-ON-W} state was registered at:
> >>>>> lock_acquire+0x82/0x300
> >>>>> try_fill_recv+0x39f/0x590
> >>>>
> >>>> Weird. Where does try_fill_recv acquire any locks?
> >>>
> >>> u64_stats_update_begin(&rq->stats.syncp);
> >>>
> >>> That's a 32bit kernel which uses a seqcount for this. sequence counts
> >>> are "lock" constructs where you need to make sure that writers are
> >>> serialized.
> >>>
> >>> Actually the problem at hand is that try_fill_recv() is called from
> >>> fully preemptible context initialy and then from softirq context.
> >>>
> >>> Obviously that's for the open() path a non issue, but lockdep does not
> >>> know about that. OTOH, there is other code which calls that from
> >>> non-softirq context.
> >>>
> >>> The hack below made it shut up. It's obvioulsy not ideal, but at least
> >>> it let me look at the actual problem I was chasing down :)
> >>>
> >>> Thanks,
> >>>
> >>> tglx
> >>>
> >>> 8<-----------
> >>> --- a/drivers/net/virtio_net.c
> >>> +++ b/drivers/net/virtio_net.c
> >>> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> >>> break;
> >>> } while (rq->vq->num_free);
> >>> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> >>> + local_bh_disable();
> >>
> >> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
> >
> > I applied this, but am still trying to think of something that
> > is 0 overhead for all configs.
> > Maybe we can select a lockdep class depending on whether napi
> > is enabled?
>
>
> Do you _really_ need 64bit counter for stats.kicks on 32bit kernels ?
>
> Adding 64bit counters just because we can might be overhead anyway.
Well 32 bit kernels don't fundamentally kick less than 64 bit ones,
and we kick more or less per packet, sometimes per batch,
people expect these to be in sync ..
> >
> >
> >>> u64_stats_update_begin(&rq->stats.syncp);
> >>> rq->stats.kicks++;
> >>> u64_stats_update_end(&rq->stats.syncp);
> >>> + local_bh_enable();
> >>> }
> >>>
> >>> return !oom;
> >>>
> >
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-06 1:25 ` Michael S. Tsirkin
@ 2020-05-06 2:24 ` Eric Dumazet
2020-05-06 7:31 ` Michael S. Tsirkin
0 siblings, 1 reply; 12+ messages in thread
From: Eric Dumazet @ 2020-05-06 2:24 UTC (permalink / raw)
To: Michael S. Tsirkin, Eric Dumazet
Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On 5/5/20 6:25 PM, Michael S. Tsirkin wrote:
> On Tue, May 05, 2020 at 06:19:09PM -0700, Eric Dumazet wrote:
>>
>>
>> On 5/5/20 5:43 PM, Michael S. Tsirkin wrote:
>>> On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
>>>>
>>>>
>>>> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
>>>>> "Michael S. Tsirkin" <mst@redhat.com> writes:
>>>>>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>>>>>>>
>>>>>>> The following lockdep splat happens reproducibly on 5.7-rc4
>>>>>>
>>>>>>> ================================
>>>>>>> WARNING: inconsistent lock state
>>>>>>> 5.7.0-rc4+ #79 Not tainted
>>>>>>> --------------------------------
>>>>>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
>>>>>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
>>>>>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
>>>>>>> {SOFTIRQ-ON-W} state was registered at:
>>>>>>> lock_acquire+0x82/0x300
>>>>>>> try_fill_recv+0x39f/0x590
>>>>>>
>>>>>> Weird. Where does try_fill_recv acquire any locks?
>>>>>
>>>>> u64_stats_update_begin(&rq->stats.syncp);
>>>>>
>>>>> That's a 32bit kernel which uses a seqcount for this. sequence counts
>>>>> are "lock" constructs where you need to make sure that writers are
>>>>> serialized.
>>>>>
>>>>> Actually the problem at hand is that try_fill_recv() is called from
>>>>> fully preemptible context initialy and then from softirq context.
>>>>>
>>>>> Obviously that's for the open() path a non issue, but lockdep does not
>>>>> know about that. OTOH, there is other code which calls that from
>>>>> non-softirq context.
>>>>>
>>>>> The hack below made it shut up. It's obvioulsy not ideal, but at least
>>>>> it let me look at the actual problem I was chasing down :)
>>>>>
>>>>> Thanks,
>>>>>
>>>>> tglx
>>>>>
>>>>> 8<-----------
>>>>> --- a/drivers/net/virtio_net.c
>>>>> +++ b/drivers/net/virtio_net.c
>>>>> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
>>>>> break;
>>>>> } while (rq->vq->num_free);
>>>>> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
>>>>> + local_bh_disable();
>>>>
>>>> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
>>>
>>> I applied this, but am still trying to think of something that
>>> is 0 overhead for all configs.
>>> Maybe we can select a lockdep class depending on whether napi
>>> is enabled?
>>
>>
>> Do you _really_ need 64bit counter for stats.kicks on 32bit kernels ?
>>
>> Adding 64bit counters just because we can might be overhead anyway.
>
> Well 32 bit kernels don't fundamentally kick less than 64 bit ones,
> and we kick more or less per packet, sometimes per batch,
> people expect these to be in sync ..
Well, we left many counters in networking stack as 'unsigned long'
and nobody complained yet of overflows on 32bit kernels.
SNMP agents are used to the fact that counters do overflow.
Problems might happen if the overflows happen too fast, say every 10 seconds,
but other than that, forcing 64bit counters for something which is not
_required_ for the data path is adding pain.
I am mentioning this, because trying to add lockdep stuff and associated
maintenance cost for 32bit kernels in 2020 makes little sense to me,
considering I added include/linux/u64_stats_sync.h 10 years ago.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-06 2:24 ` Eric Dumazet
@ 2020-05-06 7:31 ` Michael S. Tsirkin
2020-05-06 8:15 ` Jason Wang
0 siblings, 1 reply; 12+ messages in thread
From: Michael S. Tsirkin @ 2020-05-06 7:31 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Thomas Gleixner, netdev, Jason Wang, Peter Zijlstra
On Tue, May 05, 2020 at 07:24:18PM -0700, Eric Dumazet wrote:
>
>
> On 5/5/20 6:25 PM, Michael S. Tsirkin wrote:
> > On Tue, May 05, 2020 at 06:19:09PM -0700, Eric Dumazet wrote:
> >>
> >>
> >> On 5/5/20 5:43 PM, Michael S. Tsirkin wrote:
> >>> On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
> >>>>
> >>>>
> >>>> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
> >>>>> "Michael S. Tsirkin" <mst@redhat.com> writes:
> >>>>>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
> >>>>>>>
> >>>>>>> The following lockdep splat happens reproducibly on 5.7-rc4
> >>>>>>
> >>>>>>> ================================
> >>>>>>> WARNING: inconsistent lock state
> >>>>>>> 5.7.0-rc4+ #79 Not tainted
> >>>>>>> --------------------------------
> >>>>>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> >>>>>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
> >>>>>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
> >>>>>>> {SOFTIRQ-ON-W} state was registered at:
> >>>>>>> lock_acquire+0x82/0x300
> >>>>>>> try_fill_recv+0x39f/0x590
> >>>>>>
> >>>>>> Weird. Where does try_fill_recv acquire any locks?
> >>>>>
> >>>>> u64_stats_update_begin(&rq->stats.syncp);
> >>>>>
> >>>>> That's a 32bit kernel which uses a seqcount for this. sequence counts
> >>>>> are "lock" constructs where you need to make sure that writers are
> >>>>> serialized.
> >>>>>
> >>>>> Actually the problem at hand is that try_fill_recv() is called from
> >>>>> fully preemptible context initialy and then from softirq context.
> >>>>>
> >>>>> Obviously that's for the open() path a non issue, but lockdep does not
> >>>>> know about that. OTOH, there is other code which calls that from
> >>>>> non-softirq context.
> >>>>>
> >>>>> The hack below made it shut up. It's obvioulsy not ideal, but at least
> >>>>> it let me look at the actual problem I was chasing down :)
> >>>>>
> >>>>> Thanks,
> >>>>>
> >>>>> tglx
> >>>>>
> >>>>> 8<-----------
> >>>>> --- a/drivers/net/virtio_net.c
> >>>>> +++ b/drivers/net/virtio_net.c
> >>>>> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
> >>>>> break;
> >>>>> } while (rq->vq->num_free);
> >>>>> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
> >>>>> + local_bh_disable();
> >>>>
> >>>> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
> >>>
> >>> I applied this, but am still trying to think of something that
> >>> is 0 overhead for all configs.
> >>> Maybe we can select a lockdep class depending on whether napi
> >>> is enabled?
> >>
> >>
> >> Do you _really_ need 64bit counter for stats.kicks on 32bit kernels ?
> >>
> >> Adding 64bit counters just because we can might be overhead anyway.
> >
> > Well 32 bit kernels don't fundamentally kick less than 64 bit ones,
> > and we kick more or less per packet, sometimes per batch,
> > people expect these to be in sync ..
>
> Well, we left many counters in networking stack as 'unsigned long'
> and nobody complained yet of overflows on 32bit kernels.
Right. For TX it is helpful that everything is maintained
atomically so we do need the seqlock machinery anyway:
u64_stats_update_begin(&sq->stats.syncp);
sq->stats.bytes += bytes;
sq->stats.packets += packets;
sq->stats.xdp_tx += n;
sq->stats.xdp_tx_drops += drops;
sq->stats.kicks += kicks;
u64_stats_update_end(&sq->stats.syncp);
for RX kicks are currently updated separately. Which I guess is more or
less a minor bug.
if (rq->vq->num_free > min((unsigned int)budget, virtqueue_get_vring_size(rq->vq)) / 2) {
if (!try_fill_recv(vi, rq, GFP_ATOMIC))
schedule_delayed_work(&vi->refill, 0);
}
u64_stats_update_begin(&rq->stats.syncp);
for (i = 0; i < VIRTNET_RQ_STATS_LEN; i++) {
size_t offset = virtnet_rq_stats_desc[i].offset;
u64 *item;
item = (u64 *)((u8 *)&rq->stats + offset);
*item += *(u64 *)((u8 *)&stats + offset);
}
u64_stats_update_end(&rq->stats.syncp);
we should update kicks in virtnet_receive.
And as long as we do that there's no cost to 64 bit counters ...
> SNMP agents are used to the fact that counters do overflow.
>
> Problems might happen if the overflows happen too fast, say every 10 seconds,
> but other than that, forcing 64bit counters for something which is not
> _required_ for the data path is adding pain.
>
> I am mentioning this, because trying to add lockdep stuff and associated
> maintenance cost for 32bit kernels in 2020 makes little sense to me,
> considering I added include/linux/u64_stats_sync.h 10 years ago.
>
Not sure what do you suggest here...
>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [BUG] Inconsistent lock state in virtnet poll
2020-05-06 7:31 ` Michael S. Tsirkin
@ 2020-05-06 8:15 ` Jason Wang
0 siblings, 0 replies; 12+ messages in thread
From: Jason Wang @ 2020-05-06 8:15 UTC (permalink / raw)
To: Michael S. Tsirkin, Eric Dumazet; +Cc: Thomas Gleixner, netdev, Peter Zijlstra
On 2020/5/6 下午3:31, Michael S. Tsirkin wrote:
> On Tue, May 05, 2020 at 07:24:18PM -0700, Eric Dumazet wrote:
>> On 5/5/20 6:25 PM, Michael S. Tsirkin wrote:
>>> On Tue, May 05, 2020 at 06:19:09PM -0700, Eric Dumazet wrote:
>>>> On 5/5/20 5:43 PM, Michael S. Tsirkin wrote:
>>>>> On Tue, May 05, 2020 at 03:40:09PM -0700, Eric Dumazet wrote:
>>>>>> On 5/5/20 3:30 PM, Thomas Gleixner wrote:
>>>>>>> "Michael S. Tsirkin"<mst@redhat.com> writes:
>>>>>>>> On Tue, May 05, 2020 at 02:08:56PM +0200, Thomas Gleixner wrote:
>>>>>>>>> The following lockdep splat happens reproducibly on 5.7-rc4
>>>>>>>>> ================================
>>>>>>>>> WARNING: inconsistent lock state
>>>>>>>>> 5.7.0-rc4+ #79 Not tainted
>>>>>>>>> --------------------------------
>>>>>>>>> inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
>>>>>>>>> ip/356 [HC0[0]:SC1[1]:HE1:SE0] takes:
>>>>>>>>> f3ee4cd8 (&syncp->seq#2){+.?.}-{0:0}, at: net_rx_action+0xfb/0x390
>>>>>>>>> {SOFTIRQ-ON-W} state was registered at:
>>>>>>>>> lock_acquire+0x82/0x300
>>>>>>>>> try_fill_recv+0x39f/0x590
>>>>>>>> Weird. Where does try_fill_recv acquire any locks?
>>>>>>> u64_stats_update_begin(&rq->stats.syncp);
>>>>>>>
>>>>>>> That's a 32bit kernel which uses a seqcount for this. sequence counts
>>>>>>> are "lock" constructs where you need to make sure that writers are
>>>>>>> serialized.
>>>>>>>
>>>>>>> Actually the problem at hand is that try_fill_recv() is called from
>>>>>>> fully preemptible context initialy and then from softirq context.
>>>>>>>
>>>>>>> Obviously that's for the open() path a non issue, but lockdep does not
>>>>>>> know about that. OTOH, there is other code which calls that from
>>>>>>> non-softirq context.
>>>>>>>
>>>>>>> The hack below made it shut up. It's obvioulsy not ideal, but at least
>>>>>>> it let me look at the actual problem I was chasing down:)
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> tglx
>>>>>>>
>>>>>>> 8<-----------
>>>>>>> --- a/drivers/net/virtio_net.c
>>>>>>> +++ b/drivers/net/virtio_net.c
>>>>>>> @@ -1243,9 +1243,11 @@ static bool try_fill_recv(struct virtnet
>>>>>>> break;
>>>>>>> } while (rq->vq->num_free);
>>>>>>> if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) {
>>>>>>> + local_bh_disable();
>>>>>> Or use u64_stats_update_begin_irqsave() whic is a NOP on 64bit kernels
>>>>> I applied this, but am still trying to think of something that
>>>>> is 0 overhead for all configs.
>>>>> Maybe we can select a lockdep class depending on whether napi
>>>>> is enabled?
>>>> Do you_really_ need 64bit counter for stats.kicks on 32bit kernels ?
>>>>
>>>> Adding 64bit counters just because we can might be overhead anyway.
>>> Well 32 bit kernels don't fundamentally kick less than 64 bit ones,
>>> and we kick more or less per packet, sometimes per batch,
>>> people expect these to be in sync ..
>> Well, we left many counters in networking stack as 'unsigned long'
>> and nobody complained yet of overflows on 32bit kernels.
> Right. For TX it is helpful that everything is maintained
> atomically so we do need the seqlock machinery anyway:
>
> u64_stats_update_begin(&sq->stats.syncp);
> sq->stats.bytes += bytes;
> sq->stats.packets += packets;
> sq->stats.xdp_tx += n;
> sq->stats.xdp_tx_drops += drops;
> sq->stats.kicks += kicks;
> u64_stats_update_end(&sq->stats.syncp);
>
> for RX kicks are currently updated separately. Which I guess is more or
> less a minor bug.
>
> if (rq->vq->num_free > min((unsigned int)budget, virtqueue_get_vring_size(rq->vq)) / 2) {
> if (!try_fill_recv(vi, rq, GFP_ATOMIC))
> schedule_delayed_work(&vi->refill, 0);
> }
>
> u64_stats_update_begin(&rq->stats.syncp);
> for (i = 0; i < VIRTNET_RQ_STATS_LEN; i++) {
> size_t offset = virtnet_rq_stats_desc[i].offset;
> u64 *item;
>
> item = (u64 *)((u8 *)&rq->stats + offset);
> *item += *(u64 *)((u8 *)&stats + offset);
> }
> u64_stats_update_end(&rq->stats.syncp);
>
> we should update kicks in virtnet_receive.
>
> And as long as we do that there's no cost to 64 bit counters ...
>
>
Or find way to use u32 to count kick in workqueue (which should be rare)
separately.
Thanks
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-05-06 8:15 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-05-05 12:08 [BUG] Inconsistent lock state in virtnet poll Thomas Gleixner
2020-05-05 16:10 ` Michael S. Tsirkin
2020-05-05 22:30 ` Thomas Gleixner
2020-05-05 22:40 ` Eric Dumazet
2020-05-05 23:49 ` Michael S. Tsirkin
2020-05-06 0:43 ` Michael S. Tsirkin
2020-05-06 1:19 ` Eric Dumazet
2020-05-06 1:25 ` Michael S. Tsirkin
2020-05-06 2:24 ` Eric Dumazet
2020-05-06 7:31 ` Michael S. Tsirkin
2020-05-06 8:15 ` Jason Wang
2020-05-05 23:54 ` Michael S. Tsirkin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).