crypto: hisilicon/zip - Optimize performance by replacing rw_lock with spinlock
authorKuan-Wei Chiu <visitorckw@gmail.com>
Fri, 23 Aug 2024 18:38:56 +0000 (02:38 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 30 Aug 2024 10:23:43 +0000 (18:23 +0800)
The req_lock is currently implemented as a rw_lock, but there are no
instances where read_lock() is called. This means that the lock is
effectively only used by writers, making it functionally equivalent to
a simple spinlock.

As stated in Documentation/locking/spinlocks.rst:
"Reader-writer locks require more atomic memory operations than simple
spinlocks. Unless the reader critical section is long, you are better
off just using spinlocks."

Since the rw_lock in this case incurs additional atomic memory
operations without any benefit from reader-writer locking, it is more
efficient to replace it with a spinlock. This patch implements that
replacement to optimize the driver's performance.

Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/hisilicon/zip/zip_crypto.c

index 94e2d66..92d3bd0 100644 (file)
@@ -54,7 +54,7 @@ struct hisi_zip_req {
 struct hisi_zip_req_q {
        struct hisi_zip_req *q;
        unsigned long *req_bitmap;
-       rwlock_t req_lock;
+       spinlock_t req_lock;
        u16 size;
 };
 
@@ -116,17 +116,17 @@ static struct hisi_zip_req *hisi_zip_create_req(struct hisi_zip_qp_ctx *qp_ctx,
        struct hisi_zip_req *req_cache;
        int req_id;
 
-       write_lock(&req_q->req_lock);
+       spin_lock(&req_q->req_lock);
 
        req_id = find_first_zero_bit(req_q->req_bitmap, req_q->size);
        if (req_id >= req_q->size) {
-               write_unlock(&req_q->req_lock);
+               spin_unlock(&req_q->req_lock);
                dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n");
                return ERR_PTR(-EAGAIN);
        }
        set_bit(req_id, req_q->req_bitmap);
 
-       write_unlock(&req_q->req_lock);
+       spin_unlock(&req_q->req_lock);
 
        req_cache = q + req_id;
        req_cache->req_id = req_id;
@@ -140,9 +140,9 @@ static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx,
 {
        struct hisi_zip_req_q *req_q = &qp_ctx->req_q;
 
-       write_lock(&req_q->req_lock);
+       spin_lock(&req_q->req_lock);
        clear_bit(req->req_id, req_q->req_bitmap);
-       write_unlock(&req_q->req_lock);
+       spin_unlock(&req_q->req_lock);
 }
 
 static void hisi_zip_fill_addr(struct hisi_zip_sqe *sqe, struct hisi_zip_req *req)
@@ -456,7 +456,7 @@ static int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx)
 
                        goto err_free_comp_q;
                }
-               rwlock_init(&req_q->req_lock);
+               spin_lock_init(&req_q->req_lock);
 
                req_q->q = kcalloc(req_q->size, sizeof(struct hisi_zip_req),
                                   GFP_KERNEL);