Make zlib decompression multi-threaded.
Signed-off-by: Stephen Hemminger <
shemminger@...>
--- a/fs/squashfs/zlib_wrapper.c 2011-04-22 10:57:09.450024619 -0700
+++ b/fs/squashfs/zlib_wrapper.c 2011-04-22 13:15:52.509266395 -0700
@@ -26,6 +26,7 @@
#include <linux/buffer_head.h>
#include <linux/slab.h>
#include <linux/zlib.h>
+#include <linux/percpu.h>
#include <linux/vmalloc.h>
#include "squashfs_fs.h"
@@ -33,31 +34,53 @@
#include "squashfs.h"
#include "decompressor.h"
+/* don't use per superblock stream anymore. */
static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len)
{
- z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
- if (stream == NULL)
- goto failed;
- stream->workspace = vmalloc(zlib_inflate_workspacesize());
- if (stream->workspace == NULL)
- goto failed;
+ z_stream __percpu *percpu;
+ z_stream *stream;
+ int cpu, cpu0;
+
+ percpu = alloc_percpu(z_stream);
+ if (!percpu) {
+ ERROR("Failed to allocate per cpu stream\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ for_each_possible_cpu(cpu) {
+ stream = per_cpu_ptr(percpu, cpu);
+
+ stream->workspace = vmalloc(zlib_inflate_workspacesize());
+ if (stream->workspace == NULL)
+ goto failed;
+ }
- return stream;
+ return (__force void *) percpu;
failed:
- ERROR("Failed to allocate zlib workspace\n");
- kfree(stream);
+ for_each_possible_cpu(cpu0) {
+ if (cpu0 == cpu)
+ break;
+ stream = per_cpu_ptr(percpu, cpu);
+ vfree(stream->workspace);
+ }
+ free_percpu(percpu);
+
+ ERROR("Failed to allocate zlib workspaces\n");
return ERR_PTR(-ENOMEM);
}
-
static void zlib_free(void *strm)
{
- z_stream *stream = strm;
+ z_stream __percpu *percpu = (z_stream __percpu *) strm;
+ int cpu;
- if (stream)
+ for_each_possible_cpu(cpu) {
+ z_stream *stream = per_cpu_ptr(percpu, cpu);
vfree(stream->workspace);
- kfree(stream);
+
+ }
+ free_percpu(percpu);
}
@@ -67,9 +90,8 @@ static int zlib_uncompress(struct squash
{
int zlib_err, zlib_init = 0;
int k = 0, page = 0;
- z_stream *stream = msblk->stream;
-
- mutex_lock(&msblk->read_data_mutex);
+ z_stream __percpu *percpu = (z_stream __percpu *)msblk->stream;
+ z_stream *stream = get_cpu_ptr(percpu);
stream->avail_out = 0;
stream->avail_in = 0;
@@ -80,7 +102,7 @@ static int zlib_uncompress(struct squash
length -= avail;
wait_on_buffer(bh[k]);
if (!buffer_uptodate(bh[k]))
- goto release_mutex;
+ goto put_per_cpu;
stream->next_in = bh[k]->b_data + offset;
stream->avail_in = avail;
@@ -98,7 +120,7 @@ static int zlib_uncompress(struct squash
ERROR("zlib_inflateInit returned unexpected "
"result 0x%x, srclength %d\n",
zlib_err, srclength);
- goto release_mutex;
+ goto put_per_cpu;
}
zlib_init = 1;
}
@@ -111,26 +133,26 @@ static int zlib_uncompress(struct squash
if (zlib_err != Z_STREAM_END) {
ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
+ goto put_per_cpu;
}
zlib_err = zlib_inflateEnd(stream);
if (zlib_err != Z_OK) {
ERROR("zlib_inflate error, data probably corrupt\n");
- goto release_mutex;
+ goto put_per_cpu;
}
if (k < b) {
ERROR("zlib_uncompress error, data remaining\n");
- goto release_mutex;
+ goto put_per_cpu;
}
length = stream->total_out;
- mutex_unlock(&msblk->read_data_mutex);
+ put_cpu_ptr(stream);
return length;
-release_mutex:
- mutex_unlock(&msblk->read_data_mutex);
+put_per_cpu:
+ put_cpu_ptr(stream);
for (; k < b; k++)
put_bh(bh[k]);
------------------------------------------------------------------------------
Fulfilling the Lean Software Promise
Lean software platforms are now widely adopted and the benefits have been
demonstrated beyond question. Learn why your peers are replacing JEE
containers with lightweight application servers - and what you can gain
from the move.
http://p.sf.net/sfu/vmware-sfemails_______________________________________________
Squashfs-devel mailing list
Squashfs-devel@...
https://lists.sourceforge.net/lists/listinfo/squashfs-devel