From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (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 E95731E9B3A for ; Fri, 12 Jun 2026 04:27:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781238476; cv=none; b=mCgH9gUPojz2413eYmNm49MrsZEoeVEDI893ym8GLBcVvcoG2Z34IrMuV75StZ/PvDdEawVeeRb/0kSTA8DeaZll2AQhSA5TEY1uoOegfCldvr7FCuhRv1fHmo0eZvW/r4HKUSo/Bsz6RQ/KD/oi+UQzEIDdUbO7LESgpXBXGdA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781238476; c=relaxed/simple; bh=tPE3nbHwsuKt1FPdulBZsdYEALlqURBhFco6+BXHU2I=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=RO1uBVLXkqa2Q1mK32LW7/81d5GQaq2SVuwhLVzSc1LfGoGO4gfVbq41yrf0sOcJ42ZgQkfF6JoEAwFA9UMvLazLPkx5U1cVTsJZ53mj2peAJfYv3hmvBpITEA+KD14yp9jghVlQE7KiyYpRN8uj1Ahb4hzLU/1KXafnVaGqsac= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=Ouhm2PHh; arc=none smtp.client-ip=91.218.175.189 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="Ouhm2PHh" Message-ID: <352cd63b-0936-4723-ac90-f6428a3a1151@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1781238471; 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=RXz0zFjpsEGPITqy3FGqx/I8SNzd+JfjTXLop8dMmx8=; b=Ouhm2PHhrdEY1E3B7QIa38fjSbI+7kD5xWfm1K8C8CpcM+1WdHTP5o8iINqQjIaKQj8TyG ilk2AEhZy1QWiDPuv/yWvmMz0PQymnb28Pdqvbr1QavYTPhmzEunrj8HzWO+ap6OZJ0nw+ aoEZssz5b+qYj+sz0ErHetUXU8lAq8s= Date: Fri, 12 Jun 2026 12:27:42 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH RFC] mm/kmemleak: avoid soft lockup when scanning task stacks Content-Language: en-US To: leitao@debian.org Cc: catalin.marinas@arm.com, akpm@linux-foundation.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, kernel-team@meta.com, sj@kernel.org References: <20260611-kmemleak-stack-resched-v1-1-d6248ade5f4a@debian.org> <20260612031605.58235-1-lance.yang@linux.dev> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Lance Yang In-Reply-To: <20260612031605.58235-1-lance.yang@linux.dev> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT On 2026/6/12 11:16, Lance Yang wrote: > > On Thu, Jun 11, 2026 at 05:45:00AM -0700, Breno Leitao wrote: >> kmemleak_scan() walks every thread and scans its kernel stack under a >> single rcu_read_lock() with no reschedule point. On a host with very >> many threads -- amplified by KASAN/lockdep in debug builds -- this loop >> can hog a CPU long enough to trip the soft lockup watchdog: >> >> watchdog: BUG: soft lockup - CPU#35 stuck for 22s! [kmemleak:537] >> scan_block >> kmemleak_scan >> kmemleak_scan_thread >> kthread > > Neat, good catch! > >> A cond_resched() cannot be added directly: the loop runs inside an RCU >> read-side critical section. >> >> Split the scan in two parts: >> >> 1) get the list of tasks (with RCU read lock) in an array >> 2) run scan_block() for the tasks (with cond_reschd()). >> >> Is it a sane approach? > > Why not use the kernel/hung_task.c pattern here? Seems simpler, with no > extra task-array allocation ;) > >> Signed-off-by: Breno Leitao Probably wants a Fixes: tag and stable Cc too, no? >> --- > > Could break RCU only when resched is needed. Pin the current cursors, > drop RCU, cond_resched(), take RCU again, and continue only if the > cursors are still alive ;) > > If either cursor died while RCU was droped, stopping this scan round > should be fine, IMHO. > > ---8<--- > diff --git a/mm/kmemleak.c b/mm/kmemleak.c > index 7c7ba17ce7af..1062d9545054 100644 > --- a/mm/kmemleak.c > +++ b/mm/kmemleak.c > @@ -1695,6 +1695,26 @@ static void kmemleak_cond_resched(struct kmemleak_object *object) > put_object(object); > } > > +static bool kmemleak_stack_scan_break(struct task_struct *g, > + struct task_struct *p) > +{ > + bool can_cont; > + > + get_task_struct(g); > + get_task_struct(p); > + > + rcu_read_unlock(); > + cond_resched(); > + rcu_read_lock(); > + > + can_cont = pid_alive(g) && pid_alive(p); > + > + put_task_struct(p); > + put_task_struct(g); > + > + return can_cont; > +} > + > /* > * Print one leak inline. The hex dump is gated on OBJECT_ALLOCATED so it > * does not touch user memory that was freed concurrently; the rest of the > @@ -1894,7 +1914,10 @@ static void kmemleak_scan(void) > scan_block(stack, stack + THREAD_SIZE, NULL); > put_task_stack(p); > } > + if (need_resched() && !kmemleak_stack_scan_break(g, p)) > + goto unlock; > } > +unlock: > rcu_read_unlock(); > } > --- > > Not tested, though, feel free to grab it if looks sane :) > > [...] > > Cheers, Lance