Commit eeb2b202c5b886b76c3bfa76f47e450fa69389fb

Authored by Dmitry Kasatkin
Committed by Herbert Xu
1 parent 3bd2e2216b

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 ************************************ */