<br><div class="gmail_quote">From 4d52438c9640e64203c2434a74e2abfe3a4168ec Mon Sep 17 00:00:00 2001<br>From: Manish Sharma <<a href="mailto:manishrma@gmail.com" target="_blank">manishrma@gmail.com</a>><br>Date: Thu, 4 Apr 2013 10:32:08 +0530<br>
Subject: [PATCH] zram percpu implementation<br>
<br>This patch will create a percpu structures compression algo.<br>1. Takes extra memory for workspace buffers.<br>I haven't seen any performance gain with this need to find the<br>root cause.<br>---<br> drivers/staging/zram/zram_drv.c | 69 +++++++++++++++++++++++++++++++--------<br>
drivers/staging/zram/zram_drv.h | 9 +++--<br> 2 files changed, 62 insertions(+), 16 deletions(-)<br><br>diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c<br>index 071e058..5aef8cc 100644<br>
--- a/drivers/staging/zram/zram_drv.c<br>+++ b/drivers/staging/zram/zram_drv.c<br>@@ -271,9 +271,10 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,<br> unsigned long handle;<br> struct page *page;<br>
unsigned char *user_mem, *cmem, *src, *uncmem = NULL;<br>+ struct zram_buff *zbuff;<br><br> page = bvec->bv_page;<br>- src = zram->compress_buffer;<br>+/* src = zram->compress_buffer; */<br><br> if (is_partial_io(bvec)) {<br>
/*<br>@@ -318,9 +319,11 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,<br> ret = 0;<br> goto out;<br> }<br>+ zbuff = get_cpu_ptr(zram->zbuff);<br>+ src = zbuff->compress_buffer;<br>
<br> ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen,<br>- zram->compress_workmem);<br>+ zbuff->compress_workmem);<br><br> if (!is_partial_io(bvec)) {<br> kunmap_atomic(user_mem);<br>
@@ -329,6 +332,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,<br> }<br><br> if (unlikely(ret != LZO_E_OK)) {<br>+ put_cpu_ptr(zram->zbuff);<br> pr_err("Compression failed! err=%d\n", ret);<br>
goto out;<br> }<br>@@ -343,6 +347,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,<br><br> handle = zs_malloc(zram->mem_pool, clen);<br> if (!handle) {<br>+ put_cpu_ptr(zram->zbuff);<br>
pr_info("Error allocating memory for compressed "<br> "page: %u, size=%zu\n", index, clen);<br> ret = -ENOMEM;<br>@@ -366,7 +371,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index,<br>
zram_stat_inc(&zram->stats.pages_stored);<br> if (clen <= PAGE_SIZE / 2)<br> zram_stat_inc(&zram->stats.good_compress);<br>-<br>+ put_cpu_ptr(zram->zbuff);<br> out:<br> if (is_partial_io(bvec))<br>
kfree(uncmem);<br>@@ -382,13 +387,13 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index,<br> int ret;<br><br> if (rw == READ) {<br>- down_read(&zram->lock);<br>+/* down_read(&zram->lock);*/<br>
ret = zram_bvec_read(zram, bvec, index, offset, bio);<br>- up_read(&zram->lock);<br>+/* up_read(&zram->lock);*/<br> } else {<br>- down_write(&zram->lock);<br>+/* down_write(&zram->lock);*/<br>
ret = zram_bvec_write(zram, bvec, index, offset);<br>- up_write(&zram->lock);<br>+/* up_write(&zram->lock);*/<br> }<br><br> return ret;<br>@@ -506,15 +511,17 @@ error:<br> void __zram_reset_device(struct zram *zram)<br>
{<br> size_t index;<br>+ int cpu = 0;<br>+ struct zram_buff *zbuff;<br><br> zram->init_done = 0;<br><br> /* Free various per-device buffers */<br>- kfree(zram->compress_workmem);<br>+/* kfree(zram->compress_workmem);<br>
free_pages((unsigned long)zram->compress_buffer, 1);<br><br> zram->compress_workmem = NULL;<br>- zram->compress_buffer = NULL;<br>+ zram->compress_buffer = NULL; */<br><br> /* Free all pages that are still in this zram device */<br>
for (index = 0; index < zram->disksize >> PAGE_SHIFT; index++) {<br>@@ -524,10 +531,17 @@ void __zram_reset_device(struct zram *zram)<br><br> zs_free(zram->mem_pool, handle);<br> }<br>-<br>+ for_each_possible_cpu(cpu) {<br>
+ zbuff = per_cpu_ptr(zram->zbuff, cpu);<br>+ if (zbuff->compress_workmem)<br>+ kfree(zbuff->compress_workmem);<br>+ if (zbuff->compress_buffer)<br>+ free_pages((unsigned long)zbuff->compress_buffer, 1);<br>
+ }<br> vfree(zram->table);<br> zram->table = NULL;<br>-<br>+ free_percpu(zram->zbuff);<br>+ zram->zbuff = NULL;<br> zs_destroy_pool(zram->mem_pool);<br> zram->mem_pool = NULL;<br><br>
@@ -548,6 +562,8 @@ int zram_init_device(struct zram *zram)<br> {<br> int ret;<br> size_t num_pages;<br>+ int cpu = 0;<br>+ struct zram_buff *zbuff;<br><br> down_write(&zram->init_lock);<br><br>@@ -558,19 +574,44 @@ int zram_init_device(struct zram *zram)<br>
<br> zram_set_disksize(zram, totalram_pages << PAGE_SHIFT);<br><br>- zram->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>+/* zram->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>
if (!zram->compress_workmem) {<br> pr_err("Error allocating compressor working memory!\n");<br> ret = -ENOMEM;<br> goto fail_no_table;<br>+ } */<br>+ zram->zbuff = alloc_percpu(struct zram_buff);<br>
+ if (!zram->zbuff) {<br>+ printk(KERN_EMERG"ERROR: per cpu zbuff allocation failed\n");<br>+ mutex_unlock(&zram->init_lock);<br>+ return -ENOMEM;<br> }<br><br>- zram->compress_buffer =<br>
+<br>+/* zram->compress_buffer =<br> (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);<br> if (!zram->compress_buffer) {<br> pr_err("Error allocating compressor buffer space\n");<br>
ret = -ENOMEM;<br> goto fail_no_table;<br>+ } */<br>+<br>+ for_each_possible_cpu(cpu) {<br>+ printk(KERN_EMERG"[%s] Initializing for each core %d\n", cpu);<br>+ zbuff = per_cpu_ptr(zram->zbuff, cpu);<br>
+ zbuff->compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>+ if (!zbuff->compress_workmem) {<br>+ pr_err("Error allocating compressor working memory!\n");<br>+ ret = -ENOMEM;<br>
+ goto fail;<br>+ }<br>+<br>+ zbuff->compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);<br>+ if (!zbuff->compress_buffer) {<br>+ pr_err("Error allocating compressor buffer space\n");<br>
+ ret = -ENOMEM;<br>+ goto fail;<br>+ }<br> }<br><br> num_pages = zram->disksize >> PAGE_SHIFT;<br>@@ -628,7 +669,7 @@ static int create_device(struct zram *zram, int device_id)<br>
{<br> int ret = 0;<br><br>- init_rwsem(&zram->lock);<br>+/* init_rwsem(&zram->lock);*/<br> init_rwsem(&zram->init_lock);<br> spin_lock_init(&zram->stat64_lock);<br><br>diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h<br>
index df2eec4..9adca81 100644<br>--- a/drivers/staging/zram/zram_drv.h<br>+++ b/drivers/staging/zram/zram_drv.h<br>@@ -17,6 +17,7 @@<br><br> #include <linux/spinlock.h><br> #include <linux/mutex.h><br>+#include <linux/percpu.h><br>
<br> #include "../zsmalloc/zsmalloc.h"<br><br>@@ -86,10 +87,14 @@ struct zram_stats {<br> u32 bad_compress; /* % of pages with compression ratio>=75% */<br> };<br><br>-struct zram {<br>- struct zs_pool *mem_pool;<br>
+struct zram_buff {<br> void *compress_workmem;<br> void *compress_buffer;<br>+};<br>+<br>+struct zram {<br>+ struct zs_pool *mem_pool;<br>+ struct zram_buff __percpu *zbuff;<br> struct table *table;<br> spinlock_t stat64_lock; /* protect 64-bit stats */<br>
struct rw_semaphore lock; /* protect compression buffers and table<br>--<br>1.7.9.5<br><br>
</div><br>