From: James Morris Remove the lazy allocation of the deflate workspace. Instead, allocate it at initialisation time. This is needed because under some circumstances (IPSec with IPCOMP) we were trying to allocate memory under locking and might_sleep() warnings came out. Fixes bugzilla #3003 Signed-off-by: James Morris Signed-off-by: Andrew Morton --- 25-akpm/crypto/deflate.c | 77 +++++++++++++++++++---------------------------- 1 files changed, 32 insertions(+), 45 deletions(-) diff -puN crypto/deflate.c~deflate-remove-lazy-allocation crypto/deflate.c --- 25/crypto/deflate.c~deflate-remove-lazy-allocation 2004-07-08 21:44:56.085347776 -0700 +++ 25-akpm/crypto/deflate.c 2004-07-08 21:44:56.089347168 -0700 @@ -39,44 +39,16 @@ #define DEFLATE_DEF_MEMLEVEL MAX_MEM_LEVEL struct deflate_ctx { - int comp_initialized; - int decomp_initialized; struct z_stream_s comp_stream; struct z_stream_s decomp_stream; }; -static inline int deflate_gfp(void) -{ - return in_softirq() ? GFP_ATOMIC : GFP_KERNEL; -} - -static int deflate_init(void *ctx) -{ - return 0; -} - -static void deflate_exit(void *ctx) -{ - struct deflate_ctx *dctx = ctx; - - if (dctx->comp_initialized) - vfree(dctx->comp_stream.workspace); - if (dctx->decomp_initialized) - kfree(dctx->decomp_stream.workspace); -} - -/* - * Lazy initialization to make interface simple without allocating - * un-needed workspaces. Thus can be called in softirq context. - */ static int deflate_comp_init(struct deflate_ctx *ctx) { int ret = 0; struct z_stream_s *stream = &ctx->comp_stream; - stream->workspace = __vmalloc(zlib_deflate_workspacesize(), - deflate_gfp()|__GFP_HIGHMEM, - PAGE_KERNEL); + stream->workspace = vmalloc(zlib_deflate_workspacesize()); if (!stream->workspace ) { ret = -ENOMEM; goto out; @@ -89,7 +61,6 @@ static int deflate_comp_init(struct defl ret = -EINVAL; goto out_free; } - ctx->comp_initialized = 1; out: return ret; out_free: @@ -102,8 +73,7 @@ static int deflate_decomp_init(struct de int ret = 0; struct z_stream_s *stream = &ctx->decomp_stream; - stream->workspace = kmalloc(zlib_inflate_workspacesize(), - deflate_gfp()); + stream->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); if (!stream->workspace ) { ret = -ENOMEM; goto out; @@ -114,7 +84,6 @@ static int deflate_decomp_init(struct de ret = -EINVAL; goto out_free; } - ctx->decomp_initialized = 1; out: return ret; out_free: @@ -122,6 +91,36 @@ out_free: goto out; } +static void deflate_comp_exit(struct deflate_ctx *ctx) +{ + vfree(ctx->comp_stream.workspace); +} + +static void deflate_decomp_exit(struct deflate_ctx *ctx) +{ + kfree(ctx->decomp_stream.workspace); +} + +static int deflate_init(void *ctx) +{ + int ret; + + ret = deflate_comp_init(ctx); + if (ret) + goto out; + ret = deflate_decomp_init(ctx); + if (ret) + deflate_comp_exit(ctx); +out: + return ret; +} + +static void deflate_exit(void *ctx) +{ + deflate_comp_exit(ctx); + deflate_decomp_exit(ctx); +} + static int deflate_compress(void *ctx, const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen) { @@ -129,12 +128,6 @@ static int deflate_compress(void *ctx, c struct deflate_ctx *dctx = ctx; struct z_stream_s *stream = &dctx->comp_stream; - if (!dctx->comp_initialized) { - ret = deflate_comp_init(dctx); - if (ret) - goto out; - } - ret = zlib_deflateReset(stream); if (ret != Z_OK) { ret = -EINVAL; @@ -165,12 +158,6 @@ static int deflate_decompress(void *ctx, struct deflate_ctx *dctx = ctx; struct z_stream_s *stream = &dctx->decomp_stream; - if (!dctx->decomp_initialized) { - ret = deflate_decomp_init(dctx); - if (ret) - goto out; - } - ret = zlib_inflateReset(stream); if (ret != Z_OK) { ret = -EINVAL; _