linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] zram: factor-out zram_decompress_page() function
@ 2012-10-27 16:00 Sergey Senozhatsky
  2012-10-29 17:14 ` Nitin Gupta
  0 siblings, 1 reply; 12+ messages in thread
From: Sergey Senozhatsky @ 2012-10-27 16:00 UTC (permalink / raw)
  To: Nitin Gupta; +Cc: Greg Kroah-Hartman, linux-kernel

  zram: factor-out zram_decompress_page() function

  zram_bvec_read() shared decompress functionality with zram_read_before_write() function.
  Factor-out and make commonly used zram_decompress_page() function, which also simplified
  error handling in zram_bvec_read().
    
  Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>

---

 drivers/staging/zram/zram_drv.c | 115 +++++++++++++++++-----------------------
 1 file changed, 50 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index 6edefde..7585467 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -183,62 +183,25 @@ static inline int is_partial_io(struct bio_vec *bvec)
 	return bvec->bv_len != PAGE_SIZE;
 }
 
-static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
-			  u32 index, int offset, struct bio *bio)
+static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
 {
-	int ret;
-	size_t clen;
-	struct page *page;
-	unsigned char *user_mem, *cmem, *uncmem = NULL;
-
-	page = bvec->bv_page;
-
-	if (zram_test_flag(zram, index, ZRAM_ZERO)) {
-		handle_zero_page(bvec);
-		return 0;
-	}
+	int ret = LZO_E_OK;
+	size_t clen = PAGE_SIZE;
+	unsigned char *cmem;
+	unsigned long handle = zram->table[index].handle;
 
-	/* Requested page is not present in compressed area */
-	if (unlikely(!zram->table[index].handle)) {
-		pr_debug("Read before write: sector=%lu, size=%u",
-			 (ulong)(bio->bi_sector), bio->bi_size);
-		handle_zero_page(bvec);
+	if (!handle || zram_test_flag(zram, index, ZRAM_ZERO)) {
+		memset(mem, 0, PAGE_SIZE);
 		return 0;
 	}
 
-	if (is_partial_io(bvec)) {
-		/* Use  a temporary buffer to decompress the page */
-		uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
-		if (!uncmem) {
-			pr_info("Error allocating temp memory!\n");
-			return -ENOMEM;
-		}
-	}
-
-	user_mem = kmap_atomic(page);
-	if (!is_partial_io(bvec))
-		uncmem = user_mem;
-	clen = PAGE_SIZE;
-
-	cmem = zs_map_object(zram->mem_pool, zram->table[index].handle,
-				ZS_MM_RO);
-
-	if (zram->table[index].size == PAGE_SIZE) {
-		memcpy(uncmem, cmem, PAGE_SIZE);
-		ret = LZO_E_OK;
-	} else {
+	cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
+	if (zram->table[index].size == PAGE_SIZE)
+		memcpy(mem, cmem, PAGE_SIZE);
+	else
 		ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
-				    uncmem, &clen);
-	}
-
-	if (is_partial_io(bvec)) {
-		memcpy(user_mem + bvec->bv_offset, uncmem + offset,
-		       bvec->bv_len);
-		kfree(uncmem);
-	}
-
-	zs_unmap_object(zram->mem_pool, zram->table[index].handle);
-	kunmap_atomic(user_mem);
+						mem, &clen);
+	zs_unmap_object(zram->mem_pool, handle);
 
 	/* Should NEVER happen. Return bio error if it does. */
 	if (unlikely(ret != LZO_E_OK)) {
@@ -247,36 +210,58 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
 		return ret;
 	}
 
-	flush_dcache_page(page);
-
 	return 0;
 }
 
-static int zram_read_before_write(struct zram *zram, char *mem, u32 index)
+static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec,
+			  u32 index, int offset, struct bio *bio)
 {
 	int ret;
-	size_t clen = PAGE_SIZE;
-	unsigned char *cmem;
-	unsigned long handle = zram->table[index].handle;
+	struct page *page;
+	unsigned char *user_mem, *uncmem = NULL;
 
-	if (zram_test_flag(zram, index, ZRAM_ZERO) || !handle) {
-		memset(mem, 0, PAGE_SIZE);
+	page = bvec->bv_page;
+
+	if (unlikely(!zram->table[index].handle) ||
+			zram_test_flag(zram, index, ZRAM_ZERO)) {
+		pr_debug("Read before write: sector=%lu, size=%u",
+			 (ulong)(bio->bi_sector), bio->bi_size);
+		handle_zero_page(bvec);
 		return 0;
 	}
 
-	cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
-	ret = lzo1x_decompress_safe(cmem, zram->table[index].size,
-				    mem, &clen);
-	zs_unmap_object(zram->mem_pool, handle);
+	user_mem = kmap_atomic(page);
+	if (is_partial_io(bvec))
+		/* Use  a temporary buffer to decompress the page */
+		uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	else
+		uncmem = user_mem;
 
+	if (!uncmem) {
+		pr_info("Unable to allocate temp memory\n");
+		ret = -ENOMEM;
+		goto out_cleanup;
+	}
+
+	ret = zram_decompress_page(zram, uncmem, index);
 	/* Should NEVER happen. Return bio error if it does. */
 	if (unlikely(ret != LZO_E_OK)) {
 		pr_err("Decompression failed! err=%d, page=%u\n", ret, index);
 		zram_stat64_inc(zram, &zram->stats.failed_reads);
-		return ret;
+		goto out_cleanup;
 	}
 
-	return 0;
+	if (is_partial_io(bvec))
+		memcpy(user_mem + bvec->bv_offset, uncmem + offset,
+				bvec->bv_len);
+
+	flush_dcache_page(page);
+	ret = 0;
+out_cleanup:
+	kunmap_atomic(user_mem);
+	if (is_partial_io(bvec))
+		kfree(uncmem);
+	return ret;
 }
 
 static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
@@ -302,7 +287,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,
 			ret = -ENOMEM;
 			goto out;
 		}
-		ret = zram_read_before_write(zram, uncmem, index);
+		ret = zram_decompress_page(zram, uncmem, index);
 		if (ret) {
 			kfree(uncmem);
 			goto out;



^ permalink raw reply related	[flat|nested] 12+ messages in thread
* [PATCH 2/2] zram: permit sleeping while in pool zs_malloc()
@ 2012-10-30  9:03 Sergey Senozhatsky
  2012-10-30 18:04 ` Greg Kroah-Hartman
  0 siblings, 1 reply; 12+ messages in thread
