<br><div class="gmail_quote">From 4d52438c9640e64203c2434a74e2abfe3a4168ec Mon Sep 17 00:00:00 2001<br>From: Manish Sharma &lt;<a href="mailto:manishrma@gmail.com" target="_blank">manishrma@gmail.com</a>&gt;<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&#39;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-&gt;bv_page;<br>-    src = zram-&gt;compress_buffer;<br>+/*    src = zram-&gt;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-&gt;zbuff);<br>+    src = zbuff-&gt;compress_buffer;<br>



<br>    ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &amp;clen,<br>-                   zram-&gt;compress_workmem);<br>+                zbuff-&gt;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-&gt;zbuff);<br>        pr_err(&quot;Compression failed! err=%d\n&quot;, 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-&gt;mem_pool, clen);<br>    if (!handle) {<br>+        put_cpu_ptr(zram-&gt;zbuff);<br>



        pr_info(&quot;Error allocating memory for compressed &quot;<br>            &quot;page: %u, size=%zu\n&quot;, 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(&amp;zram-&gt;stats.pages_stored);<br>    if (clen &lt;= PAGE_SIZE / 2)<br>        zram_stat_inc(&amp;zram-&gt;stats.good_compress);<br>-<br>+    put_cpu_ptr(zram-&gt;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(&amp;zram-&gt;lock);<br>+/*        down_read(&amp;zram-&gt;lock);*/<br>



        ret = zram_bvec_read(zram, bvec, index, offset, bio);<br>-        up_read(&amp;zram-&gt;lock);<br>+/*        up_read(&amp;zram-&gt;lock);*/<br>    } else {<br>-        down_write(&amp;zram-&gt;lock);<br>+/*        down_write(&amp;zram-&gt;lock);*/<br>



        ret = zram_bvec_write(zram, bvec, index, offset);<br>-        up_write(&amp;zram-&gt;lock);<br>+/*        up_write(&amp;zram-&gt;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-&gt;init_done = 0;<br><br>    /* Free various per-device buffers */<br>-    kfree(zram-&gt;compress_workmem);<br>+/*    kfree(zram-&gt;compress_workmem);<br>



    free_pages((unsigned long)zram-&gt;compress_buffer, 1);<br><br>    zram-&gt;compress_workmem = NULL;<br>-    zram-&gt;compress_buffer = NULL;<br>+    zram-&gt;compress_buffer = NULL; */<br><br>    /* Free all pages that are still in this zram device */<br>



    for (index = 0; index &lt; zram-&gt;disksize &gt;&gt; PAGE_SHIFT; index++) {<br>@@ -524,10 +531,17 @@ void __zram_reset_device(struct zram *zram)<br><br>        zs_free(zram-&gt;mem_pool, handle);<br>    }<br>-<br>+    for_each_possible_cpu(cpu) {<br>



+        zbuff = per_cpu_ptr(zram-&gt;zbuff, cpu);<br>+        if (zbuff-&gt;compress_workmem)<br>+            kfree(zbuff-&gt;compress_workmem);<br>+        if (zbuff-&gt;compress_buffer)<br>+            free_pages((unsigned long)zbuff-&gt;compress_buffer, 1);<br>



+    }<br>    vfree(zram-&gt;table);<br>    zram-&gt;table = NULL;<br>-<br>+    free_percpu(zram-&gt;zbuff);<br>+    zram-&gt;zbuff = NULL;<br>    zs_destroy_pool(zram-&gt;mem_pool);<br>    zram-&gt;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(&amp;zram-&gt;init_lock);<br><br>@@ -558,19 +574,44 @@ int zram_init_device(struct zram *zram)<br>



<br>    zram_set_disksize(zram, totalram_pages &lt;&lt; PAGE_SHIFT);<br><br>-    zram-&gt;compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>+/*    zram-&gt;compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>



    if (!zram-&gt;compress_workmem) {<br>        pr_err(&quot;Error allocating compressor working memory!\n&quot;);<br>        ret = -ENOMEM;<br>        goto fail_no_table;<br>+    } */<br>+    zram-&gt;zbuff = alloc_percpu(struct zram_buff);<br>



+    if (!zram-&gt;zbuff) {<br>+        printk(KERN_EMERG&quot;ERROR: per cpu zbuff allocation failed\n&quot;);<br>+        mutex_unlock(&amp;zram-&gt;init_lock);<br>+        return -ENOMEM;<br>    }<br><br>-    zram-&gt;compress_buffer =<br>



+<br>+/*    zram-&gt;compress_buffer =<br>        (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);<br>    if (!zram-&gt;compress_buffer) {<br>        pr_err(&quot;Error allocating compressor buffer space\n&quot;);<br>



        ret = -ENOMEM;<br>        goto fail_no_table;<br>+    } */<br>+<br>+    for_each_possible_cpu(cpu) {<br>+        printk(KERN_EMERG&quot;[%s] Initializing for each core %d\n&quot;, cpu);<br>+        zbuff = per_cpu_ptr(zram-&gt;zbuff, cpu);<br>



+        zbuff-&gt;compress_workmem = kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);<br>+        if (!zbuff-&gt;compress_workmem) {<br>+               pr_err(&quot;Error allocating compressor working memory!\n&quot;);<br>+            ret = -ENOMEM;<br>



+            goto fail;<br>+        }<br>+<br>+        zbuff-&gt;compress_buffer = (void *)__get_free_pages(__GFP_ZERO, 1);<br>+        if (!zbuff-&gt;compress_buffer) {<br>+            pr_err(&quot;Error allocating compressor buffer space\n&quot;);<br>



+            ret = -ENOMEM;<br>+            goto fail;<br>+        }<br>    }<br><br>    num_pages = zram-&gt;disksize &gt;&gt; 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(&amp;zram-&gt;lock);<br>+/*    init_rwsem(&amp;zram-&gt;lock);*/<br>    init_rwsem(&amp;zram-&gt;init_lock);<br>    spin_lock_init(&amp;zram-&gt;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 &lt;linux/spinlock.h&gt;<br> #include &lt;linux/mutex.h&gt;<br>+#include &lt;linux/percpu.h&gt;<br>



<br> #include &quot;../zsmalloc/zsmalloc.h&quot;<br><br>@@ -86,10 +87,14 @@ struct zram_stats {<br>    u32 bad_compress;    /* % of pages with compression ratio&gt;=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>