All of lore.kernel.org
 help / color / mirror / Atom feed
* [Patch net] net_sched: replace yield() with cond_resched()
@ 2017-04-05  1:52 Cong Wang
  2017-04-05  3:55 ` Mike Galbraith
  0 siblings, 1 reply; 8+ messages in thread
From: Cong Wang @ 2017-04-05  1:52 UTC (permalink / raw)
  To: netdev; +Cc: efault, Cong Wang

yield() should be rendered dead, according to Mike.

It is hard to wait properly for all qdisc's to transmit
all packets. So just keep the original logic.

Reported-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 net/sched/sch_generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 1a2f9e9..4725d2f 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -925,7 +925,7 @@ void dev_deactivate_many(struct list_head *head)
 	/* Wait for outstanding qdisc_run calls. */
 	list_for_each_entry(dev, head, close_list)
 		while (some_qdisc_is_busy(dev))
-			yield();
+			cond_resched();
 }
 
 void dev_deactivate(struct net_device *dev)
-- 
2.5.5

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-05  1:52 [Patch net] net_sched: replace yield() with cond_resched() Cong Wang
@ 2017-04-05  3:55 ` Mike Galbraith
  2017-04-05  5:19   ` Cong Wang
  0 siblings, 1 reply; 8+ messages in thread
From: Mike Galbraith @ 2017-04-05  3:55 UTC (permalink / raw)
  To: Cong Wang, netdev

On Tue, 2017-04-04 at 18:52 -0700, Cong Wang wrote:

> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 1a2f9e9..4725d2f 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -925,7 +925,7 @@ void dev_deactivate_many(struct list_head *head)
>  	/* Wait for outstanding qdisc_run calls. */
>  	list_for_each_entry(dev, head, close_list)
>  		while (some_qdisc_is_busy(dev))
> -			yield();
> +			cond_resched();
>  }

That won't help, cond_resched() has the same impact upon a lone
SCHED_FIFO task as yield() does.. none.

	-Mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-05  3:55 ` Mike Galbraith
@ 2017-04-05  5:19   ` Cong Wang
  2017-04-05  5:56     ` Mike Galbraith
  0 siblings, 1 reply; 8+ messages in thread
From: Cong Wang @ 2017-04-05  5:19 UTC (permalink / raw)
  To: Mike Galbraith; +Cc: Linux Kernel Network Developers

On Tue, Apr 4, 2017 at 8:55 PM, Mike Galbraith <efault@gmx.de> wrote:
> On Tue, 2017-04-04 at 18:52 -0700, Cong Wang wrote:
>
>> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
>> index 1a2f9e9..4725d2f 100644
>> --- a/net/sched/sch_generic.c
>> +++ b/net/sched/sch_generic.c
>> @@ -925,7 +925,7 @@ void dev_deactivate_many(struct list_head *head)
>>       /* Wait for outstanding qdisc_run calls. */
>>       list_for_each_entry(dev, head, close_list)
>>               while (some_qdisc_is_busy(dev))
>> -                     yield();
>> +                     cond_resched();
>>  }
>
> That won't help, cond_resched() has the same impact upon a lone
> SCHED_FIFO task as yield() does.. none.

Hmm? In the comment you quote:

 * If you want to use yield() to wait for something, use wait_event().
 * If you want to use yield() to be 'nice' for others, use cond_resched().

So if cond_resched() doesn't help, why this misleading comment?

