111 lines
3.8 KiB
Diff
111 lines
3.8 KiB
Diff
From baa2300f62d4a20b94791de1a7fbbb32063ddbb2 Mon Sep 17 00:00:00 2001
|
|
Message-Id: <baa2300f62d4a20b94791de1a7fbbb32063ddbb2.1601675152.git.zanussi@kernel.org>
|
|
In-Reply-To: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org>
|
|
References: <5b5a156f9808b1acf1205606e03da117214549ea.1601675151.git.zanussi@kernel.org>
|
|
From: Mike Galbraith <umgwanakikbuti@gmail.com>
|
|
Date: Thu, 20 Oct 2016 11:15:22 +0200
|
|
Subject: [PATCH 247/333] drivers/zram: Don't disable preemption in
|
|
zcomp_stream_get/put()
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.148-rt64.tar.xz
|
|
|
|
In v4.7, the driver switched to percpu compression streams, disabling
|
|
preemption via get/put_cpu_ptr(). Use a per-zcomp_strm lock here. We
|
|
also have to fix an lock order issue in zram_decompress_page() such
|
|
that zs_map_object() nests inside of zcomp_stream_put() as it does in
|
|
zram_bvec_write().
|
|
|
|
Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com>
|
|
[bigeasy: get_locked_var() -> per zcomp_strm lock]
|
|
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
|
|
---
|
|
drivers/block/zram/zcomp.c | 12 ++++++++++--
|
|
drivers/block/zram/zcomp.h | 1 +
|
|
drivers/block/zram/zram_drv.c | 5 +++--
|
|
3 files changed, 14 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
|
|
index 4ed0a78fdc09..dd65a27ae2cc 100644
|
|
--- a/drivers/block/zram/zcomp.c
|
|
+++ b/drivers/block/zram/zcomp.c
|
|
@@ -116,12 +116,19 @@ ssize_t zcomp_available_show(const char *comp, char *buf)
|
|
|
|
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
|
|
{
|
|
- return *get_cpu_ptr(comp->stream);
|
|
+ struct zcomp_strm *zstrm;
|
|
+
|
|
+ zstrm = *this_cpu_ptr(comp->stream);
|
|
+ spin_lock(&zstrm->zcomp_lock);
|
|
+ return zstrm;
|
|
}
|
|
|
|
void zcomp_stream_put(struct zcomp *comp)
|
|
{
|
|
- put_cpu_ptr(comp->stream);
|
|
+ struct zcomp_strm *zstrm;
|
|
+
|
|
+ zstrm = *this_cpu_ptr(comp->stream);
|
|
+ spin_unlock(&zstrm->zcomp_lock);
|
|
}
|
|
|
|
int zcomp_compress(struct zcomp_strm *zstrm,
|
|
@@ -171,6 +178,7 @@ int zcomp_cpu_up_prepare(unsigned int cpu, struct hlist_node *node)
|
|
pr_err("Can't allocate a compression stream\n");
|
|
return -ENOMEM;
|
|
}
|
|
+ spin_lock_init(&zstrm->zcomp_lock);
|
|
*per_cpu_ptr(comp->stream, cpu) = zstrm;
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
|
|
index 41c1002a7d7d..d424eafcbf8e 100644
|
|
--- a/drivers/block/zram/zcomp.h
|
|
+++ b/drivers/block/zram/zcomp.h
|
|
@@ -14,6 +14,7 @@ struct zcomp_strm {
|
|
/* compression/decompression buffer */
|
|
void *buffer;
|
|
struct crypto_comp *tfm;
|
|
+ spinlock_t zcomp_lock;
|
|
};
|
|
|
|
/* dynamic per-device compression frontend */
|
|
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
|
|
index 95b28f842533..98bf78861e52 100644
|
|
--- a/drivers/block/zram/zram_drv.c
|
|
+++ b/drivers/block/zram/zram_drv.c
|
|
@@ -1028,6 +1028,7 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index,
|
|
unsigned long handle;
|
|
unsigned int size;
|
|
void *src, *dst;
|
|
+ struct zcomp_strm *zstrm;
|
|
|
|
if (zram_wb_enabled(zram)) {
|
|
zram_slot_lock(zram, index);
|
|
@@ -1062,6 +1063,7 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index,
|
|
|
|
size = zram_get_obj_size(zram, index);
|
|
|
|
+ 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);
|
|
@@ -1069,14 +1071,13 @@ 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);
|
|
- zcomp_stream_put(zram->comp);
|
|
}
|
|
zs_unmap_object(zram->mem_pool, handle);
|
|
+ zcomp_stream_put(zram->comp);
|
|
zram_slot_unlock(zram, index);
|
|
|
|
/* Should NEVER happen. Return bio error if it does. */
|
|
--
|
|
2.17.1
|
|
|