From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 474291EDA0E for ; Tue, 9 Dec 2025 13:07:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.92.199 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765285631; cv=none; b=ahT7VHklLZVn8Mbgn8bZqnsDxHX0nQ9In5AjYyuYz1XFNo1Z+a6YRNka5if2buXhQvE9w4gkKqESfEOhwKnR0ojCSZoAwqL+9zofmA9eRK/ZkvCPiNWOrO3PFi7Pr1rZ2+QU438fzsTY5sCKzgf/LcSB1znw+aru3YDyMmoCsjY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765285631; c=relaxed/simple; bh=V9SYceCk/MU4Qt7Bpgs4BBdgBXhqLq8G8iW7RA/xJiE=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=fLHNY3NgoSTa6we7XY+sz0R2jwYDiy9A2Gazu5aIeHtmXRnfzbJSIvxMfUmOgqHk+5C48CQUSR+70P9z+pQpUSpMZWrgfDLV26f5mIRIeWm4uldvrlmLRDw5WOAEuDMEiMekRQVQUbhwDkZn13vYbiZwk8gYE2HP4z0aAF5cTx0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=lFCijdJ3; arc=none smtp.client-ip=90.155.92.199 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="lFCijdJ3" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=ZqkcMJ1H8I0z3yhv2a7IWRoxLTllMw4GadjtwWUFsoA=; b=lFCijdJ3F7KqFNjPAqMaRZPDyt 5SvptvwzUXQIVN90VKtwF/vHdmruKMF6n2SzjSVJT+Td+DG/gNdJyoRwNXLx4uO/NDcTjjmCvvN2+ FYX/bR/XpC8pgjvgc2mzq+AGN/O+R22DjFuHrSoRe9zhgq5v6s9AGpxPjzdM7G14/A6UtjtXU75oH dS7aOjnCa6VqoArxzxWeKUPsqRUA5Z//ruWzw+TagJ77msPHwHVdnamsQBxldHquWawCqsJ1U3NE6 noinBaRHlqlo104BnNVIegTTkSBGHLQ10alNHyVv2w99OKjbUhjSSiU0TLE4dDPfSZLb8ej8QBQfp Aymw/8ng==; Received: from 77-249-17-252.cable.dynamic.v4.ziggo.nl ([77.249.17.252] helo=noisy.programming.kicks-ass.net) by desiato.infradead.org with esmtpsa (Exim 4.98.2 #2 (Red Hat Linux)) id 1vSwYi-0000000Bmsy-2USK; Tue, 09 Dec 2025 12:11:12 +0000 Received: by noisy.programming.kicks-ass.net (Postfix, from userid 1000) id 75E8A30045C; Tue, 09 Dec 2025 14:06:29 +0100 (CET) Date: Tue, 9 Dec 2025 14:06:29 +0100 From: Peter Zijlstra To: Tim Chen Cc: Ingo Molnar , K Prateek Nayak , "Gautham R . Shenoy" , Vincent Guittot , Juri Lelli , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , Madadi Vineeth Reddy , Hillf Danton , Shrikanth Hegde , Jianyong Wu , Yangyu Chen , Tingyin Duan , Vern Hao , Vern Hao , Len Brown , Aubrey Li , Zhao Liu , Chen Yu , Chen Yu , Adam Li , Aaron Lu , Tim Chen , linux-kernel@vger.kernel.org Subject: Re: [PATCH v2 07/23] sched/cache: Introduce per runqueue task LLC preference counter Message-ID: <20251209130629.GO3707891@noisy.programming.kicks-ass.net> References: <63091f7ca7bb473fbc176af86a87d27a07a6e149.1764801860.git.tim.c.chen@linux.intel.com> 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=us-ascii Content-Disposition: inline In-Reply-To: <63091f7ca7bb473fbc176af86a87d27a07a6e149.1764801860.git.tim.c.chen@linux.intel.com> On Wed, Dec 03, 2025 at 03:07:26PM -0800, Tim Chen wrote: > +#ifdef CONFIG_SCHED_CACHE > + > +static unsigned int *alloc_new_pref_llcs(unsigned int *old, unsigned int **gc) > +{ > + unsigned int *new = NULL; > + > + new = kcalloc(new_max_llcs, sizeof(unsigned int), > + GFP_KERNEL | __GFP_NOWARN); > + > + if (!new) { > + *gc = NULL; > + } else { > + /* > + * Place old entry in garbage collector > + * for later disposal. > + */ > + *gc = old; > + } > + return new; > +} > + > +static void populate_new_pref_llcs(unsigned int *old, unsigned int *new) > +{ > + int i; > + > + if (!old) > + return; > + > + for (i = 0; i < max_llcs; i++) > + new[i] = old[i]; > +} > + > +static int resize_llc_pref(void) > +{ > + unsigned int *__percpu *tmp_llc_pref; > + int i, ret = 0; > + > + if (new_max_llcs <= max_llcs) > + return 0; > + > + /* > + * Allocate temp percpu pointer for old llc_pref, > + * which will be released after switching to the > + * new buffer. > + */ > + tmp_llc_pref = alloc_percpu_noprof(unsigned int *); > + if (!tmp_llc_pref) > + return -ENOMEM; > + > + for_each_present_cpu(i) > + *per_cpu_ptr(tmp_llc_pref, i) = NULL; > + > + /* > + * Resize the per rq nr_pref_llc buffer and > + * switch to this new buffer. > + */ > + for_each_present_cpu(i) { > + struct rq_flags rf; > + unsigned int *new; > + struct rq *rq; > + > + rq = cpu_rq(i); > + new = alloc_new_pref_llcs(rq->nr_pref_llc, per_cpu_ptr(tmp_llc_pref, i)); > + if (!new) { > + ret = -ENOMEM; > + > + goto release_old; > + } > + > + /* > + * Locking rq ensures that rq->nr_pref_llc values > + * don't change with new task enqueue/dequeue > + * when we repopulate the newly enlarged array. > + */ guard(rq_lock_irq)(rq); Notably, this cannot be with IRQs disabled, as you're doing allocations. > + rq_lock_irqsave(rq, &rf); > + populate_new_pref_llcs(rq->nr_pref_llc, new); > + rq->nr_pref_llc = new; > + rq_unlock_irqrestore(rq, &rf); > + } > + > +release_old: > + /* > + * Load balance is done under rcu_lock. > + * Wait for load balance before and during resizing to > + * be done. They may refer to old nr_pref_llc[] > + * that hasn't been resized. > + */ > + synchronize_rcu(); > + for_each_present_cpu(i) > + kfree(*per_cpu_ptr(tmp_llc_pref, i)); > + > + free_percpu(tmp_llc_pref); > + > + /* succeed and update */ > + if (!ret) > + max_llcs = new_max_llcs; > + > + return ret; > +} I think you need at least cpus_read_lock(), because present_cpu is dynamic -- but I'm not quite sure what lock is used to serialize it.