I picked the latter one, because the former is harder to implement
properly (at least for -net) we need qdisc's to notify this waiter once
they finish transmitting packets, which means we probably need
a per-netdevice wait struct.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-05  5:19   ` Cong Wang
@ 2017-04-05  5:56     ` Mike Galbraith
  2017-04-05 23:42       ` Cong Wang
  0 siblings, 1 reply; 8+ messages in thread
From: Mike Galbraith @ 2017-04-05  5:56 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers

On Tue, 2017-04-04 at 22:19 -0700, Cong Wang wrote:
> On Tue, Apr 4, 2017 at 8:55 PM, Mike Galbraith <efault@gmx.de> wrote:

> > That won't help, cond_resched() has the same impact upon a lone
> > SCHED_FIFO task as yield() does.. none.
> 
> Hmm? In the comment you quote:
> 
>  * If you want to use yield() to wait for something, use wait_event().
>  * If you want to use yield() to be 'nice' for others, use cond_resched().
> 
> So if cond_resched() doesn't help, why this misleading comment?

This is not an oh let's be nice guys thing, it's a perfect match of...

<copy/paste>
 * while (!event)
 *      yield();
(/copy/paste>

..get off the CPU until this happens thing.  With nobody to yield the C
PU to, some_qdisc_is_busy() will remain true forever more.

> I picked the latter one, because the former is harder to implement
> properly (at least for -net) we need qdisc's to notify this waiter once
> they finish transmitting packets, which means we probably need
> a per-netdevice wait struct.

Yup, why I merely notified net-fu masters of lurking spinner.  I met it
 because I sometimes run most kthreads at prio 1, some prioritized, and
kworkers at prio 2.  (never mind why, but they're excellent reasons)

	-Mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-05  5:56     ` Mike Galbraith
@ 2017-04-05 23:42       ` Cong Wang
  2017-04-06  1:54         ` Mike Galbraith
  0 siblings, 1 reply; 8+ messages in thread
From: Cong Wang @ 2017-04-05 23:42 UTC (permalink / raw)
  To: Mike Galbraith; +Cc: Linux Kernel Network Developers

