[PATCH 1/2] lib/bitmap: move bitmap allocators for device to linux/device.h

Yury Norov posted 2 patches 2 years, 2 months ago
[PATCH 1/2] lib/bitmap: move bitmap allocators for device to linux/device.h
Posted by Yury Norov 2 years, 2 months ago
The allocators are simple wrappers around bitmap_{alloc,free}().
So move them from bitmap to device sources.

Similarly to other device wrappers, turn them to static inlines
and place in header.

Signed-off-by: Yury Norov <yury.norov@gmail.com>
---
 include/linux/bitmap.h |  8 --------
 include/linux/device.h | 30 ++++++++++++++++++++++++++++++
 lib/bitmap.c           | 33 ---------------------------------
 3 files changed, 30 insertions(+), 41 deletions(-)

diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 03644237e1ef..ce8fcd8736f1 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -11,8 +11,6 @@
 #include <linux/string.h>
 #include <linux/types.h>
 
-struct device;
-
 /*
  * bitmaps provide bit arrays that consume one or more unsigned
  * longs.  The bitmap interface and available operations are listed
@@ -125,12 +123,6 @@ unsigned long *bitmap_alloc_node(unsigned int nbits, gfp_t flags, int node);
 unsigned long *bitmap_zalloc_node(unsigned int nbits, gfp_t flags, int node);
 void bitmap_free(const unsigned long *bitmap);
 
-/* Managed variants of the above. */
-unsigned long *devm_bitmap_alloc(struct device *dev,
-				 unsigned int nbits, gfp_t flags);
-unsigned long *devm_bitmap_zalloc(struct device *dev,
-				  unsigned int nbits, gfp_t flags);
-
 /*
  * lib/bitmap.c provides these functions:
  */
diff --git a/include/linux/device.h b/include/linux/device.h
index 56d93a1ffb7b..01b8161b283a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -435,6 +435,36 @@ struct device_dma_parameters {
 	unsigned long segment_boundary_mask;
 };
 
