]> git.baikalelectronics.ru Git - kernel.git/commitdiff
zram: Fix __zram_bvec_{read,write}() locking order
authorPeter Zijlstra <peterz@infradead.org>
Mon, 19 Oct 2020 10:13:53 +0000 (12:13 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 19 Oct 2020 15:32:28 +0000 (09:32 -0600)
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>
Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/zram/zram_drv.c

index bff3d4021c18e17ac43f80edf76f17b84c30f6d9..e13201424ba2956372256af5a7777cfea61763db 100644 (file)
@@ -1218,10 +1218,11 @@ out:
 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)) {
@@ -1252,6 +1253,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);
@@ -1259,8 +1263,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);