linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Yury Norov <yury.norov@gmail.com>
To: linux-kernel@vger.kernel.org, Yury Norov <yury.norov@gmail.com>,
	"James E.J. Bottomley" <jejb@linux.ibm.com>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Alexey Klimov <aklimov@redhat.com>,
	Amitkumar Karwar <amitkarwar@gmail.com>,
	Andi Kleen <ak@linux.intel.com>, Andrew Lunn <andrew@lunn.ch>,
	Andrew Morton <akpm@linux-foundation.org>,
	Andy Gross <agross@kernel.org>, Andy Lutomirski <luto@kernel.org>,
	Andy Shevchenko <andy@infradead.org>,
	Anup Patel <anup.patel@wdc.com>, Ard Biesheuvel <ardb@kernel.org>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Arnd Bergmann <arnd@arndb.de>, Borislav Petkov <bp@alien8.de>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Christoph Hellwig <hch@lst.de>, Christoph Lameter <cl@linux.com>,
	Daniel Vetter <daniel@ffwll.ch>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	David Airlie <airlied@linux.ie>,
	David Laight <David.Laight@ACULAB.COM>,
	Dennis Zhou <dennis@kernel.org>,
	Dinh Nguyen <dinguyen@kernel.org>,
	Geetha sowjanya <gakula@marvell.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Guo Ren <guoren@kernel.org>, Hans de Goede <hdegoede@redhat.com>,
	Heiko Carstens <hca@linux.ibm.com>,
	Ian Rogers <irogers@google.com>, Ingo Molnar <mingo@redhat.com>,
	Jakub Kicinski <kuba@kernel.org>,
	Jason Wessel <jason.wessel@windriver.com>,
	Jens Axboe <axboe@fb.com>, Jiri Olsa <jolsa@redhat.com>,
	Jonathan Cameron <jic23@kernel.org>,
	Juri Lelli <juri.lelli@redhat.com>,
	Kalle Valo <kvalo@codeaurora.org>,
	Kees Cook <keescook@chromium.org>,
	Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>,
	Lee Jones <lee.jones@linaro.org>, Marc Zyngier <maz@kernel.org>,
	Marcin Wojtas <mw@semihalf.com>,
	Mark Gross <markgross@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Matti Vaittinen <mazziesaccount@gmail.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Mel Gorman <mgorman@suse.de>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>,
	Nicholas Piggin <npiggin@gmail.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Petr Mladek <pmladek@suse.com>,
	Randy Dunlap <rdunlap@infradead.org>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	Roy Pledge <Roy.Pledge@nxp.com>,
	Russell King <linux@armlinux.org.uk>,
	Saeed Mahameed <saeedm@nvidia.com>,
	Sagi Grimberg <sagi@grimberg.me>,
	Sergey Senozhatsky <senozhatsky@chromium.org>,
	Solomon Peachy <pizza@shaftnet.org>,
	Stephen Boyd <sboyd@kernel.org>,
	Stephen Rothwell <sfr@canb.auug.org.au>,
	Steven Rostedt <rostedt@goodmis.org>,
	Subbaraya Sundeep <sbhatta@marvell.com>,
	Sudeep Holla <sudeep.holla@arm.com>,
	Sunil Goutham <sgoutham@marvell.com>,
	Tariq Toukan <tariqt@nvidia.com>, Tejun Heo <tj@kernel.org>,
	Thomas Bogendoerfer <tsbogend@alpha.franken.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Vineet Gupta <vgupta@kernel.org>,
	Viresh Kumar <viresh.kumar@linaro.org>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Vlastimil Babka <vbabka@suse.cz>, Will Deacon <will@kernel.org>,
	bcm-kernel-feedback-list@broadcom.com, kvm@vger.kernel.org,
	linux-alpha@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-crypto@vger.kernel.org, linux-csky@vger.kernel.org,
	linux-ia64@vger.kernel.org, linux-mips@vger.kernel.org,
	linux-mm@kvack.org, linux-perf-users@vger.kernel.org,
	linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
	linux-snps-arc@lists.infradead.org,
	linuxppc-dev@lists.ozlabs.org
