Skip to content

Commit 2d623c9

Browse files
umgwanakikbutijnettlet
authored andcommitted
drivers/zram: Don't disable preemption in zcomp_stream_get/put()
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 <[email protected]> [bigeasy: get_locked_var() -> per zcomp_strm lock] Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
1 parent 1f46b8d commit 2d623c9

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

drivers/block/zram/zcomp.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,19 @@ ssize_t zcomp_available_show(const char *comp, char *buf)
118118

119119
struct zcomp_strm *zcomp_stream_get(struct zcomp *comp)
120120
{
121-
return *get_cpu_ptr(comp->stream);
121+
struct zcomp_strm *zstrm;
122+
123+
zstrm = *this_cpu_ptr(comp->stream);
124+
spin_lock(&zstrm->zcomp_lock);
125+
return zstrm;
122126
}
123127

124128
void zcomp_stream_put(struct zcomp *comp)
125129
{
126-
put_cpu_ptr(comp->stream);
130+
struct zcomp_strm *zstrm;
131+
132+
zstrm = *this_cpu_ptr(comp->stream);
133+
spin_unlock(&zstrm->zcomp_lock);
127134
}
128135

129136
int zcomp_compress(struct zcomp_strm *zstrm,
@@ -174,6 +181,7 @@ static int __zcomp_cpu_notifier(struct zcomp *comp,
174181
pr_err("Can't allocate a compression stream\n");
175182
return NOTIFY_BAD;
176183
}
184+
spin_lock_init(&zstrm->zcomp_lock);
177185
*per_cpu_ptr(comp->stream, cpu) = zstrm;
178186
break;
179187
case CPU_DEAD:

drivers/block/zram/zcomp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ struct zcomp_strm {
1414
/* compression/decompression buffer */
1515
void *buffer;
1616
struct crypto_comp *tfm;
17+
spinlock_t zcomp_lock;
1718
};
1819

1920
/* dynamic per-device compression frontend */

drivers/block/zram/zram_drv.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
577577
struct zram_meta *meta = zram->meta;
578578
unsigned long handle;
579579
unsigned int size;
580+
struct zcomp_strm *zstrm;
580581

581582
zram_lock_table(&meta->table[index]);
582583
handle = meta->table[index].handle;
@@ -588,16 +589,15 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
588589
return 0;
589590
}
590591

592+
zstrm = zcomp_stream_get(zram->comp);
591593
cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO);
592594
if (size == PAGE_SIZE) {
593595
memcpy(mem, cmem, PAGE_SIZE);
594596
} else {
595-
struct zcomp_strm *zstrm = zcomp_stream_get(zram->comp);
596-
597597
ret = zcomp_decompress(zstrm, cmem, size, mem);
598-
zcomp_stream_put(zram->comp);
599598
}
600599
zs_unmap_object(meta->mem_pool, handle);
600+
zcomp_stream_put(zram->comp);
601601
zram_unlock_table(&meta->table[index]);
602602

603603
/* Should NEVER happen. Return bio error if it does. */

0 commit comments

Comments
 (0)