Message ID | 20201019101353.GJ2628@hirez.programming.kicks-ass.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | zram: Fix __zram_bvec_{read,write}() locking order | expand |
On Mon, Oct 19, 2020 at 12:13:53PM +0200, Peter Zijlstra wrote: > > Mikhail reported a lockdep spat detailing how __zram_bvec_read() and > __zram_bvec_write() use zstrm->lock and zspage->lock in opposite order. > > Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> Acked-by: Minchan Kim <minchan@kernel.org> Thanks for the fix.
On 2020-10-19 12:13:53 [+0200], Peter Zijlstra wrote: > > Mikhail reported a lockdep spat detailing how __zram_bvec_read() and > __zram_bvec_write() use zstrm->lock and zspage->lock in opposite order. > > Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> We have the same patch in RT. I didn't submit it with the other local-lock patches because this splat pops up once pin_tag() is made a sleeping lock. I missed the part where migrate_read_lock() can be a lock. So: Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Sebastian
On 10/19/20 4:13 AM, Peter Zijlstra wrote: > > Mikhail reported a lockdep spat detailing how __zram_bvec_read() and > __zram_bvec_write() use zstrm->lock and zspage->lock in opposite order. Applied, thanks.
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 9100ac36670a..c1e2c2e1cde8 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -1216,10 +1216,11 @@ static void zram_free_page(struct zram *zram, size_t index) static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, struct bio *bio, bool partial_io) { - int ret; + struct zcomp_strm *zstrm; unsigned long handle; unsigned int size; void *src, *dst; + int ret; zram_slot_lock(zram, index); if (zram_test_flag(zram, index, ZRAM_WB)) { @@ -1250,6 +1251,9 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, size = zram_get_obj_size(zram, index); + if (size != PAGE_SIZE) + zstrm = zcomp_stream_get(zram->comp); + src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { dst = kmap_atomic(page); @@ -1257,8 +1261,6 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index, kunmap_atomic(dst); ret = 0; } else { - struct zcomp_strm *zstrm = zcomp_stream_get(zram->comp); - dst = kmap_atomic(page); ret = zcomp_decompress(zstrm, src, size, dst); kunmap_atomic(dst);