aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 05:42:36 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2008-07-10 08:34:38 -0400
commit872ac8743cb400192a9fce4ba2d3ffd7bb309685 (patch)
tree21190c21fea4cb35918aae5469d0d066171ae0c0
parent6329d3021bcfa9038621e6e917d98929421d8ec8 (diff)
crypto: chainiv - Invoke completion function
When chainiv postpones requests it never calls their completion functions. This causes symptoms such as memory leaks when IPsec is in use. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/chainiv.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/crypto/chainiv.c b/crypto/chainiv.c
index 6da3f577e4db..9affadee3287 100644
--- a/crypto/chainiv.c
+++ b/crypto/chainiv.c
@@ -117,6 +117,7 @@ static int chainiv_init(struct crypto_tfm *tfm)
117static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx) 117static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx)
118{ 118{
119 int queued; 119 int queued;
120 int err = ctx->err;
120 121
121 if (!ctx->queue.qlen) { 122 if (!ctx->queue.qlen) {
122 smp_mb__before_clear_bit(); 123 smp_mb__before_clear_bit();
@@ -131,7 +132,7 @@ static int async_chainiv_schedule_work(struct async_chainiv_ctx *ctx)
131 BUG_ON(!queued); 132 BUG_ON(!queued);
132 133
133out: 134out:
134 return ctx->err; 135 return err;
135} 136}
136 137
137static int async_chainiv_postpone_request(struct skcipher_givcrypt_request *req) 138static int async_chainiv_postpone_request(struct skcipher_givcrypt_request *req)
@@ -227,6 +228,7 @@ static void async_chainiv_do_postponed(struct work_struct *work)
227 postponed); 228 postponed);
228 struct skcipher_givcrypt_request *req; 229 struct skcipher_givcrypt_request *req;
229 struct ablkcipher_request *subreq; 230 struct ablkcipher_request *subreq;
231 int err;
230 232
231 /* Only handle one request at a time to avoid hogging keventd. */ 233 /* Only handle one request at a time to avoid hogging keventd. */
232 spin_lock_bh(&ctx->lock); 234 spin_lock_bh(&ctx->lock);
@@ -241,7 +243,11 @@ static void async_chainiv_do_postponed(struct work_struct *work)
241 subreq = skcipher_givcrypt_reqctx(req); 243 subreq = skcipher_givcrypt_reqctx(req);
242 subreq->base.flags |= CRYPTO_TFM_REQ_MAY_SLEEP; 244 subreq->base.flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
243 245
244 async_chainiv_givencrypt_tail(req); 246 err = async_chainiv_givencrypt_tail(req);
247
248 local_bh_disable();
249 skcipher_givcrypt_complete(req, err);
250 local_bh_enable();
245} 251}
246 252
247static int async_chainiv_init(struct crypto_tfm *tfm) 253static int async_chainiv_init(struct crypto_tfm *tfm)