From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (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 9C8953C197E for ; Mon, 10 Aug 2026 11:31:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786361479; cv=none; b=RY3TbVqWztzOo6RPFgzsqNZBgCwJKJWSL4sD6xV25am0IBt8CXoRhSBkBSRuGX+9q45O7dzxUzQUO9EfZy9ZZpNA+41cp3VXMdE/jBFh9eGmU/+eqkemxCpaiLHORaJt5DfLuMczIvmGNiuUQMpUvuEXC03S5pmFk1ng364ymHM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786361479; c=relaxed/simple; bh=ZLFHzsTzu0vgm8YRib6oX/5dJRrmsdclFpM3jyMEPwE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Kwmd3JgOT1o8PT6z2L/Cbxn60wDXtbDKeLQcW5Psb0YV8pyTg4RX9P8dg6fKeCQQT2Ry5e+VpyoNTT+Ydhc3qjsALbviAODo23y/QKGpCsh09gTHeHNLj528GvdgJpVVr/QenR46CAP1TZb6fqRMiugceBee9qDlFrYQ4IZ3gtA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org; spf=pass smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=RYlPkncc; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="RYlPkncc" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=H+dKeUvpI1Nc29+6fm2OUGnH7BUfm7XFw0QlxPVxFpc=; b=RYlPknccucYC579350n+kZTGy6 8pKpZph4KoE2n98uNeXKR6mfYbgf/Xs0n2Qwka+psJE7h8hlnogG7rPhGWk4nm42LoPIOdr+wDVFT UpSff/1Q272mpY37Af6OqB2vm3YbzezPbSzeuuatDNS/dAPdUaEH5EfCOKqhQNQzoC/6Eivkpwh+k 9w9w3rPxH3G0X/2Dm+ur7F5+US9H0xKi2DEr4C5ZoQ5+C1FyxdQuL/wSl51dp1/2dh+lWV6v7oZy6 SyTjCBhwJiHKkS7NBdyzyrPQTErCccFvf6THok+tkPzrVKU6rF1z2syLNYK6oSy2Gom9AZwhm/m9P q0BiiIpw==; Received: from authenticated-user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wtODo-002iey-1k; Mon, 10 Aug 2026 11:31:13 +0000 From: Breno Leitao Date: Mon, 10 Aug 2026 04:29:24 -0700 Subject: [PATCH v2 1/3] locking/csd-lock: Pack csd_lock_wait_toolong() state into a struct 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: 7bit Message-Id: <20260810-csd-stall-duration-v2-1-795083bf04a4@debian.org> References: <20260810-csd-stall-duration-v2-0-795083bf04a4@debian.org> In-Reply-To: <20260810-csd-stall-duration-v2-0-795083bf04a4@debian.org> To: paulmck@kernel.org, Andrew Morton , d@ilvokhin.com Cc: linux-kernel@vger.kernel.org, Peter Zijlstra , Ingo Molnar , Sebastian Andrzej Siewior , linux-kernel@vger.kernel.org, kernel-team@meta.com, Thomas Gleixner , Breno Leitao X-Mailer: b4 0.16-dev-f8e9d X-Developer-Signature: v=1; a=openpgp-sha256; l=6140; i=leitao@debian.org; h=from:subject:message-id; bh=ZLFHzsTzu0vgm8YRib6oX/5dJRrmsdclFpM3jyMEPwE=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBqebZxtjjFaEdmihQkr2b6XVVrWLDmlJI8ssC7f WhTUvAArTKJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCanm2cQAKCRA1o5Of/Hh3 bQ0bD/0fgZrOZ0dJw5IqCjQbYyFtgYxeduecvCnI9zzQf4EgJ6TUSZCtfODKg7vdQe20jROZ6pS cz1WNYZLef5iRH+SrbeNi1/bAlYli3VAREYyU1THUo+LrSVm4/Kb4Ms2hvJFq0H2V2CWLp/QC25 RHB1EHAuGUmOAIsQ7ic3XcPPce39hGGwytnJ/WmKww18BFrzmzPf7TgvmE0NIA49zkzSph85ZUX MWG2Y/VPDmv6Vs+gNpceczpjVYB2580tGAlCA8SfaOkpY8VuRAe/2WIWDGJQ+y9dYCPnigN8ba/ UBWtGDHT7DVq2fGZSEeJzxclTl7ZzCdZ23hmkj0a0Fm5cWAGYOoM6YM6NdTgy6Gq2kTq1hpuA3T SCgBt3vceLe5IlYsjtRda35Fc8YA4tHOvPfZ3yphDLnWtxICg2qsQFIRaOj9wO4XUC8nMV7B74c 2GYJze11XnBTgqfzHTUfJ92XyMXkNCHU0XzJO9iED9GMfTOVB4M+gvMyTKU3AuLtDj0hWTNqwNC pO5pvMHkzG0+SUjqmlFzo5CKJkTrh9wO8DtjrI0LxF/AGOkQHwhhWoH3n2AHTmmvH7sfztJCgci S9lPEeBK7ITrWW6StwEiKSbYb53xyQX8UZBFU7bB3dHPW7l/G6h+nLcNhiZwwv71NTxwApsN5yh 9A/xaNF45VRaoig== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao csd_lock_wait_toolong() has some fields and they are being expanded now, separate them into a structure, that can be easily digestible. This simplify the function aslo, given the fields were passed by reference, and the ts0/ts1 names say nothing about what the two timestamps hold. Pack them into struct csd_wait_state and name the timestamps for what they store, ts_start and ts_report. The local ts2 becomes ts_now. Reporting a further timestamp, such as next patch, then costs a struct member rather than another argument. No functional change. Suggested-by: Dmitry Ilvokhin Signed-off-by: Breno Leitao --- kernel/smp.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/kernel/smp.c b/kernel/smp.c index 52dffc86555cd..e00b8f620c5d9 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -223,50 +223,58 @@ bool csd_lock_is_stuck(void) return !!atomic_read(&n_csd_lock_stuck); } +/* State that csd_lock_wait_toolong() carries across the __csd_lock_wait() loop. */ +struct csd_wait_state { + u64 ts_start; /* When the wait began. */ + u64 ts_report; /* When the last complaint was printed. */ + int bug_id; + unsigned long nmessages; +}; + /* * Complain if too much time spent waiting. Note that only * the CSD_TYPE_SYNC/ASYNC types provide the destination CPU, * so waiting on other types gets much less information. */ -static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, int *bug_id, unsigned long *nmessages) +static bool csd_lock_wait_toolong(call_single_data_t *csd, struct csd_wait_state *state) { int cpu = -1; int cpux; bool firsttime; - u64 ts2, ts_delta; + u64 ts_now, ts_delta; call_single_data_t *cpu_cur_csd; unsigned int flags = READ_ONCE(csd->node.u_flags); unsigned long long csd_lock_timeout_ns = csd_lock_timeout * NSEC_PER_MSEC; if (!(flags & CSD_FLAG_LOCK)) { - if (!unlikely(*bug_id)) + if (!unlikely(state->bug_id)) return true; cpu = csd_lock_wait_getcpu(csd); pr_alert("csd: CSD lock (#%d) got unstuck on CPU#%02d, CPU#%02d released the lock.\n", - *bug_id, raw_smp_processor_id(), cpu); + state->bug_id, raw_smp_processor_id(), cpu); atomic_dec(&n_csd_lock_stuck); return true; } - ts2 = ktime_get_mono_fast_ns(); + ts_now = ktime_get_mono_fast_ns(); /* How long since we last checked for a stuck CSD lock.*/ - ts_delta = ts2 - *ts1; - if (likely(ts_delta <= csd_lock_timeout_ns * (*nmessages + 1) * - (!*nmessages ? 1 : (ilog2(num_online_cpus()) / 2 + 1)) || + ts_delta = ts_now - state->ts_report; + if (likely(ts_delta <= csd_lock_timeout_ns * (state->nmessages + 1) * + (!state->nmessages ? 1 : (ilog2(num_online_cpus()) / 2 + 1)) || csd_lock_timeout_ns == 0)) return false; - if (ts0 > ts2) { + if (state->ts_start > ts_now) { /* Our own sched_clock went backward; don't blame another CPU. */ - ts_delta = ts0 - ts2; + ts_delta = state->ts_start - ts_now; pr_alert("sched_clock on CPU %d went backward by %llu ns\n", raw_smp_processor_id(), ts_delta); - *ts1 = ts2; + state->ts_report = ts_now; return false; } - firsttime = !*bug_id; + firsttime = !state->bug_id; if (firsttime) - *bug_id = atomic_inc_return(&csd_bug_count); + state->bug_id = atomic_inc_return(&csd_bug_count); cpu = csd_lock_wait_getcpu(csd); if (WARN_ONCE(cpu < 0 || cpu >= nr_cpu_ids, "%s: cpu = %d\n", __func__, cpu)) cpux = 0; @@ -274,11 +282,11 @@ static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, in cpux = cpu; cpu_cur_csd = smp_load_acquire(&per_cpu(cur_csd, cpux)); /* Before func and info. */ /* How long since this CSD lock was stuck. */ - ts_delta = ts2 - ts0; + ts_delta = ts_now - state->ts_start; pr_alert("csd: %s non-responsive CSD lock (#%d) on CPU#%d, waiting %lld ns for CPU#%02d %pS(%ps).\n", - firsttime ? "Detected" : "Continued", *bug_id, raw_smp_processor_id(), (s64)ts_delta, + firsttime ? "Detected" : "Continued", state->bug_id, raw_smp_processor_id(), (s64)ts_delta, cpu, csd->func, csd->info); - (*nmessages)++; + state->nmessages++; if (firsttime) atomic_inc(&n_csd_lock_stuck); /* @@ -289,23 +297,23 @@ static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, in BUG_ON(panic_on_ipistall > 0 && (s64)ts_delta > ((s64)panic_on_ipistall * NSEC_PER_MSEC)); if (cpu_cur_csd && csd != cpu_cur_csd) { pr_alert("\tcsd: CSD lock (#%d) handling prior %pS(%ps) request.\n", - *bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)), + state->bug_id, READ_ONCE(per_cpu(cur_csd_func, cpux)), READ_ONCE(per_cpu(cur_csd_info, cpux))); } else { pr_alert("\tcsd: CSD lock (#%d) %s.\n", - *bug_id, !cpu_cur_csd ? "unresponsive" : "handling this request"); + state->bug_id, !cpu_cur_csd ? "unresponsive" : "handling this request"); } if (cpu >= 0) { if (atomic_cmpxchg_acquire(&per_cpu(trigger_backtrace, cpu), 1, 0)) dump_cpu_task(cpu); if (!cpu_cur_csd) { - pr_alert("csd: Re-sending CSD lock (#%d) IPI from CPU#%02d to CPU#%02d\n", *bug_id, raw_smp_processor_id(), cpu); + pr_alert("csd: Re-sending CSD lock (#%d) IPI from CPU#%02d to CPU#%02d\n", state->bug_id, raw_smp_processor_id(), cpu); arch_send_call_function_single_ipi(cpu); } } if (firsttime) dump_stack(); - *ts1 = ts2; + state->ts_report = ts_now; return false; } @@ -319,13 +327,11 @@ static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, in */ static void __csd_lock_wait(call_single_data_t *csd) { - unsigned long nmessages = 0; - int bug_id = 0; - u64 ts0, ts1; + struct csd_wait_state state = {}; - ts1 = ts0 = ktime_get_mono_fast_ns(); + state.ts_report = state.ts_start = ktime_get_mono_fast_ns(); for (;;) { - if (csd_lock_wait_toolong(csd, ts0, &ts1, &bug_id, &nmessages)) + if (csd_lock_wait_toolong(csd, &state)) break; cpu_relax(); } -- 2.53.0-Meta