From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 82B9553E15 for ; Wed, 11 Sep 2024 05:13:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031634; cv=none; b=uiP+lnyghcZoxcONFmu1xkAG7B4GMeFErq87ZPHkOjn8xMDaT59szwJoCx4zkFMPkOp8TKw8jZBXHY12Ze5VhIvXIanMWGM2Ho6JIpjkh8fOdnPy+mwInGZSneehpRA2GYDu3bKNyV8vgC25NL+am1kS4snuYqgqyK326abAD1Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031634; c=relaxed/simple; bh=5e6eNv5ryoge/gb2rmpIFFM9vycX3OtF//kUGJokz3w=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OArFYWUd79Nu6JoHdRbxxrsNXyYx9quiyzG0fpjyF/spzQ2gi7XePZAuNBgqi+BVVf1QIsC6fI7oalckU8VYPocQgi+XXoLs4lW4bmjd7Obib1e+8yTffKZUk6e24881aaSvo3qea83GJSmc6BrZ7OP2Z8QayvQQaEhPQesay+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=oW/2gyk0; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=yHBtkjZ4; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="oW/2gyk0"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="yHBtkjZ4" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=d+OokvN1l+gdCyN4uvEIpHtTR19aqjU/bCRqWUh13ys=; b=oW/2gyk0upSbrkLBKtincnlEmbY6aMgx3x9eKMA2rMDkXI+9ucB4PgIt7nvrCmkd319J9l eTTQ1aC02zViwnrryRa6jjYm+hgz3CZpFOqBb3wtftJAN2WddG45XS1mUUZdpJN7hXP5M8 602h4AlTQ3vUPGaInInaTFRs6s5gLsVaPEIJi1iaOtUoTTeY6yntTdumY4w+0QMGl6BG3l 6Rj8EV5a8kFks7b3rNuvuKNh/lQr8FjsqrXNC4QN5kWGxgO/hwFYJ2mp4FjqfyAn9gxoWR s+Wbjs0qsWWsL1s2ftEDySdB2pt8zO5Ee54FuhJ3aLymJMeaoeVPraxP6p7RMw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031630; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=d+OokvN1l+gdCyN4uvEIpHtTR19aqjU/bCRqWUh13ys=; b=yHBtkjZ4Jm45gLyVODQU3NBASvE8x/2u7j0vLScripvkiZgIPC7gJJvLApbyaIRDxHfkcm r7zjcZWoKJ9rRSAQ== Date: Wed, 11 Sep 2024 07:13:27 +0200 Subject: [PATCH v2 01/15] MAINTAINERS: Add missing file include/linux/delay.h Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-1-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen include/linux/delay.h is not covered by MAINTAINERS file. Add it to the "HIGH-RESOLUTION TIMERS, TIMER WHEEL, CLOCKEVENTS" section. Signed-off-by: Anna-Maria Behnsen Acked-by: Frederic Weisbecker --- v2: New (splitted as requested by Frederic) --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 42decde38320..d9135d8ece99 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10010,6 +10010,7 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/co= re F: Documentation/timers/ F: include/linux/clockchips.h +F: include/linux/delay.h F: include/linux/hrtimer.h F: include/linux/timer.h F: kernel/time/clockevents.c --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E3D057CB6 for ; Wed, 11 Sep 2024 05:13:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031635; cv=none; b=JKjKA7+8urNUq8mnnbmTsLY5dIZ2aB0lLLlqU8ujxQDyJ0vLsZtm0Dsoiw1DIDrIEOvBnCTj9SlwuhXKIKUJ2E664zz12XZYB474HTyC2y4QEjf4NT5woL3IpGGBy3Bv+nHGOmzE9Chcwjm+DGFpDZtp/LhVlICwvmdIahMAXM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031635; c=relaxed/simple; bh=/eflTGd/OUjOTfPVMHJckgqS9lf8hEVy5FkeKQMmkv0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iMoqUt96IYaXwVHxjFYEWk5ZW66euV4wIYRyzKAKMXyVPJD4jmnw0hf/wIrMKsc8go/jN3Ctf4+G0pIs9Tfc9khtgFf9bF3kszIfCzM4KiTLeO6uK5nEt525uDVygKJ+3po3qhMRiSbeHLbjmVIBDVm/EjE6JPBj5d+rZW8gJaE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0aX8/atp; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+xIgNA9R; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0aX8/atp"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+xIgNA9R" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wqdatRXIH6wU/EgroMCFw17H2l6WXjO6QdKMschES0Y=; b=0aX8/atpekNlfwb/SW0yFXaHQ5PNT+7cVj8kL2Bd2oe3edLOqjVWvxXb9lasEAbDcRGkKr u1qLnssIyf301fLZxVPNy/rqXzKQTkgoDOUGNRfwU1C7iwSm56b/m+j/RIp8DRKhuNRJFR UOajdbMeGY0l9tFgeKq3koOjeoaqieAcTyEy6RvloocR/Ri/VPFOUo+Up8EsH6uNDfbAZb vUYWTjPOy/pCwpr0QmcqVELEP1BtVkWbGmHLbtqwocb9FdIBcQCuZEEM2C8d41RrMCPKBB PEiaF9e3vuMq6mAv2WgK+DTOY1arXirZHJr1yMhHngvWP0T2+3kIFr+pX5dEWA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wqdatRXIH6wU/EgroMCFw17H2l6WXjO6QdKMschES0Y=; b=+xIgNA9R0Fjxw8LdC4OYAbwzP5caRBFf2JR3UxfyqCj/fGEsUvfPZikjC8AWlGMrtUVadW RbTayzF+PTbkAuAg== Date: Wed, 11 Sep 2024 07:13:28 +0200 Subject: [PATCH v2 02/15] timers: Move *sleep*() and timeout functions into a separate file Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-2-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen All schedule_timeout() and *sleep*() related functions are interfaces on top of timer list timers and hrtimers to add a sleep to the code. As they are built on top of the timer list timers and hrtimers, the [hr]timer interfaces are already used except when queuing the timer in schedule_timeout(). But there exists the appropriate interface add_timer() which does the same job with an extra check for an already pending timer. Split all those functions as they are into a separate file and use add_timer() instead of __mod_timer() in schedule_timeout(). While at it fix minor formatting issues and a multi line printk function call in schedule_timeout(). Signed-off-by: Anna-Maria Behnsen Acked-by: Frederic Weisbecker --- v2: - Drop adding delay.h to MAINTAINERS file - Some more minor formatting fixups --- MAINTAINERS | 1 + kernel/time/Makefile | 2 +- kernel/time/hrtimer.c | 120 ----------------- kernel/time/sleep_timeout.c | 317 ++++++++++++++++++++++++++++++++++++++++= ++++ kernel/time/timer.c | 192 --------------------------- 5 files changed, 319 insertions(+), 313 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index d9135d8ece99..e9cb09990e2a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10015,6 +10015,7 @@ F: include/linux/hrtimer.h F: include/linux/timer.h F: kernel/time/clockevents.c F: kernel/time/hrtimer.c +F: kernel/time/sleep_timeout.c F: kernel/time/timer.c F: kernel/time/timer_list.c F: kernel/time/timer_migration.* diff --git a/kernel/time/Makefile b/kernel/time/Makefile index 4af2a264a160..fe0ae82124fe 100644 --- a/kernel/time/Makefile +++ b/kernel/time/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y +=3D time.o timer.o hrtimer.o +obj-y +=3D time.o timer.o hrtimer.o sleep_timeout.o obj-y +=3D timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o obj-y +=3D timeconv.o timecounter.o alarmtimer.o =20 diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index e834b2bd83df..2750ce6cb2e4 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -2242,123 +2242,3 @@ void __init hrtimers_init(void) hrtimers_prepare_cpu(smp_processor_id()); open_softirq(HRTIMER_SOFTIRQ, hrtimer_run_softirq); } - -/** - * schedule_hrtimeout_range_clock - sleep until timeout - * @expires: timeout value (ktime_t) - * @delta: slack in expires timeout (ktime_t) - * @mode: timer mode - * @clock_id: timer clock to be used - */ -int __sched -schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, - const enum hrtimer_mode mode, clockid_t clock_id) -{ - struct hrtimer_sleeper t; - - /* - * Optimize when a zero timeout value is given. It does not - * matter whether this is an absolute or a relative time. - */ - if (expires && *expires =3D=3D 0) { - __set_current_state(TASK_RUNNING); - return 0; - } - - /* - * A NULL parameter means "infinite" - */ - if (!expires) { - schedule(); - return -EINTR; - } - - hrtimer_init_sleeper_on_stack(&t, clock_id, mode); - hrtimer_set_expires_range_ns(&t.timer, *expires, delta); - hrtimer_sleeper_start_expires(&t, mode); - - if (likely(t.task)) - schedule(); - - hrtimer_cancel(&t.timer); - destroy_hrtimer_on_stack(&t.timer); - - __set_current_state(TASK_RUNNING); - - return !t.task ? 0 : -EINTR; -} -EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock); - -/** - * schedule_hrtimeout_range - sleep until timeout - * @expires: timeout value (ktime_t) - * @delta: slack in expires timeout (ktime_t) - * @mode: timer mode - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * The @delta argument gives the kernel the freedom to schedule the - * actual wakeup to a time that is both power and performance friendly - * for regular (non RT/DL) tasks. - * The kernel give the normal best effort behavior for "@expires+@delta", - * but may decide to fire the timer earlier, but no earlier than @expires. - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns unless the current task is explicitly - * woken up, (e.g. by wake_up_process()). - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task or the current task is explicitly woken - * up. - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Returns 0 when the timer has expired. If the task was woken before the - * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or - * by an explicit wakeup, it returns -EINTR. - */ -int __sched schedule_hrtimeout_range(ktime_t *expires, u64 delta, - const enum hrtimer_mode mode) -{ - return schedule_hrtimeout_range_clock(expires, delta, mode, - CLOCK_MONOTONIC); -} -EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); - -/** - * schedule_hrtimeout - sleep until timeout - * @expires: timeout value (ktime_t) - * @mode: timer mode - * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns unless the current task is explicitly - * woken up, (e.g. by wake_up_process()). - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task or the current task is explicitly woken - * up. - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Returns 0 when the timer has expired. If the task was woken before the - * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or - * by an explicit wakeup, it returns -EINTR. - */ -int __sched schedule_hrtimeout(ktime_t *expires, - const enum hrtimer_mode mode) -{ - return schedule_hrtimeout_range(expires, 0, mode); -} -EXPORT_SYMBOL_GPL(schedule_hrtimeout); diff --git a/kernel/time/sleep_timeout.c b/kernel/time/sleep_timeout.c new file mode 100644 index 000000000000..78b2e7e30b1e --- /dev/null +++ b/kernel/time/sleep_timeout.c @@ -0,0 +1,317 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Kernel internal schedule timeout and sleeping functions + */ + +#include +#include +#include +#include +#include + +#include "tick-internal.h" + +/* + * Since schedule_timeout()'s timer is defined on the stack, it must store + * the target task on the stack as well. + */ +struct process_timer { + struct timer_list timer; + struct task_struct *task; +}; + +static void process_timeout(struct timer_list *t) +{ + struct process_timer *timeout =3D from_timer(timeout, t, timer); + + wake_up_process(timeout->task); +} + +/** + * schedule_timeout - sleep until timeout + * @timeout: timeout value in jiffies + * + * Make the current task sleep until @timeout jiffies have elapsed. + * The function behavior depends on the current task state + * (see also set_current_state() description): + * + * %TASK_RUNNING - the scheduler is called, but the task does not sleep + * at all. That happens because sched_submit_work() does nothing for + * tasks in %TASK_RUNNING state. + * + * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process()). + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task or the current task is explicitly woken + * up. + * + * The current task state is guaranteed to be %TASK_RUNNING when this + * routine returns. + * + * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule + * the CPU away without a bound on the timeout. In this case the return + * value will be %MAX_SCHEDULE_TIMEOUT. + * + * Returns: 0 when the timer has expired otherwise the remaining time in + * jiffies will be returned. In all cases the return value is guaranteed + * to be non-negative. + */ +signed long __sched schedule_timeout(signed long timeout) +{ + struct process_timer timer; + unsigned long expire; + + switch (timeout) { + case MAX_SCHEDULE_TIMEOUT: + /* + * These two special cases are useful to be comfortable + * in the caller. Nothing more. We could take + * MAX_SCHEDULE_TIMEOUT from one of the negative value + * but I' d like to return a valid offset (>=3D0) to allow + * the caller to do everything it want with the retval. + */ + schedule(); + goto out; + default: + /* + * Another bit of PARANOID. Note that the retval will be + * 0 since no piece of kernel is supposed to do a check + * for a negative retval of schedule_timeout() (since it + * should never happens anyway). You just have the printk() + * that will tell you if something is gone wrong and where. + */ + if (timeout < 0) { + pr_err("%s: wrong timeout value %lx\n", __func__, timeout); + dump_stack(); + __set_current_state(TASK_RUNNING); + goto out; + } + } + + expire =3D timeout + jiffies; + + timer.task =3D current; + timer_setup_on_stack(&timer.timer, process_timeout, 0); + timer.timer.expires =3D expire; + add_timer(&timer.timer); + schedule(); + del_timer_sync(&timer.timer); + + /* Remove the timer from the object tracker */ + destroy_timer_on_stack(&timer.timer); + + timeout =3D expire - jiffies; + + out: + return timeout < 0 ? 0 : timeout; +} +EXPORT_SYMBOL(schedule_timeout); + +/* + * We can use __set_current_state() here because schedule_timeout() calls + * schedule() unconditionally. + */ +signed long __sched schedule_timeout_interruptible(signed long timeout) +{ + __set_current_state(TASK_INTERRUPTIBLE); + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(schedule_timeout_interruptible); + +signed long __sched schedule_timeout_killable(signed long timeout) +{ + __set_current_state(TASK_KILLABLE); + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(schedule_timeout_killable); + +signed long __sched schedule_timeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(schedule_timeout_uninterruptible); + +/* + * Like schedule_timeout_uninterruptible(), except this task will not cont= ribute + * to load average. + */ +signed long __sched schedule_timeout_idle(signed long timeout) +{ + __set_current_state(TASK_IDLE); + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(schedule_timeout_idle); + +/** + * schedule_hrtimeout_range_clock - sleep until timeout + * @expires: timeout value (ktime_t) + * @delta: slack in expires timeout (ktime_t) + * @mode: timer mode + * @clock_id: timer clock to be used + */ +int __sched schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, + const enum hrtimer_mode mode, clockid_t clock_id) +{ + struct hrtimer_sleeper t; + + /* + * Optimize when a zero timeout value is given. It does not + * matter whether this is an absolute or a relative time. + */ + if (expires && *expires =3D=3D 0) { + __set_current_state(TASK_RUNNING); + return 0; + } + + /* + * A NULL parameter means "infinite" + */ + if (!expires) { + schedule(); + return -EINTR; + } + + hrtimer_init_sleeper_on_stack(&t, clock_id, mode); + hrtimer_set_expires_range_ns(&t.timer, *expires, delta); + hrtimer_sleeper_start_expires(&t, mode); + + if (likely(t.task)) + schedule(); + + hrtimer_cancel(&t.timer); + destroy_hrtimer_on_stack(&t.timer); + + __set_current_state(TASK_RUNNING); + + return !t.task ? 0 : -EINTR; +} +EXPORT_SYMBOL_GPL(schedule_hrtimeout_range_clock); + +/** + * schedule_hrtimeout_range - sleep until timeout + * @expires: timeout value (ktime_t) + * @delta: slack in expires timeout (ktime_t) + * @mode: timer mode + * + * Make the current task sleep until the given expiry time has + * elapsed. The routine will return immediately unless + * the current task state has been set (see set_current_state()). + * + * The @delta argument gives the kernel the freedom to schedule the + * actual wakeup to a time that is both power and performance friendly + * for regular (non RT/DL) tasks. + * The kernel give the normal best effort behavior for "@expires+@delta", + * but may decide to fire the timer earlier, but no earlier than @expires. + * + * You can set the task state as follows - + * + * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process()). + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task or the current task is explicitly woken + * up. + * + * The current task state is guaranteed to be TASK_RUNNING when this + * routine returns. + * + * Returns: 0 when the timer has expired. If the task was woken before the + * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or + * by an explicit wakeup, it returns -EINTR. + */ +int __sched schedule_hrtimeout_range(ktime_t *expires, u64 delta, + const enum hrtimer_mode mode) +{ + return schedule_hrtimeout_range_clock(expires, delta, mode, + CLOCK_MONOTONIC); +} +EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); + +/** + * schedule_hrtimeout - sleep until timeout + * @expires: timeout value (ktime_t) + * @mode: timer mode + * + * Make the current task sleep until the given expiry time has + * elapsed. The routine will return immediately unless + * the current task state has been set (see set_current_state()). + * + * You can set the task state as follows - + * + * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to + * pass before the routine returns unless the current task is explicitly + * woken up, (e.g. by wake_up_process()). + * + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is + * delivered to the current task or the current task is explicitly woken + * up. + * + * The current task state is guaranteed to be TASK_RUNNING when this + * routine returns. + * + * Returns: 0 when the timer has expired. If the task was woken before the + * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or + * by an explicit wakeup, it returns -EINTR. + */ +int __sched schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode m= ode) +{ + return schedule_hrtimeout_range(expires, 0, mode); +} +EXPORT_SYMBOL_GPL(schedule_hrtimeout); + +/** + * msleep - sleep safely even with waitqueue interruptions + * @msecs: Time in milliseconds to sleep for + */ +void msleep(unsigned int msecs) +{ + unsigned long timeout =3D msecs_to_jiffies(msecs); + + while (timeout) + timeout =3D schedule_timeout_uninterruptible(timeout); +} +EXPORT_SYMBOL(msleep); + +/** + * msleep_interruptible - sleep waiting for signals + * @msecs: Time in milliseconds to sleep for + */ +unsigned long msleep_interruptible(unsigned int msecs) +{ + unsigned long timeout =3D msecs_to_jiffies(msecs); + + while (timeout && !signal_pending(current)) + timeout =3D schedule_timeout_interruptible(timeout); + return jiffies_to_msecs(timeout); +} +EXPORT_SYMBOL(msleep_interruptible); + +/** + * usleep_range_state - Sleep for an approximate time in a given state + * @min: Minimum time in usecs to sleep + * @max: Maximum time in usecs to sleep + * @state: State of the current task that will be while sleeping + * + * In non-atomic context where the exact wakeup time is flexible, use + * usleep_range_state() instead of udelay(). The sleep improves responsiv= eness + * by avoiding the CPU-hogging busy-wait of udelay(), and the range reduces + * power usage by allowing hrtimers to take advantage of an already- + * scheduled interrupt instead of scheduling a new one just for this sleep. + */ +void __sched usleep_range_state(unsigned long min, unsigned long max, unsi= gned int state) +{ + ktime_t exp =3D ktime_add_us(ktime_get(), min); + u64 delta =3D (u64)(max - min) * NSEC_PER_USEC; + + for (;;) { + __set_current_state(state); + /* Do not return before the requested sleep time has elapsed */ + if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) + break; + } +} +EXPORT_SYMBOL(usleep_range_state); diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 2b38f3035a3e..bb53d22cc911 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -2526,141 +2525,6 @@ void update_process_times(int user_tick) run_posix_cpu_timers(); } =20 -/* - * Since schedule_timeout()'s timer is defined on the stack, it must store - * the target task on the stack as well. - */ -struct process_timer { - struct timer_list timer; - struct task_struct *task; -}; - -static void process_timeout(struct timer_list *t) -{ - struct process_timer *timeout =3D from_timer(timeout, t, timer); - - wake_up_process(timeout->task); -} - -/** - * schedule_timeout - sleep until timeout - * @timeout: timeout value in jiffies - * - * Make the current task sleep until @timeout jiffies have elapsed. - * The function behavior depends on the current task state - * (see also set_current_state() description): - * - * %TASK_RUNNING - the scheduler is called, but the task does not sleep - * at all. That happens because sched_submit_work() does nothing for - * tasks in %TASK_RUNNING state. - * - * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to - * pass before the routine returns unless the current task is explicitly - * woken up, (e.g. by wake_up_process()). - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task or the current task is explicitly woken - * up. - * - * The current task state is guaranteed to be %TASK_RUNNING when this - * routine returns. - * - * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule - * the CPU away without a bound on the timeout. In this case the return - * value will be %MAX_SCHEDULE_TIMEOUT. - * - * Returns 0 when the timer has expired otherwise the remaining time in - * jiffies will be returned. In all cases the return value is guaranteed - * to be non-negative. - */ -signed long __sched schedule_timeout(signed long timeout) -{ - struct process_timer timer; - unsigned long expire; - - switch (timeout) - { - case MAX_SCHEDULE_TIMEOUT: - /* - * These two special cases are useful to be comfortable - * in the caller. Nothing more. We could take - * MAX_SCHEDULE_TIMEOUT from one of the negative value - * but I' d like to return a valid offset (>=3D0) to allow - * the caller to do everything it want with the retval. - */ - schedule(); - goto out; - default: - /* - * Another bit of PARANOID. Note that the retval will be - * 0 since no piece of kernel is supposed to do a check - * for a negative retval of schedule_timeout() (since it - * should never happens anyway). You just have the printk() - * that will tell you if something is gone wrong and where. - */ - if (timeout < 0) { - printk(KERN_ERR "schedule_timeout: wrong timeout " - "value %lx\n", timeout); - dump_stack(); - __set_current_state(TASK_RUNNING); - goto out; - } - } - - expire =3D timeout + jiffies; - - timer.task =3D current; - timer_setup_on_stack(&timer.timer, process_timeout, 0); - __mod_timer(&timer.timer, expire, MOD_TIMER_NOTPENDING); - schedule(); - del_timer_sync(&timer.timer); - - /* Remove the timer from the object tracker */ - destroy_timer_on_stack(&timer.timer); - - timeout =3D expire - jiffies; - - out: - return timeout < 0 ? 0 : timeout; -} -EXPORT_SYMBOL(schedule_timeout); - -/* - * We can use __set_current_state() here because schedule_timeout() calls - * schedule() unconditionally. - */ -signed long __sched schedule_timeout_interruptible(signed long timeout) -{ - __set_current_state(TASK_INTERRUPTIBLE); - return schedule_timeout(timeout); -} -EXPORT_SYMBOL(schedule_timeout_interruptible); - -signed long __sched schedule_timeout_killable(signed long timeout) -{ - __set_current_state(TASK_KILLABLE); - return schedule_timeout(timeout); -} -EXPORT_SYMBOL(schedule_timeout_killable); - -signed long __sched schedule_timeout_uninterruptible(signed long timeout) -{ - __set_current_state(TASK_UNINTERRUPTIBLE); - return schedule_timeout(timeout); -} -EXPORT_SYMBOL(schedule_timeout_uninterruptible); - -/* - * Like schedule_timeout_uninterruptible(), except this task will not cont= ribute - * to load average. - */ -signed long __sched schedule_timeout_idle(signed long timeout) -{ - __set_current_state(TASK_IDLE); - return schedule_timeout(timeout); -} -EXPORT_SYMBOL(schedule_timeout_idle); - #ifdef CONFIG_HOTPLUG_CPU static void migrate_timer_list(struct timer_base *new_base, struct hlist_h= ead *head) { @@ -2757,59 +2621,3 @@ void __init init_timers(void) posix_cputimers_init_work(); open_softirq(TIMER_SOFTIRQ, run_timer_softirq); } - -/** - * msleep - sleep safely even with waitqueue interruptions - * @msecs: Time in milliseconds to sleep for - */ -void msleep(unsigned int msecs) -{ - unsigned long timeout =3D msecs_to_jiffies(msecs); - - while (timeout) - timeout =3D schedule_timeout_uninterruptible(timeout); -} - -EXPORT_SYMBOL(msleep); - -/** - * msleep_interruptible - sleep waiting for signals - * @msecs: Time in milliseconds to sleep for - */ -unsigned long msleep_interruptible(unsigned int msecs) -{ - unsigned long timeout =3D msecs_to_jiffies(msecs); - - while (timeout && !signal_pending(current)) - timeout =3D schedule_timeout_interruptible(timeout); - return jiffies_to_msecs(timeout); -} - -EXPORT_SYMBOL(msleep_interruptible); - -/** - * usleep_range_state - Sleep for an approximate time in a given state - * @min: Minimum time in usecs to sleep - * @max: Maximum time in usecs to sleep - * @state: State of the current task that will be while sleeping - * - * In non-atomic context where the exact wakeup time is flexible, use - * usleep_range_state() instead of udelay(). The sleep improves responsiv= eness - * by avoiding the CPU-hogging busy-wait of udelay(), and the range reduces - * power usage by allowing hrtimers to take advantage of an already- - * scheduled interrupt instead of scheduling a new one just for this sleep. - */ -void __sched usleep_range_state(unsigned long min, unsigned long max, - unsigned int state) -{ - ktime_t exp =3D ktime_add_us(ktime_get(), min); - u64 delta =3D (u64)(max - min) * NSEC_PER_USEC; - - for (;;) { - __set_current_state(state); - /* Do not return before the requested sleep time has elapsed */ - if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS)) - break; - } -} -EXPORT_SYMBOL(usleep_range_state); --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E85C2558B7 for ; Wed, 11 Sep 2024 05:13:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031634; cv=none; b=rOND8DT0N0Ai6+GSPlnVjziIhITO2a/m0e9q8Lk9DQMg1EpUiYSk+DbVZwQlLvSujpwSlE+0xw72P2/b4CRlYC0+wyiYgKuDxWcF6fz0mH9u+inoEssuNGxXdvpQrRKw1nS2wat6zu3zacltbEhQfjdyN607Ify3srOodL8U2lE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031634; c=relaxed/simple; bh=eWl5OokrWCLk5+ZNm9+QPwTpkCmLx1Qmlf54JGzmflQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=gcYDgbI0IaHLXS62PJCu1YrWNHTDdubRYPteeCB9ruHE0i7z4UdauGQ72A2MzMnAOkz3QnwWjhL2oQqgI1BuuF+d4G58zaj/7o6hXQ7B7VT9iHC8SKP1DTp71fgwMzKBrgyWM13XJWhRvxYYR7I3cXQpumQk2pIsl0IHp3uKkEc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ZSgFm+O+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=T/kCTsfY; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ZSgFm+O+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="T/kCTsfY" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s+Doq4e/xcT9xXHQDOTyJ76uKwGRsxonwhuTH5qPvAk=; b=ZSgFm+O+CqyVdxMB8YR9cIIVdXH1gEJBt1Od++tlWbRrXtniAHe3OvSL1fvB/+rxdPkr1h Euh/w+wT+m1oqOVGp5koPYVud+WeFzlYl2FU1qWAw6ZRyrI3mPTRXA7IAS++TrybLRUx50 Uf3YuM7iEwOFGNj5nnO8gFjCP2acp5ZQMpiivR0qXh9PtUsXg0GlXpUG4lbiih/QZdMgaq 3z/Uj/tYnqGxMi87HShe8iVlQWxQUToUCpL3mjx5APZMb5+uLabY3bWmE65P4Dby/AWzLe 9jVX5qhI2koBD34N6MLJBmGWZh7SDR1tHRfqdlYGuseGoe00TPBMFEL/lgheQQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=s+Doq4e/xcT9xXHQDOTyJ76uKwGRsxonwhuTH5qPvAk=; b=T/kCTsfY7MMMyUgG3RG7PqyYm+S6IkB+UCUU7TktXO5B/ooZjEkyp6P8JmMiBkdm/OdNCX eCO4rIgzsMJjPEDw== Date: Wed, 11 Sep 2024 07:13:29 +0200 Subject: [PATCH v2 03/15] timers: Update schedule_[hr]timeout*() related function descriptions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-3-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen schedule_timeout*() functions do not have proper kernel-doc formatted function descriptions. schedule_hrtimeout() and schedule_hrtimeout_range() have a almost identical description. Add missing function descriptions. Remove copy of function description and add a pointer to the existing description instead. Signed-off-by: Anna-Maria Behnsen Acked-by: Frederic Weisbecker --- v2: New in v2 --- kernel/time/sleep_timeout.c | 66 ++++++++++++++++++++++++++++-------------= ---- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/kernel/time/sleep_timeout.c b/kernel/time/sleep_timeout.c index 78b2e7e30b1e..560d17c30aa5 100644 --- a/kernel/time/sleep_timeout.c +++ b/kernel/time/sleep_timeout.c @@ -110,8 +110,17 @@ signed long __sched schedule_timeout(signed long timeo= ut) EXPORT_SYMBOL(schedule_timeout); =20 /* - * We can use __set_current_state() here because schedule_timeout() calls - * schedule() unconditionally. + * __set_current_state() can be used in schedule_timeout_*() functions, be= cause + * schedule_timeout() calls schedule() unconditionally. + */ + +/** + * schedule_timeout_interruptible - sleep until timeout (interruptible) + * @timeout: timeout value in jiffies + * + * See schedule_timeout() for details. + * + * Task state is set to TASK_INTERRUPTIBLE before starting the timeout. */ signed long __sched schedule_timeout_interruptible(signed long timeout) { @@ -120,6 +129,14 @@ signed long __sched schedule_timeout_interruptible(sig= ned long timeout) } EXPORT_SYMBOL(schedule_timeout_interruptible); =20 +/** + * schedule_timeout_killable - sleep until timeout (killable) + * @timeout: timeout value in jiffies + * + * See schedule_timeout() for details. + * + * Task state is set to TASK_KILLABLE before starting the timeout. + */ signed long __sched schedule_timeout_killable(signed long timeout) { __set_current_state(TASK_KILLABLE); @@ -127,6 +144,14 @@ signed long __sched schedule_timeout_killable(signed l= ong timeout) } EXPORT_SYMBOL(schedule_timeout_killable); =20 +/** + * schedule_timeout_uninterruptible - sleep until timeout (uninterruptible) + * @timeout: timeout value in jiffies + * + * See schedule_timeout() for details. + * + * Task state is set to TASK_UNINTERRUPTIBLE before starting the timeout. + */ signed long __sched schedule_timeout_uninterruptible(signed long timeout) { __set_current_state(TASK_UNINTERRUPTIBLE); @@ -134,9 +159,15 @@ signed long __sched schedule_timeout_uninterruptible(s= igned long timeout) } EXPORT_SYMBOL(schedule_timeout_uninterruptible); =20 -/* - * Like schedule_timeout_uninterruptible(), except this task will not cont= ribute - * to load average. +/** + * schedule_timeout_idle - sleep until timeout (idle) + * @timeout: timeout value in jiffies + * + * See schedule_timeout() for details. + * + * Task state is set to TASK_IDLE before starting the timeout. It is simil= ar to + * schedule_timeout_uninterruptible(), except this task will not contribut= e to + * load average. */ signed long __sched schedule_timeout_idle(signed long timeout) { @@ -151,6 +182,9 @@ EXPORT_SYMBOL(schedule_timeout_idle); * @delta: slack in expires timeout (ktime_t) * @mode: timer mode * @clock_id: timer clock to be used + * + * Details are explained in schedule_hrtimeout_range() function descriptio= n as + * this function is commonly used. */ int __sched schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, const enum hrtimer_mode mode, clockid_t clock_id) @@ -236,26 +270,8 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout_range); * @expires: timeout value (ktime_t) * @mode: timer mode * - * Make the current task sleep until the given expiry time has - * elapsed. The routine will return immediately unless - * the current task state has been set (see set_current_state()). - * - * You can set the task state as follows - - * - * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to - * pass before the routine returns unless the current task is explicitly - * woken up, (e.g. by wake_up_process()). - * - * %TASK_INTERRUPTIBLE - the routine may return early if a signal is - * delivered to the current task or the current task is explicitly woken - * up. - * - * The current task state is guaranteed to be TASK_RUNNING when this - * routine returns. - * - * Returns: 0 when the timer has expired. If the task was woken before the - * timer expired by a signal (only possible in state TASK_INTERRUPTIBLE) or - * by an explicit wakeup, it returns -EINTR. + * See schedule_hrtimeout_range() for details. @delta argument of + * schedule_hrtimeout_range() is set to 0 and has therefore no impact. */ int __sched schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode m= ode) { --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F81D5A117 for ; Wed, 11 Sep 2024 05:13:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031636; cv=none; b=FZ0r2zrlPmLiAe5JHw4e+BdPFYG/MJPAM9M9zBCSkeNSGMeCvgsfaRo0r8JEjoCTF7Y7xj5dU75soXPihPGpYVtCxh6v1MEXseUwslZyeesPmSPTyYZjTaHvaNNwRhY2YyjGdesz3cE4Ed5xMmAIPmqSl9aM/IFlI6dyk169NS4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031636; c=relaxed/simple; bh=LfK+R+ftP6sokQ0GJlGESgvoBcdHOQjPW0DWwh/C9AI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PHen3joBceRAurM0DfnBsImwlT86ZbSdO5nlNQWi0DSRusmu5EWBjNOI90yb7fXCbtlN1BYsW0JSdWuDCeJVHhaccLrpegu9Y8ySvQg6b4RRjnHaCEJ5hBwsgsE4oz9zDqdkNHrOSvL4+esNosn2Y6QoFZ+5ZJJuXhY+AHOAawU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1nxeDVLn; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0M+ZH50y; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1nxeDVLn"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0M+ZH50y" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/qfn40Y/k109wQ4LtwO3H/8C6z24lcBDehQDK7V1Sj4=; b=1nxeDVLnHU+gFSNUEpCjBMcbigE191YYo1hVm/7vNthUtyhXyqyzWFXRL+m/DdMs6dNR0w RbOOm30VlPab92EwXSMye5u8tE1gtoSOpBJm2RFl2WJKf7JEt5ofRd1MbitIDXQt4pRBwm RrFG6Vf7mNLFwLbkdK3uwJPX1p7CrTGTbpuoCIrFKe0j8lAhZQAXunfqosMlq/n/44MIxX DUV8m1eTPSpnrqriKO+YsLr/DOQ6sOE4DiNTyxnjoq2pc3cmd0MYVYxvbUsL13VJxk1hQD SdYE8p3ytNsQXGTbppzJBWZt7okvDiB9mesYvr0v76v98sHsAQay3C49L3lB9g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031631; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/qfn40Y/k109wQ4LtwO3H/8C6z24lcBDehQDK7V1Sj4=; b=0M+ZH50yw//HJTG8q9IdLUSDvkth/ozPO2TyySSGXJTqaBIKgSPIz8uv63Rzq2PA8umwvn 2mntOTl1vFQnJbBg== Date: Wed, 11 Sep 2024 07:13:30 +0200 Subject: [PATCH v2 04/15] timers: Rename usleep_idle_range() to usleep_range_idle() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-4-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Andrew Morton , damon@lists.linux.dev, linux-mm@kvack.org, SeongJae Park usleep_idle_range() is a variant of usleep_range(). Both are using usleep_range_state() as a base. To be able to find all the related functions in one go, rename it usleep_idle_range() to usleep_range_idle(). No functional change. Cc: Andrew Morton Cc: damon@lists.linux.dev Cc: linux-mm@kvack.org Signed-off-by: Anna-Maria Behnsen Reviewed-by: Frederic Weisbecker Reviewed-by: SeongJae Park --- v2: Fix typos in commit message --- include/linux/delay.h | 2 +- mm/damon/core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/delay.h b/include/linux/delay.h index ff9cda975e30..2bc586aa2068 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -68,7 +68,7 @@ static inline void usleep_range(unsigned long min, unsign= ed long max) usleep_range_state(min, max, TASK_UNINTERRUPTIBLE); } =20 -static inline void usleep_idle_range(unsigned long min, unsigned long max) +static inline void usleep_range_idle(unsigned long min, unsigned long max) { usleep_range_state(min, max, TASK_IDLE); } diff --git a/mm/damon/core.c b/mm/damon/core.c index 7a87628b76ab..94fe2f1f9b0e 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1887,7 +1887,7 @@ static void kdamond_usleep(unsigned long usecs) if (usecs > 20 * USEC_PER_MSEC) schedule_timeout_idle(usecs_to_jiffies(usecs)); else - usleep_idle_range(usecs, usecs + 1); + usleep_range_idle(usecs, usecs + 1); } =20 /* Returns negative error code if it's not activated but should return */ --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60C857DA6E; Wed, 11 Sep 2024 05:13:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; cv=none; b=krZaoN7rUqEnRGhZZvhoqvvyvBqWIYpWbFRncgQjELrMkG2MI6FDoSgyITcrGt0tmp4ug8DtI1hZLLA12ObHty8FkyLVYkm3JUoVgRKCcyeK0T5a1s25Vgus0gBEw/R8X/8Ns0/+nt8kPByZiORWWyclD6uUN5bBXoZfhX9WugY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; c=relaxed/simple; bh=PSdFixi1A6Umhm2r1O9C1W23384QQYJFhFzHQJP6w/Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Nc8xcdi9UGLBWPegWhwudLWZbYcNG4b5yDIJ0O1UU/Jzbabj2/gUF3ZrHVEAgvcKGqGsJ/wyUUu8Gw+Y4Ib3JW251FqiBF79x3kzry8AqfUmhDyOwXtNVWjnKdbjOvZtb1C46XzBECFBpMthtpu+ndl427WYqNelY9cL7Xz8r8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Smoy2RAm; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=8jZ3xqDY; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Smoy2RAm"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="8jZ3xqDY" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Iv5Ec4sU3jBfOz3h23+1WN6paI/dxkRBzfx9DpzovAA=; b=Smoy2RAmMVqs1ASAPodyHMjbtC2J+uf4/YdRfhXAIGVq1XWASiP6U502t/moNRwUSPI4dM U4NLgkYfQ0oAMpp9dDybI+L7sGSwnNyR3HGNpnInCsAe7gnQ+RmCpqfrquRHBGlHYmP+V/ pWpFFgqnt933tpaFb33fiLx7jeAFX0CwmeieSfcRVxaY3Z530pu6ZKcNZ1vA3KyOAnqJFE KVWohQZY7BuHVU9fRD96O+D/kRZLNol8ut+1Y8PPcC7Fbavn6+UoVA2J+K5a51bqL80iqK v4f+O5LvGrRgBOzgtyXF6cVeQE/mwvXEiefpPuf/3bKk8/j0Q5M/AtTNyTsisw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Iv5Ec4sU3jBfOz3h23+1WN6paI/dxkRBzfx9DpzovAA=; b=8jZ3xqDYmJopJmwt1L+gmig8izrNgxEYZlbUDp8spjXgBeI2vakxqQ+v8mrD4GWiT4aYAv P6TuvyzfVTTM1pDg== Date: Wed, 11 Sep 2024 07:13:31 +0200 Subject: [PATCH v2 05/15] timers: Update function descriptions of sleep/delay related functions Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-5-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Arnd Bergmann , linux-arch@vger.kernel.org A lot of commonly used functions for inserting a sleep or delay lack a proper function description. Add function descriptions to all of them to have important information in a central place close to the code. No functional change. Cc: Arnd Bergmann Cc: linux-arch@vger.kernel.org Signed-off-by: Anna-Maria Behnsen --- v2: - Fix typos - Fix proper usage of kernel-doc return formatting --- include/asm-generic/delay.h | 41 +++++++++++++++++++++++++++++++---- include/linux/delay.h | 48 ++++++++++++++++++++++++++++++---------- kernel/time/sleep_timeout.c | 53 ++++++++++++++++++++++++++++++++++++++++-= ---- 3 files changed, 120 insertions(+), 22 deletions(-) diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h index e448ac61430c..70a1b20f3e1a 100644 --- a/include/asm-generic/delay.h +++ b/include/asm-generic/delay.h @@ -12,11 +12,39 @@ extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); =20 /* - * The weird n/20000 thing suppresses a "comparison is always false due to - * limited range of data type" warning with non-const 8-bit arguments. + * Implementation details: + * + * * The weird n/20000 thing suppresses a "comparison is always false due = to + * limited range of data type" warning with non-const 8-bit arguments. + * * 0x10c7 is 2**32 / 1000000 (rounded up) -> udelay + * * 0x5 is 2**32 / 1000000000 (rounded up) -> ndelay */ =20 -/* 0x10c7 is 2**32 / 1000000 (rounded up) */ +/** + * udelay - Inserting a delay based on microseconds with busy waiting + * @usec: requested delay in microseconds + * + * When delaying in an atomic context ndelay(), udelay() and mdelay() are = the + * only valid variants of delaying/sleeping to go with. + * + * When inserting delays in non atomic context which are shorter than the = time + * which is required to queue e.g. an hrtimer and to enter then the schedu= ler, + * it is also valuable to use udelay(). But is not simple to specify a gen= eric + * threshold for this which will fit for all systems, but an approximation= would + * be a threshold for all delays up to 10 microseconds. + * + * When having a delay which is larger than the architecture specific + * %MAX_UDELAY_MS value, please make sure mdelay() is used. Otherwise a ov= erflow + * risk is given. + * + * Please note that ndelay(), udelay() and mdelay() may return early for s= everal + * reasons (https://lists.openwall.net/linux-kernel/2011/01/09/56): + * + * #. computed loops_per_jiffy too low (due to the time taken to execute t= he + * timer interrupt.) + * #. cache behaviour affecting the time it takes to execute the loop func= tion. + * #. CPU clock rate changes. + */ #define udelay(n) \ ({ \ if (__builtin_constant_p(n)) { \ @@ -29,7 +57,12 @@ extern void __delay(unsigned long loops); } \ }) =20 -/* 0x5 is 2**32 / 1000000000 (rounded up) */ +/** + * ndelay - Inserting a delay based on nanoseconds with busy waiting + * @nsec: requested delay in nanoseconds + * + * See udelay() for basic information about ndelay() and it's variants. + */ #define ndelay(n) \ ({ \ if (__builtin_constant_p(n)) { \ diff --git a/include/linux/delay.h b/include/linux/delay.h index 2bc586aa2068..23623fa79768 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -6,17 +6,7 @@ * Copyright (C) 1993 Linus Torvalds * * Delay routines, using a pre-computed "loops_per_jiffy" value. - * - * Please note that ndelay(), udelay() and mdelay() may return early for - * several reasons: - * 1. computed loops_per_jiffy too low (due to the time taken to - * execute the timer interrupt.) - * 2. cache behaviour affecting the time it takes to execute the - * loop function. - * 3. CPU clock rate changes. - * - * Please see this thread: - * https://lists.openwall.net/linux-kernel/2011/01/09/56 + * Sleep routines using timer list timers or hrtimers. */ =20 #include @@ -35,12 +25,21 @@ extern unsigned long loops_per_jiffy; * The 2nd mdelay() definition ensures GCC will optimize away the=20 * while loop for the common cases where n <=3D MAX_UDELAY_MS -- Paul G. */ - #ifndef MAX_UDELAY_MS #define MAX_UDELAY_MS 5 #endif =20 #ifndef mdelay +/** + * mdelay - Inserting a delay based on microseconds with busy waiting + * @n: requested delay in microseconds + * + * See udelay() for basic information about mdelay() and it's variants. + * + * Please double check, whether mdelay() is the right way to go or whether= a + * refactoring of the code is the better variant to be able to use msleep() + * instead. + */ #define mdelay(n) (\ (__builtin_constant_p(n) && (n)<=3DMAX_UDELAY_MS) ? udelay((n)*1000) : \ ({unsigned long __ms=3D(n); while (__ms--) udelay(1000);})) @@ -63,16 +62,41 @@ unsigned long msleep_interruptible(unsigned int msecs); void usleep_range_state(unsigned long min, unsigned long max, unsigned int state); =20 +/** + * usleep_range - Sleep for an approximate time + * @min: Minimum time in microseconds to sleep + * @max: Maximum time in microseconds to sleep + * + * For basic information please refere to usleep_range_state(). + * + * The task will be in the state TASK_UNINTERRUPTIBLE during the sleep. + */ static inline void usleep_range(unsigned long min, unsigned long max) { usleep_range_state(min, max, TASK_UNINTERRUPTIBLE); } =20 +/** + * usleep_range_idle - Sleep for an approximate time with idle time accoun= ting + * @min: Minimum time in microseconds to sleep + * @max: Maximum time in microseconds to sleep + * + * For basic information please refere to usleep_range_state(). + * + * The sleeping task has the state TASK_IDLE during the sleep to prevent + * contribution to the load avarage. + */ static inline void usleep_range_idle(unsigned long min, unsigned long max) { usleep_range_state(min, max, TASK_IDLE); } =20 +/** + * ssleep - wrapper for seconds arount msleep + * @seconds: Requested sleep duration in seconds + * + * Please refere to msleep() for detailed information. + */ static inline void ssleep(unsigned int seconds) { msleep(seconds * 1000); diff --git a/kernel/time/sleep_timeout.c b/kernel/time/sleep_timeout.c index 560d17c30aa5..21f412350b15 100644 --- a/kernel/time/sleep_timeout.c +++ b/kernel/time/sleep_timeout.c @@ -281,7 +281,34 @@ EXPORT_SYMBOL_GPL(schedule_hrtimeout); =20 /** * msleep - sleep safely even with waitqueue interruptions - * @msecs: Time in milliseconds to sleep for + * @msecs: Requested sleep duration in milliseconds + * + * msleep() uses jiffy based timeouts for the sleep duration. The accuracy= of + * the resulting sleep duration depends on: + * + * * HZ configuration + * * sleep duration (as granularity of a bucket which collects timers incr= eases + * with the timer wheel levels) + * + * When the timer is queued into the second level of the timer wheel the m= aximum + * additional delay will be 12.5%. For explanation please check the detail= ed + * description about the basics of the timer wheel. In case this is accura= te + * enough check which sleep length is selected to make sure required accur= acy is + * given. Please use therefore the following simple steps: + * + * #. Decide which slack is fine for the requested sleep duration - but do= not + * use values shorter than 1/8 + * #. Check whether your sleep duration is equal or greater than the follo= wing + * result: ``TICK_NSEC / slack / NSEC_PER_MSEC`` + * + * Examples: + * + * * ``HZ=3D1000`` with `slack=3D1/4``: all sleep durations greater or equ= al 4ms will meet + * the constrains. + * * ``HZ=3D250`` with ``slack=3D1/4``: all sleep durations greater or equ= al 16ms will meet + * the constrains. + * + * See also the signal aware variant msleep_interruptible(). */ void msleep(unsigned int msecs) { @@ -294,7 +321,15 @@ EXPORT_SYMBOL(msleep); =20 /** * msleep_interruptible - sleep waiting for signals - * @msecs: Time in milliseconds to sleep for + * @msecs: Requested sleep duration in milliseconds + * + * See msleep() for some basic information. + * + * The difference between msleep() and msleep_interruptible() is that the = sleep + * could be interrupted by a signal delivery and then returns early. + * + * Returns: The remaining time of the sleep duration transformed to msecs = (see + * schedule_timeout() for details). */ unsigned long msleep_interruptible(unsigned int msecs) { @@ -312,11 +347,17 @@ EXPORT_SYMBOL(msleep_interruptible); * @max: Maximum time in usecs to sleep * @state: State of the current task that will be while sleeping * + * usleep_range_state() sleeps at least for the minimum specified time but= not + * longer than the maximum specified amount of time. The range might reduce + * power usage by allowing hrtimers to coalesce an already scheduled inter= rupt + * with this hrtimer. In the worst case, an interrupt is scheduled for the= upper + * bound. + * + * The sleeping task is set to the specified state before starting the sle= ep. + * * In non-atomic context where the exact wakeup time is flexible, use - * usleep_range_state() instead of udelay(). The sleep improves responsiv= eness - * by avoiding the CPU-hogging busy-wait of udelay(), and the range reduces - * power usage by allowing hrtimers to take advantage of an already- - * scheduled interrupt instead of scheduling a new one just for this sleep. + * usleep_range() or its variants instead of udelay(). The sleep improves + * responsiveness by avoiding the CPU-hogging busy-wait of udelay(). */ void __sched usleep_range_state(unsigned long min, unsigned long max, unsi= gned int state) { --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 930F17DA76 for ; Wed, 11 Sep 2024 05:13:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; cv=none; b=rvAavjyOFvgBSmA3qHVQBSuuIleEyFGb2XHYc+9X3q2TFiodelPqbz7FU7zwvsqT6iD4VK6WCBTBpka8Nd8Ff3YOtXEiPZBjOjTJGFgvJeuRfE2x2jkERTIIzjXRMfHt8d/rcKcbngCuKKdFgCk3H3LC+KpGqmSfAEJUFtKs6Jg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; c=relaxed/simple; bh=7kNqdXwdUO9/IpfBmIdMGRUAVzjRp2Kc3/vJYDgks9A=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LBtF8vYYkvD4maQoZEtthiCBD82XmwGpz8UmdPGOeuA5XD1/dRIMDAcW8pFqW4unv0S3PiG3y0Qdpqlh2cBXM9P6vf5xgOssnguNs5wOTXD3WrFow6yAQqzhVUyHDeWGNj3bQ34xxCceX7SZThtySXKECddmgFDGuJoDGAUya9A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=FdFovYyA; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NDb7wmuk; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="FdFovYyA"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NDb7wmuk" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F4fL5hcjRXOThZ7KBgdAy6TEeH1clm4HbG/CjFmZlDE=; b=FdFovYyATS9pTzzS4D8tcN5BrKTRO8ws4H8aT9mVXpMwrilnwvjlUAd/r6q2BkmFlzRP3K NYr/8Cpr1w7Du0RBGdVt7hrsJpRIYVMS3ojP1NEVlH5qI6g9yavBD0wF1zcJAgYaX2vA69 3JQls7R44Q+WD/7qJZR28gYvDspWWCweeTR34J7AAEuXBI33fKM/XvONcX5NtxhahK9wiT SJ48Zd436Ef+y6TL8NiAKoUrn/1gz4NKPB3N2pyUDCoatah5Ik0VDkG2hPiKGuH/KQ++2R WNCYUHMmswXnWZxxP4zpu0T9/E8llGr1sqdMyt90pHYFSy2WYot5zVOzrm5h8A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F4fL5hcjRXOThZ7KBgdAy6TEeH1clm4HbG/CjFmZlDE=; b=NDb7wmukiM1q8phUYl04XH84C14C30GeHoaWMQDVJld3b17zQMXQ83M36ns1ZTxVI1fLdE dkUKEV6sj6y2T4Dg== Date: Wed, 11 Sep 2024 07:13:32 +0200 Subject: [PATCH v2 06/15] delay: Rework udelay and ndelay Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-6-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen udelay() as well as ndelay() are defines and no functions and are using constants to be able to transform a sleep time into loops and to prevent too long udelays/ndelays. There was a compiler error with non-const 8 bit arguments which was fixed by commit a87e553fabe8 ("asm-generic: delay.h fix udelay and ndelay for 8 bit args"). When using a function, the non-const 8 bit argument is type casted and the problem would be gone. Transform udelay() and ndelay() into proper functions, remove the no longer and confusing division, add defines for the magic values and add some explanations as well. Suggested-by: Thomas Gleixner Signed-off-by: Anna-Maria Behnsen Reviewed-by: Frederic Weisbecker --- v2: New in v2 (as suggested by Thomas) --- include/asm-generic/delay.h | 64 +++++++++++++++++++++++++----------------= ---- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h index 70a1b20f3e1a..40d30dc2488b 100644 --- a/include/asm-generic/delay.h +++ b/include/asm-generic/delay.h @@ -2,6 +2,8 @@ #ifndef __ASM_GENERIC_DELAY_H #define __ASM_GENERIC_DELAY_H =20 +#include + /* Undefined functions to get compile-time errors */ extern void __bad_udelay(void); extern void __bad_ndelay(void); @@ -12,13 +14,18 @@ extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); =20 /* - * Implementation details: - * - * * The weird n/20000 thing suppresses a "comparison is always false due = to - * limited range of data type" warning with non-const 8-bit arguments. - * * 0x10c7 is 2**32 / 1000000 (rounded up) -> udelay - * * 0x5 is 2**32 / 1000000000 (rounded up) -> ndelay + * The microseconds/nanosecond delay multiplicators are used to convert a + * constant microseconds/nanoseconds value to a value which can be used by= the + * architectures specific implementation to transform it into loops. + */ +#define UDELAY_CONST_MULT ((unsigned long)DIV_ROUND_UP(1ULL << 32, USEC_PE= R_SEC)) +#define NDELAY_CONST_MULT ((unsigned long)DIV_ROUND_UP(1ULL << 32, NSEC_PE= R_SEC)) + +/* + * The maximum constant udelay/ndelay value picked out of thin air to prev= ent + * too long constant udelays/ndelays. */ +#define DELAY_CONST_MAX 20000 =20 /** * udelay - Inserting a delay based on microseconds with busy waiting @@ -45,17 +52,17 @@ extern void __delay(unsigned long loops); * #. cache behaviour affecting the time it takes to execute the loop func= tion. * #. CPU clock rate changes. */ -#define udelay(n) \ - ({ \ - if (__builtin_constant_p(n)) { \ - if ((n) / 20000 >=3D 1) \ - __bad_udelay(); \ - else \ - __const_udelay((n) * 0x10c7ul); \ - } else { \ - __udelay(n); \ - } \ - }) +static __always_inline void udelay(unsigned long usec) +{ + if (__builtin_constant_p(usec)) { + if (usec >=3D DELAY_CONST_MAX) + __bad_udelay(); + else + __const_udelay(usec * UDELAY_CONST_MULT); + } else { + __udelay(usec); + } +} =20 /** * ndelay - Inserting a delay based on nanoseconds with busy waiting @@ -63,16 +70,17 @@ extern void __delay(unsigned long loops); * * See udelay() for basic information about ndelay() and it's variants. */ -#define ndelay(n) \ - ({ \ - if (__builtin_constant_p(n)) { \ - if ((n) / 20000 >=3D 1) \ - __bad_ndelay(); \ - else \ - __const_udelay((n) * 5ul); \ - } else { \ - __ndelay(n); \ - } \ - }) +static __always_inline void ndelay(unsigned long nsec) +{ + if (__builtin_constant_p(nsec)) { + if (nsec >=3D DELAY_CONST_MAX) + __bad_udelay(); + else + __const_udelay(nsec * NDELAY_CONST_MULT); + } else { + __udelay(nsec); + } +} +#define ndelay(x) ndelay(x) =20 #endif /* __ASM_GENERIC_DELAY_H */ --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31BD77E111 for ; Wed, 11 Sep 2024 05:13:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; cv=none; b=B2760odFcNyBM6mKLF0tSk6BzuADEwW+jThIt29HufzaoR8IV/+jz8tH6dWdEQ1b/XiXC2UxaCcsOpi0mNePODEcVE27XebLmSZZ7eVGDLBXwQl0KSewlChpDzFOjFsUI2YosNf5I7kesKdnOXejrZIrETlQI1LUre5BHbyKm3c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; c=relaxed/simple; bh=Y0mUmw49im+/GxQ7ebJqx9Ja6vnn3XngWh6DjT6xiJ4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SrRkzEuIRrqgetC3AH4Zm5BauIB72b81WKWOo4Ah4+2UbXfWn9yuhxbmvQnMf0kWMt+I2UQ3A11CJ48UTLflhxBiQfeVDWsKjIe4psXzjr/SAgMkqbjDCNkSxi385Do9SbwZ00EphKM3bolc91KtnGktyRYE/82fcqIM3K37aa4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=u1DOw1re; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=eXA1Yii/; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="u1DOw1re"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="eXA1Yii/" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QzFZJPN6OCoOjFijLF5zzv1PdmAEslKaMmEzLI7TVjw=; b=u1DOw1rekShoZKYrisI0JTDw0ueDxQ8yOvgBI4siUh5NJNxMPHdC4McmKm4TUvGmwX7DlO vJcjBXpn33sCGsQEDnO82zhG6Ga6RTeTX+zaDRY0T4jffoD2n9sefDTK3mMmxfYi00+Jq+ xbWi/gzjF6T1YghA76QHhFNgDd/ajrbCfjZWY7j+bvbKU0IKdCbRHpRhLQEcatlM/ygwYC NmbAQX2W0t1j/cYn/G5g2mxAmWbTswen9SFKw0+P52MTBdIzBqLwih6YxbqpdRSzAfC5yR ngKRoPN9gFufCzHna6+XaoYCbrVffWPlFoBhBpXR9k0Px3gCrPNMRdfVQ8peoQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031632; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QzFZJPN6OCoOjFijLF5zzv1PdmAEslKaMmEzLI7TVjw=; b=eXA1Yii/JbU6EU7r0wGToYKKRGQcrldJLVEVG4g5V0MinWISWmtw5FCmF6Tv8TPhogPZcf EIKYD1cuMA5uvJDw== Date: Wed, 11 Sep 2024 07:13:33 +0200 Subject: [PATCH v2 07/15] timers: Adjust flseep() to reflect reality Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-7-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Heiner Kallweit , "David S. Miller" fsleep() simply implements the recommondations of the outdated documentation in "Documentation/timers/timers-howto.rst". This should be a user friendly interface to choose always the best timeout function approach: - udelay() for very short sleep durations shorter than 10 microseconds - usleep_range() for sleep durations until 20 milliseconds - msleep() for the others The actual implementation has several problems: - It does not take into account that HZ resolution also has an impact on granularity of jiffies and has also an impact on the granularity of the buckets of timer wheel levels. This means that accuracy for the timeout does not have an upper limit. When executing fsleep(20000) on a HZ=3D100 system, the possible additional slack will be 50% as the granularity of the buckets in the lowest level is 10 milliseconds. - The upper limit of usleep_range() is twice the requested timeout. When no other interrupts occur in this range, the maximum value is used. This means that the requested sleep length has then an additional delay of 100%. Change the thresholds for the decisions in fsleep() to make sure the maximum slack which is added to the sleep duration is 25%. Note: Outdated documentation will be updated in a followup patch. Cc: Heiner Kallweit Cc: David S. Miller Signed-off-by: Anna-Maria Behnsen Reviewed-by: Frederic Weisbecker --- include/linux/delay.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/include/linux/delay.h b/include/linux/delay.h index 23623fa79768..b49a63c85c43 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -11,6 +11,7 @@ =20 #include #include +#include =20 extern unsigned long loops_per_jiffy; =20 @@ -102,15 +103,35 @@ static inline void ssleep(unsigned int seconds) msleep(seconds * 1000); } =20 -/* see Documentation/timers/timers-howto.rst for the thresholds */ +static const unsigned int max_slack_shift =3D 2; +#define USLEEP_RANGE_UPPER_BOUND ((TICK_NSEC << max_slack_shift) / NSEC_PE= R_USEC) + +/** + * fsleep - flexible sleep which autoselects the best mechanism + * @usecs: requested sleep duration in microseconds + * + * flseep() selects the best mechanism that will provide maximum 25% slack + * to the requested sleep duration. Therefore it uses: + * + * * udelay() loop for sleep durations <=3D 10 microseconds to avoid hrtim= er + * overhead for really short sleep durations. + * * usleep_range() for sleep durations which would lead with the usage of + * msleep() to a slack larger than 25%. This depends on the granularity = of + * jiffies. + * * msleep() for all other sleep durations. + * + * Note: When %CONFIG_HIGH_RES_TIMERS is not set, all sleeps are processed= with + * the granularity of jiffies and the slack might exceed 25% especially for + * short sleep durations. + */ static inline void fsleep(unsigned long usecs) { if (usecs <=3D 10) udelay(usecs); - else if (usecs <=3D 20000) - usleep_range(usecs, 2 * usecs); + else if (usecs < USLEEP_RANGE_UPPER_BOUND) + usleep_range(usecs, usecs + (usecs >> max_slack_shift)); else - msleep(DIV_ROUND_UP(usecs, 1000)); + msleep(DIV_ROUND_UP(usecs, USEC_PER_MSEC)); } =20 #endif /* defined(_LINUX_DELAY_H) */ --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F31377DA9E for ; Wed, 11 Sep 2024 05:13:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; cv=none; b=iiT5Txpz0E9iA3CMe+12JWU47mFulOxY0XnAHqkPiyITBuYgpBpRRf0pU5ucIfZg5fl1rBjAW8DfOMAdyNh18gbogKM/dRc/sLWC5TS7eSkRROVDz8FxENGb20FQDdrTSS+pxMkCA9JUQ6HeOjL1DqcyZm8TjmT+wR2pZBKdk7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; c=relaxed/simple; bh=slPR/XUl9n4yCnGskGvmFLbw4vNgR0nqofOb59d+i2I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=R9clo+nzR6U44Bl4QUI7iTqqF+90QRxw0nUaVKBze3x6Y7MtQ3RZyTieRbO64HRj2zd5g35/zRy+OapIiEk7cPUa2Zrn6or+DamHxLJaL3tMZcmsHGDfwSIWgFJrXCWVGmmrj//dLejWMvUPBxj6QwDW9zavHRE4YQXrsl9VSzs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=tZ7Jo8+P; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=FLfAgtOq; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="tZ7Jo8+P"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="FLfAgtOq" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z6vDQ8OrtE5tfTIWOA9AkJWnV/XdCc+NosMWCRhCJCs=; b=tZ7Jo8+P/9B40FBGihKmE6n5MfupBcXrXJ0RzEgsKoQ+IY09Fnp4IHAMQeJD2A2EPG0Dh8 ixHIMvr2nMXTiuFzRYuKAnyaF+mDTFQYcWZej6x2al+8hQwT701UWn+yk/G3vU9+G0038T NlfHzHhMaraRZgoNjRFbrByExUEdzjy72WHp61JD6tC4Tcnr+VtcLldy+czOmrvCeDRW7n L+yClvg23Cq3DUrsYlyzfqsA4OEQ2xu56oRfqp58gHzklFVBzm5n8o0Wj/hq/zNrheE2ZA GUFDMgUtZbGWsMpCiYhK0ODGPi2zpiTiRPWjNuXPWE//3hT7YQP2If0jtZmSMQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z6vDQ8OrtE5tfTIWOA9AkJWnV/XdCc+NosMWCRhCJCs=; b=FLfAgtOqurk66aa8g8iQTkdDuocQxfo8snrO0+LncEvZ+h8IjnLSVutdhxUA1cZoWccM7y sgFxwKMnEsrBA3Cw== Date: Wed, 11 Sep 2024 07:13:34 +0200 Subject: [PATCH v2 08/15] mm/damon/core: Use generic upper bound recommondation for usleep_range() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-8-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , SeongJae Park , Andrew Morton , damon@lists.linux.dev, linux-mm@kvack.org The upper bound for usleep_range_idle() was taken from the outdated documentation. As a recommondation for the upper bound of usleep_range() depends on HZ configuration it is not possible to hard code it. Use the define "USLEEP_RANGE_UPPER_BOUND" instead. Cc: SeongJae Park Cc: Andrew Morton Cc: damon@lists.linux.dev Cc: linux-mm@kvack.org Signed-off-by: Anna-Maria Behnsen Reviewed-by: SeongJae Park Reviewed-by: Frederic Weisbecker --- mm/damon/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 94fe2f1f9b0e..4b971871da75 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1883,8 +1883,7 @@ static unsigned long damos_wmark_wait_us(struct damos= *scheme) =20 static void kdamond_usleep(unsigned long usecs) { - /* See Documentation/timers/timers-howto.rst for the thresholds */ - if (usecs > 20 * USEC_PER_MSEC) + if (usecs >=3D USLEEP_RANGE_UPPER_BOUND) schedule_timeout_idle(usecs_to_jiffies(usecs)); else usleep_range_idle(usecs, usecs + 1); --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 31C387E583 for ; Wed, 11 Sep 2024 05:13:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; cv=none; b=UQpiJd8R5o1TJU/PQi74YyBb1P0Np4s9pdWuKHWia571lz5Gk0yNWlxNmW2rbS0T1lqqMPemUXQvX/TqMPIg/prr65pOunvUR1ZDgqMKJeww/UarFL/8Q8LwcpqEjex84/rx7UZcrjrlNfwA91PDf7ROritbzTxj1RtZ2pX4afc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031637; c=relaxed/simple; bh=8rAJHPbtbN9E6pLkIP1/MlsY+gRBYnFfgvI+DhXdP5E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZoRF4MHkekVk5AcH12jMqPGPh/919cIW4vGzLXqoUZCNik0dulsNHTJGaTv0QlCACfjUFK5T5voZQomeMblBMHM6I3P3l8pY6kUcFH00qUtIkxdr00IXXHeaX08n78/s1kHzR2whNdg/HbgZiKyl2bxAOwnod8/x06a8u3qhPS4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=kMI2G0OR; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=PyMbHoX/; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="kMI2G0OR"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="PyMbHoX/" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R0M7Wr68xib3pXvNOYvULR95dTa0mXvdGPVRKK8CDzw=; b=kMI2G0OR020zrfLLC+7RLo1wjK5nPAymaW9S9UhIe3O0PRPfF9A0Olb5w+dMBA2iEwu7ZF bPgvvB5DgN7D3GLbskm9Y9zZyIAeSlB+U9QqoDbU+Rltbw24/abgbRa1i/ioXbVXQav0oB DSI0DbVvRQwImEtBGJnCACcCMuG4pjFV6Kz3jTVyBoM1dRN1iDygifRbwSWGsIFyvFkfiC FBjaKa3oO/fTc51OhNrOOUlj9gUQgI75zJlybF1oqtiMxYCqksNBYJiO+RmPu+iApE3hO/ OWmY7TOUrgA8l2EucQbFlSZgDtQ6sf0mgAL7cO8CY0kNfbPViKERPYbkctxyFA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031633; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=R0M7Wr68xib3pXvNOYvULR95dTa0mXvdGPVRKK8CDzw=; b=PyMbHoX/CGUwfDsyNiJThDTbY53xMotqdV2BKxE7uZmZ/4QLSm9wGCi6AdszqpwQMOLZiy eVsFkGKqbLYD6jAw== Date: Wed, 11 Sep 2024 07:13:35 +0200 Subject: [PATCH v2 09/15] timers: Add a warning to usleep_range_state() for wrong order of arguments Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-9-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Andy Whitcroft , Joe Perches There is a warning in checkpatch script that triggers, when min and max arguments of usleep_range_state() are in reverse order. This check does only cover callsites which uses constants. Move this check into the code as a WARN_ON_ONCE() to also cover callsites not using constants and get rid of it in checkpatch. Cc: Andy Whitcroft Cc: Joe Perches Signed-off-by: Anna-Maria Behnsen --- kernel/time/sleep_timeout.c | 2 ++ scripts/checkpatch.pl | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/time/sleep_timeout.c b/kernel/time/sleep_timeout.c index 21f412350b15..4b805d7e1903 100644 --- a/kernel/time/sleep_timeout.c +++ b/kernel/time/sleep_timeout.c @@ -364,6 +364,8 @@ void __sched usleep_range_state(unsigned long min, unsi= gned long max, unsigned i ktime_t exp =3D ktime_add_us(ktime_get(), min); u64 delta =3D (u64)(max - min) * NSEC_PER_USEC; =20 + WARN_ON_ONCE(max < min); + for (;;) { __set_current_state(state); /* Do not return before the requested sleep time has elapsed */ diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 39032224d504..ba3359bdd1fa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -7088,10 +7088,6 @@ sub process { if ($min eq $max) { WARN("USLEEP_RANGE", "usleep_range should not use min =3D=3D max args; see Documentati= on/timers/timers-howto.rst\n" . "$here\n$stat\n"); - } elsif ($min =3D~ /^\d+$/ && $max =3D~ /^\d+$/ && - $min > $max) { - WARN("USLEEP_RANGE", - "usleep_range args reversed, use min then max; see Documentation/= timers/timers-howto.rst\n" . "$here\n$stat\n"); } } =20 --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7CFD18174E for ; Wed, 11 Sep 2024 05:13:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031638; cv=none; b=Ldub2nfEkon434MkVzQbswLOQibmQCCACBgOQ/UtlolGOuOZjYwmdRXDeHrIztGDWfMGaxz/iIDXItNaFGifudJc4BlPPwXin+GdJ+a4/P0zbOSqX6t9lkp77k7oBzjv5HUuBqDoLEXU5JXy+5zXzC1bh5npAnpNRdWAFL4PuiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031638; c=relaxed/simple; bh=avhPIsslozTS9vqIfiFf0QzVkFvw//68+ibKKgIAU8c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LPZv0a62zW4FHzF/wV8MP/App8b0oadO7/bG+0b2zXW+8jSj3PGFKeqESLbot1QpXXvu1dlogs9elh2TaTJUsXBFwxdm6G/lLqWKSAwFf8XDMkSOopDpaOV9hV+e+4mhJeWFhOdxx2iCmJA7DRRGmaj6MG0VbgJLUlNG/dsDgsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=IT3ofUeU; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=8+rr6Zq7; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="IT3ofUeU"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="8+rr6Zq7" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fC0f59bC3NttoHYilTyaZRvTfVq89aChhHzFQAJfHQY=; b=IT3ofUeUobgaPJPhrnXCcNB+AaUmZiE5LCYIQzSK/nFmT9qTg3i3vpm/tevbAq73bFgNFS vhLjeaz62CiUGEewl22UDUaak222MsnhLWytdg3mqWdoY1vbAkI1Nem9wrH0qxwtbCwbGE TWt1mdMGfmpQu9mcbl1l/BoA1KqczYycRej0xaRUfM/Ev3XMHyLZT3yiGtd1vwm4iLlHta XB7wiV/UKWwZB2eQMlp4MB3brGSO9QDt/AHcp5VB7anlcr/3vPaHUzCnEwSwy5k5j+sEFw Udm16Yc5BVE6X0n8Xei9o1Nf3vIrkt7T59ylwVy+y7eX/XdGYd+RzRrMhkDjaw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fC0f59bC3NttoHYilTyaZRvTfVq89aChhHzFQAJfHQY=; b=8+rr6Zq7ULBSeBAqVO9xPTPvtT2a+cBp67DKp+yL+JmARmcpk+MoUTB6gTePLeg174yt2Z o89sjACC99WMi4Ag== Date: Wed, 11 Sep 2024 07:13:36 +0200 Subject: [PATCH v2 10/15] checkpatch: Remove broken sleep/delay related checks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-10-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Andy Whitcroft , Joe Perches , Dwaipayan Ray checkpatch.pl checks for several things related to sleep and delay functions. In all warnings the outdated documentation is referenced. All broken parts are listed one by one in the following with an explanation why this check is broken. For a basic background of those functions please also refere to the updated function descriptions of udelay(), nsleep_range() and msleep(). Be aware: The change is done with a perl knowledge of the level "I'm able to spell perl". The following checks are broken: - Check: (! ($delay < 10) ) Message: "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" Why is the check broken: When it is an atomic context, udelay() is mandatory. - Check: ($min eq $max) Message: "usleep_range should not use min =3D=3D max args; see Documentation/timers/timers-howto.rst\n" Why is the check broken: When the requested accuracy for the sleep duration requires it, it is also valid to use min =3D=3D max. - Check: ($delay > 2000) Message: "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" Why is the check broken: The threshold when to start using mdelay() to prevent an overflow depends on MAX_UDELAY_MS. This value is architecture dependent. The used value for the check and reference is arm specific. Generic would be 5ms, but this would "break" arm, loongarch and mips and also the arm value might "break" mips and loongarch in some configurations. - Check: ($1 < 20) Message: "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" Why is the check broken: msleep(1) might sleep up to 20ms but only on a HZ=3D100 system. On a HZ=3D1000 system this will= be 2ms. This means, the threshold cannot be hard coded as it depends on HZ (jiffy granularity and timer wheel bucket/level granularity) and also on the required accuracy of the callsite. See msleep() and also the USLEEP_RANGE_UPPER_BOUND value. Remove all broken checks. Update checkpatch documentation accordingly. Cc: Andy Whitcroft Cc: Joe Perches Cc: Dwaipayan Ray Signed-off-by: Anna-Maria Behnsen Acked-by: Frederic Weisbecker --- v2: Rephrase commit message --- Documentation/dev-tools/checkpatch.rst | 6 ------ scripts/checkpatch.pl | 34 ------------------------------= ---- 2 files changed, 40 deletions(-) diff --git a/Documentation/dev-tools/checkpatch.rst b/Documentation/dev-too= ls/checkpatch.rst index a9fac978a525..f5c27be9e673 100644 --- a/Documentation/dev-tools/checkpatch.rst +++ b/Documentation/dev-tools/checkpatch.rst @@ -466,12 +466,6 @@ API usage **UAPI_INCLUDE** No #include statements in include/uapi should use a uapi/ path. =20 - **USLEEP_RANGE** - usleep_range() should be preferred over udelay(). The proper way of - using usleep_range() is mentioned in the kernel docs. - - See: https://www.kernel.org/doc/html/latest/timers/timers-howto.html#d= elays-information-on-the-various-kernel-delay-sleep-mechanisms - =20 Comments -------- diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index ba3359bdd1fa..80497da4aaac 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6601,28 +6601,6 @@ sub process { } } =20 -# prefer usleep_range over udelay - if ($line =3D~ /\budelay\s*\(\s*(\d+)\s*\)/) { - my $delay =3D $1; - # ignore udelay's < 10, however - if (! ($delay < 10) ) { - CHK("USLEEP_RANGE", - "usleep_range is preferred over udelay; see Documentation/timers/t= imers-howto.rst\n" . $herecurr); - } - if ($delay > 2000) { - WARN("LONG_UDELAY", - "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n"= . $herecurr); - } - } - -# warn about unexpectedly long msleep's - if ($line =3D~ /\bmsleep\s*\((\d+)\);/) { - if ($1 < 20) { - WARN("MSLEEP", - "msleep < 20ms can sleep for up to 20ms; see Documentation/timers= /timers-howto.rst\n" . $herecurr); - } - } - # check for comparisons of jiffies if ($line =3D~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { WARN("JIFFIES_COMPARISON", @@ -7079,18 +7057,6 @@ sub process { } } =20 -# check usleep_range arguments - if ($perl_version_ok && - defined $stat && - $stat =3D~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncA= rg)\s*\)/) { - my $min =3D $1; - my $max =3D $7; - if ($min eq $max) { - WARN("USLEEP_RANGE", - "usleep_range should not use min =3D=3D max args; see Documentati= on/timers/timers-howto.rst\n" . "$here\n$stat\n"); - } - } - # check for naked sscanf if ($perl_version_ok && defined $stat && --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0ED8C135A69 for ; Wed, 11 Sep 2024 05:13:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031638; cv=none; b=VJeJ4pYWof9Ay7XXbwx+XVIY5IeIJ6pE3D6+HeWKVsHsrvaBNW3iQMNd6a1Nf3SNQlqV12wjbmJyhGhcsvMFW5lnJ2LJjCGjGG/FVOOj4phlCrUkuDqesUidQOaAPJzNpzpHyGbM+gBwIhfPVVRzLX4pq3DKUPJupacWehlEABo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031638; c=relaxed/simple; bh=Iu3t2ZvhGZM9V5B2n78D4EKuKhs3LJgqXVMR5djIgTU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DLKyvoBUtnKeMGZc55NB3hn9iRu8fIKsMqHnBdp3oghpshidygpsS3KhlScwuiMjKcltlu019p6bVKZwXSnD/00fJL9c/GgZSNGDQyDNwO514DZgF+Qlqn372qulSSfpXvoheAJ0v/Ak7AO9r493An4abHT1ftZKLQzO5BquUUk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=L9fLRPya; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=AFD16mbE; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="L9fLRPya"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="AFD16mbE" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bSVvJgxFrZ1dz8pJPoMJBQ5YpWwDGPyuOlPl0CM7qhs=; b=L9fLRPyaXs4/x11oQ+mv1tmuOekPYxDufkhOvTYTdVprrcsTR/HOEctVjtODtRKclyI4Cc BR79NdLGf61GxhVyLZoehzvKI19AFKh5AHGQIuqdz2ZZpC9KaYFYdZSNFbsJlZdoL2wF/5 Idw2crkmxEx51JS9pCMojsHC7mOPjSNLXaPWlCy3BrSLewewmMic6gJaFkM05QBKWObZoD foHL7m7hrBVGm1AzxZdEW+LnMsOKo1HxngIlMWIbtYyElni8HQF2M0QW7avj8P6XtBdBHN C4uxUokYv2zcxAuuDHajl7s2vD2G51PwrZzcB2+EMZSHRoYRHE3iov1ky+u6TA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bSVvJgxFrZ1dz8pJPoMJBQ5YpWwDGPyuOlPl0CM7qhs=; b=AFD16mbEdPZnlXKye/ZCjg6YOji25EPUgGJdTP2f7huIwQmc7HO+i23XRQFOEwEWFmoR64 d1ft4kewo31+fqAw== Date: Wed, 11 Sep 2024 07:13:37 +0200 Subject: [PATCH v2 11/15] regulator: core: Use fsleep() to get best sleep mechanism Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-11-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Liam Girdwood , Mark Brown _regulator_delay_helper() implements the recommondation of the outdated documentation which sleep mechanism should be used. There is already a function in place which does everything and also maps to reality called fsleep(). Use fsleep() directly. Cc: Liam Girdwood Cc: Mark Brown Signed-off-by: Anna-Maria Behnsen Reviewed-by: Frederic Weisbecker --- v2: Use fsleep() directly --- drivers/regulator/core.c | 47 ++++----------------------------------------= --- 1 file changed, 4 insertions(+), 43 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7674b7f2df14..5d4cfb14fada 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2667,45 +2667,6 @@ static int regulator_ena_gpio_ctrl(struct regulator_= dev *rdev, bool enable) return 0; } =20 -/** - * _regulator_delay_helper - a delay helper function - * @delay: time to delay in microseconds - * - * Delay for the requested amount of time as per the guidelines in: - * - * Documentation/timers/timers-howto.rst - * - * The assumption here is that these regulator operations will never used = in - * atomic context and therefore sleeping functions can be used. - */ -static void _regulator_delay_helper(unsigned int delay) -{ - unsigned int ms =3D delay / 1000; - unsigned int us =3D delay % 1000; - - if (ms > 0) { - /* - * For small enough values, handle super-millisecond - * delays in the usleep_range() call below. - */ - if (ms < 20) - us +=3D ms * 1000; - else - msleep(ms); - } - - /* - * Give the scheduler some room to coalesce with any other - * wakeup sources. For delays shorter than 10 us, don't even - * bother setting up high-resolution timers and just busy- - * loop. - */ - if (us >=3D 10) - usleep_range(us, us + 100); - else - udelay(us); -} - /** * _regulator_check_status_enabled * @@ -2760,7 +2721,7 @@ static int _regulator_do_enable(struct regulator_dev = *rdev) s64 remaining =3D ktime_us_delta(end, ktime_get_boottime()); =20 if (remaining > 0) - _regulator_delay_helper(remaining); + fsleep(remaining); } =20 if (rdev->ena_pin) { @@ -2794,7 +2755,7 @@ static int _regulator_do_enable(struct regulator_dev = *rdev) int time_remaining =3D delay; =20 while (time_remaining > 0) { - _regulator_delay_helper(rdev->desc->poll_enabled_time); + fsleep(rdev->desc->poll_enabled_time); =20 if (rdev->desc->ops->get_status) { ret =3D _regulator_check_status_enabled(rdev); @@ -2813,7 +2774,7 @@ static int _regulator_do_enable(struct regulator_dev = *rdev) return -ETIMEDOUT; } } else { - _regulator_delay_helper(delay); + fsleep(delay); } =20 trace_regulator_enable_complete(rdev_get_name(rdev)); @@ -3741,7 +3702,7 @@ static int _regulator_do_set_voltage(struct regulator= _dev *rdev, } =20 /* Insert any necessary delays */ - _regulator_delay_helper(delay); + fsleep(delay); =20 if (best_val >=3D 0) { unsigned long data =3D best_val; --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8D0E1311AC; Wed, 11 Sep 2024 05:13:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031639; cv=none; b=gUkzqv46ueOgAJSvYk3dm7seM2Iwz4Tq+wD8xW72FuRHDqa5wBhYF5nUr/JDsGvAf7gltPmu6xfJMrBmfXfNGqN2c+Abtt6HckQPtLPPXsuClbAf5qJ/T9BERn9+zhAhdfjK1+HS3GcJ/9g/T9l/rIsTzU99R8C3ToK2XIPrHlY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031639; c=relaxed/simple; bh=4wZOhasrUFvkS2mb929tmW0a4bdElDKj4tVHbruyRXA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FLqGbfvGJ9oR5U4WgiKlCZKy7fBIMZyOik51LKgKGvYqrA5DbIWSBd88xmkM15WNyfLUMRAzGKidgwEG2yajnp+lXVn0p8HG+DXpizEIarDt+CY+o/2Lb1mwPS69tdgveixE9xs5UnuBOB+vgOybrrDZjPQJtv10aDudip9N6iE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1McUAerT; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=9Rx/tsqf; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1McUAerT"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="9Rx/tsqf" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AfajaFeZI83lFduG7CKpozyUerHLUcwmwL6H0ejEapI=; b=1McUAerTDnykbb607X6HZcOdWRi99+O/Ed8+hFUfTlnYpU8gx6U06ZDUW24Fe4jOG/AOJT H2S7trd71N9cHxhb8+mRGMEpcjK/r2AUIr+z4VkQRTVklnOGVhNCHjYQ6GWlzVqNMPB2Dx u9v9eiBiXSE9ft07ifGOifLPJD5R1YgF4tZJmSCHgeseyhnkl5H3eusDYVAInYyMysVWnN Rfhnit4Fuokes4GfxUaeI+to/P/EmCWBBwaQaqYkVUSyeVz27M7EQxGec8ENYO3gKVgrjJ Oi7G/+Y1XtHInkIk4N9WjcTmO1RT8H5piXkpymMmUEoAa0UF4zBfgdwIaAWg2w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031634; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AfajaFeZI83lFduG7CKpozyUerHLUcwmwL6H0ejEapI=; b=9Rx/tsqf3aTcs62gDJpBTJs9diWutozT6F6UcymLJ6R3Rm9oIyZsPNKub2Junk9z7Xr46s SM6I1+Gqo1Om3XAw== Date: Wed, 11 Sep 2024 07:13:38 +0200 Subject: [PATCH v2 12/15] iopoll/regmap/phy/snd: Fix comment referencing outdated timer documentation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-12-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Andrew Lunn , Heiner Kallweit , Jaroslav Kysela , Takashi Iwai , netdev@vger.kernel.org, linux-sound@vger.kernel.org Function descriptions in iopoll.h, regmap.h, phy.h and sound/soc/sof/ops.h copied all the same outdated documentation about sleep/delay function limitations. In those comments, the generic (and still outdated) timer documentation file is referenced. As proper function descriptions for used delay and sleep functions are in place, simply update the descriptions to reference to them. While at it fix missing colon after "Returns" in function description and move return value description to the end of the function description. Cc: Andrew Lunn Cc: Heiner Kallweit Cc: Jaroslav Kysela Cc: Takashi Iwai Cc: netdev@vger.kernel.org Cc: linux-sound@vger.kernel.org Signed-off-by: Anna-Maria Behnsen Reviewed-by: Andrew Lunn Reviewed-by: Frederic Weisbecker --- v2: Add cleanup of usage of 'Returns' in function description --- include/linux/iopoll.h | 52 +++++++++++++++++++++++++---------------------= ---- include/linux/phy.h | 9 +++++---- include/linux/regmap.h | 38 ++++++++++++++++++------------------ sound/soc/sof/ops.h | 8 ++++---- 4 files changed, 54 insertions(+), 53 deletions(-) diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index 19a7b00baff4..91324c331a4b 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h @@ -19,19 +19,19 @@ * @op: accessor function (takes @args as its arguments) * @val: Variable to read the value into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * @sleep_before_read: if it is true, sleep @sleep_us before read. * @args: arguments for @op poll * - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either - * case, the last read value at @args is stored in @val. Must not - * be called from atomic context if sleep_us or timeout_us are used. - * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @args is stored in @val. Must not + * be called from atomic context if sleep_us or timeout_us are used. */ #define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \ sleep_before_read, args...) \ @@ -64,22 +64,22 @@ * @op: accessor function (takes @args as its arguments) * @val: Variable to read the value into * @cond: Break condition (usually involving @val) - * @delay_us: Time to udelay between reads in us (0 tight-loops). Should - * be less than ~10us since udelay is used (see - * Documentation/timers/timers-howto.rst). + * @delay_us: Time to udelay between reads in us (0 tight-loops). Please + * read udelay() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * @delay_before_read: if it is true, delay @delay_us before read. * @args: arguments for @op poll * - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either - * case, the last read value at @args is stored in @val. - * * This macro does not rely on timekeeping. Hence it is safe to call even= when * timekeeping is suspended, at the expense of an underestimation of wall = clock * time, which is rather minimal with a non-zero delay_us. * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @args is stored in @val. */ #define read_poll_timeout_atomic(op, val, cond, delay_us, timeout_us, \ delay_before_read, args...) \ @@ -119,17 +119,17 @@ * @addr: Address to poll * @val: Variable to read the value into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either - * case, the last read value at @addr is stored in @val. Must not - * be called from atomic context if sleep_us or timeout_us are used. - * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @addr is stored in @val. Must not + * be called from atomic context if sleep_us or timeout_us are used. */ #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr) @@ -140,16 +140,16 @@ * @addr: Address to poll * @val: Variable to read the value into * @cond: Break condition (usually involving @val) - * @delay_us: Time to udelay between reads in us (0 tight-loops). Should - * be less than ~10us since udelay is used (see - * Documentation/timers/timers-howto.rst). + * @delay_us: Time to udelay between reads in us (0 tight-loops). Please + * read udelay() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either - * case, the last read value at @addr is stored in @val. - * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either + * case, the last read value at @addr is stored in @val. */ #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_u= s) \ read_poll_timeout_atomic(op, val, cond, delay_us, timeout_us, false, addr) diff --git a/include/linux/phy.h b/include/linux/phy.h index 6b7d40d49129..cadf51441ee1 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1374,12 +1374,13 @@ int phy_read_mmd(struct phy_device *phydev, int dev= ad, u32 regnum); * @regnum: The register on the MMD to read * @val: Variable to read the register into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * @sleep_before_read: if it is true, sleep @sleep_us before read. - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either * case, the last read value at @args is stored in @val. Must not * be called from atomic context if sleep_us or timeout_us are used. */ diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 122e38161acb..d733b08466fd 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -106,17 +106,17 @@ struct reg_sequence { * @addr: Address to poll * @val: Unsigned integer variable to read the value into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read + * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout or the regmap_read * error return value in case of a error read. In the two former cases, * the last read value at @addr is stored in @val. Must not be called * from atomic context if sleep_us or timeout_us are used. - * - * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. */ #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_u= s) \ ({ \ @@ -133,20 +133,20 @@ struct reg_sequence { * @addr: Address to poll * @val: Unsigned integer variable to read the value into * @cond: Break condition (usually involving @val) - * @delay_us: Time to udelay between reads in us (0 tight-loops). - * Should be less than ~10us since udelay is used - * (see Documentation/timers/timers-howto.rst). + * @delay_us: Time to udelay between reads in us (0 tight-loops). Please + * read udelay() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read - * error return value in case of a error read. In the two former cases, - * the last read value at @addr is stored in @val. - * * This is modelled after the readx_poll_timeout_atomic macros in linux/io= poll.h. * * Note: In general regmap cannot be used in atomic context. If you want t= o use * this macro then first setup your regmap for atomic use (flat or no cache * and MMIO regmap). + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout or the regmap_read + * error return value in case of a error read. In the two former cases, + * the last read value at @addr is stored in @val. */ #define regmap_read_poll_timeout_atomic(map, addr, val, cond, delay_us, ti= meout_us) \ ({ \ @@ -177,17 +177,17 @@ struct reg_sequence { * @field: Regmap field to read from * @val: Unsigned integer variable to read the value into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_field_= read + * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. + * + * Returns: 0 on success and -ETIMEDOUT upon a timeout or the regmap_field= _read * error return value in case of a error read. In the two former cases, * the last read value at @addr is stored in @val. Must not be called * from atomic context if sleep_us or timeout_us are used. - * - * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. */ #define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout= _us) \ ({ \ diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 2584621c3b2d..d73644e85b6e 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -597,12 +597,12 @@ snd_sof_is_chain_dma_supported(struct snd_sof_dev *sd= ev, u32 dai_type) * @addr: Address to poll * @val: Variable to read the value into * @cond: Break condition (usually involving @val) - * @sleep_us: Maximum time to sleep between reads in us (0 - * tight-loops). Should be less than ~20ms since usleep_range - * is used (see Documentation/timers/timers-howto.rst). + * @sleep_us: Maximum time to sleep between reads in us (0 tight-loops). P= lease + * read usleep_range() function description for details and + * limitations. * @timeout_us: Timeout in us, 0 means never timeout * - * Returns 0 on success and -ETIMEDOUT upon a timeout. In either + * Returns: 0 on success and -ETIMEDOUT upon a timeout. In either * case, the last read value at @addr is stored in @val. Must not * be called from atomic context if sleep_us or timeout_us are used. * --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECFE613AA27 for ; Wed, 11 Sep 2024 05:13:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031640; cv=none; b=kHPj675uEqgBZDWzcMpI0fOU5PWW6oDPsz3pLOCibO947cvvI/pWMZAcTbuFh6omKvLiiKK+lAZezQoQHf6mQ9AoXXJIYy+S6LWylnqnhcFK/AJMU02kevI+uUV5Ni4JZDO6GnzGW/Fn2ZiX0R2LvUkHZuefT1QrUVdW6ppChEk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031640; c=relaxed/simple; bh=EpnYZjgt9MQ9cFJx0dkRuPLx78ce3vuzPvPVRnnX8nk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=c28osNiS+/DJzQJndyaKGAv/Ht0Vo6z9cSv04tlZ+3b4qIC+xcUuGdTPj4jM7+ghTSfGnilgGmofm+YbfrkwJaYyGTAjvn4PAk36nja4RtnDaT3r23fgfGDd7XiqiwWrMayopfW5Or8RWQc76ECj0dcAYF05OrhYWVVD5NVwVEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=UiR2NcsA; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Rnjh4EVK; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="UiR2NcsA"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Rnjh4EVK" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TYHTnWg90GO/Adzm/xlNmVzdNdsY7txrgGU6OMGh5ag=; b=UiR2NcsAC9i4ZW/0yyfeerjtAB84C6rxBP2AjJVghd8Zc693ibg0t0LPO124a/gcvvy1jT cyvc7nAZO/r7Q1P9n7Az6s9X3LcCho5bRI78pKX454ysg4y40GcE6ot9vfcAcFsOMUKWBu l+tyUqRBZhBr9fGWBpRQIWJh19Rt7e4+LdWtLn/E6nCOZPw0wHDnHIIXmwC5nPxMg4e04o QposPh3H05412DmD3/6zKTCN22un+RbJIB25KF3mojgSZtQsDn0SM4Y7asD3X7/6+27Qew r+IbqEd79alZ3uJPVvLLR08KqnBM1xAUWTkjNgWphUHgdrL9UqfYgktI0fVNmg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TYHTnWg90GO/Adzm/xlNmVzdNdsY7txrgGU6OMGh5ag=; b=Rnjh4EVKzBewiHVfpCXtDI+g14W3w20GvMd+olwoEufskS5lpV/SML3o+WmsePJPn74JmH aZ6OOfeBk4eyPSBw== Date: Wed, 11 Sep 2024 07:13:39 +0200 Subject: [PATCH v2 13/15] powerpc/rtas: Use fsleep() to minimize additional sleep duration Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-13-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Michael Ellerman , Nathan Lynch , linuxppc-dev@lists.ozlabs.org When commit 38f7b7067dae ("powerpc/rtas: rtas_busy_delay() improvements") was introduced, documentation about proper usage of sleep realted functions was outdated. The commit message references the usage of a HZ=3D100 system. When using a 20ms sleep duration on such a system and therefore using msleep(), the possible additional slack will be +10ms. When the system is configured with HZ=3D100 the granularity of a jiffy and = of a bucket of the lowest timer wheel level is 10ms. To make sure a timer will not expire early (when queueing of the timer races with an concurrent update of jiffies), timers are always queued into the next bucket. This is the reason for the maximal possible slack of 10ms. fsleep() limits the maximal possible slack to 25% by making threshold between usleep_range() and msleep() HZ dependent. As soon as the accuracy of msleep() is sufficient, the less expensive timer list timer based sleeping function is used instead of the more expensive hrtimer based usleep_range() function. The udelay() will not be used in this specific usecase as the lowest sleep length is larger than 1 microsecond. Use fsleep() directly instead of using an own heuristic for the best sleeping mechanism to use.. Cc: Michael Ellerman Cc: Nathan Lynch Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Anna-Maria Behnsen Acked-by: Michael Ellerman (powerpc) Reviewed-by: Frederic Weisbecker --- v2: fix typos --- arch/powerpc/kernel/rtas.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index f7e86e09c49f..d31c9799cab2 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -1390,21 +1390,14 @@ bool __ref rtas_busy_delay(int status) */ ms =3D clamp(ms, 1U, 1000U); /* - * The delay hint is an order-of-magnitude suggestion, not - * a minimum. It is fine, possibly even advantageous, for - * us to pause for less time than hinted. For small values, - * use usleep_range() to ensure we don't sleep much longer - * than actually needed. - * - * See Documentation/timers/timers-howto.rst for - * explanation of the threshold used here. In effect we use - * usleep_range() for 9900 and 9901, msleep() for - * 9902-9905. + * The delay hint is an order-of-magnitude suggestion, not a + * minimum. It is fine, possibly even advantageous, for us to + * pause for less time than hinted. To make sure pause time will + * not be way longer than requested independent of HZ + * configuration, use fsleep(). See fsleep() for details of + * used sleeping functions. */ - if (ms <=3D 20) - usleep_range(ms * 100, ms * 1000); - else - msleep(ms); + fsleep(ms * 1000); break; case RTAS_BUSY: ret =3D true; --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 379C513AD33; Wed, 11 Sep 2024 05:13:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031639; cv=none; b=VGIN10LM6fQ8jDqKk6on3hGFlc5SN51jFMUkAZfvXxe4F7TobRDrmjmqNDSg/P2VED0IQc1g/8gNrEdBsxjltuy8/Uyv7ZY10BqypZU7d156hnmc2GTs6K/8T31V4yUF8prOcSICZe8VZkiqQL5Htkof7upaIt0NqsKS7tHFrKQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031639; c=relaxed/simple; bh=75n5UjPAswXizo2Gb+4Lf6s8hs9mh1+0oQvxojBGbbE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NlyeVwq7lSdz9br3lVb62qF4l6uUYiHNU24wGsCS8p27msPihk9uIxnPdRUVhHM5FdNk025EQ5cPf2fh7OlCWDvijEavca5NmF9dxPIoxzvCYyoGXKhnqIm63SjFCzwFABpwQZ/A1Xoy24ouBvPLIsfeWPrLoytQ9H1SA4VnxzA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=WPScN9Z8; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1EVEp+Av; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="WPScN9Z8"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1EVEp+Av" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v75l3ZYBbsP13asMW41FuZtAe9X+N+Ak4ZgbeSG9nK0=; b=WPScN9Z8IeSAv86lO8Bw3riaXLVV7NCUdbYsICok0sZPVj2SPuzytHiR8iMdQs5TTRh8K8 lGFKvr9Sam2D21YLhSzqESLtPqls4QFpbiYNw3vIQgyidc1W2hkfWLEdi9xNwMY7FnNSne nwouI20sH0u9hfpOCQOLLvIfUX7TU85zvnVwr1c3i806CA6d5eI+C0MfOG1yp/yoPKWMK4 WA2WhRmSu+VPd8fOgLEw2yc6huOoymZR9VOFjzi+1Xdj0BW8bgXEQbz2tF6HFiMCulSb3T MUkRlbxUP9fGf97RvHvufeoTUmUxTp48FbKpUqHtEco3QXmArGqay+mbUNPp5Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=v75l3ZYBbsP13asMW41FuZtAe9X+N+Ak4ZgbeSG9nK0=; b=1EVEp+AvXwK1t9YRIjQVMvmqiYRDTEOToq6hHQI2KuI7Zt2eigi3WEYv5lKj1//dT/V+MK uRTztjD6Kt030fDw== Date: Wed, 11 Sep 2024 07:13:40 +0200 Subject: [PATCH v2 14/15] media: anysee: Fix link to outdated sleep function documentation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-14-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen , Mauro Carvalho Chehab , linux-media@vger.kernel.org The TODO FIXME comment references the outdated lower limit for msleep() function of 20ms. As this is not right and the proper documentation of msleep() is now part of the function description, remove the old stuff and point to the up to date documentation. Cc: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org Signed-off-by: Anna-Maria Behnsen --- drivers/media/usb/dvb-usb-v2/anysee.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-= usb-v2/anysee.c index 8699846eb416..b2f5db961245 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c @@ -55,10 +55,8 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, =20 /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32 * (EPIPE, Broken pipe). Function supports currently msleep() as a - * parameter but I would not like to use it, since according to - * Documentation/timers/timers-howto.rst it should not be used such - * short, under < 20ms, sleeps. Repeating failed message would be - * better choice as not to add unwanted delays... + * parameter. Check msleep() for details. Repeating failed message would + * be better choice as not to add unwanted delays... * Fixing that correctly is one of those or both; * 1) use repeat if possible * 2) add suitable delay --=20 2.39.2 From nobody Sat Nov 30 05:33:32 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2701613C816 for ; Wed, 11 Sep 2024 05:13:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031641; cv=none; b=CpIK6oe7qHmZScXyop5HRngPoD+4HhZvT/n5aTxrDTM8hNgM7FK9o8TXS+Cc7CtDgm4Ahv2H6vun3vNJa26p3Rgh4HSns7QJzAGeknciffkMfxsqRimKyDagwv7lOQ/vjP3LnqVF5WPIahxhIoLkxzEK/f3/vYXm48s5/BjX/q0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726031641; c=relaxed/simple; bh=MnkTO+SoXn9ALpaHKD0yv6agPOoMrHkkYtt8oXOQSeI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jjV9pdqIKeVCMGCCGOdOQmpc2GXbWnRvBOP7CbDnylK1dWKQDcC7MYTuzXgazIjovImVveFG8NLFg36VfloVsOgxdr9nXK3xjxt9IoBSrJEp114vwd4VKPRZTmFQox8CYd4CnRZ3l0F44FeMtYHjoSmfdV4qZ7/FLIcjY73pz34= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qUJUVXpo; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=xGenxOzP; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qUJUVXpo"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="xGenxOzP" From: Anna-Maria Behnsen DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vaCS8Wy4nmdabahzumttPewmZzyJlsqugb8Ai6FeVCc=; b=qUJUVXpo+w8k7UOLSozBCH3cfFvB+lbfSSFMDP2O1zhNoZTEAVIhcmdR4a89QDj36ng/1u e8UulYJWUTFbCNLJsLcFA6zarbw4i2GJMGH5VOFdzPDFWWYCefzSydjkRAYR1h7kT659mU PMdWCXNv4yZUNEmfKU4IBv755M6a3WdflUPaT3HD38w98Aq/xMhzn91F550TQBM8fy0FbK 9NwhaKrws13IybhbCoUZZNu+nVkZ5CtxshASgdUeUTAxTAwNz1CvRl3GccEJf+BWG8Q/9i h76WpFCgvISispVKKYnZgyLBpEEWIxpMdibu4BhSbX1s23WH5vJj2anrWWesBA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1726031635; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vaCS8Wy4nmdabahzumttPewmZzyJlsqugb8Ai6FeVCc=; b=xGenxOzPtacHbWbO5o8pyUlGMMDPx3VtSeFvOvW5vBolYYgFOqfFIO4h2tGhk4uDqQpPyq 0uat33lrr53ZjEBA== Date: Wed, 11 Sep 2024 07:13:41 +0200 Subject: [PATCH v2 15/15] timers/Documentation: Cleanup delay/sleep documentation Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240911-devel-anna-maria-b4-timers-flseep-v2-15-b0d3f33ccfe0@linutronix.de> References: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> In-Reply-To: <20240911-devel-anna-maria-b4-timers-flseep-v2-0-b0d3f33ccfe0@linutronix.de> To: Frederic Weisbecker , Thomas Gleixner , Jonathan Corbet Cc: linux-kernel@vger.kernel.org, Len Brown , "Rafael J. Wysocki" , Anna-Maria Behnsen The documentation which tries to give advises how to properly inserting delays or sleeps is outdated. The file name is 'timers-howto.rst' which might be missleading as it is only about delay and sleep mechanisms and not how to use timers. Update the documentation by integrating the important parts from the related function descriptions and move it all into a self explaining file with the name "delay_sleep_functions.rst". Signed-off-by: Anna-Maria Behnsen Reviewed-by: Frederic Weisbecker --- Documentation/timers/delay_sleep_functions.rst | 122 +++++++++++++++++++++= ++++ Documentation/timers/index.rst | 2 +- Documentation/timers/timers-howto.rst | 115 ---------------------= -- 3 files changed, 123 insertions(+), 116 deletions(-) diff --git a/Documentation/timers/delay_sleep_functions.rst b/Documentation= /timers/delay_sleep_functions.rst new file mode 100644 index 000000000000..05d7c3c8fbe8 --- /dev/null +++ b/Documentation/timers/delay_sleep_functions.rst @@ -0,0 +1,122 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Delay and sleep mechanisms +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + +This document seeks to answer the common question: "What is the +RightWay (TM) to insert a delay?" + +This question is most often faced by driver writers who have to +deal with hardware delays and who may not be the most intimately +familiar with the inner workings of the Linux Kernel. + +The following table gives a rough overview about the existing function +'families' and their limitations. This overview table does not replace the +reading of the function description before usage! + +.. list-table:: + :widths: 20 20 20 20 20 + :header-rows: 2 + + * - + - `*delay()` + - `usleep_range*()` + - `*sleep()` + - `fsleep()` + * - + - busy-wait loop + - hrtimers based + - timer list timers based + - combines the others + * - Usage in atomic Context + - yes + - no + - no + - no + * - precise on "short intervals" + - yes + - yes + - depends + - yes + * - precise on "long intervals" + - Do not use! + - yes + - max 12.5% slack + - yes + * - interruptible variant + - no + - yes + - yes + - no + +A generic advice for non atomic contexts could be: + +#. Use `fsleep()` whenever unsure (as it combines all the advantages of the + others) +#. Use `*sleep()` whenever possible +#. Use `usleep_range*()` whenever accuracy of `*sleep()` is not sufficient +#. Use `*delay()` for very, very short delays + +Find some more detailed information about the function 'families' in the n= ext +sections. + +`*delay()` family of functions +------------------------------ + +These functions use the jiffy estimation of clock speed and will busy wait= for +enough loop cycles to achieve the desired delay. udelay() is the basic +implementation and ndelay() as well as mdelay() are variants. + +These functions are mainly used to add a delay in atomic context. Please m= ake +sure to ask yourself before adding a delay in atomic context: Is this real= ly +required? + +.. kernel-doc:: include/asm-generic/delay.h + :identifiers: udelay ndelay + +.. kernel-doc:: include/linux/delay.h + :identifiers: mdelay + + +`usleep_range*()` and `*sleep()` family of functions +---------------------------------------------------- + +These functions uses hrtimers or timer list timers to provide the requested +sleeping duration. For a decision which function is the right one to use, = take +some basic information into account: + +#. hrtimers are more expensive as they are using an rb-tree (instead of ha= shing) +#. hrtimers are more expensive when the requested sleeping duration is the= first + timer which means real hardware has to be programmed +#. timer list timers always providing some sort of slack as they are jiffy + based + +The generic advice is repeated here: + +#. Use `fsleep()` whenever unsure (as it combines all the advantages of the + others) +#. Use `*sleep()` whenever possible +#. Use `usleep_range*()` whenever accuracy of `*sleep()` is not sufficient + +First check fsleep() function description and to learn more about accuracy, +please check msleep() function description. + + +`usleep_range*()` +~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: include/linux/delay.h + :identifiers: usleep_range usleep_range_idle + +.. kernel-doc:: kernel/time/sleep_timeout.c + :identifiers: usleep_range_state + + +`*sleep()` +~~~~~~~~~~ + +.. kernel-doc:: kernel/time/sleep_timeout.c + :identifiers: msleep msleep_interruptible + +.. kernel-doc:: include/linux/delay.h + :identifiers: ssleep fsleep diff --git a/Documentation/timers/index.rst b/Documentation/timers/index.rst index 983f91f8f023..4e88116e4dcf 100644 --- a/Documentation/timers/index.rst +++ b/Documentation/timers/index.rst @@ -12,7 +12,7 @@ Timers hrtimers no_hz timekeeping - timers-howto + delay_sleep_functions =20 .. only:: subproject and html =20 diff --git a/Documentation/timers/timers-howto.rst b/Documentation/timers/t= imers-howto.rst deleted file mode 100644 index ef7a4652ccc9..000000000000 --- a/Documentation/timers/timers-howto.rst +++ /dev/null @@ -1,115 +0,0 @@ -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -delays - Information on the various kernel delay / sleep mechanisms -=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - -This document seeks to answer the common question: "What is the -RightWay (TM) to insert a delay?" - -This question is most often faced by driver writers who have to -deal with hardware delays and who may not be the most intimately -familiar with the inner workings of the Linux Kernel. - - -Inserting Delays ----------------- - -The first, and most important, question you need to ask is "Is my -code in an atomic context?" This should be followed closely by "Does -it really need to delay in atomic context?" If so... - -ATOMIC CONTEXT: - You must use the `*delay` family of functions. These - functions use the jiffy estimation of clock speed - and will busy wait for enough loop cycles to achieve - the desired delay: - - ndelay(unsigned long nsecs) - udelay(unsigned long usecs) - mdelay(unsigned long msecs) - - udelay is the generally preferred API; ndelay-level - precision may not actually exist on many non-PC devices. - - mdelay is macro wrapper around udelay, to account for - possible overflow when passing large arguments to udelay. - In general, use of mdelay is discouraged and code should - be refactored to allow for the use of msleep. - -NON-ATOMIC CONTEXT: - You should use the `*sleep[_range]` family of functions. - There are a few more options here, while any of them may - work correctly, using the "right" sleep function will - help the scheduler, power management, and just make your - driver better :) - - -- Backed by busy-wait loop: - - udelay(unsigned long usecs) - - -- Backed by hrtimers: - - usleep_range(unsigned long min, unsigned long max) - - -- Backed by jiffies / legacy_timers - - msleep(unsigned long msecs) - msleep_interruptible(unsigned long msecs) - - Unlike the `*delay` family, the underlying mechanism - driving each of these calls varies, thus there are - quirks you should be aware of. - - - SLEEPING FOR "A FEW" USECS ( < ~10us? ): - * Use udelay - - - Why not usleep? - On slower systems, (embedded, OR perhaps a speed- - stepped PC!) the overhead of setting up the hrtimers - for usleep *may* not be worth it. Such an evaluation - will obviously depend on your specific situation, but - it is something to be aware of. - - SLEEPING FOR ~USECS OR SMALL MSECS ( 10us - 20ms): - * Use usleep_range - - - Why not msleep for (1ms - 20ms)? - Explained originally here: - https://lore.kernel.org/r/15327.1186166232@lwn.net - - msleep(1~20) may not do what the caller intends, and - will often sleep longer (~20 ms actual sleep for any - value given in the 1~20ms range). In many cases this - is not the desired behavior. - - - Why is there no "usleep" / What is a good range? - Since usleep_range is built on top of hrtimers, the - wakeup will be very precise (ish), thus a simple - usleep function would likely introduce a large number - of undesired interrupts. - - With the introduction of a range, the scheduler is - free to coalesce your wakeup with any other wakeup - that may have happened for other reasons, or at the - worst case, fire an interrupt for your upper bound. - - The larger a range you supply, the greater a chance - that you will not trigger an interrupt; this should - be balanced with what is an acceptable upper bound on - delay / performance for your specific code path. Exact - tolerances here are very situation specific, thus it - is left to the caller to determine a reasonable range. - - SLEEPING FOR LARGER MSECS ( 10ms+ ) - * Use msleep or possibly msleep_interruptible - - - What's the difference? - msleep sets the current task to TASK_UNINTERRUPTIBLE - whereas msleep_interruptible sets the current task to - TASK_INTERRUPTIBLE before scheduling the sleep. In - short, the difference is whether the sleep can be ended - early by a signal. In general, just use msleep unless - you know you have a need for the interruptible variant. - - FLEXIBLE SLEEPING (any delay, uninterruptible) - * Use fsleep --=20 2.39.2