summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch')
-rw-r--r--debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch103
1 files changed, 103 insertions, 0 deletions
diff --git a/debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch b/debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch
new file mode 100644
index 000000000..dfb12a9b2
--- /dev/null
+++ b/debian/patches-rt/0246-drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch
@@ -0,0 +1,103 @@
+From: Mike Galbraith <umgwanakikbuti@gmail.com>
+Date: Thu, 20 Oct 2016 11:15:22 +0200
+Subject: [PATCH 246/342] drivers/zram: Don't disable preemption in
+ zcomp_stream_get/put()
+Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=2689fcbfe8b15a102ec207f5b8c94095333fae9c
+
+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 04e4297f8318..2919ad13bce9 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. */