[PATCH v4 24/40] RDMA/rtrs: optimize __rtrs_get_permit() by using find_and_set_bit_lock()

Yury Norov
2024-06-20T17:58:18Z

The function opencodes find_and_set_bit_lock() with a while-loop polling
on test_and_set_bit_lock(). Use the dedicated function instead.

Signed-off-by: Yury Norov <yury.norov@gmail.com>
---
drivers/infiniband/ulp/rtrs/rtrs-clt.c | 16 ++++------------
1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
index 88106cf5ce55..52b7728f6c63 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -10,6 +10,7 @@
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME " L" __stringify(__LINE__) ": " fmt

+#include <linux/find_atomic.h>
#include <linux/module.h>
#include <linux/rculist.h>
#include <linux/random.h>
@@ -72,18 +73,9 @@ __rtrs_get_permit(struct rtrs_clt_sess *clt, enum rtrs_clt_con_type con_type)
struct rtrs_permit *permit;
int bit;

- /*
- * Adapted from null_blk get_tag(). Callers from different cpus may
- * grab the same bit, since find_first_zero_bit is not atomic.
- * But then the test_and_set_bit_lock will fail for all the
- * callers but one, so that they will loop again.
- * This way an explicit spinlock is not required.
- */
- do {
- bit = find_first_zero_bit(clt->permits_map, max_depth);
- if (bit >= max_depth)
- return NULL;
- } while (test_and_set_bit_lock(bit, clt->permits_map));
+ bit = find_and_set_bit_lock(clt->permits_map, max_depth);
+ if (bit >= max_depth)
+ return NULL;

permit = get_permit(clt, bit);
WARN_ON(permit->mem_id != bit);
--
2.43.0