From: Sergey Senozhatsky @ 2012-10-30  9:03 UTC (permalink / raw)
  To: Nitin Gupta; +Cc: Greg Kroah-Hartman, linux-kernel

    zram: permit sleeping while in pool zs_malloc()
    
    zram pool is created with GFP_NOIO flag, which may trigger errors because nested allocation
    are able to sleep. set __GFP_WAIT pool flag in zram_init_device() to allow sleeping.
    
     BUG: sleeping function called from invalid context at mm/page_alloc.c:2603
     in_atomic(): 1, irqs_disabled(): 0, pid: 2555, name: mkfs.reiserfs
     2 locks held by mkfs.reiserfs/2555:
      #0:  (&zram->init_lock){+++++.}, at: [<ffffffffa0127d18>] zram_make_request+0x48/0x270 [zram]
      #1:  (&zram->lock){++++..}, at: [<ffffffffa012742b>] zram_bvec_rw+0x3b/0x510 [zram]
     Pid: 2555, comm: mkfs.reiserfs Tainted: G         C   3.7.0-rc3-dbg-01664-gf2d9543-dirty #1401
     Call Trace:
      [<ffffffff8107984a>] __might_sleep+0x15a/0x250
      [<ffffffff8111df9b>] __alloc_pages_nodemask+0x1bb/0x920
      [<ffffffffa00f0b93>] ? zs_malloc+0x63/0x480 [zsmalloc]
      [<ffffffff81320e2d>] ? do_raw_spin_unlock+0x5d/0xb0
      [<ffffffffa00f0cf5>] zs_malloc+0x1c5/0x480 [zsmalloc]
      [<ffffffffa0127574>] zram_bvec_rw+0x184/0x510 [zram]
      [<ffffffffa0127e85>] zram_make_request+0x1b5/0x270 [zram]
      [<ffffffff812ec0c2>] generic_make_request+0xc2/0x110
      [<ffffffff812ec17a>] submit_bio+0x6a/0x140
      [<ffffffff8119f27b>] submit_bh+0xfb/0x130
      [<ffffffff811a2710>] __block_write_full_page+0x220/0x3d0
      [<ffffffff810a7784>] ? __lock_is_held+0x54/0x80
      [<ffffffff8119ffb0>] ? end_buffer_async_read+0x210/0x210
      [<ffffffff811a7aa0>] ? blkdev_get_blocks+0xd0/0xd0
      [<ffffffff811a7aa0>] ? blkdev_get_blocks+0xd0/0xd0
      [<ffffffff8119ffb0>] ? end_buffer_async_read+0x210/0x210
      [<ffffffff811a298f>] block_write_full_page_endio+0xcf/0x100
      [<ffffffff8111f555>] ? clear_page_dirty_for_io+0x105/0x130
      [<ffffffff811a29d5>] block_write_full_page+0x15/0x20
      [<ffffffff811a7038>] blkdev_writepage+0x18/0x20
      [<ffffffff8111f3aa>] __writepage+0x1a/0x50
      [<ffffffff8111f8b0>] write_cache_pages+0x200/0x630
      [<ffffffff8111e883>] ? free_hot_cold_page+0x113/0x1a0
      [<ffffffff8111f390>] ? global_dirtyable_memory+0x40/0x40
      [<ffffffff8111fd2d>] generic_writepages+0x4d/0x70
      [<ffffffff81121071>] do_writepages+0x21/0x50
      [<ffffffff81116939>] __filemap_fdatawrite_range+0x59/0x60
      [<ffffffff81116a40>] filemap_write_and_wait_range+0x50/0x70
      [<ffffffff811a73a4>] blkdev_fsync+0x24/0x50
      [<ffffffff8119d5bd>] do_fsync+0x5d/0x90
      [<ffffffff8119d990>] sys_fsync+0x10/0x20
      [<ffffffff815dce06>] tracesys+0xd4/0xd9
    
    Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>

