Messages in this thread Patch in this message | | | Date | Mon, 11 May 2015 16:22:47 +0200 | From | Peter Zijlstra <> | Subject | Re: [PATCH] sched: Introduce TASK_NOLOAD and TASK_IDLE |
| |
On Sat, May 09, 2015 at 11:49:01AM +0300, Julian Anastasov wrote:
> After checking our code in net/netfilter/ipvs/ip_vs_sync.c, > sync_thread_master(), we may also need some wrappers: > > - schedule_timeout_idle (instead of schedule_timeout call): > __set_current_state(TASK_IDLE); > return schedule_timeout(timeout); > > - we here are really idle, so "N" looks ok
So I don't get the point of the schedule_timeout_*() stubs. What are they for? Why would one use an unconditional schedule_timeout() call? Isn't that what msleep() is for?
> - pair of __wait_event_idle(wq, condition) and > wait_event_idle(wq, condition) macros > > - we here are write-blocked for socket, not sure > if this blocked vs idle difference is useful to > represent, in new bit for this blocked state "B"=2048, > with 2 TASK_NOLOAD variants: N(idle) and B(blocked, > 2|1024|2048, eg. for read-blocked or write-blocked). > It will need additional argument 'state'/'blocked' for > *wait_event_idle().
Completely untested.
--- include/linux/wait.h | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/include/linux/wait.h b/include/linux/wait.h index 2db83349865b..b9ef6bacf633 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -307,6 +307,26 @@ do { \ __ret; \ }) +#define __wait_event_idle(wq, condition) \ + (void)___wait_event(wq, condition, TASK_IDLE, 0, 0, \ + schedule()) + + +/** + * wait_event_idle - sleep until a condition get true; do not contribute to the loadavg + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * See wait_event() + */ +#define wait_event_idle(wq, condition) \ +do { \ + might_sleep(); \ + if (condition) \ + break; \ + __wait_event_idle(wq, condition); \ +} while (0) + #define __wait_event_timeout(wq, condition, timeout) \ ___wait_event(wq, ___wait_cond_timeout(condition), \ TASK_UNINTERRUPTIBLE, 0, timeout, \ @@ -346,8 +366,8 @@ do { \ __ret = schedule_timeout(__ret); try_to_freeze()) /* - * like wait_event_timeout() -- except it uses TASK_INTERRUPTIBLE to avoid - * increasing load and is freezable. + * like wait_event_timeout() -- except it uses TASK_INTERRUPTIBLE + * and is freezable. */ #define wait_event_freezable_timeout(wq, condition, timeout) \ ({ \ @@ -358,6 +378,23 @@ do { \ __ret; \ }) +#define __wait_event_idle_timeout(wq, condition, timeout) \ + ___wait_event(wq, ___wait_cond_timeout(condition), \ + TASK_IDLE, 0, timeout, \ + __ret = schedule_timeout(__ret)) + +/* + * like wait_event_timeout() -- except it uses TASK_IDLE to avoid loadavg + */ +#define wait_event_idle_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + might_sleep(); \ + if (!___wait_cond_timeout(condition)) \ + ret = __wait_event_idle_timeout(wq, condition, timeout);\ + __ret; \ +}) + #define __wait_event_cmd(wq, condition, cmd1, cmd2) \ (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0, \ cmd1; schedule(); cmd2)
| |