On Tue, Apr 4, 2017 at 10:56 PM, Mike Galbraith <efault@gmx.de> wrote:
> On Tue, 2017-04-04 at 22:19 -0700, Cong Wang wrote:
>> On Tue, Apr 4, 2017 at 8:55 PM, Mike Galbraith <efault@gmx.de> wrote:
>
>> > That won't help, cond_resched() has the same impact upon a lone
>> > SCHED_FIFO task as yield() does.. none.
>>
>> Hmm? In the comment you quote:
>>
>>  * If you want to use yield() to wait for something, use wait_event().
>>  * If you want to use yield() to be 'nice' for others, use cond_resched().
>>
>> So if cond_resched() doesn't help, why this misleading comment?
>
> This is not an oh let's be nice guys thing, it's a perfect match of...
>
> <copy/paste>
>  * while (!event)
>  *      yield();
> (/copy/paste>
>
> ..get off the CPU until this happens thing.  With nobody to yield the C
> PU to, some_qdisc_is_busy() will remain true forever more.


This is exactly the misleading part, a while-loop waiting for an event
can always be a be-nice-for-others thing, because if not we can just
spin as a spinlock. You probably want to improve that comment to
explain when cond_resched() is a right solution to replace yield(),
so that I could know when it is not.

Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-05 23:42       ` Cong Wang
@ 2017-04-06  1:54         ` Mike Galbraith
  2017-04-06 22:13           ` Stephen Hemminger
  0 siblings, 1 reply; 8+ messages in thread
From: Mike Galbraith @ 2017-04-06  1:54 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers

On Wed, 2017-04-05 at 16:42 -0700, Cong Wang wrote:
> On Tue, Apr 4, 2017 at 10:56 PM, Mike Galbraith <efault@gmx.de> wrote:
> > On Tue, 2017-04-04 at 22:19 -0700, Cong Wang wrote:
> > > On Tue, Apr 4, 2017 at 8:55 PM, Mike Galbraith <efault@gmx.de> wrote:
> > 
> > > > That won't help, cond_resched() has the same impact upon a lone
> > > > SCHED_FIFO task as yield() does.. none.
> > > 
> > > Hmm? In the comment you quote:
> > > 
> > >  * If you want to use yield() to wait for something, use wait_event().
> > >  * If you want to use yield() to be 'nice' for others, use cond_resched().
> > > 
> > > So if cond_resched() doesn't help, why this misleading comment?
> > 
> > This is not an oh let's be nice guys thing, it's a perfect match of...
> > 
> > 
> >  * while (!event)
> >  *      yield();
> > (/copy/paste>
> > 
> > ..get off the CPU until this happens thing.  With nobody to yield the C
> > PU to, some_qdisc_is_busy() will remain true forever more.
> 
> 
> This is exactly the misleading part, a while-loop waiting for an event
> can always be a be-nice-for-others thing, because if not we can just
> spin as a spinlock.

Ah, but the kworker _is_ spinning on a 'lock' or sorts, starving the
'owner', ergo this polling loop fails the 'may be nice' litmus test. 
 No polling loop is safe without a guarantee that the polling thread
cannot block the loop breaking event.

	-Mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-06  1:54         ` Mike Galbraith
@ 2017-04-06 22:13           ` Stephen Hemminger
  2017-04-07  3:59             ` Mike Galbraith
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2017-04-06 22:13 UTC (permalink / raw)
  To: Mike Galbraith; +Cc: Cong Wang, Linux Kernel Network Developers

On Thu, 06 Apr 2017 03:54:19 +0200
Mike Galbraith <efault@gmx.de> wrote:

> On Wed, 2017-04-05 at 16:42 -0700, Cong Wang wrote:
> > On Tue, Apr 4, 2017 at 10:56 PM, Mike Galbraith <efault@gmx.de> wrote:  
> > > On Tue, 2017-04-04 at 22:19 -0700, Cong Wang wrote:  
> > > > On Tue, Apr 4, 2017 at 8:55 PM, Mike Galbraith <efault@gmx.de> wrote:  
> > >   
> > > > > That won't help, cond_resched() has the same impact upon a lone
> > > > > SCHED_FIFO task as yield() does.. none.  
> > > > 
> > > > Hmm? In the comment you quote:
> > > > 
> > > >  * If you want to use yield() to wait for something, use wait_event().
> > > >  * If you want to use yield() to be 'nice' for others, use cond_resched().
> > > > 
> > > > So if cond_resched() doesn't help, why this misleading comment?  
> > > 
> > > This is not an oh let's be nice guys thing, it's a perfect match of...
> > > 
> > > 
> > >  * while (!event)
> > >  *      yield();  
> > > (/copy/paste>  
> > > 
> > > ..get off the CPU until this happens thing.  With nobody to yield the C
> > > PU to, some_qdisc_is_busy() will remain true forever more.  
> > 
> > 
> > This is exactly the misleading part, a while-loop waiting for an event
> > can always be a be-nice-for-others thing, because if not we can just
> > spin as a spinlock.  
> 
> Ah, but the kworker _is_ spinning on a 'lock' or sorts, starving the
> 'owner', ergo this polling loop fails the 'may be nice' litmus test. 
>  No polling loop is safe without a guarantee that the polling thread
> cannot block the loop breaking event.
> 
> 	-Mike

Why not replace yield with msleep(1) which gets rid of the inversion
issues?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Patch net] net_sched: replace yield() with cond_resched()
  2017-04-06 22:13           ` Stephen Hemminger
@ 2017-04-07  3:59             ` Mike Galbraith
  0 siblings, 0 replies; 8+ messages in thread
From: Mike Galbraith @ 2017-04-07  3:59 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Cong Wang, Linux Kernel Network Developers

On Thu, 2017-04-06 at 18:13 -0400, Stephen Hemminger wrote:

> Why not replace yield with msleep(1) which gets rid of the inversion
> issues?

That's fine, just not super efficient, if that matters.

	-Mike

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-04-07  3:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-05  1:52 [Patch net] net_sched: replace yield() with cond_resched() Cong Wang
2017-04-05  3:55 ` Mike Galbraith
2017-04-05  5:19   ` Cong Wang
2017-04-05  5:56     ` Mike Galbraith
2017-04-05 23:42       ` Cong Wang
2017-04-06  1:54         ` Mike Galbraith
2017-04-06 22:13           ` Stephen Hemminger
2017-04-07  3:59             ` Mike Galbraith

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.