diff options
author | Dmitry Kasatkin <dmitry.kasatkin@nokia.com> | 2010-12-29 05:52:04 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2010-12-29 05:52:04 -0500 |
commit | 6c39d116ba308ccf9007773a090ca6d20eb68459 (patch) | |
tree | 4928ffd2efc23fe19431f32dfa6f188248e1d643 /drivers/crypto | |
parent | 8ad225e8e4f530f500c12ec77fd5a51caf6a2f66 (diff) |
crypto: omap-sham - backlog handling fix
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>
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/omap-sham.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index eb988e7a2fd9..2e71123516e0 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c | |||
@@ -664,7 +664,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) | |||
664 | static int omap_sham_handle_queue(struct omap_sham_dev *dd, | 664 | static int omap_sham_handle_queue(struct omap_sham_dev *dd, |
665 | struct ahash_request *req) | 665 | struct ahash_request *req) |
666 | { | 666 | { |
667 | struct crypto_async_request *async_req, *backlog = 0; | 667 | struct crypto_async_request *async_req, *backlog; |
668 | struct omap_sham_reqctx *ctx; | 668 | struct omap_sham_reqctx *ctx; |
669 | struct ahash_request *prev_req; | 669 | struct ahash_request *prev_req; |
670 | unsigned long flags; | 670 | unsigned long flags; |
@@ -677,11 +677,10 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd, | |||
677 | spin_unlock_irqrestore(&dd->lock, flags); | 677 | spin_unlock_irqrestore(&dd->lock, flags); |
678 | return ret; | 678 | return ret; |
679 | } | 679 | } |
680 | backlog = crypto_get_backlog(&dd->queue); | ||
680 | async_req = crypto_dequeue_request(&dd->queue); | 681 | async_req = crypto_dequeue_request(&dd->queue); |
681 | if (async_req) { | 682 | if (async_req) |
682 | dd->flags |= FLAGS_BUSY; | 683 | dd->flags |= FLAGS_BUSY; |
683 | backlog = crypto_get_backlog(&dd->queue); | ||
684 | } | ||
685 | spin_unlock_irqrestore(&dd->lock, flags); | 684 | spin_unlock_irqrestore(&dd->lock, flags); |
686 | 685 | ||
687 | if (!async_req) | 686 | if (!async_req) |