From nobody Mon Apr 6 13:28:23 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2824BC54EE9 for ; Tue, 27 Sep 2022 16:02:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232950AbiI0QCn (ORCPT ); Tue, 27 Sep 2022 12:02:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41252 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232294AbiI0QBo (ORCPT ); Tue, 27 Sep 2022 12:01:44 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DEBD3B71B for ; Tue, 27 Sep 2022 09:01:42 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1120BB81C5C for ; Tue, 27 Sep 2022 16:01:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BFCFEC433D6; Tue, 27 Sep 2022 16:01:39 +0000 (UTC) Received: from rostedt by gandalf.local.home with local (Exim 4.96) (envelope-from ) id 1odD2o-00G2wK-12; Tue, 27 Sep 2022 12:02:50 -0400 Message-ID: <20220927160249.931823392@goodmis.org> User-Agent: quilt/0.66 Date: Tue, 27 Sep 2022 12:02:32 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Daniel Bristot de Oliveira , Peter Zijlstra , Ingo Molnar , Will Deacon , Boqun Feng , stable@vger.kerne.org, Waiman Long Subject: [for-next][PATCH 16/20] tracing: Disable interrupt or preemption before acquiring arch_spinlock_t References: <20220927160216.349640304@goodmis.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Waiman Long It was found that some tracing functions in kernel/trace/trace.c acquire an arch_spinlock_t with preemption and irqs enabled. An example is the tracing_saved_cmdlines_size_read() function which intermittently causes a "BUG: using smp_processor_id() in preemptible" warning when the LTP read_all_proc test is run. That can be problematic in case preemption happens after acquiring the lock. Add the necessary preemption or interrupt disabling code in the appropriate places before acquiring an arch_spinlock_t. The convention here is to disable preemption for trace_cmdline_lock and interupt for max_lock. Link: https://lkml.kernel.org/r/20220922145622.1744826-1-longman@redhat.com Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Will Deacon Cc: Boqun Feng Cc: stable@vger.kerne.org Fixes: a35873a0993b ("tracing: Add conditional snapshot") Fixes: 939c7a4f04fc ("tracing: Introduce saved_cmdlines_size file") Suggested-by: Steven Rostedt Signed-off-by: Waiman Long Signed-off-by: Steven Rostedt (Google) --- kernel/trace/trace.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d3005279165d..aed7ea6e6045 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1193,12 +1193,14 @@ void *tracing_cond_snapshot_data(struct trace_array= *tr) { void *cond_data =3D NULL; =20 + local_irq_disable(); arch_spin_lock(&tr->max_lock); =20 if (tr->cond_snapshot) cond_data =3D tr->cond_snapshot->cond_data; =20 arch_spin_unlock(&tr->max_lock); + local_irq_enable(); =20 return cond_data; } @@ -1334,9 +1336,11 @@ int tracing_snapshot_cond_enable(struct trace_array = *tr, void *cond_data, goto fail_unlock; } =20 + local_irq_disable(); arch_spin_lock(&tr->max_lock); tr->cond_snapshot =3D cond_snapshot; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); =20 mutex_unlock(&trace_types_lock); =20 @@ -1363,6 +1367,7 @@ int tracing_snapshot_cond_disable(struct trace_array = *tr) { int ret =3D 0; =20 + local_irq_disable(); arch_spin_lock(&tr->max_lock); =20 if (!tr->cond_snapshot) @@ -1373,6 +1378,7 @@ int tracing_snapshot_cond_disable(struct trace_array = *tr) } =20 arch_spin_unlock(&tr->max_lock); + local_irq_enable(); =20 return ret; } @@ -2200,6 +2206,11 @@ static size_t tgid_map_max; =20 #define SAVED_CMDLINES_DEFAULT 128 #define NO_CMDLINE_MAP UINT_MAX +/* + * Preemption must be disabled before acquiring trace_cmdline_lock. + * The various trace_arrays' max_lock must be acquired in a context + * where interrupt is disabled. + */ static arch_spinlock_t trace_cmdline_lock =3D __ARCH_SPIN_LOCK_UNLOCKED; struct saved_cmdlines_buffer { unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; @@ -2412,7 +2423,11 @@ static int trace_save_cmdline(struct task_struct *ts= k) * the lock, but we also don't want to spin * nor do we want to disable interrupts, * so if we miss here, then better luck next time. + * + * This is called within the scheduler and wake up, so interrupts + * had better been disabled and run queue lock been held. */ + lockdep_assert_preemption_disabled(); if (!arch_spin_trylock(&trace_cmdline_lock)) return 0; =20 @@ -5890,9 +5905,11 @@ tracing_saved_cmdlines_size_read(struct file *filp, = char __user *ubuf, char buf[64]; int r; =20 + preempt_disable(); arch_spin_lock(&trace_cmdline_lock); r =3D scnprintf(buf, sizeof(buf), "%u\n", savedcmd->cmdline_num); arch_spin_unlock(&trace_cmdline_lock); + preempt_enable(); =20 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); } @@ -5917,10 +5934,12 @@ static int tracing_resize_saved_cmdlines(unsigned i= nt val) return -ENOMEM; } =20 + preempt_disable(); arch_spin_lock(&trace_cmdline_lock); savedcmd_temp =3D savedcmd; savedcmd =3D s; arch_spin_unlock(&trace_cmdline_lock); + preempt_enable(); free_saved_cmdlines_buffer(savedcmd_temp); =20 return 0; @@ -6373,10 +6392,12 @@ int tracing_set_tracer(struct trace_array *tr, cons= t char *buf) =20 #ifdef CONFIG_TRACER_SNAPSHOT if (t->use_max_tr) { + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (tr->cond_snapshot) ret =3D -EBUSY; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); if (ret) goto out; } @@ -7436,10 +7457,12 @@ tracing_snapshot_write(struct file *filp, const cha= r __user *ubuf, size_t cnt, goto out; } =20 + local_irq_disable(); arch_spin_lock(&tr->max_lock); if (tr->cond_snapshot) ret =3D -EBUSY; arch_spin_unlock(&tr->max_lock); + local_irq_enable(); if (ret) goto out; =20 --=20 2.35.1