---

 drivers/staging/zram/zram_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c
index d2e0a85..47f2e3a 100644
--- a/drivers/staging/zram/zram_drv.c
+++ b/drivers/staging/zram/zram_drv.c
@@ -576,7 +576,7 @@ int zram_init_device(struct zram *zram)
 	/* zram devices sort of resembles non-rotational disks */
 	queue_flag_set_unlocked(QUEUE_FLAG_NONROT, zram->disk->queue);
 
-	zram->mem_pool = zs_create_pool("zram", GFP_NOIO | __GFP_HIGHMEM);
+	zram->mem_pool = zs_create_pool("zram", GFP_NOIO | __GFP_WAIT | __GFP_HIGHMEM);
 	if (!zram->mem_pool) {
 		pr_err("Error creating memory pool\n");
 		ret = -ENOMEM;


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-10-31  7:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-27 16:00 [PATCH 1/2] zram: factor-out zram_decompress_page() function Sergey Senozhatsky
2012-10-29 17:14 ` Nitin Gupta
2012-10-29 17:33   ` Sergey Senozhatsky
2012-10-29 18:05   ` [PATCH 1/2] zram: factor-out zram_decompress_page() function (v2) Sergey Senozhatsky
2012-10-29 18:32     ` Nitin Gupta
2012-10-29 18:57       ` Sergey Senozhatsky
2012-10-29 19:00       ` [PATCH 1/2] zram: factor-out zram_decompress_page() function (v3) Sergey Senozhatsky
2012-10-30 21:04   ` [PATCH 1/2] zram: factor-out zram_decompress_page() function Sergey Senozhatsky
2012-10-31  3:55     ` Nitin Gupta
2012-10-31  7:05       ` zram: use after free Sergey Senozhatsky
  -- strict thread matches above, loose matches on Subject: below --
2012-10-30  9:03 [PATCH 2/2] zram: permit sleeping while in pool zs_malloc() Sergey Senozhatsky
2012-10-30 18:04 ` Greg Kroah-Hartman
2012-10-30 18:58   ` [PATCH 1/2] zram: factor-out zram_decompress_page() function Sergey Senozhatsky
2012-10-30 19:18     ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).