lib/sbitmap: allocate sb->map via kvzalloc_node
authorMing Lei <ming.lei@redhat.com>
Wed, 16 Mar 2022 01:27:08 +0000 (09:27 +0800)
committerJens Axboe <axboe@kernel.dk>
Tue, 22 Mar 2022 02:01:34 +0000 (20:01 -0600)
sbitmap has been used in scsi for replacing atomic operations on
sdev->device_busy, so IOPS on some fast scsi storage can be improved.

However, sdev->device_busy can be changed in fast path, so we have to
allocate the sb->map statically. sdev->device_busy has been capped to 1024,
but some drivers may configure the default depth as < 8, then
cause each sbitmap word to hold only one bit. Finally 1024 * 128(
sizeof(sbitmap_word)) bytes is needed for sb->map, given it is order 5
allocation, sometimes it may fail.

Avoid the issue by using kvzalloc_node() for allocating sb->map.

Cc: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20220316012708.354668-1-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/sbitmap.h
lib/sbitmap.c

index dffeb82..8f5a86e 100644 (file)
@@ -174,7 +174,7 @@ static inline unsigned int __map_depth(const struct sbitmap *sb, int index)
 static inline void sbitmap_free(struct sbitmap *sb)
 {
        free_percpu(sb->alloc_hint);
-       kfree(sb->map);
+       kvfree(sb->map);
        sb->map = NULL;
 }
 
index 2eb3de1..ae4fd4d 100644 (file)
@@ -110,7 +110,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift,
                sb->alloc_hint = NULL;
        }
 
-       sb->map = kcalloc_node(sb->map_nr, sizeof(*sb->map), flags, node);
+       sb->map = kvzalloc_node(sb->map_nr * sizeof(*sb->map), flags, node);
        if (!sb->map) {
                free_percpu(sb->alloc_hint);
                return -ENOMEM;