From: Frederic Weisbecker <frederic@kernel.org>
To: Victor Hassan <victor@allwinnertech.com>
Cc: fweisbec@gmail.com, tglx@linutronix.de, mingo@kernel.org,
jindong.yue@nxp.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] tick/broadcast: Do not set oneshot_mask except was_periodic was true
Date: Mon, 3 Apr 2023 12:26:27 +0200 [thread overview]
Message-ID: <ZCqp02hiCell/5AR@lothringen> (raw)
In-Reply-To: <20230328063629.108510-1-victor@allwinnertech.com>
On Tue, Mar 28, 2023 at 02:36:29PM +0800, Victor Hassan wrote:
> If a broadcast timer is registered after the system switched to oneshot
> mode, a hang_task err could occur like that:
>
> INFO: task kworker/u15:0:7 blocked for more than 120 seconds.
> Tainted: G E 5.15.41-android13-8-00002-xxx #1
> "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> task:kworker/u16:0 state:D stack: 9808 pid: 7 ppid: 2 flags:0x00000008
> Workqueue: events_unbound deferred_probe_work_func.cfi_jt
> Call trace:
> __switch_to+0y240/0x490
> __schedule+0x620/0xafc
> schedule+0x110/0x204
> schedule_hrtimeout_range_clock+0x9c/0x118
> usleep_range_state+0x150/0x1ac
> _regulator_do_enable+0x528/0x878
> set_machine_constraints+0x6a0/0xf2c
> regulator_register+0x3ac/0x7ac
> devm_regulator_register+0xbc/0x120
> pmu_ext_regulator_probe+0xb0/0x1b4 [pmu_ext_regulator]
> platform_probe+0x70/0x194
> really_proe+0x320/0x68c
> __driver_probe_device+0x204/0x260
> driver_probe_device+0x48/0x1e0
>
> When the new broadcast timer was registered after the system switched
> to oneshot mode, the broadcast timer was not used as periodic. If the
> oneshot mask was set incorrectly, all cores which did not enter cpu_idle
> state can't enter cpu_idle normally, causing the hrtimer mechanism to
> break.
>
> This patch fixes the issue by moving the update action about oneshot
> mask to a more strict conditions. The tick_broadcast_setup_oneshot would
> be called in two typical condition, and they all will work.
>
> 1. tick_handle_periodic -> tick_broadcast_setup_oneshot
>
> The origin broadcast was periodic, so it can set the oneshot_mask bits
> for those waiting for periodic broadcast and program the broadcast timer
> to fire.
>
> 2. tick_install_broadcast_device -> tick_broadcast_setup_oneshot
>
> The origin broadcast was oneshot, so the cores which enter the cpu_idle
> already used the oneshot_mask bits. It is unnecessary to update the
> oneshot_mask.
>
> Fixes: 9c336c9935cf ("tick/broadcast: Allow late registered device to enter oneshot mode")
>
> Signed-off-by: Victor Hassan <victor@allwinnertech.com>
> ---
> kernel/time/tick-broadcast.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
> index 93bf2b4e47e5..fdbbba487978 100644
> --- a/kernel/time/tick-broadcast.c
> +++ b/kernel/time/tick-broadcast.c
> @@ -1041,12 +1041,13 @@ static void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
> */
> cpumask_copy(tmpmask, tick_broadcast_mask);
> cpumask_clear_cpu(cpu, tmpmask);
> - cpumask_or(tick_broadcast_oneshot_mask,
> - tick_broadcast_oneshot_mask, tmpmask);
>
> if (was_periodic && !cpumask_empty(tmpmask)) {
> ktime_t nextevt = tick_get_next_period();
>
> + cpumask_or(tick_broadcast_oneshot_mask,
> + tick_broadcast_oneshot_mask, tmpmask);
> +
Good catch, it looks like one issue that can trigger is due to the resulting
ignored calls to tick_broadcast_exit(). Indeed if the cpu is already in
tick_broadcast_oneshot_mask then cpuidle won't call the exit.
Leading to such race:
* CPU 1 stop its tick, next event is in one hour
* CPU 0 registers new broadcast and sets CPU 1 in tick_broadcast_oneshot_mask
* CPU 1 runs into cpuidle_enter_state(), and tick_broadcast_enter() is ignored because
the CPU is already in tick_broadcast_oneshot_mask
* CPU 1 goes to sleep
* CPU 0 runs the broadcast callback, sees that the next timer for CPU 1
is in one hour, program the broadcast to that deadline
* CPU 1 gets an interrupt that enqueues a new timer expiring in the next jiffy
* CPU 1 don't call tick_broadcast_exit and thus don't remove itself from
tick_broadcast_oneshot_mask
* CPU 1 re-enters in cpuidle_enter_state(), tick_broadcast_enter() is again
ignored so the new timer isn't propagated to the broadcast.
* CPU 1 goes to sleep and won't be woken before one hour.
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Thanks.
> clockevents_switch_state(bc, CLOCK_EVT_STATE_ONESHOT);
> tick_broadcast_init_next_event(tmpmask, nextevt);
> tick_broadcast_set_event(bc, cpu, nextevt);
> --
> 2.29.0
>
next prev parent reply other threads:[~2023-04-03 10:26 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-28 6:36 [PATCH] tick/broadcast: Do not set oneshot_mask except was_periodic was true Victor Hassan
2023-03-31 1:46 ` Victor Hassan
2023-04-03 10:26 ` Frederic Weisbecker [this message]
2023-04-04 11:37 ` Victor Hassan
2023-04-04 12:21 ` Frederic Weisbecker
2023-04-07 6:51 ` Victor Hassan
2023-04-10 7:06 ` Victor Hassan
2023-04-11 8:55 ` Frederic Weisbecker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZCqp02hiCell/5AR@lothringen \
--to=frederic@kernel.org \
--cc=fweisbec@gmail.com \
--cc=jindong.yue@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=tglx@linutronix.de \
--cc=victor@allwinnertech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.