From: Yury Norov <yury.norov@gmail.com>
To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
Yury Norov <yury.norov@gmail.com>
Subject: [PATCH 4/7] lib/find_bit: add find_next{,_and}_bit_wrap
Date: Mon, 19 Sep 2022 14:05:56 -0700 [thread overview]
Message-ID: <20220919210559.1509179-5-yury.norov@gmail.com> (raw)
In-Reply-To: <20220919210559.1509179-1-yury.norov@gmail.com>
The helper is better optimized for the worst case: in case of empty
cpumask, current code traverses 2 * size:
next = cpumask_next_and(prev, src1p, src2p);
if (next >= nr_cpu_ids)
next = cpumask_first_and(src1p, src2p);
At bitmap level we can stop earlier after checking 'size + offset' bits.
Signed-off-by: Yury Norov <yury.norov@gmail.com>
---
include/linux/find.h | 46 ++++++++++++++++++++++++++++++++++++++++++++
lib/cpumask.c | 12 +++---------
2 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/include/linux/find.h b/include/linux/find.h
index 128615a3f93e..77c087b7a451 100644
--- a/include/linux/find.h
+++ b/include/linux/find.h
@@ -290,6 +290,52 @@ unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
}
#endif
+/**
+ * find_next_and_bit_wrap - find the next set bit in both memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @size: The bitmap size in bits
+ * @offset: The bitnumber to start searching at
+ *
+ * Returns the bit number for the next set bit, or first set bit up to @offset
+ * If no bits are set, returns @size.
+ */
+static inline
+unsigned long find_next_and_bit_wrap(const unsigned long *addr1,
+ const unsigned long *addr2,
+ unsigned long size, unsigned long offset)
+{
+ unsigned long bit = find_next_and_bit(addr1, addr2, size, offset);
+
+ if (bit < size)
+ return bit;
+
+ bit = find_first_and_bit(addr1, addr2, offset);
+ return bit < offset ? bit : size;
+}
+
+/**
+ * find_next_bit_wrap - find the next set bit in both memory regions
+ * @addr: The first address to base the search on
+ * @size: The bitmap size in bits
+ * @offset: The bitnumber to start searching at
+ *
+ * Returns the bit number for the next set bit, or first set bit up to @offset
+ * If no bits are set, returns @size.
+ */
+static inline
+unsigned long find_next_bit_wrap(const unsigned long *addr,
+ unsigned long size, unsigned long offset)
+{
+ unsigned long bit = find_next_bit(addr, size, offset);
+
+ if (bit < size)
+ return bit;
+
+ bit = find_first_bit(addr, offset);
+ return bit < offset ? 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
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 2c4a63b6f03f..c7c392514fd3 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -166,10 +166,8 @@ unsigned int cpumask_any_and_distribute(const struct cpumask *src1p,
/* NOTE: our first selection will skip 0. */
prev = __this_cpu_read(distribute_cpu_mask_prev);
- next = cpumask_next_and(prev, src1p, src2p);
- if (next >= nr_cpu_ids)
- next = cpumask_first_and(src1p, src2p);
-
+ next = find_next_and_bit_wrap(cpumask_bits(src1p), cpumask_bits(src2p),
+ nr_cpumask_bits, prev + 1);
if (next < nr_cpu_ids)
__this_cpu_write(distribute_cpu_mask_prev, next);
@@ -183,11 +181,7 @@ unsigned int cpumask_any_distribute(const struct cpumask *srcp)
/* NOTE: our first selection will skip 0. */
prev = __this_cpu_read(distribute_cpu_mask_prev);
-
- next = cpumask_next(prev, srcp);
- if (next >= nr_cpu_ids)
- next = cpumask_first(srcp);
-
+ next = find_next_bit_wrap(cpumask_bits(srcp), nr_cpumask_bits, prev + 1);
if (next < nr_cpu_ids)
__this_cpu_write(distribute_cpu_mask_prev, next);
--
2.34.1
next prev parent reply other threads:[~2022-09-19 21:06 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-19 21:05 [PATCH 0/7] cpumask: repair cpumask_check() Yury Norov
2022-09-19 21:05 ` [PATCH 1/7] cpumask: fix checking valid cpu range Yury Norov
2022-09-28 12:18 ` Valentin Schneider
2022-09-28 14:49 ` Yury Norov
2022-09-30 17:04 ` Valentin Schneider
2022-10-01 2:02 ` Yury Norov
2022-09-19 21:05 ` [PATCH 2/7] net: fix cpu_max_bits_warn() usage in netif_attrmask_next{,_and} Yury Norov
2022-09-26 17:34 ` Jakub Kicinski
2022-09-26 17:47 ` Yury Norov
2022-09-19 21:05 ` [PATCH 3/7] cpumask: switch for_each_cpu{,_not} to use for_each_bit() Yury Norov
2022-09-19 21:05 ` Yury Norov [this message]
2022-09-19 21:05 ` [PATCH 5/7] lib/bitmap: introduce for_each_set_bit_wrap() macro Yury Norov
2022-09-19 21:05 ` [PATCH 6/7] lib/find: optimize for_each() macros Yury Norov
2022-09-19 21:05 ` [PATCH 7/7] lib/bitmap: add tests for for_each() loops Yury Norov
2022-09-25 15:47 ` [PATCH 0/7] cpumask: repair cpumask_check() Yury Norov
2022-09-26 15:09 ` Jakub Kicinski
2022-09-26 16:27 ` 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=20220919210559.1509179-5-yury.norov@gmail.com \
--to=yury.norov@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.