crypto: omap-sham - avoid executing tasklet where not needed
authorTero Kristo <t-kristo@ti.com>
Thu, 4 Aug 2016 10:28:36 +0000 (13:28 +0300)
committerHerbert Xu <herbert@gondor.apana.org.au>
Tue, 13 Sep 2016 12:20:55 +0000 (20:20 +0800)
Some of the call paths of OMAP SHA driver can avoid executing the next
step of the crypto queue under tasklet; instead, execute the next step
directly via function call. This avoids a costly round-trip via the
scheduler giving a slight performance boost.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/omap-sham.c

index 7fe4eef12fe2fa411d635851bb9da2aad08a30e0..fd50005fd9428f30f8ad2763096a3a365cc90848 100644 (file)
@@ -1005,9 +1005,6 @@ static void omap_sham_finish_req(struct ahash_request *req, int err)
 
        if (req->base.complete)
                req->base.complete(&req->base, err);
-
-       /* handle new request */
-       tasklet_schedule(&dd->done_task);
 }
 
 static int omap_sham_handle_queue(struct omap_sham_dev *dd,
@@ -1018,6 +1015,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
        unsigned long flags;
        int err = 0, ret = 0;
 
+retry:
        spin_lock_irqsave(&dd->lock, flags);
        if (req)
                ret = ahash_enqueue_request(&dd->queue, req);
@@ -1061,11 +1059,19 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd,
                err = omap_sham_final_req(dd);
        }
 err1:
-       if (err != -EINPROGRESS)
+       dev_dbg(dd->dev, "exit, err: %d\n", err);
+
+       if (err != -EINPROGRESS) {
                /* done_task will not finish it, so do it here */
                omap_sham_finish_req(req, err);
+               req = NULL;
 
-       dev_dbg(dd->dev, "exit, err: %d\n", err);
+               /*
+                * Execute next request immediately if there is anything
+                * in queue.
+                */
+               goto retry;
+       }
 
        return ret;
 }
@@ -1653,6 +1659,10 @@ finish:
        dev_dbg(dd->dev, "update done: err: %d\n", err);
        /* finish curent request */
        omap_sham_finish_req(dd->req, err);
+
+       /* If we are not busy, process next req */
+       if (!test_bit(FLAGS_BUSY, &dd->flags))
+               omap_sham_handle_queue(dd, NULL);
 }
 
 static irqreturn_t omap_sham_irq_common(struct omap_sham_dev *dd)