* schedule()
@ 2002-02-26 19:57 Richard B. Johnson
2002-02-26 20:05 ` schedule() Jeff Garzik
2002-02-26 20:13 ` schedule() Davide Libenzi
0 siblings, 2 replies; 12+ messages in thread
From: Richard B. Johnson @ 2002-02-26 19:57 UTC (permalink / raw)
To: Linux kernel
I just read on this list that:
while(something)
{
current->policy |= SCHED_YIELD;
schedule();
}
Will no longer be allowed in a kernel module! If this is true, how
do I loop, waiting for a bit in a port, without wasting CPU time?
A lot of hardware does not generate interrupts upon a condition,
there is no CPU activity that could send a wake_up_interruptible()
to something sleeping.
For instance, I need to write data to a hardware FIFO, one long-word
at a time, but I can't just write. I have to wait for a bit to be
set or reset for each and every write. I'm going to be burning a
lot of CPU cycles if I can't schedule() while the trickle-down-effect
of the hardware is happening.
Cheers,
Dick Johnson
Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips).
111,111,111 * 111,111,111 = 12,345,678,987,654,321
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: schedule() 2002-02-26 19:57 schedule() Richard B. Johnson @ 2002-02-26 20:05 ` Jeff Garzik 2002-02-26 20:14 ` schedule() Richard B. Johnson 2002-02-27 0:56 ` schedule() Nigel Gamble 2002-02-26 20:13 ` schedule() Davide Libenzi 1 sibling, 2 replies; 12+ messages in thread From: Jeff Garzik @ 2002-02-26 20:05 UTC (permalink / raw) To: root; +Cc: Linux kernel "Richard B. Johnson" wrote: > > I just read on this list that: > > while(something) > { > current->policy |= SCHED_YIELD; > schedule(); > } > > Will no longer be allowed in a kernel module! If this is true, how > do I loop, waiting for a bit in a port, without wasting CPU time? Call yield() or better yet, schedule_timeout() In 2.4, define the above to be yield() in some compatibility module... -- Jeff Garzik | "UNIX enhancements aren't." Building 1024 | -- says /usr/games/fortune MandrakeSoft | ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:05 ` schedule() Jeff Garzik @ 2002-02-26 20:14 ` Richard B. Johnson 2002-02-27 0:56 ` schedule() Nigel Gamble 1 sibling, 0 replies; 12+ messages in thread From: Richard B. Johnson @ 2002-02-26 20:14 UTC (permalink / raw) To: Jeff Garzik; +Cc: Linux kernel On Tue, 26 Feb 2002, Jeff Garzik wrote: > "Richard B. Johnson" wrote: > > > > I just read on this list that: > > > > while(something) > > { > > current->policy |= SCHED_YIELD; > > schedule(); > > } > > > > Will no longer be allowed in a kernel module! If this is true, how > > do I loop, waiting for a bit in a port, without wasting CPU time? > > Call yield() or better yet, schedule_timeout() > > In 2.4, define the above to be yield() in some compatibility module... Okay, thanks. I'll change my code to YIELD and define a macro for both versions. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips). 111,111,111 * 111,111,111 = 12,345,678,987,654,321 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:05 ` schedule() Jeff Garzik 2002-02-26 20:14 ` schedule() Richard B. Johnson @ 2002-02-27 0:56 ` Nigel Gamble 2002-02-27 15:29 ` schedule() Richard B. Johnson 1 sibling, 1 reply; 12+ messages in thread From: Nigel Gamble @ 2002-02-27 0:56 UTC (permalink / raw) To: Jeff Garzik; +Cc: root, Linux kernel On Tue, 26 Feb 2002, Jeff Garzik wrote: > "Richard B. Johnson" wrote: > > > > I just read on this list that: > > > > while(something) > > { > > current->policy |= SCHED_YIELD; > > schedule(); > > } > > > > Will no longer be allowed in a kernel module! If this is true, how > > do I loop, waiting for a bit in a port, without wasting CPU time? > > Call yield() or better yet, schedule_timeout() Yes, please use schedule_timeout() if at all possible, or make sure that the loop will only ever execute for a few 100us at most. One thing to bear in mind is that using yield() will waste CPU time if the code is ever called by a real-time process (unless it is a SCHED_RR process with other runnable SCHED_RR processes at the same priority), because there will be no other process that the scheduler is allowed to run, so the RT process will just be chosen to run again, with no delay. We really need high resolution timers, so that schedule_timeout() can be used for delays of less than one jiffy. Nigel Gamble nigel@nrg.org Mountain View, CA, USA. http://www.nrg.org/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-27 0:56 ` schedule() Nigel Gamble @ 2002-02-27 15:29 ` Richard B. Johnson 0 siblings, 0 replies; 12+ messages in thread From: Richard B. Johnson @ 2002-02-27 15:29 UTC (permalink / raw) To: Nigel Gamble; +Cc: Jeff Garzik, Linux kernel On Tue, 26 Feb 2002, Nigel Gamble wrote: [SNIPPED] > On Tue, 26 Feb 2002, Jeff Garzik wrote: > > "Richard B. Johnson" wrote: [SNIPPED] > > > > Call yield() or better yet, schedule_timeout() > > Yes, please use schedule_timeout() if at all possible, or make sure that > the loop will only ever execute for a few 100us at most. > This can't be guaranteed. Many machine-to-machine communications links need to continually retry (forever) without hurting the operation of anything else. Yes, there are a few wasted CPU cycles, but everything needs to run until the "plug that got kicked out" is discovered and plugged back in (days, perhaps). Its almost like; "There is no such thing as a fatal hardware error...". Software needs to report that things are not right and also needs to report when things got fixed. A bad chip is merely an exception that needs to be worked around in software. So, I don't have anything that loops forever when something is broken. However, it will retry forever until it's fixed. > One thing to bear in mind is that using yield() will waste CPU time if > the code is ever called by a real-time process (unless it is a SCHED_RR > process with other runnable SCHED_RR processes at the same priority), > because there will be no other process that the scheduler is allowed to > run, so the RT process will just be chosen to run again, with no delay. > Yeah. I looked at the code and it doesn't schedule directly in 2.4.1. It just says "reschedule later on after I'm preempted". I don't think my code wants to spin to the next HZ before it gives up the CPU. It already knows that the hardware is not ready and has volunteered to give up the CPU now. After the next HZ, the hardware would be ready. The driver(s) count on the fact that most everybody sleeps (is I/O bound) most of the while so it will probably be getting the CPU back in less than a HZ most of the time. > We really need high resolution timers, so that schedule_timeout() can be > used for delays of less than one jiffy. > Maybe, but we really need a sleep_on_proc(procedure, timeout) where procedure is a pointer to a procedure that returns 0 for okay, and takes a pointer-to-void (so the caller can pass whatever parameters it needs). /* * Returns 0 if the procedure returned 0. * Returns -1 if it timed out. */ int sleep_on_proc(int(*procedure)(void *), size_t timeout); The kernel can decide how to handle the scheduling and the drivers are not affected by such changes. Driver code would do something like: int my_spinner(void *inf) { FOO *foo = (FOO *) inf; /* Get my parameters */ if(readl(foo->status) & READY) return 0; return -1; } To use this, the kernel sleeper would be called as: if(sleep_on_proc(my_spinner(inf), TIMEOUT)) fail_thing(); else good_thing(); Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips). 111,111,111 * 111,111,111 = 12,345,678,987,654,321 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 19:57 schedule() Richard B. Johnson 2002-02-26 20:05 ` schedule() Jeff Garzik @ 2002-02-26 20:13 ` Davide Libenzi 2002-02-26 20:17 ` schedule() Richard B. Johnson 1 sibling, 1 reply; 12+ messages in thread From: Davide Libenzi @ 2002-02-26 20:13 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Linux kernel On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > I just read on this list that: > > while(something) > { > current->policy |= SCHED_YIELD; > schedule(); > } > > Will no longer be allowed in a kernel module! If this is true, how > do I loop, waiting for a bit in a port, without wasting CPU time? > > A lot of hardware does not generate interrupts upon a condition, > there is no CPU activity that could send a wake_up_interruptible() > to something sleeping. > > For instance, I need to write data to a hardware FIFO, one long-word > at a time, but I can't just write. I have to wait for a bit to be > set or reset for each and every write. I'm going to be burning a > lot of CPU cycles if I can't schedule() while the trickle-down-effect > of the hardware is happening. What did it do yield() to you ? Doesn't it work for your case ? - Davide ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:13 ` schedule() Davide Libenzi @ 2002-02-26 20:17 ` Richard B. Johnson 2002-02-26 20:19 ` schedule() Davide Libenzi 0 siblings, 1 reply; 12+ messages in thread From: Richard B. Johnson @ 2002-02-26 20:17 UTC (permalink / raw) To: Davide Libenzi; +Cc: Linux kernel On Tue, 26 Feb 2002, Davide Libenzi wrote: > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > > > > > I just read on this list that: > > > > while(something) > > { > > current->policy |= SCHED_YIELD; > > schedule(); > > } > > > > Will no longer be allowed in a kernel module! If this is true, how > > do I loop, waiting for a bit in a port, without wasting CPU time? > > > > A lot of hardware does not generate interrupts upon a condition, > > there is no CPU activity that could send a wake_up_interruptible() > > to something sleeping. > > > > For instance, I need to write data to a hardware FIFO, one long-word > > at a time, but I can't just write. I have to wait for a bit to be > > set or reset for each and every write. I'm going to be burning a > > lot of CPU cycles if I can't schedule() while the trickle-down-effect > > of the hardware is happening. > > What did it do yield() to you ? Doesn't it work for your case ? > There isn't one in 2.4.x I'll modify my drivers to use YIELD and #define it depending upon version. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips). 111,111,111 * 111,111,111 = 12,345,678,987,654,321 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:17 ` schedule() Richard B. Johnson @ 2002-02-26 20:19 ` Davide Libenzi 2002-02-26 20:47 ` schedule() Richard B. Johnson 2002-02-26 21:14 ` schedule() Richard B. Johnson 0 siblings, 2 replies; 12+ messages in thread From: Davide Libenzi @ 2002-02-26 20:19 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Linux kernel On Tue, 26 Feb 2002, Richard B. Johnson wrote: > On Tue, 26 Feb 2002, Davide Libenzi wrote: > > > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > > > > > > > > > I just read on this list that: > > > > > > while(something) > > > { > > > current->policy |= SCHED_YIELD; > > > schedule(); > > > } > > > > > > Will no longer be allowed in a kernel module! If this is true, how > > > do I loop, waiting for a bit in a port, without wasting CPU time? > > > > > > A lot of hardware does not generate interrupts upon a condition, > > > there is no CPU activity that could send a wake_up_interruptible() > > > to something sleeping. > > > > > > For instance, I need to write data to a hardware FIFO, one long-word > > > at a time, but I can't just write. I have to wait for a bit to be > > > set or reset for each and every write. I'm going to be burning a > > > lot of CPU cycles if I can't schedule() while the trickle-down-effect > > > of the hardware is happening. > > > > What did it do yield() to you ? Doesn't it work for your case ? > > > There isn't one in 2.4.x I'll modify my drivers to use YIELD > and #define it depending upon version. In 2.5 yield() maps to sys_sched_yield(). You can handle it in the same way in your includes if version <= 2.4. - Davide ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:19 ` schedule() Davide Libenzi @ 2002-02-26 20:47 ` Richard B. Johnson 2002-02-26 20:50 ` schedule() Davide Libenzi 2002-02-26 21:14 ` schedule() Richard B. Johnson 1 sibling, 1 reply; 12+ messages in thread From: Richard B. Johnson @ 2002-02-26 20:47 UTC (permalink / raw) To: Davide Libenzi; +Cc: Linux kernel On Tue, 26 Feb 2002, Davide Libenzi wrote: > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > On Tue, 26 Feb 2002, Davide Libenzi wrote: > > > > > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > > > > > > > > > > > > > I just read on this list that: > > > > > > > > while(something) > > > > { > > > > current->policy |= SCHED_YIELD; > > > > schedule(); > > > > } > > > > > > > > Will no longer be allowed in a kernel module! If this is true, how > > > > do I loop, waiting for a bit in a port, without wasting CPU time? > > > > > > > > A lot of hardware does not generate interrupts upon a condition, > > > > there is no CPU activity that could send a wake_up_interruptible() > > > > to something sleeping. > > > > > > > > For instance, I need to write data to a hardware FIFO, one long-word > > > > at a time, but I can't just write. I have to wait for a bit to be > > > > set or reset for each and every write. I'm going to be burning a > > > > lot of CPU cycles if I can't schedule() while the trickle-down-effect > > > > of the hardware is happening. > > > > > > What did it do yield() to you ? Doesn't it work for your case ? > > > > > There isn't one in 2.4.x I'll modify my drivers to use YIELD > > and #define it depending upon version. > > In 2.5 yield() maps to sys_sched_yield(). You can handle it in the same > way in your includes if version <= 2.4. > > Can't find it in any header file. Script started on Tue Feb 26 15:45:06 2002 # grep "sys_sched_yield()" /usr/src/linux/include/linux/*.h # grep "sys_sched_yield()" /usr/src/linux/include/asm/*.h You have new mail in /var/spool/mail/root # exit exit Script done on Tue Feb 26 15:46:46 2002 I'll #define a macro and be done with it. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips). 111,111,111 * 111,111,111 = 12,345,678,987,654,321 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:47 ` schedule() Richard B. Johnson @ 2002-02-26 20:50 ` Davide Libenzi 0 siblings, 0 replies; 12+ messages in thread From: Davide Libenzi @ 2002-02-26 20:50 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Linux kernel On Tue, 26 Feb 2002, Richard B. Johnson wrote: > On Tue, 26 Feb 2002, Davide Libenzi wrote: > > > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > > > On Tue, 26 Feb 2002, Davide Libenzi wrote: > > > > > > > On Tue, 26 Feb 2002, Richard B. Johnson wrote: > > > > > > > > > > > > > > > > > > > I just read on this list that: > > > > > > > > > > while(something) > > > > > { > > > > > current->policy |= SCHED_YIELD; > > > > > schedule(); > > > > > } > > > > > > > > > > Will no longer be allowed in a kernel module! If this is true, how > > > > > do I loop, waiting for a bit in a port, without wasting CPU time? > > > > > > > > > > A lot of hardware does not generate interrupts upon a condition, > > > > > there is no CPU activity that could send a wake_up_interruptible() > > > > > to something sleeping. > > > > > > > > > > For instance, I need to write data to a hardware FIFO, one long-word > > > > > at a time, but I can't just write. I have to wait for a bit to be > > > > > set or reset for each and every write. I'm going to be burning a > > > > > lot of CPU cycles if I can't schedule() while the trickle-down-effect > > > > > of the hardware is happening. > > > > > > > > What did it do yield() to you ? Doesn't it work for your case ? > > > > > > > There isn't one in 2.4.x I'll modify my drivers to use YIELD > > > and #define it depending upon version. > > > > In 2.5 yield() maps to sys_sched_yield(). You can handle it in the same > > way in your includes if version <= 2.4. > > > > > > Can't find it in any header file. > > Script started on Tue Feb 26 15:45:06 2002 > # grep "sys_sched_yield()" /usr/src/linux/include/linux/*.h > # grep "sys_sched_yield()" /usr/src/linux/include/asm/*.h > You have new mail in /var/spool/mail/root > # exit > exit > > Script done on Tue Feb 26 15:46:46 2002 > > I'll #define a macro and be done with it. It'd be too easy if it'd be inside an header file :-) asmlinkage long sys_sched_yield(void); in kernel/sched.c - Davide ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 20:19 ` schedule() Davide Libenzi 2002-02-26 20:47 ` schedule() Richard B. Johnson @ 2002-02-26 21:14 ` Richard B. Johnson 2002-02-26 22:37 ` schedule() Davide Libenzi 1 sibling, 1 reply; 12+ messages in thread From: Richard B. Johnson @ 2002-02-26 21:14 UTC (permalink / raw) To: Davide Libenzi; +Cc: Linux kernel On Tue, 26 Feb 2002, Davide Libenzi wrote: > > In 2.5 yield() maps to sys_sched_yield(). You can handle it in the same > way in your includes if version <= 2.4. It's not exported as well as not defined in a header! It results in an undefined symbol in the module. Cheers, Dick Johnson Penguin : Linux version 2.4.1 on an i686 machine (797.90 BogoMips). 111,111,111 * 111,111,111 = 12,345,678,987,654,321 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: schedule() 2002-02-26 21:14 ` schedule() Richard B. Johnson @ 2002-02-26 22:37 ` Davide Libenzi 0 siblings, 0 replies; 12+ messages in thread From: Davide Libenzi @ 2002-02-26 22:37 UTC (permalink / raw) To: Richard B. Johnson; +Cc: Linux kernel On Tue, 26 Feb 2002, Richard B. Johnson wrote: > On Tue, 26 Feb 2002, Davide Libenzi wrote: > > > > In 2.5 yield() maps to sys_sched_yield(). You can handle it in the same > > way in your includes if version <= 2.4. > > It's not exported as well as not defined in a header! It results in > an undefined symbol in the module. You can try to ask Marcelo to add a line in include/linux/sched.h and one in kernel/ksym.c In this way a compatibility interface can be achieved for code that needs it. - Davide ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2002-02-27 15:27 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-02-26 19:57 schedule() Richard B. Johnson 2002-02-26 20:05 ` schedule() Jeff Garzik 2002-02-26 20:14 ` schedule() Richard B. Johnson 2002-02-27 0:56 ` schedule() Nigel Gamble 2002-02-27 15:29 ` schedule() Richard B. Johnson 2002-02-26 20:13 ` schedule() Davide Libenzi 2002-02-26 20:17 ` schedule() Richard B. Johnson 2002-02-26 20:19 ` schedule() Davide Libenzi 2002-02-26 20:47 ` schedule() Richard B. Johnson 2002-02-26 20:50 ` schedule() Davide Libenzi 2002-02-26 21:14 ` schedule() Richard B. Johnson 2002-02-26 22:37 ` schedule() Davide Libenzi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®