[PATCH rdma-core 2/5] mlx5: Adapt bitmap usage to use util API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Maher Sanalla <msanalla@xxxxxxxxxx>

Replace the usage of ccan bitmap with the newly added bitmap
implementation in util.

As part of it, remove mlx5 bitmap API.

Signed-off-by: Maher Sanalla <msanalla@xxxxxxxxxx>
Reviewed-by: Avihai Horon <avihaih@xxxxxxxxxx>
Signed-off-by: Yishai Hadas <yishaih@xxxxxxxxxx>
---
 providers/mlx5/bitmap.h    | 109 --------------------------
 providers/mlx5/buf.c       | 187 +++++++++------------------------------------
 providers/mlx5/dr_buddy.c  |  12 +--
 providers/mlx5/mlx5.h      |  17 +----
 providers/mlx5/mlx5_vfio.c |   3 +-
 providers/mlx5/mlx5_vfio.h |   2 +-
 providers/mlx5/mlx5dv_dr.h |   6 +-
 7 files changed, 53 insertions(+), 283 deletions(-)
 delete mode 100644 providers/mlx5/bitmap.h

diff --git a/providers/mlx5/bitmap.h b/providers/mlx5/bitmap.h
deleted file mode 100644
index b2c8a36..0000000
--- a/providers/mlx5/bitmap.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2000, 2011 Mellanox Technology Inc.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef BITMAP_H
-#define BITMAP_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/mman.h>
-#include <linux/errno.h>
-#include <util/util.h>
-#include "mlx5.h"
-
-/* Only ia64 requires this */
-#ifdef __ia64__
-#define MLX5_SHM_ADDR ((void *)0x8000000000000000UL)
-#define MLX5_SHMAT_FLAGS (SHM_RND)
-#else
-#define MLX5_SHM_ADDR NULL
-#define MLX5_SHMAT_FLAGS 0
-#endif
-
-#ifndef HPAGE_SIZE
-#define HPAGE_SIZE		(2UL * 1024 * 1024)
-#endif
-
-#define MLX5_SHM_LENGTH		HPAGE_SIZE
-#define MLX5_Q_CHUNK_SIZE	32768
-#define MLX5_SHM_NUM_REGION	64
-
-static inline unsigned long mlx5_ffz(uint32_t word)
-{
-	return __builtin_ffs(~word) - 1;
-}
-
-static inline uint32_t mlx5_find_first_zero_bit(const unsigned long *addr,
-					 uint32_t size)
-{
-	const unsigned long *p = addr;
-	uint32_t result = 0;
-	unsigned long tmp;
-
-	while (size & ~(BITS_PER_LONG - 1)) {
-		tmp = *(p++);
-		if (~tmp)
-			goto found;
-		result += BITS_PER_LONG;
-		size -= BITS_PER_LONG;
-	}
-	if (!size)
-		return result;
-
-	tmp = (*p) | (~0UL << size);
-	if (tmp == (uint32_t)~0UL)	/* Are any bits zero? */
-		return result + size;	/* Nope. */
-found:
-	return result + mlx5_ffz(tmp);
-}
-
-static inline void mlx5_set_bit(unsigned int nr, unsigned long *addr)
-{
-	addr[(nr / BITS_PER_LONG)] |= (1 << (nr % BITS_PER_LONG));
-}
-
-static inline void mlx5_clear_bit(unsigned int nr,  unsigned long *addr)
-{
-	addr[(nr / BITS_PER_LONG)] &= ~(1 << (nr % BITS_PER_LONG));
-}
-
-static inline int mlx5_test_bit(unsigned int nr, const unsigned long *addr)
-{
-	return !!(addr[(nr / BITS_PER_LONG)] & (1 <<  (nr % BITS_PER_LONG)));
-}
-
-#endif
diff --git a/providers/mlx5/buf.c b/providers/mlx5/buf.c
index 83c32b0..3a3a792 100644
--- a/providers/mlx5/buf.c
+++ b/providers/mlx5/buf.c
@@ -38,155 +38,38 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <sys/mman.h>
+#include <util/bitmap.h>
 
 #include "mlx5.h"
