Skip to content

Commit 6ffef4c

Browse files
minchankgregkh
authored andcommitted
zram: fix lockdep warning of free block handling
[ Upstream commit 3c9959e ] Patch series "zram idle page writeback", v3. Inherently, swap device has many idle pages which are rare touched since it was allocated. It is never problem if we use storage device as swap. However, it's just waste for zram-swap. This patchset supports zram idle page writeback feature. * Admin can define what is idle page "no access since X time ago" * Admin can define when zram should writeback them * Admin can define when zram should stop writeback to prevent wearout Details are in each patch's description. This patch (of 7): ================================ WARNING: inconsistent lock state 4.19.0+ #390 Not tainted -------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. zram_verify/2095 [HC0[0]:SC1[1]:HE1:SE0] takes: 00000000b1828693 (&(&zram->bitmap_lock)->rlock){+.?.}, at: put_entry_bdev+0x1e/0x50 {SOFTIRQ-ON-W} state was registered at: _raw_spin_lock+0x2c/0x40 zram_make_request+0x755/0xdc9 generic_make_request+0x373/0x6a0 submit_bio+0x6c/0x140 __swap_writepage+0x3a8/0x480 shrink_page_list+0x1102/0x1a60 shrink_inactive_list+0x21b/0x3f0 shrink_node_memcg.constprop.99+0x4f8/0x7e0 shrink_node+0x7d/0x2f0 do_try_to_free_pages+0xe0/0x300 try_to_free_pages+0x116/0x2b0 __alloc_pages_slowpath+0x3f4/0xf80 __alloc_pages_nodemask+0x2a2/0x2f0 __handle_mm_fault+0x42e/0xb50 handle_mm_fault+0x55/0xb0 __do_page_fault+0x235/0x4b0 page_fault+0x1e/0x30 irq event stamp: 228412 hardirqs last enabled at (228412): [<ffffffff98245846>] __slab_free+0x3e6/0x600 hardirqs last disabled at (228411): [<ffffffff98245625>] __slab_free+0x1c5/0x600 softirqs last enabled at (228396): [<ffffffff98e0031e>] __do_softirq+0x31e/0x427 softirqs last disabled at (228403): [<ffffffff98072051>] irq_exit+0xd1/0xe0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&(&zram->bitmap_lock)->rlock); <Interrupt> lock(&(&zram->bitmap_lock)->rlock); *** DEADLOCK *** no locks held by zram_verify/2095. stack backtrace: CPU: 5 PID: 2095 Comm: zram_verify Not tainted 4.19.0+ #390 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 Call Trace: <IRQ> dump_stack+0x67/0x9b print_usage_bug+0x1bd/0x1d3 mark_lock+0x4aa/0x540 __lock_acquire+0x51d/0x1300 lock_acquire+0x90/0x180 _raw_spin_lock+0x2c/0x40 put_entry_bdev+0x1e/0x50 zram_free_page+0xf6/0x110 zram_slot_free_notify+0x42/0xa0 end_swap_bio_read+0x5b/0x170 blk_update_request+0x8f/0x340 scsi_end_request+0x2c/0x1e0 scsi_io_completion+0x98/0x650 blk_done_softirq+0x9e/0xd0 __do_softirq+0xcc/0x427 irq_exit+0xd1/0xe0 do_IRQ+0x93/0x120 common_interrupt+0xf/0xf </IRQ> With writeback feature, zram_slot_free_notify could be called in softirq context by end_swap_bio_read. However, bitmap_lock is not aware of that so lockdep yell out: get_entry_bdev spin_lock(bitmap->lock); irq softirq end_swap_bio_read zram_slot_free_notify zram_slot_lock <-- deadlock prone zram_free_page put_entry_bdev spin_lock(bitmap->lock); <-- deadlock prone With akpm's suggestion (i.e. bitmap operation is already atomic), we could remove bitmap lock. It might fail to find a empty slot if serious contention happens. However, it's not severe problem because huge page writeback has already possiblity to fail if there is severe memory pressure. Worst case is just keeping the incompressible in memory, not storage. The other problem is zram_slot_lock in zram_slot_slot_free_notify. To make it safe is this patch introduces zram_slot_trylock where zram_slot_free_notify uses it. Although it's rare to be contented, this patch adds new debug stat "miss_free" to keep monitoring how often it happens. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Minchan Kim <[email protected]> Reviewed-by: Sergey Senozhatsky <[email protected]> Reviewed-by: Joey Pabalinas <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 39255e9 commit 6ffef4c

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

