lib/sbitmap: allocate sb->map via kvzalloc_node
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2071832 Upstream Status: From upstream linux mainline 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> (cherry picked from commit 863a66cdb4df25fd146d9851c3289072298566d5) Signed-off-by: Ewan D. Milne <emilne@redhat.com>
This commit is contained in:
parent
cce2fcde29
commit
95b38e96d3
|
@ -165,7 +165,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue