From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f172.google.com (mail-yw1-f172.google.com [209.85.128.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA860188A3A for ; Fri, 12 Dec 2025 21:03:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765573396; cv=none; b=R2cWPK5R+c54LNXtSQdCzf2rpJd/C/jkeLt8fLRVfeigBQUiJHbZByhLJ2mnVWMorkLav2/92hjSHBaqclEXajAVV97e1rlEMRBK5pdT49WXIYfmuzoNYhOGHq7nlwVYox5cgKkpbEe6v6ZUiunEZ/ibyoL9UMVroUyNi+171uk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765573396; c=relaxed/simple; bh=PXFdaGhtRLTbSQCIx8oGavKtLWApnRaV5VDybWFf3/k=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=CXDXW0Py8yRVlknQYfwLnDKKZDQO4jk0XrZqy5T1Ywoxh1juvgnlbBrm06XYF8Ok2d4MwzteXtmzhIev3g/D/MLhi4lbkpG2qRZcicaGkbDF4rtn5aVJWsc1ME2su8UkkoM7GD8wGbWQTzrMH1nz0I1hFzF6lkJHkci6s6RCOnU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ix7/60eW; arc=none smtp.client-ip=209.85.128.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ix7/60eW" Received: by mail-yw1-f172.google.com with SMTP id 00721157ae682-78c696717dbso16845047b3.1 for ; Fri, 12 Dec 2025 13:03:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765573394; x=1766178194; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=OlakO7PCpeQf96QoYwYxYf6sV3eLgUSgxVFM7UINzn8=; b=Ix7/60eW6Wz7KmtS/uZRc28qncc0/T2JbvfklTBFmwiDBJe21ppGDOMzeOlPk+I65S eGFzUXqrh86DjfAv5p/VtgBpVDID4fGNWaTDyP1o9ub3qubC7OSCTKuBPXh2vcABe/Y8 gXIy3ec3CIkFbnbGjlsQrpqp0fuSLZjXtxhZcDuV2GJefZyB48wtQqb13Ct7YTIvs7mH ZeYW+1e9/F3iwaSgGJfj/oLEtaLZGNYz7S2iJcSqs1n6h2oaoEIkllwB2W1qor3vR0S3 zI0YRmabKMWz7gJV3iSs6tWi7xcVEltxi83OWrlPFrUYR29DwYnSRFXCBD0cxS7KMxPe LTDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765573394; x=1766178194; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OlakO7PCpeQf96QoYwYxYf6sV3eLgUSgxVFM7UINzn8=; b=FSi2nHD1nJ2w2X0CB3Zxs0ChwYahu5jYoKICtyfYYih5vQPAwg4NOpYQHre5U44OOH /4jqYDVi6oq0As/EQJxbBCU77xSrZhbbzrCsdKgFte37lASe+meRsdfL+XFbPqTcqMn6 IfhUo8EsgnzT6H1eBU/AXovEVOhD0FU7Ol4pqTanP0yDXOWyc5fB51n+QiwCS6fos96h pNnviwhG+AnBZM+eBVCKttMBc50MJKBU5HhjSj/risvWDtpkDtnuQrkPyoK5FJRoAm87 6roWyR2N4fdBjwVEnsLEkwTvnZKb79dn9wXZgkuNAjcsPXBdbmvoZ9g8vSnSWKRLJ5MR TQ+Q== X-Forwarded-Encrypted: i=1; AJvYcCUXBxiIfYJ21RTc/9iuMIb3W0p3ThOyP6aiauUi78HF7EqTqY18UHnyRVI5rKLZtQWTJhF0hl7slVKJ9uI=@vger.kernel.org X-Gm-Message-State: AOJu0Yy/B7VbVzUg5RhxFeBVgG52yQIAzbV2nMxfFYi3S0k00spDZSCA EPvUAPaHfE5t0/IAKiN3cCJMZ7/h7OBPzU4WtTyCCQ+eZu3P6S6OBzNG X-Gm-Gg: AY/fxX7rP0Mzg611MLIDqYVkVqOfcmxoRMjHSNdrH2TrSDqzqA7X4zuQsTCeP2QBjkU GL4rJtbMYZ7SrSnnQrqgBUzdDperCZVIxztcdYNCgZq+KEjLhtSkrGiFUGcdcXf8fWQK7cszDgb TfHmm8Q8QYjAs7EoD7QEW4B7DmD1p6s7DI4a/B85UA0mmxFkriu/L9r+G7Y+BgCcU5rWDESTGg5 rT0C9JMlaRmFmtoAqBX7V22Y8ucuGF0Ri92FkG5q3GuVRja0T2towb9GyGq/arVITRoPgtsevmq 6h1K3sFzmE6aDvVh3yxjuo5oMKVfWVpVrgSyNEV9j3006ZRFpHfcTnub5+vK7nHMcJoIKpmAkPf 5owEWCSLT1xGaJRas8uZzrJMBL6Oerg+HCpmEW7WcG44HRaSV53wmGwp2ElGr9zdYRjD1ZIxxQB xjiXzxYxs= X-Google-Smtp-Source: AGHT+IHVeJmeFKA9T3WU4JIPFXXYhdB5LqT8WaCxdp+hJLRIYHTpNmyh82Aa01B6YH8aTkjq5s6fnA== X-Received: by 2002:a05:690c:6102:b0:786:5789:57c8 with SMTP id 00721157ae682-78e66d504e8mr29884057b3.30.1765573393704; Fri, 12 Dec 2025 13:03:13 -0800 (PST) Received: from localhost ([2601:346:0:79bd:4103:3ec7:acf8:c8aa]) by smtp.gmail.com with ESMTPSA id 00721157ae682-78e748ce551sm399807b3.6.2025.12.12.13.03.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Dec 2025 13:03:13 -0800 (PST) Date: Fri, 12 Dec 2025 16:03:11 -0500 From: Yury Norov To: K Prateek Nayak Cc: Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Anna-Maria Behnsen , Frederic Weisbecker , Thomas Gleixner , linux-kernel@vger.kernel.org, Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , "Gautham R. Shenoy" , Swapnil Sapkal , Shrikanth Hegde , Chen Yu , Rasmus Villemoes Subject: Re: [RESEND RFC PATCH v2 06/29] cpumask: Introduce for_each_cpu_and_wrap() and bitfield helpers Message-ID: References: <20251208083602.31898-1-kprateek.nayak@amd.com> <20251208092744.32737-6-kprateek.nayak@amd.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: <20251208092744.32737-6-kprateek.nayak@amd.com> On Mon, Dec 08, 2025 at 09:26:52AM +0000, K Prateek Nayak wrote: > There is a developing pattern of using cpumask_and() followed by > for_each_cpu_wrap() in the scheduler. > > To avoid a temporary variable and needlessly iterating over the cpumask > twice - once for the cpumask_and() operation and the second in the > for_each_cpu_wrap() loop - introduce a new for_each_cpu_and_wrap() > helper to iterate over the common bits set on two bitfields starting at > a specific position without needing an intermediate cpumask variable. > > Cc: Yury Norov > Cc: Rasmus Villemoes > Signed-off-by: K Prateek Nayak > --- > include/linux/cpumask.h | 20 ++++++++++++++++++++ > include/linux/find.h | 37 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 57 insertions(+) > > diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h > index ff8f41ab7ce6..b7a984c2a7d5 100644 > --- a/include/linux/cpumask.h > +++ b/include/linux/cpumask.h > @@ -406,6 +406,26 @@ unsigned int cpumask_random(const struct cpumask *src) > #define for_each_cpu_and(cpu, mask1, mask2) \ > for_each_and_bit(cpu, cpumask_bits(mask1), cpumask_bits(mask2), small_cpumask_bits) > > +/** > + * for_each_cpu_wrap - iterate over every cpu in both masks, starting at a for_each_cpu_and_wrap With that, Acked-by: Yury Norov (NVIDIA) > + * specified location. > + * @cpu: the (optionally unsigned) integer iterator > + * @mask1: the first cpumask pointer > + * @mask2: the second cpumask pointer > + * @start: the start location > + * > + * This saves a temporary CPU mask in many places. It is equivalent to: > + * struct cpumask tmp; > + * cpumask_and(&tmp, &mask1, &mask2); > + * for_each_cpu_wrap(cpu, &tmp, start) > + * ... > + * > + * After the loop, cpu is >= nr_cpu_ids. > + */ > +#define for_each_cpu_and_wrap(cpu, mask1, mask2, start) \ > + for_each_and_bit_wrap(cpu, cpumask_bits(mask1), cpumask_bits(mask2), \ > + small_cpumask_bits, start) > + > /** > * for_each_cpu_andnot - iterate over every cpu present in one mask, excluding > * those present in another. > diff --git a/include/linux/find.h b/include/linux/find.h > index 9d720ad92bc1..fff9e2d55e4d 100644 > --- a/include/linux/find.h > +++ b/include/linux/find.h > @@ -487,6 +487,29 @@ unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size, > return bit < start ? bit : size; > } > > +/* Helper for for_each_and_bit_wrap(). */ > +static __always_inline > +unsigned long __for_each_and_wrap(const unsigned long *bitmap1, const unsigned long *bitmap2, > + unsigned long size, unsigned long start, unsigned long n) > +{ > + unsigned long bit; > + > + /* If not wrapped around */ > + if (n > start) { > + /* and have a bit, just return it. */ > + bit = find_next_and_bit(bitmap1, bitmap2, size, n); > + if (bit < size) > + return bit; > + > + /* Otherwise, wrap around and ... */ > + n = 0; > + } > + > + /* Search the other part. */ > + bit = find_next_and_bit(bitmap1, bitmap2, start, n); > + return bit < start ? bit : size; > +} > + > /** > * find_next_clump8 - find next 8-bit clump with set bits in a memory region > * @clump: location to store copy of found clump > @@ -682,6 +705,20 @@ unsigned long find_next_bit_le(const void *addr, unsigned > (bit) < (size); \ > (bit) = __for_each_wrap((addr), (size), (start), (bit) + 1)) > > +/** > + * for_each_and_bit_wrap - iterate over all set bits in (*addr1 & *addr2) > + * starting from @start, and wrapping around the end of bitmap. > + * @bit: offset for current iteration > + * @addr1: address of first bitmap > + * @addr2: address of second bitmask to and with the first > + * @size: bitmap size in number of bits > + * @start: Starting bit for bitmap traversing, wrapping around the bitmap end > + */ > +#define for_each_and_bit_wrap(bit, addr1, addr2, size, start) \ > + for ((bit) = find_next_and_bit_wrap((addr1), (addr2), (size), (start)); \ > + (bit) < (size); \ > + (bit) = __for_each_and_wrap((addr1), (addr2), (size), (start), (bit) + 1)) > + > /** > * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits > * @start: bit offset to start search and to store the current iteration offset > -- > 2.43.0