drivers/block/zram/zram_drv.c

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ static size_t huge_class_size;
5353

5454
static void zram_free_page(struct zram *zram, size_t index);
5555

56+
static int zram_slot_trylock(struct zram *zram, u32 index)
57+
{
58+
return bit_spin_trylock(ZRAM_LOCK, &zram->table[index].value);
59+
}
60+
5661
static void zram_slot_lock(struct zram *zram, u32 index)
5762
{
5863
bit_spin_lock(ZRAM_LOCK, &zram->table[index].value);
@@ -401,7 +406,6 @@ static ssize_t backing_dev_store(struct device *dev,
401406
goto out;
402407

403408
reset_bdev(zram);
404-
spin_lock_init(&zram->bitmap_lock);
405409

406410
zram->old_block_size = old_block_size;
407411
zram->bdev = bdev;
@@ -445,29 +449,24 @@ static ssize_t backing_dev_store(struct device *dev,
445449

446450
static unsigned long get_entry_bdev(struct zram *zram)
447451
{
448-
unsigned long entry;
449-
450-
spin_lock(&zram->bitmap_lock);
452+
unsigned long blk_idx = 1;
453+
retry:
451454
/* skip 0 bit to confuse zram.handle = 0 */
452-
entry = find_next_zero_bit(zram->bitmap, zram->nr_pages, 1);
453-
if (entry == zram->nr_pages) {
454-
spin_unlock(&zram->bitmap_lock);
455+
blk_idx = find_next_zero_bit(zram->bitmap, zram->nr_pages, blk_idx);
456+
if (blk_idx == zram->nr_pages)
455457
return 0;
456-
}
457458

458-
set_bit(entry, zram->bitmap);
459-
spin_unlock(&zram->bitmap_lock);
459+
if (test_and_set_bit(blk_idx, zram->bitmap))
460+
goto retry;
460461

461-
return entry;
462+
return blk_idx;
462463
}
463464

464465
static void put_entry_bdev(struct zram *zram, unsigned long entry)
465466
{
466467
int was_set;
467468

468-
spin_lock(&zram->bitmap_lock);
469469
was_set = test_and_clear_bit(entry, zram->bitmap);
470-
spin_unlock(&zram->bitmap_lock);
471470
WARN_ON_ONCE(!was_set);
472471
}
473472

@@ -888,9 +887,10 @@ static ssize_t debug_stat_show(struct device *dev,
888887

889888
down_read(&zram->init_lock);
890889
ret = scnprintf(buf, PAGE_SIZE,
891-
"version: %d\n%8llu\n",
890+
"version: %d\n%8llu %8llu\n",
892891
version,
893-
(u64)atomic64_read(&zram->stats.writestall));
892+
(u64)atomic64_read(&zram->stats.writestall),
893+
(u64)atomic64_read(&zram->stats.miss_free));
894894
up_read(&zram->init_lock);
895895

896896
return ret;
@@ -1402,10 +1402,14 @@ static void zram_slot_free_notify(struct block_device *bdev,
14021402

14031403
zram = bdev->bd_disk->private_data;
14041404

1405-
zram_slot_lock(zram, index);
1405+
atomic64_inc(&zram->stats.notify_free);
1406+
if (!zram_slot_trylock(zram, index)) {
1407+
atomic64_inc(&zram->stats.miss_free);
1408+
return;
1409+
}
1410+
14061411
zram_free_page(zram, index);
14071412
zram_slot_unlock(zram, index);
1408-
atomic64_inc(&zram->stats.notify_free);
14091413
}
14101414

14111415
static int zram_rw_page(struct block_device *bdev, sector_t sector,

drivers/block/zram/zram_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ struct zram_stats {
7979
atomic64_t pages_stored; /* no. of pages currently stored */
8080
atomic_long_t max_used_pages; /* no. of maximum pages stored */
8181
atomic64_t writestall; /* no. of write slow paths */
82+
atomic64_t miss_free; /* no. of missed free */
8283
};
8384

8485
struct zram {
@@ -110,7 +111,6 @@ struct zram {
110111
unsigned int old_block_size;
111112
unsigned long *bitmap;
112113
unsigned long nr_pages;
113-
spinlock_t bitmap_lock;
114114
#endif
115115
#ifdef CONFIG_ZRAM_MEMORY_TRACKING
116116
struct dentry *debugfs_dir;

0 commit comments

Comments
 (0)