Commit eeb2b202c5b886b76c3bfa76f47e450fa69389fb
Committed by
Herbert Xu
1 parent
3bd2e2216b
Exists in
master
and in
4 other branches
crypto: omap-aes - redundant locking is removed
Submitting request involved double locking for enqueuing and dequeuing. Now it is done under the same lock. FLAGS_BUSY is now handled under the same lock. Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@nokia.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Showing 1 changed file with 32 additions and 38 deletions Side-by-side Diff
drivers/crypto/omap-aes.c
... | ... | @@ -78,7 +78,7 @@ |
78 | 78 | #define FLAGS_NEW_IV BIT(5) |
79 | 79 | #define FLAGS_INIT BIT(6) |
80 | 80 | #define FLAGS_FAST BIT(7) |
81 | -#define FLAGS_BUSY 8 | |
81 | +#define FLAGS_BUSY BIT(8) | |
82 | 82 | |
83 | 83 | struct omap_aes_ctx { |
84 | 84 | struct omap_aes_dev *dd; |
85 | 85 | |
... | ... | @@ -179,9 +179,8 @@ |
179 | 179 | |
180 | 180 | static int omap_aes_hw_init(struct omap_aes_dev *dd) |
181 | 181 | { |
182 | - int err = 0; | |
183 | - | |
184 | 182 | clk_enable(dd->iclk); |
183 | + | |
185 | 184 | if (!(dd->flags & FLAGS_INIT)) { |
186 | 185 | /* is it necessary to reset before every operation? */ |
187 | 186 | omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET, |
188 | 187 | |
189 | 188 | |
... | ... | @@ -193,20 +192,17 @@ |
193 | 192 | __asm__ __volatile__("nop"); |
194 | 193 | __asm__ __volatile__("nop"); |
195 | 194 | |
196 | - err = omap_aes_wait(dd, AES_REG_SYSSTATUS, | |
197 | - AES_REG_SYSSTATUS_RESETDONE); | |
198 | - if (!err) | |
199 | - dd->flags |= FLAGS_INIT; | |
195 | + if (omap_aes_wait(dd, AES_REG_SYSSTATUS, | |
196 | + AES_REG_SYSSTATUS_RESETDONE)) { | |
197 | + clk_disable(dd->iclk); | |
198 | + return -ETIMEDOUT; | |
199 | + } | |
200 | + dd->flags |= FLAGS_INIT; | |
200 | 201 | } |
201 | 202 | |
202 | - return err; | |
203 | + return 0; | |
203 | 204 | } |
204 | 205 | |
205 | -static void omap_aes_hw_cleanup(struct omap_aes_dev *dd) | |
206 | -{ | |
207 | - clk_disable(dd->iclk); | |
208 | -} | |
209 | - | |
210 | 206 | static void omap_aes_write_ctrl(struct omap_aes_dev *dd) |
211 | 207 | { |
212 | 208 | unsigned int key32; |
... | ... | @@ -538,6 +534,8 @@ |
538 | 534 | |
539 | 535 | pr_debug("err: %d\n", err); |
540 | 536 | |
537 | + dd->flags &= ~FLAGS_BUSY; | |
538 | + | |
541 | 539 | ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req)); |
542 | 540 | |
543 | 541 | if (!dd->total) |
... | ... | @@ -553,7 +551,7 @@ |
553 | 551 | |
554 | 552 | omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START); |
555 | 553 | |
556 | - omap_aes_hw_cleanup(dd); | |
554 | + clk_disable(dd->iclk); | |
557 | 555 | |
558 | 556 | omap_stop_dma(dd->dma_lch_in); |
559 | 557 | omap_stop_dma(dd->dma_lch_out); |
560 | 558 | |
561 | 559 | |
562 | 560 | |
563 | 561 | |
564 | 562 | |
... | ... | @@ -580,22 +578,26 @@ |
580 | 578 | return err; |
581 | 579 | } |
582 | 580 | |
583 | -static int omap_aes_handle_req(struct omap_aes_dev *dd) | |
581 | +static int omap_aes_handle_req(struct omap_aes_dev *dd, | |
582 | + struct ablkcipher_request *req) | |
584 | 583 | { |
585 | 584 | struct crypto_async_request *async_req, *backlog; |
586 | 585 | struct omap_aes_ctx *ctx; |
587 | 586 | struct omap_aes_reqctx *rctx; |
588 | - struct ablkcipher_request *req; | |
589 | 587 | unsigned long flags; |
588 | + int err = 0; | |
590 | 589 | |
591 | - if (dd->total) | |
592 | - goto start; | |
593 | - | |
594 | 590 | spin_lock_irqsave(&dd->lock, flags); |
591 | + if (req) | |
592 | + err = ablkcipher_enqueue_request(&dd->queue, req); | |
593 | + if (dd->flags & FLAGS_BUSY) { | |
594 | + spin_unlock_irqrestore(&dd->lock, flags); | |
595 | + return err; | |
596 | + } | |
595 | 597 | backlog = crypto_get_backlog(&dd->queue); |
596 | 598 | async_req = crypto_dequeue_request(&dd->queue); |
597 | - if (!async_req) | |
598 | - clear_bit(FLAGS_BUSY, &dd->flags); | |
599 | + if (async_req) | |
600 | + dd->flags |= FLAGS_BUSY; | |
599 | 601 | spin_unlock_irqrestore(&dd->lock, flags); |
600 | 602 | |
601 | 603 | if (!async_req) |
602 | 604 | |
603 | 605 | |
604 | 606 | |
... | ... | @@ -637,20 +639,23 @@ |
637 | 639 | if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) |
638 | 640 | pr_err("request size is not exact amount of AES blocks\n"); |
639 | 641 | |
640 | -start: | |
641 | - return omap_aes_crypt_dma_start(dd); | |
642 | + omap_aes_crypt_dma_start(dd); | |
643 | + | |
644 | + return err; | |
642 | 645 | } |
643 | 646 | |
644 | 647 | static void omap_aes_task(unsigned long data) |
645 | 648 | { |
646 | 649 | struct omap_aes_dev *dd = (struct omap_aes_dev *)data; |
647 | - int err; | |
648 | 650 | |
649 | 651 | pr_debug("enter\n"); |
650 | 652 | |
651 | - err = omap_aes_crypt_dma_stop(dd); | |
653 | + omap_aes_crypt_dma_stop(dd); | |
652 | 654 | |
653 | - err = omap_aes_handle_req(dd); | |
655 | + if (dd->total) | |
656 | + omap_aes_crypt_dma_start(dd); | |
657 | + else | |
658 | + omap_aes_handle_req(dd, NULL); | |
654 | 659 | |
655 | 660 | pr_debug("exit\n"); |
656 | 661 | } |
... | ... | @@ -661,8 +666,6 @@ |
661 | 666 | crypto_ablkcipher_reqtfm(req)); |
662 | 667 | struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req); |
663 | 668 | struct omap_aes_dev *dd; |
664 | - unsigned long flags; | |
665 | - int err; | |
666 | 669 | |
667 | 670 | pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, |
668 | 671 | !!(mode & FLAGS_ENCRYPT), |
... | ... | @@ -674,16 +677,7 @@ |
674 | 677 | |
675 | 678 | rctx->mode = mode; |
676 | 679 | |
677 | - spin_lock_irqsave(&dd->lock, flags); | |
678 | - err = ablkcipher_enqueue_request(&dd->queue, req); | |
679 | - spin_unlock_irqrestore(&dd->lock, flags); | |
680 | - | |
681 | - if (!test_and_set_bit(FLAGS_BUSY, &dd->flags)) | |
682 | - omap_aes_handle_req(dd); | |
683 | - | |
684 | - pr_debug("exit\n"); | |
685 | - | |
686 | - return err; | |
680 | + return omap_aes_handle_req(dd, req); | |
687 | 681 | } |
688 | 682 | |
689 | 683 | /* ********************** ALG API ************************************ */ |