From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754151AbbEKOXM (ORCPT ); Mon, 11 May 2015 10:23:12 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:50196 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751614AbbEKOXJ (ORCPT ); Mon, 11 May 2015 10:23:09 -0400 Date: Mon, 11 May 2015 16:22:47 +0200 From: Peter Zijlstra To: Julian Anastasov Cc: Ingo Molnar , Linus Torvalds , Oleg Nesterov , linux-kernel@vger.kernel.org, neilb@suse.de Subject: Re: [PATCH] sched: Introduce TASK_NOLOAD and TASK_IDLE Message-ID: <20150511142247.GT27504@twins.programming.kicks-ass.net> References: <20150508124748.GH27504@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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)