patches.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: "Guilherme G. Piccoli" <gpiccoli@igalia.com>,
	Thadeu Lima de Souza Cascardo <cascardo@igalia.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	"Paul E . McKenney" <paulmck@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	john.stultz@linaro.org, linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.14 03/28] clocksource: Fix the CPUs' choice in the watchdog per CPU verification
Date: Fri, 30 May 2025 08:39:09 -0400	[thread overview]
Message-ID: <20250530123934.2574748-3-sashal@kernel.org> (raw)
In-Reply-To: <20250530123934.2574748-1-sashal@kernel.org>

From: "Guilherme G. Piccoli" <gpiccoli@igalia.com>

[ Upstream commit 08d7becc1a6b8c936e25d827becabfe3bff72a36 ]

Right now, if the clocksource watchdog detects a clocksource skew, it might
perform a per CPU check, for example in the TSC case on x86.  In other
words: supposing TSC is detected as unstable by the clocksource watchdog
running at CPU1, as part of marking TSC unstable the kernel will also run a
check of TSC readings on some CPUs to be sure it is synced between them
all.

But that check happens only on some CPUs, not all of them; this choice is
based on the parameter "verify_n_cpus" and in some random cpumask
calculation. So, the watchdog runs such per CPU checks on up to
"verify_n_cpus" random CPUs among all online CPUs, with the risk of
repeating CPUs (that aren't double checked) in the cpumask random
calculation.

But if "verify_n_cpus" > num_online_cpus(), it should skip the random
calculation and just go ahead and check the clocksource sync between
all online CPUs, without the risk of skipping some CPUs due to
duplicity in the random cpumask calculation.

Tests in a 4 CPU laptop with TSC skew detected led to some cases of the per
CPU verification skipping some CPU even with verify_n_cpus=8, due to the
duplicity on random cpumask generation. Skipping the randomization when the
number of online CPUs is smaller than verify_n_cpus, solves that.

Suggested-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Link: https://lore.kernel.org/all/20250323173857.372390-1-gpiccoli@igalia.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

Perfect! Now I understand the issue. Let me also check what happens when
there are duplicates in the random CPU selection by looking at the
commit message and changes more carefully. **Analysis:** **YES** - This
commit should be backported to stable kernel trees. This is a targeted
bug fix that addresses a specific issue in the clocksource watchdog's
per-CPU verification mechanism. Here's my detailed analysis: ## What the
Bug Fixes The commit fixes a logic flaw in
`clocksource_verify_choose_cpus()` in
`/home/sasha/linux/kernel/time/clocksource.c:309`. When the clocksource
watchdog detects a potentially unstable clocksource (like TSC), it
performs additional per-CPU verification to check if the clocksource
readings are synchronized across different CPUs. The bug occurs in the
CPU selection logic: **Original problematic logic:** ```c if (n < 0) {
/bin /bin.usr-is-merged /boot /dev /etc /home /init /lib /lib.usr-is-
merged /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin
/sbin.usr-is-merged /snap /srv /sys /tmp /usr /var Check all of the
CPUs. model/ prompt/ src/ target/ cpumask_copy(&cpus_chosen,
cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
return; } ``` **Fixed logic:** ```c if (n < 0 || n >= num_online_cpus())
{ /bin /bin.usr-is-merged /boot /dev /etc /home /init /lib /lib.usr-is-
merged /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin
/sbin.usr-is-merged /snap /srv /sys /tmp /usr /var Check all of the
CPUs. model/ prompt/ src/ target/ cpumask_copy(&cpus_chosen,
cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
return; } ``` ## The Problem When `verify_n_cpus` (default value 8) is
greater than `num_online_cpus()`, the code would fall through to the
random CPU selection logic, which has a critical flaw: it can select the
same CPU multiple times due to the random nature of
`get_random_u32_below()`. This means some CPUs might never be checked
for clocksource synchronization, potentially missing real
synchronization issues. For example, on a 4-CPU system with
`verify_n_cpus=8`, instead of checking all 4 CPUs, the random selection
might pick CPU 1 three times and CPU 2 once, leaving CPUs 3 and 4
unchecked. ## Why This Should Be Backported 1. **Fixes a Real Bug**:
This addresses an actual functional issue where clocksource verification
might miss CPUs, potentially failing to detect real synchronization
problems. 2. **Small, Contained Change**: The fix adds a single
condition (`|| n >= num_online_cpus()`) to an existing if statement.
This is minimal and low-risk. 3. **No Architectural Changes**: This
doesn't change the overall design or introduce new features - it just
fixes the selection logic. 4. **Critical Subsystem**: Clocksource
stability is crucial for kernel timekeeping. Missing synchronization
issues could lead to time-related bugs. 5. **Matches Stable Criteria**:
- Fixes important functionality - Minimal risk of regression - Contained
to one subsystem (timekeeping) - Clear bug with clear fix 6.
**Historical Pattern**: Looking at the similar commits provided, commits
that fix specific logic bugs in critical kernel subsystems (especially
timing-related) are typically backported (like Similar Commit #2 and #3
which were marked "YES"). ## Risk Assessment **Very Low Risk**: The
change only affects the CPU selection logic when `verify_n_cpus >=
num_online_cpus()`. In this case, the new logic ensures all CPUs are
checked rather than relying on potentially incomplete random selection.
This is strictly an improvement with no downside. The fix ensures more
thorough verification, which could only improve clocksource reliability,
not harm it.

 kernel/time/clocksource.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 2a7802ec480cc..7831827d5af52 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -310,7 +310,7 @@ static void clocksource_verify_choose_cpus(void)
 {
 	int cpu, i, n = verify_n_cpus;
 
-	if (n < 0) {
+	if (n < 0 || n >= num_online_cpus()) {
 		/* Check all of the CPUs. */
 		cpumask_copy(&cpus_chosen, cpu_online_mask);
 		cpumask_clear_cpu(smp_processor_id(), &cpus_chosen);
-- 
2.39.5


  parent reply	other threads:[~2025-05-30 12:39 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-30 12:39 [PATCH AUTOSEL 6.14 01/28] ACPICA: fix acpi operand cache leak in dswstate.c Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 02/28] ASoC: amd: yc: Add quirk for Lenovo Yoga Pro 7 14ASP9 Sasha Levin
2025-05-30 12:39 ` Sasha Levin [this message]
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 04/28] power: supply: gpio-charger: Fix wakeup source leaks on device unbind Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 05/28] tools/nolibc: use intmax definitions from compiler Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 06/28] power: supply: collie: Fix wakeup source leaks on device unbind Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 07/28] mmc: Add quirk to disable DDR50 tuning Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 08/28] ACPICA: Avoid sequence overread in call to strncmp() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 09/28] mmc: sdhci-esdhc-imx: Save tuning value when card stays powered in suspend Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 10/28] EDAC/igen6: Skip absent memory controllers Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 11/28] ASoC: tas2770: Power cycle amp on ISENSE/VSENSE change Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 12/28] ASoC: intel/sdw_utils: Assign initial value in asoc_sdw_rt_amp_spk_rtd_init() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 13/28] ACPI: bus: Bail out if acpi_kobj registration fails Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 14/28] ACPI: Add missing prototype for non CONFIG_SUSPEND/CONFIG_X86 case Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 15/28] ACPICA: fix acpi parse and parseext cache leaks Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 16/28] ACPICA: Apply pack(1) to union aml_resource Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 17/28] ALSA: hda: cs35l41: Fix swapped l/r audio channels for Acer Helios laptops Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 18/28] power: supply: bq27xxx: Retrieve again when busy Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 19/28] pmdomain: core: Reset genpd->states to avoid freeing invalid data Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 20/28] ACPICA: utilities: Fix overflow check in vsnprintf() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 21/28] platform-msi: Add msi_remove_device_irq_domain() in platform_device_msi_free_irqs_all() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 22/28] ASoC: tegra210_ahub: Add check to of_device_get_match_data() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 23/28] Make 'cc-option' work correctly for the -Wno-xyzzy pattern Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 24/28] gpiolib: of: Add polarity quirk for s5m8767 Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 25/28] PM: runtime: fix denying of auto suspend in pm_suspend_timer_fn() Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 26/28] tools/nolibc: use pselect6_time64 if available Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 27/28] power: supply: max17040: adjust thermal channel scaling Sasha Levin
2025-05-30 12:39 ` [PATCH AUTOSEL 6.14 28/28] ACPI: battery: negate current when discharging Sasha Levin

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=20250530123934.2574748-3-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=cascardo@igalia.com \
    --cc=gpiccoli@igalia.com \
    --cc=john.stultz@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=paulmck@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).