crypto: omap-sham - backlog handling fix
authorDmitry Kasatkin <dmitry.kasatkin@nokia.com>
Wed, 29 Dec 2010 10:52:04 +0000 (21:52 +1100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Wed, 29 Dec 2010 10:52:04 +0000 (21:52 +1100)
Previous commit "removed redundant locking" introduced
a bug in handling backlog.
In certain cases, when async request complete callback will
call complete() on -EINPROGRESS code, it will cause uncompleted requests.
It does not happen in implementation similar to crypto test manager,
but it will happen in implementation similar to dm-crypt.
Backlog needs to be checked before dequeuing next request.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/omap-sham.c

index eb988e7a2fd9be63281e941e9f07680e065c94b3..2e71123516e09f2d02667ddc11024196c8275da3 100644 (file)
@@ -664,7 +664,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
 static int omap_sham_handle_queue(struct omap_sham_dev *dd,
                                  struct ahash_request *req)
 {
-       struct crypto_async_request *async_req, *backlog = 0;
+       struct crypto_async_request *async_req, *backlog;
        struct omap_sham_reqctx *ctx;
        struct ahash_request *prev_req;
        unsigned long flags;
@@ -677,11 +677,10 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
                spin_unlock_irqrestore(&dd->lock, flags);
                return ret;
        }
+       backlog = crypto_get_backlog(&dd->queue);
        async_req = crypto_dequeue_request(&dd->queue);
-       if (async_req) {
+       if (async_req)
                dd->flags |= FLAGS_BUSY;
-               backlog = crypto_get_backlog(&dd->queue);
-       }
        spin_unlock_irqrestore(&dd->lock, flags);
 
        if (!async_req)