Signed-off-by: Stephen Hemminger <shemminger@xxxxxxxxxx> --- a/fs/squashfs/xz_wrapper.c 2011-04-22 13:55:21.251194626 -0700 +++ b/fs/squashfs/xz_wrapper.c 2011-04-22 13:55:35.779665142 -0700 @@ -47,9 +47,11 @@ static void *squashfs_xz_init(struct squ int len) { struct comp_opts *comp_opts = buff; + struct squashfs_xz __percpu *percpu; struct squashfs_xz *stream; int dict_size = msblk->block_size; int err, n; + int cpu, cpu0; if (comp_opts) { /* check compressor options are the expected length */ @@ -71,47 +73,58 @@ static void *squashfs_xz_init(struct squ dict_size = max_t(int, dict_size, SQUASHFS_METADATA_SIZE); - stream = kmalloc(sizeof(*stream), GFP_KERNEL); - if (stream == NULL) { - err = -ENOMEM; - goto failed; - } + percpu = alloc_percpu(struct squashfs_xz); + if (!percpu) + goto nomem; + + for_each_possible_cpu(cpu) { + stream = per_cpu_ptr(percpu, cpu); - stream->state = xz_dec_init(XZ_PREALLOC, dict_size); - if (stream->state == NULL) { - kfree(stream); - err = -ENOMEM; - goto failed; + stream->state = xz_dec_init(XZ_PREALLOC, dict_size); + if (stream->state == NULL) + goto cleanup_cpu; } - return stream; + return (__force void *) percpu; +cleanup_cpu: + for_each_possible_cpu(cpu0) { + if (cpu0 == cpu) + break; + + stream = per_cpu_ptr(percpu, cpu); + xz_dec_end(stream->state); + } + free_percpu(percpu); +nomem: + err = -ENOMEM; failed: ERROR("Failed to initialise xz decompressor\n"); return ERR_PTR(err); } - static void squashfs_xz_free(void *strm) { - struct squashfs_xz *stream = strm; + struct squashfs_xz __percpu *percpu + = (struct squashfs_xz __percpu *) strm; + int cpu; - if (stream) { + for_each_possible_cpu(cpu) { + struct squashfs_xz *stream = per_cpu_ptr(percpu, cpu); xz_dec_end(stream->state); - kfree(stream); } + free_percpu(percpu); } - static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void **buffer, struct buffer_head **bh, int b, int offset, int length, int srclength, int pages) { enum xz_ret xz_err; int avail, total = 0, k = 0, page = 0; - struct squashfs_xz *stream = msblk->stream; - - mutex_lock(&msblk->read_data_mutex); + struct squashfs_xz __percpu *percpu + = (struct squashfs_xz __percpu *)msblk->stream; + struct squashfs_xz *stream = get_cpu_ptr(percpu); xz_dec_reset(stream->state); stream->buf.in_pos = 0; @@ -158,11 +171,11 @@ static int squashfs_xz_uncompress(struct } total += stream->buf.out_pos; - mutex_unlock(&msblk->read_data_mutex); + put_cpu_ptr(stream); return total; release_mutex: - mutex_unlock(&msblk->read_data_mutex); + put_cpu_ptr(stream); for (; k < b; k++) put_bh(bh[k]); -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html