|
|
@@ -230,6 +230,7 @@ static struct zram_meta *zram_meta_alloc(u64 disksize)
|
|
|
}
|
|
|
|
|
|
rwlock_init(&meta->tb_lock);
|
|
|
+ mutex_init(&meta->buffer_lock);
|
|
|
return meta;
|
|
|
|
|
|
free_table:
|
|
|
@@ -412,6 +413,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
|
|
|
struct page *page;
|
|
|
unsigned char *user_mem, *cmem, *src, *uncmem = NULL;
|
|
|
struct zram_meta *meta = zram->meta;
|
|
|
+ bool locked = false;
|
|
|
|
|
|
page = bvec->bv_page;
|
|
|
src = meta->compress_buffer;
|
|
|
@@ -431,6 +433,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&meta->buffer_lock);
|
|
|
+ locked = true;
|
|
|
user_mem = kmap_atomic(page);
|
|
|
|
|
|
if (is_partial_io(bvec)) {
|
|
|
@@ -457,7 +461,6 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
|
|
|
|
|
|
ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen,
|
|
|
meta->compress_workmem);
|
|
|
-
|
|
|
if (!is_partial_io(bvec)) {
|
|
|
kunmap_atomic(user_mem);
|
|
|
user_mem = NULL;
|
|
|
@@ -514,6 +517,8 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
|
|
|
atomic_inc(&zram->stats.good_compress);
|
|
|
|
|
|
out:
|
|
|
+ if (locked)
|
|
|
+ mutex_unlock(&meta->buffer_lock);
|
|
|
if (is_partial_io(bvec))
|
|
|
kfree(uncmem);
|
|
|
|
|
|
@@ -527,15 +532,10 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
- if (rw == READ) {
|
|
|
- down_read(&zram->lock);
|
|
|
+ if (rw == READ)
|
|
|
ret = zram_bvec_read(zram, bvec, index, offset, bio);
|
|
|
- up_read(&zram->lock);
|
|
|
- } else {
|
|
|
- down_write(&zram->lock);
|
|
|
+ else
|
|
|
ret = zram_bvec_write(zram, bvec, index, offset);
|
|
|
- up_write(&zram->lock);
|
|
|
- }
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
@@ -808,7 +808,6 @@ static int create_device(struct zram *zram, int device_id)
|
|
|
{
|
|
|
int ret = -ENOMEM;
|
|
|
|
|
|
- init_rwsem(&zram->lock);
|
|
|
init_rwsem(&zram->init_lock);
|
|
|
|
|
|
zram->queue = blk_alloc_queue(GFP_KERNEL);
|