[PATCH 1/2] zram: fix quadratic writeback bitmap search

From: Sergey Senozhatsky

Date: Fri Oct 30 2026 - 00:18:03 EST


zram_reserve_bdev_block() always scans writeback's bitmap from
offset 0, which results in quadratic complexity. Introduce
per-device bitmap cursor member that is set to next to most
recently allocated bit, so next time the bitmap scan starts
from that offset.

Signed-off-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>
---
drivers/block/zram/zram_drv.c | 17 ++++++++++++++---
drivers/block/zram/zram_drv.h | 1 +
2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 9593c14a1f81..632045b65bdb 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -694,6 +694,7 @@ static void reset_bdev(struct zram *zram)
zram->disk->fops = &zram_devops;
kvfree(zram->bitmap);
zram->bitmap = NULL;
+ zram->bitmap_cursor = 0;
zram->nr_pages = 0;
}

@@ -786,6 +787,7 @@ static ssize_t backing_dev_store(struct device *dev,
zram->bdev = I_BDEV(inode);
zram->backing_dev = backing_dev;
zram->bitmap = bitmap;
+ zram->bitmap_cursor = 0;
zram->nr_pages = nr_pages;

pr_info("setup backing device %s\n", file_name);
@@ -807,10 +809,19 @@ static unsigned long zram_reserve_bdev_block(struct zram *zram)
{
unsigned long blk_idx;

- blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages, 0);
- if (blk_idx == zram->nr_pages)
- return INVALID_BDEV_BLOCK;
+ /* continue after the last allocated block */
+ blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages,
+ zram->bitmap_cursor);
+ /* wrap */
+ if (blk_idx == zram->nr_pages) {
+ blk_idx = find_next_zero_bit(zram->bitmap, zram->bitmap_cursor,
+ 0);
+ /* bitmap is full */
+ if (blk_idx == zram->bitmap_cursor)
+ return INVALID_BDEV_BLOCK;
+ }

+ zram->bitmap_cursor = blk_idx + 1;
set_bit(blk_idx, zram->bitmap);
atomic64_inc(&zram->stats.bd_count);
return blk_idx;
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 7a55d751417e..c563a7c13a49 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -152,6 +152,7 @@ struct zram {
u64 bd_wb_limit;
struct block_device *bdev;
unsigned long *bitmap;
+ unsigned long bitmap_cursor;
unsigned long nr_pages;
#endif
#ifdef CONFIG_ZRAM_MEMORY_TRACKING
--
2.56.0.317.g454f8302e1-goog