Subject: [PATCH 1/9] lib/bitmap: add bitmap_weight_{eq,gt,le}
Date: Sat, 27 Nov 2021 19:56:56 -0800	[thread overview]
Message-ID: <20211128035704.270739-2-yury.norov@gmail.com> (raw)
In-Reply-To: <20211128035704.270739-1-yury.norov@gmail.com>

Many kernel users call bitmap_weight() to compare the result against
some number or expression:
	if (bitmap_weight(...) > 1)
		do_something();

It works OK, but may be significantly improved for large bitmaps: if
first few words count set bits to a number greater than given, we can
stop counting and immediately return.

The same idea would work in other direction: if we know that the number
of set bits that we counted so far is small enough, so that it would be
smaller than required number even if all bits of the rest of the bitmap
are set, we can return earlier.

This patch adds new bitmap_weight_{eq,gt,le} functions to allow this
optimization, and the following patches apply them where appropriate.

Signed-off-by: Yury Norov <yury.norov@gmail.com>
---
 include/linux/bitmap.h | 33 ++++++++++++++++++++++
 lib/bitmap.c           | 63 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 7dba0847510c..996041f771c8 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -51,6 +51,9 @@ struct device;
  *  bitmap_empty(src, nbits)                    Are all bits zero in *src?
  *  bitmap_full(src, nbits)                     Are all bits set in *src?
  *  bitmap_weight(src, nbits)                   Hamming Weight: number set bits
+ *  bitmap_weight_eq(src, nbits, num)           Hamming Weight is equal to num
+ *  bitmap_weight_gt(src, nbits, num)           Hamming Weight is greater than num
+ *  bitmap_weight_le(src, nbits, num)           Hamming Weight is less than num
  *  bitmap_set(dst, pos, nbits)                 Set specified bit area
  *  bitmap_clear(dst, pos, nbits)               Clear specified bit area
  *  bitmap_find_next_zero_area(buf, len, pos, n, mask)  Find bit free area
@@ -162,6 +165,9 @@ int __bitmap_intersects(const unsigned long *bitmap1,
 int __bitmap_subset(const unsigned long *bitmap1,
 		    const unsigned long *bitmap2, unsigned int nbits);
 int __bitmap_weight(const unsigned long *bitmap, unsigned int nbits);
+bool __bitmap_weight_eq(const unsigned long *bitmap, unsigned int nbits, unsigned int num);
+bool __bitmap_weight_gt(const unsigned long *bitmap, unsigned int nbits, unsigned int num);
+bool __bitmap_weight_le(const unsigned long *bitmap, unsigned int nbits, unsigned int num);
 void __bitmap_set(unsigned long *map, unsigned int start, int len);
 void __bitmap_clear(unsigned long *map, unsigned int start, int len);
 
@@ -403,6 +409,33 @@ static __always_inline int bitmap_weight(const unsigned long *src, unsigned int
 	return __bitmap_weight(src, nbits);
 }
 
+static __always_inline bool bitmap_weight_eq(const unsigned long *src,
+			unsigned int nbits, unsigned int num)
+{
+	if (small_const_nbits(nbits))
+		return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)) == num;
+
+	return __bitmap_weight_eq(src, nbits, num);
+}
+
+static __always_inline bool bitmap_weight_gt(const unsigned long *src,
+			unsigned int nbits, unsigned int num)
+{
+	if (small_const_nbits(nbits))
+		return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)) > num;
+
+	return __bitmap_weight_gt(src, nbits, num);
+}
+
+static __always_inline bool bitmap_weight_le(const unsigned long *src,
+			unsigned int nbits, unsigned int num)
+{
+	if (small_const_nbits(nbits))
+		return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)) < num;
+
+	return __bitmap_weight_le(src, nbits, num);
+}
+
 static __always_inline void bitmap_set(unsigned long *map, unsigned int start,
 		unsigned int nbits)
 {
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 926408883456..72e7ab2d7bdd 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -348,6 +348,69 @@ int __bitmap_weight(const unsigned long *bitmap, unsigned int bits)
 }
 EXPORT_SYMBOL(__bitmap_weight);
 
+bool __bitmap_weight_eq(const unsigned long *bitmap, unsigned int bits, unsigned int num)
+{
+	unsigned int k, w, lim = bits / BITS_PER_LONG;
+
+	for (k = 0, w = 0; k < lim; k++) {
+		if (w + bits - k * BITS_PER_LONG < num)
+			return false;
+
+		w += hweight_long(bitmap[k]);
+
+		if (w > num)
+			return false;
+	}
+
+	if (bits % BITS_PER_LONG)
+		w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
+
+	return w == num;
+}
+EXPORT_SYMBOL(__bitmap_weight_eq);
+
+bool __bitmap_weight_gt(const unsigned long *bitmap, unsigned int bits, unsigned int num)
+{
+	unsigned int k, w, lim = bits / BITS_PER_LONG;
+
+	for (k = 0, w = 0; k < lim; k++) {
+		if (w + bits - k * BITS_PER_LONG <= num)
+			return false;
+
+		w += hweight_long(bitmap[k]);
+
+		if (w > num)
+			return true;
+	}
+
+	if (bits % BITS_PER_LONG)
+		w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
+
+	return w > num;
+}
+EXPORT_SYMBOL(__bitmap_weight_gt);
+
+bool __bitmap_weight_le(const unsigned long *bitmap, unsigned int bits, unsigned int num)
+{
+	unsigned int k, w, lim = bits / BITS_PER_LONG;
+
+	for (k = 0, w = 0; k < lim; k++) {
+		if (w + bits - k * BITS_PER_LONG < num)
+			return true;
+
+		w += hweight_long(bitmap[k]);
+
+		if (w >= num)
+			return false;
+	}
+
+	if (bits % BITS_PER_LONG)
+		w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
+
+	return w < num;
+}
+EXPORT_SYMBOL(__bitmap_weight_le);
+
 void __bitmap_set(unsigned long *map, unsigned int start, int len)
 {
 	unsigned long *p = map + BIT_WORD(start);
-- 
2.25.1


  reply	other threads:[~2021-11-28  6:24 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-28  3:56 [PATCH 0/9] lib/bitmap: optimize bitmap_weight() usage Yury Norov
2021-11-28  3:56 ` Yury Norov [this message]
2021-11-28  3:56 ` [PATCH 2/9] lib/bitmap: implement bitmap_{empty, full} with bitmap_weight_eq() Yury Norov
2021-11-28  4:37   ` [PATCH 2/9] lib/bitmap: implement bitmap_{empty,full} " Michał Mirosław
2021-11-28  6:27     ` Yury Norov
2021-11-28 18:10   ` Michał Mirosław
2021-12-14 19:43     ` [PATCH 2/9] lib/bitmap: implement bitmap_{empty, full} " Yury Norov
2021-12-15  8:40       ` [PATCH 2/9] lib/bitmap: implement bitmap_{empty,full} " David Laight
2021-12-15 17:45         ` [PATCH 2/9] lib/bitmap: implement bitmap_{empty, full} " Yury Norov
2021-11-28  3:56 ` [PATCH 3/9] all: replace bitmap_weigth() with bitmap_{empty, full, eq, gt, le} Yury Norov
2021-11-28  4:47   ` [PATCH 3/9] all: replace bitmap_weigth() with bitmap_{empty,full,eq,gt,le} Michał Mirosław
2021-11-28  8:01   ` Greg Kroah-Hartman
2021-11-28  3:56 ` [PATCH 4/9] tools: sync bitmap_weight() usage with the kernel Yury Norov
2021-11-28  3:57 ` [PATCH 5/9] lib/cpumask: add cpumask_weight_{eq,gt,le} Yury Norov
2021-11-28  3:57 ` [PATCH 6/9] lib/nodemask: add nodemask_weight_{eq,gt,le} Yury Norov
2021-11-28  3:57 ` [PATCH 7/9] lib/cpumask: add num_{possible, present, active}_cpus_{eq, gt, le} Yury Norov
2021-11-28  4:56   ` [PATCH 7/9] lib/cpumask: add num_{possible,present,active}_cpus_{eq,gt,le} Michał Mirosław
2021-11-28  5:09     ` Michał Mirosław
2021-11-28  6:34     ` Yury Norov
2021-11-28 17:07   ` Joe Perches
2021-11-28 17:43     ` Yury Norov
2021-11-28 17:54       ` Dennis Zhou
2021-11-28 18:47         ` Yury Norov
2021-11-28 17:56       ` [PATCH 7/9] lib/cpumask: add num_{possible, present, active}_cpus_{eq, gt, le} Emil Renner Berthing
2021-11-28 17:57       ` [PATCH 7/9] lib/cpumask: add num_{possible,present,active}_cpus_{eq,gt,le} Joe Perches
2021-11-28  3:57 ` [PATCH 8/9] lib/nodemask: add num_node_state_eq() Yury Norov
2021-11-28  3:57 ` [PATCH 9/9] MAINTAINERS: add cpumask and nodemask files to BITMAP_API Yury Norov
2021-11-28 11:08 ` [PATCH 0/9] lib/bitmap: optimize bitmap_weight() usage Nicholas Piggin
2021-11-28 23:36   ` Yury Norov
2021-11-28 18:05 ` Michał Mirosław
2021-11-28 18:03   ` mirq-test
2021-11-29  6:38   ` Yury Norov
2021-11-29 16:34     ` Michał Mirosław
2021-12-02  0:31       ` Yury Norov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211128035704.270739-2-yury.norov@gmail.com \
    --to=yury.norov@gmail.com \
    --cc=David.Laight@ACULAB.COM \
    --cc=Roy.Pledge@nxp.com \
    --cc=acme@kernel.org \
    --cc=agross@kernel.org \
    --cc=airlied@linux.ie \
    --cc=ak@linux.intel.com \
    --cc=aklimov@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=amitkarwar@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=andy@infradead.org \
    --cc=anup.patel@wdc.com \
    --cc=ardb@kernel.org \
    --cc=arnd@arndb.de \
    --cc=axboe@fb.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=cl@linux.com \
    --cc=daniel@ffwll.ch \
    --cc=dave.hansen@linux.intel.com \
    --cc=dennis@kernel.org \
    --cc=dinguyen@kernel.org \
    --cc=gakula@marvell.com \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=guoren@kernel.org \
    --cc=hca@linux.ibm.com \
    --cc=hch@lst.de \
    --cc=hdegoede@redhat.com \
    --cc=irogers@google.com \
    --cc=jason.wessel@windriver.com \
    --cc=jejb@linux.ibm.com \
    --cc=jic23@kernel.org \
    --cc=jolsa@redhat.com \
    --cc=juri.lelli@redhat.com \
    --cc=keescook@chromium.org \
    --cc=krzysztof.kozlowski@canonical.com \
    --cc=kuba@kernel.org \
    --cc=kvalo@codeaurora.org \
    --cc=kvm@vger.kernel.org \
    --cc=lee.jones@linaro.org \
    --cc=linux-alpha@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-csky@vger.kernel.org \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=linux-snps-arc@lists.infradead.org \
    --cc=linux@armlinux.org.uk \
    --cc=linux@rasmusvillemoes.dk \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=luto@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=markgross@kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=maz@kernel.org \
    --cc=mazziesaccount@gmail.com \
    --cc=mchehab@kernel.org \
    --cc=mgorman@suse.de \
    --cc=mike.marciniszyn@cornelisnetworks.com \
    --cc=mingo@redhat.com \
    --cc=mpe@ellerman.id.au \
    --cc=mw@semihalf.com \
    --cc=npiggin@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=paulmck@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pizza@shaftnet.org \
    --cc=pmladek@suse.com \
    --cc=rafael@kernel.org \
    --cc=rdunlap@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=saeedm@nvidia.com \
    --cc=sagi@grimberg.me \
    --cc=sbhatta@marvell.com \
    --cc=sboyd@kernel.org \
    --cc=senozhatsky@chromium.org \
    --cc=sfr@canb.auug.org.au \
    --cc=sgoutham@marvell.com \
    --cc=sudeep.holla@arm.com \
    --cc=tariqt@nvidia.com \
    --cc=tglx@linutronix.de \
    --cc=tj@kernel.org \
    --cc=tsbogend@alpha.franken.de \
    --cc=ulf.hansson@linaro.org \
    --cc=vbabka@suse.cz \
    --cc=vgupta@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=viresh.kumar@linaro.org \
    --cc=vivien.didelot@gmail.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).