+static inline void devm_bitmap_free(void *data)
+{
+	unsigned long *bitmap = data;
+
+	bitmap_free(bitmap);
+}
+
+static inline unsigned long *devm_bitmap_alloc(struct device *dev,
+				 unsigned int nbits, gfp_t flags)
+{
+	unsigned long *bitmap;
+	int ret;
+
+	bitmap = bitmap_alloc(nbits, flags);
+	if (!bitmap)
+		return NULL;
+
+	ret = devm_add_action_or_reset(dev, devm_bitmap_free, bitmap);
+	if (ret)
+		return NULL;
+
+	return bitmap;
+}
+
+static inline unsigned long *devm_bitmap_zalloc(struct device *dev,
+				  unsigned int nbits, gfp_t flags)
+{
+	return devm_bitmap_alloc(dev, nbits, flags | __GFP_ZERO);
+}
+
 /**
  * enum device_link_state - Device link states.
  * @DL_STATE_NONE: The presence of the drivers is not being tracked.
diff --git a/lib/bitmap.c b/lib/bitmap.c
index ddb31015e38a..41f32fa3a80f 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -8,7 +8,6 @@
 #include <linux/bitops.h>
 #include <linux/bug.h>
 #include <linux/ctype.h>
-#include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/export.h>
 #include <linux/kernel.h>
@@ -1415,38 +1414,6 @@ void bitmap_free(const unsigned long *bitmap)
 }
 EXPORT_SYMBOL(bitmap_free);
 
-static void devm_bitmap_free(void *data)
-{
-	unsigned long *bitmap = data;
-
-	bitmap_free(bitmap);
-}
-
-unsigned long *devm_bitmap_alloc(struct device *dev,
-				 unsigned int nbits, gfp_t flags)
-{
-	unsigned long *bitmap;
-	int ret;
-
-	bitmap = bitmap_alloc(nbits, flags);
-	if (!bitmap)
-		return NULL;
-
-	ret = devm_add_action_or_reset(dev, devm_bitmap_free, bitmap);
-	if (ret)
-		return NULL;
-
-	return bitmap;
-}
-EXPORT_SYMBOL_GPL(devm_bitmap_alloc);
-
-unsigned long *devm_bitmap_zalloc(struct device *dev,
-				  unsigned int nbits, gfp_t flags)
-{
-	return devm_bitmap_alloc(dev, nbits, flags | __GFP_ZERO);
-}
-EXPORT_SYMBOL_GPL(devm_bitmap_zalloc);
-
 #if BITS_PER_LONG == 64
 /**
  * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap
-- 
2.39.2
Re: [PATCH 1/2] lib/bitmap: move bitmap allocators for device to linux/device.h
Posted by Greg Kroah-Hartman 2 years, 2 months ago
On Sat, Oct 07, 2023 at 04:35:09PM -0700, Yury Norov wrote:
> The allocators are simple wrappers around bitmap_{alloc,free}().
> So move them from bitmap to device sources.

No, they belong in the bitmap.h file, as they are devm_* versions of the
same functions in this file.  They don't belong in the device.h file.

> Similarly to other device wrappers, turn them to static inlines
> and place in header.

Why do these need to be inline functions?

thanks,

greg k-h
Re: [PATCH 1/2] lib/bitmap: move bitmap allocators for device to linux/device.h
Posted by Yury Norov 2 years, 2 months ago
On Sun, Oct 08, 2023 at 06:53:49AM +0200, Greg Kroah-Hartman wrote:
> On Sat, Oct 07, 2023 at 04:35:09PM -0700, Yury Norov wrote:
> > The allocators are simple wrappers around bitmap_{alloc,free}().
> > So move them from bitmap to device sources.
> 
> No, they belong in the bitmap.h file, as they are devm_* versions of the
> same functions in this file.  They don't belong in the device.h file.

OK then. I don't thing that the functions are anything wrong, and
don't want to 'get rid of them' in any way.

But could you please elaborate? I'm not too familiar to devm_* things,
and to me devm_alloc/free() look similar to e.g.
vfio_dma_bitmap_alloc_all() or iova_bitmap_alloc(), which allocate
memory for bitmap + do some other initialization things.

And they all reside in corresponding subsystems. Why devm differs? 
 
> > Similarly to other device wrappers, turn them to static inlines
> > and place in header.
> 
> Why do these need to be inline functions?

Because they are small. devm_bitmap_free() and devm_bitmap_zalloc()
are pure one-line wrappers, and devm_bimap_alloc() is a 2 function
calls followed by conditionals, which is similar  to
__devm_add_action_or_reset() or devm_kmalloc_array() in the same file,
and much less than some other inliners in the source tree.

In my plans, I want to move bitmap_{z,}alloc/free() to linux/bitmap.h,
and that way devm_bitmap_alloc() together with other users would be
propagated __kmalloc_array() by compiler without generating pretty
useless call/ret's, and benefit from compile-time optimizations if
__builtin_constant_p() hits.

Maybe it's worth to do in this series.

Thanks,
Yury
Re: [PATCH 1/2] lib/bitmap: move bitmap allocators for device to linux/device.h
Posted by Greg Kroah-Hartman 2 years, 2 months ago
On Sun, Oct 08, 2023 at 08:39:13AM -0700, Yury Norov wrote:
> On Sun, Oct 08, 2023 at 06:53:49AM +0200, Greg Kroah-Hartman wrote:
> > On Sat, Oct 07, 2023 at 04:35:09PM -0700, Yury Norov wrote:
> > > The allocators are simple wrappers around bitmap_{alloc,free}().
> > > So move them from bitmap to device sources.
> > 
> > No, they belong in the bitmap.h file, as they are devm_* versions of the
> > same functions in this file.  They don't belong in the device.h file.
> 
> OK then. I don't thing that the functions are anything wrong, and
> don't want to 'get rid of them' in any way.
> 
> But could you please elaborate? I'm not too familiar to devm_* things,
> and to me devm_alloc/free() look similar to e.g.
> vfio_dma_bitmap_alloc_all() or iova_bitmap_alloc(), which allocate
> memory for bitmap + do some other initialization things.
> 
> And they all reside in corresponding subsystems. Why devm differs? 

They are just "devm" versions of the normal functions, so they belong
next to those normal functions as well.

> > > Similarly to other device wrappers, turn them to static inlines
> > > and place in header.
> > 
> > Why do these need to be inline functions?
> 
> Because they are small. devm_bitmap_free() and devm_bitmap_zalloc()
> are pure one-line wrappers, and devm_bimap_alloc() is a 2 function
> calls followed by conditionals, which is similar  to
> __devm_add_action_or_reset() or devm_kmalloc_array() in the same file,
> and much less than some other inliners in the source tree.

Are you sure this works properly?  the _free functions for devm_* calls
are set as function pointers and you just passed in a function pointer
to an inline function in your patch.  How is that going to work?  Will
you get even more versions than the original one had (hint, I think you
will, one per file it is called in...)

> In my plans, I want to move bitmap_{z,}alloc/free() to linux/bitmap.h,
> and that way devm_bitmap_alloc() together with other users would be
> propagated __kmalloc_array() by compiler without generating pretty
> useless call/ret's, and benefit from compile-time optimizations if
> __builtin_constant_p() hits.

Does that really matter for _alloc() calls?  These should not be on a
fast path (or at least the devm_*() ones should not be.  What workload
has this as being a bottleneck?

And remember, in modern systems with retbleed mitigations enabled, there
are no 'ret' calls in the kernel at all!

thanks,

greg k-h