-#include "bitmap.h"
 
-static int mlx5_bitmap_init(struct mlx5_bitmap *bmp, uint32_t num,
-			    uint32_t mask)
-{
-	bmp->last = 0;
-	bmp->top  = 0;
-	bmp->max  = num;
-	bmp->avail = num;
-	bmp->mask = mask;
-	bmp->avail = bmp->max;
-	bmp->table = calloc(BITS_TO_LONGS(bmp->max), sizeof(*bmp->table));
-	if (!bmp->table)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static void bitmap_free_range(struct mlx5_bitmap *bmp, uint32_t obj,
-			      int cnt)
-{
-	int i;
+/* Only ia64 requires this */
+#ifdef __ia64__
+#define MLX5_SHM_ADDR ((void *)0x8000000000000000UL)
+#define MLX5_SHMAT_FLAGS (SHM_RND)
+#else
+#define MLX5_SHM_ADDR NULL
+#define MLX5_SHMAT_FLAGS 0
+#endif
 
-	obj &= bmp->max - 1;
-
-	for (i = 0; i < cnt; i++)
-		mlx5_clear_bit(obj + i, bmp->table);
-	bmp->last = min(bmp->last, obj);
-	bmp->top = (bmp->top + bmp->max) & bmp->mask;
-	bmp->avail += cnt;
-}
-
-static int mlx5_bitmap_empty(struct mlx5_bitmap *bmp)
-{
-	return (bmp->avail == bmp->max) ? 1 : 0;
-}
-
-static int bitmap_avail(struct mlx5_bitmap *bmp)
-{
-	return bmp->avail;
-}
+#ifndef HPAGE_SIZE
+#define HPAGE_SIZE              (2UL * 1024 * 1024)
+#endif
 
-static void mlx5_bitmap_cleanup(struct mlx5_bitmap *bmp)
-{
-	if (bmp->table)
-		free(bmp->table);
-}
+#define MLX5_SHM_LENGTH         HPAGE_SIZE
+#define MLX5_Q_CHUNK_SIZE       32768
 
 static void free_huge_mem(struct mlx5_hugetlb_mem *hmem)
 {
-	mlx5_bitmap_cleanup(&hmem->bitmap);
+	if (hmem->bitmap)
+		free(hmem->bitmap);
+
 	if (shmdt(hmem->shmaddr) == -1)
 		mlx5_dbg(stderr, MLX5_DBG_CONTIG, "%s\n", strerror(errno));
 	shmctl(hmem->shmid, IPC_RMID, NULL);
 	free(hmem);
 }
 
-static int mlx5_bitmap_alloc(struct mlx5_bitmap *bmp)
-{
-	uint32_t obj;
-	int ret;
-
-	obj = mlx5_find_first_zero_bit(bmp->table, bmp->max);
-	if (obj < bmp->max) {
-		mlx5_set_bit(obj, bmp->table);
-		bmp->last = (obj + 1);
-		if (bmp->last == bmp->max)
-			bmp->last = 0;
-		obj |= bmp->top;
-		ret = obj;
-	} else
-		ret = -1;
-
-	if (ret != -1)
-		--bmp->avail;
-
-	return ret;
-}
-
-static uint32_t find_aligned_range(unsigned long *bmp,
-				   uint32_t start, uint32_t nbits,
-				   int len, int alignment)
-{
-	uint32_t end, i;
-
-again:
-	start = align(start, alignment);
-
-	while ((start < nbits) && mlx5_test_bit(start, bmp))
-		start += alignment;
-
-	if (start >= nbits)
-		return -1;
-
-	end = start + len;
-	if (end > nbits)
-		return -1;
-
-	for (i = start + 1; i < end; i++) {
-		if (mlx5_test_bit(i, bmp)) {
-			start = i + 1;
-			goto again;
-		}
-	}
-
-	return start;
-}
-
-static int bitmap_alloc_range(struct mlx5_bitmap *bmp, int cnt,
-			      int align)
-{
-	uint32_t obj;
-	int ret, i;
-
-	if (cnt == 1 && align == 1)
-		return mlx5_bitmap_alloc(bmp);
-
-	if (cnt > bmp->max)
-		return -1;
-
-	obj = find_aligned_range(bmp->table, bmp->last,
-				 bmp->max, cnt, align);
-	if (obj >= bmp->max) {
-		bmp->top = (bmp->top + bmp->max) & bmp->mask;
-		obj = find_aligned_range(bmp->table, 0, bmp->max,
-					 cnt, align);
-	}
-
-	if (obj < bmp->max) {
-		for (i = 0; i < cnt; i++)
-			mlx5_set_bit(obj + i, bmp->table);
-		if (obj == bmp->last) {
-			bmp->last = (obj + cnt);
-			if (bmp->last >= bmp->max)
-				bmp->last = 0;
-		}
-		obj |= bmp->top;
-		ret = obj;
-	} else
-		ret = -1;
-
-	if (ret != -1)
-		bmp->avail -= cnt;
-
-	return obj;
-}
-
 static struct mlx5_hugetlb_mem *alloc_huge_mem(size_t size)
 {
 	struct mlx5_hugetlb_mem *hmem;
@@ -209,12 +92,14 @@ static struct mlx5_hugetlb_mem *alloc_huge_mem(size_t size)
 		goto out_rmid;
 	}
 
-	if (mlx5_bitmap_init(&hmem->bitmap, shm_len / MLX5_Q_CHUNK_SIZE,
-			     shm_len / MLX5_Q_CHUNK_SIZE - 1)) {
+	hmem->bitmap = bitmap_alloc0(shm_len / MLX5_Q_CHUNK_SIZE);
+	if (!hmem->bitmap) {
 		mlx5_dbg(stderr, MLX5_DBG_CONTIG, "%s\n", strerror(errno));
 		goto out_shmdt;
 	}
 
+	hmem->bmp_size = shm_len / MLX5_Q_CHUNK_SIZE;
+
 	/*
 	 * Marked to be destroyed when process detaches from shmget segment
 	 */
@@ -250,9 +135,13 @@ static int alloc_huge_buf(struct mlx5_context *mctx, struct mlx5_buf *buf,
 
 	mlx5_spin_lock(&mctx->hugetlb_lock);
 	list_for_each(&mctx->hugetlb_list, hmem, entry) {
-		if (bitmap_avail(&hmem->bitmap)) {
-			buf->base = bitmap_alloc_range(&hmem->bitmap, nchunk, 1);
-			if (buf->base != -1) {
+		if (!bitmap_full(hmem->bitmap, hmem->bmp_size)) {
+			buf->base = bitmap_find_free_region(hmem->bitmap,
+							    hmem->bmp_size,
+							    nchunk);
+			if (buf->base != hmem->bmp_size) {
+				bitmap_fill_region(hmem->bitmap, buf->base,
+						   buf->base + nchunk);
 				buf->hmem = hmem;
 				found = 1;
 				break;
@@ -266,16 +155,14 @@ static int alloc_huge_buf(struct mlx5_context *mctx, struct mlx5_buf *buf,
 		if (!hmem)
 			return -1;
 
-		buf->base = bitmap_alloc_range(&hmem->bitmap, nchunk, 1);
-		if (buf->base == -1) {
-			free_huge_mem(hmem);
-			return -1;
-		}
+		buf->base = 0;
+		assert(nchunk <= hmem->bmp_size);
+		bitmap_fill_region(hmem->bitmap, 0, nchunk);
 
 		buf->hmem = hmem;
 
 		mlx5_spin_lock(&mctx->hugetlb_lock);
-		if (bitmap_avail(&hmem->bitmap))
+		if (nchunk != hmem->bmp_size)
 			list_add(&mctx->hugetlb_list, &hmem->entry);
 		else
 			list_add_tail(&mctx->hugetlb_list, &hmem->entry);
@@ -295,8 +182,8 @@ static int alloc_huge_buf(struct mlx5_context *mctx, struct mlx5_buf *buf,
 
 out_fork:
 	mlx5_spin_lock(&mctx->hugetlb_lock);
-	bitmap_free_range(&hmem->bitmap, buf->base, nchunk);
-	if (mlx5_bitmap_empty(&hmem->bitmap)) {
+	bitmap_zero_region(hmem->bitmap, buf->base, buf->base + nchunk);
+	if (bitmap_empty(hmem->bitmap, hmem->bmp_size)) {
 		list_del(&hmem->entry);
 		mlx5_spin_unlock(&mctx->hugetlb_lock);
 		free_huge_mem(hmem);
@@ -315,8 +202,8 @@ static void free_huge_buf(struct mlx5_context *ctx, struct mlx5_buf *buf)
 		return;
 
 	mlx5_spin_lock(&ctx->hugetlb_lock);
-	bitmap_free_range(&buf->hmem->bitmap, buf->base, nchunk);
-	if (mlx5_bitmap_empty(&buf->hmem->bitmap)) {
+	bitmap_zero_region(buf->hmem->bitmap, buf->base, buf->base + nchunk);
+	if (bitmap_empty(buf->hmem->bitmap, buf->hmem->bmp_size)) {
 		list_del(&buf->hmem->entry);
 		mlx5_spin_unlock(&ctx->hugetlb_lock);
 		free_huge_mem(buf->hmem);
diff --git a/providers/mlx5/dr_buddy.c b/providers/mlx5/dr_buddy.c
index e153677..8713fe4 100644
--- a/providers/mlx5/dr_buddy.c
+++ b/providers/mlx5/dr_buddy.c
@@ -34,23 +34,23 @@
  */
 
 #include <stdlib.h>
-#include <ccan/bitmap.h>
+#include <util/bitmap.h>
 #include "mlx5dv_dr.h"
 
 struct dr_icm_pool;
 struct dr_icm_buddy_mem;
 
-static int dr_find_first_bit(const bitmap *set_addr,
-			     const bitmap *addr,
+static int dr_find_first_bit(const unsigned long *set_addr,
+			     const unsigned long *addr,
 			     unsigned int size)
 {
 	unsigned int set_size = (size - 1) / BITS_PER_LONG + 1;
 	unsigned long set_idx;
 
 	/* find the first free in the first level */
-	set_idx =  bitmap_ffs(set_addr, 0, set_size);
+	set_idx =  bitmap_find_first_bit(set_addr, 0, set_size);
 	/* find the next level */
-	return bitmap_ffs(addr, set_idx * BITS_PER_LONG, size);
+	return bitmap_find_first_bit(addr, set_idx * BITS_PER_LONG, size);
 }
 
 int dr_buddy_init(struct dr_icm_buddy_mem *buddy, uint32_t max_order)
@@ -161,7 +161,7 @@ static void dr_buddy_update_upper_bitmap(struct dr_icm_buddy_mem *buddy,
 
 	/* clear upper layer of search if needed */
 	dr_buddy_get_seg_borders(seg, &l, &h);
-	m = bitmap_ffs(buddy->bits[order], l, h);
+	m = bitmap_find_first_bit(buddy->bits[order], l, h);
 	if (m == h) /* nothing in the long that includes seg */
 		bitmap_clear_bit(buddy->set_bit[order], seg / BITS_PER_LONG);
 }
diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h
index 1eca478..4656153 100644
--- a/providers/mlx5/mlx5.h
+++ b/providers/mlx5/mlx5.h
@@ -44,9 +44,8 @@
 #include <util/udma_barrier.h>
 #include <util/util.h>
 #include "mlx5-abi.h"
-#include <ccan/bitmap.h>
+#include <util/bitmap.h>
 #include <ccan/list.h>
-#include "bitmap.h"
 #include <ccan/minmax.h>
 #include "mlx5dv.h"
 
@@ -289,7 +288,7 @@ struct mlx5_hca_cap_2_caps {
 };
 
 struct reserved_qpn_blk {
-	bitmap *bmp;
+	unsigned long *bmp;
 	uint32_t first_qpn;
 	struct list_node entry;
 	unsigned int next_avail_slot;
@@ -419,19 +418,11 @@ struct mlx5_context {
 	pthread_mutex_t			crypto_login_mutex;
 };
 
-struct mlx5_bitmap {
-	uint32_t		last;
-	uint32_t		top;
-	uint32_t		max;
-	uint32_t		avail;
-	uint32_t		mask;
-	unsigned long	       *table;
-};
-
 struct mlx5_hugetlb_mem {
 	int			shmid;
 	void		       *shmaddr;
-	struct mlx5_bitmap	bitmap;
+	unsigned long		*bitmap;
+	unsigned long		bmp_size;
 	struct list_node	entry;
 };
 
diff --git a/providers/mlx5/mlx5_vfio.c b/providers/mlx5/mlx5_vfio.c
index 3f1811d..b9cdfeb 100644
--- a/providers/mlx5/mlx5_vfio.c
+++ b/providers/mlx5/mlx5_vfio.c
@@ -142,7 +142,8 @@ static int mlx5_vfio_alloc_page(struct mlx5_vfio_context *ctx, uint64_t *iova)
 	pthread_mutex_lock(&ctx->mem_alloc.block_list_mutex);
 	while (true) {
 		list_for_each(&ctx->mem_alloc.block_list, page_block, next_block) {
-			pg = bitmap_ffs(page_block->free_pages, 0, MLX5_VFIO_BLOCK_NUM_PAGES);
+			pg = bitmap_find_first_bit(page_block->free_pages, 0,
+						   MLX5_VFIO_BLOCK_NUM_PAGES);
 			if (pg != MLX5_VFIO_BLOCK_NUM_PAGES) {
 				bitmap_clear_bit(page_block->free_pages, pg);
 				*iova = page_block->iova + pg * MLX5_ADAPTER_PAGE_SIZE;
diff --git a/providers/mlx5/mlx5_vfio.h b/providers/mlx5/mlx5_vfio.h
index 2165a22..88cc332 100644
--- a/providers/mlx5/mlx5_vfio.h
+++ b/providers/mlx5/mlx5_vfio.h
@@ -163,7 +163,7 @@ struct page_block {
 	void *page_ptr;
 	uint64_t iova;
 	struct list_node next_block;
-	BITMAP_DECLARE(free_pages, MLX5_VFIO_BLOCK_NUM_PAGES);
+	BMP_DECLARE(free_pages, MLX5_VFIO_BLOCK_NUM_PAGES);
 };
 
 struct vfio_mem_allocator {
diff --git a/providers/mlx5/mlx5dv_dr.h b/providers/mlx5/mlx5dv_dr.h
index 16e5340..3cc3035 100644
--- a/providers/mlx5/mlx5dv_dr.h
+++ b/providers/mlx5/mlx5dv_dr.h
@@ -35,7 +35,7 @@
 
 #include <ccan/list.h>
 #include <ccan/minmax.h>
-#include <ccan/bitmap.h>
+#include <util/bitmap.h>
 #include <stdatomic.h>
 #include "mlx5dv.h"
 #include "mlx5_ifc.h"
@@ -1619,9 +1619,9 @@ int dr_send_postsend_action(struct mlx5dv_dr_domain *dmn,
 struct dr_icm_mr;
 
 struct dr_icm_buddy_mem {
-	bitmap			**bits;
+	unsigned long		**bits;
 	unsigned int		*num_free;
-	bitmap			**set_bit;
+	unsigned long		**set_bit;
 	uint32_t		max_order;
 	struct list_node	list_node;
 	struct dr_icm_mr	*icm_mr;
-- 
1.8.3.1




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux