Update some patch for uadk from mainline. To get more information, please visit the homepage: https://github.comp/Linaro/uadk Signed-off-by: Yang Shen <shenyang39@huawei.com>
145 lines
4.5 KiB
Diff
145 lines
4.5 KiB
Diff
From 2004801f44c0b6259b051e5a55bde5c54306fd63 Mon Sep 17 00:00:00 2001
|
|
From: Weili Qian <qianweili@huawei.com>
|
|
Date: Mon, 18 Jul 2022 10:17:06 +0800
|
|
Subject: [PATCH 154/183] drv/qm: modify the lock for send and receive BD
|
|
|
|
If the same lock is used for BD receiving and BD sending,
|
|
the BD receiving and BD sending threads compete for lock in
|
|
asynchronous scenarios, affecting tasks performance.
|
|
|
|
Signed-off-by: Weili Qian <qianweili@huawei.com>
|
|
---
|
|
drv/hisi_qm_udrv.c | 38 +++++++++++++++++++++++++-------------
|
|
include/hisi_qm_udrv.h | 3 ++-
|
|
2 files changed, 27 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/drv/hisi_qm_udrv.c b/drv/hisi_qm_udrv.c
|
|
index f1468a4..da756c4 100644
|
|
--- a/drv/hisi_qm_udrv.c
|
|
+++ b/drv/hisi_qm_udrv.c
|
|
@@ -322,14 +322,22 @@ static int hisi_qm_setup_info(struct hisi_qp *qp, struct hisi_qm_priv *config)
|
|
q_info->region_size[UACCE_QFRT_DUS] - sizeof(uint32_t);
|
|
q_info->ds_rx_base = q_info->ds_tx_base - sizeof(uint32_t);
|
|
|
|
- ret = pthread_spin_init(&q_info->lock, PTHREAD_PROCESS_SHARED);
|
|
+ ret = pthread_spin_init(&q_info->rv_lock, PTHREAD_PROCESS_SHARED);
|
|
if (ret) {
|
|
- WD_DEV_ERR(qp->h_ctx, "failed to init qinfo lock!\n");
|
|
+ WD_DEV_ERR(qp->h_ctx, "failed to init qinfo rv_lock!\n");
|
|
goto err_out;
|
|
}
|
|
|
|
+ ret = pthread_spin_init(&q_info->sd_lock, PTHREAD_PROCESS_SHARED);
|
|
+ if (ret) {
|
|
+ WD_DEV_ERR(qp->h_ctx, "failed to init qinfo sd_lock!\n");
|
|
+ goto err_destory_lock;
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
+err_destory_lock:
|
|
+ pthread_spin_destroy(&q_info->rv_lock);
|
|
err_out:
|
|
hisi_qm_unset_region(qp->h_ctx, q_info);
|
|
return ret;
|
|
@@ -339,14 +347,16 @@ static void hisi_qm_clear_info(struct hisi_qp *qp)
|
|
{
|
|
struct hisi_qm_queue_info *q_info = &qp->q_info;
|
|
|
|
- pthread_spin_destroy(&q_info->lock);
|
|
+ pthread_spin_destroy(&q_info->sd_lock);
|
|
+ pthread_spin_destroy(&q_info->rv_lock);
|
|
hisi_qm_unset_region(qp->h_ctx, q_info);
|
|
}
|
|
|
|
static int get_free_num(struct hisi_qm_queue_info *q_info)
|
|
{
|
|
/* The device should reserve one buffer. */
|
|
- return (QM_Q_DEPTH - 1) - q_info->used_num;
|
|
+ return (QM_Q_DEPTH - 1) -
|
|
+ __atomic_load_n(&q_info->used_num, __ATOMIC_RELAXED);
|
|
}
|
|
|
|
int hisi_qm_get_free_sqe_num(handle_t h_qp)
|
|
@@ -441,10 +451,10 @@ int hisi_qm_send(handle_t h_qp, const void *req, __u16 expect, __u16 *count)
|
|
return -WD_HW_EACCESS;
|
|
}
|
|
|
|
- pthread_spin_lock(&q_info->lock);
|
|
+ pthread_spin_lock(&q_info->sd_lock);
|
|
free_num = get_free_num(q_info);
|
|
if (!free_num) {
|
|
- pthread_spin_unlock(&q_info->lock);
|
|
+ pthread_spin_unlock(&q_info->sd_lock);
|
|
return -WD_EBUSY;
|
|
}
|
|
|
|
@@ -455,10 +465,12 @@ int hisi_qm_send(handle_t h_qp, const void *req, __u16 expect, __u16 *count)
|
|
tail = (tail + send_num) % QM_Q_DEPTH;
|
|
q_info->db(q_info, QM_DBELL_CMD_SQ, tail, 0);
|
|
q_info->sq_tail_index = tail;
|
|
- q_info->used_num += send_num;
|
|
+
|
|
+ /* Make sure used_num is changed before the next thread gets free sqe. */
|
|
+ __atomic_add_fetch(&q_info->used_num, send_num, __ATOMIC_RELAXED);
|
|
*count = send_num;
|
|
|
|
- pthread_spin_unlock(&q_info->lock);
|
|
+ pthread_spin_unlock(&q_info->sd_lock);
|
|
|
|
return 0;
|
|
}
|
|
@@ -469,21 +481,21 @@ static int hisi_qm_recv_single(struct hisi_qm_queue_info *q_info, void *resp)
|
|
struct cqe *cqe;
|
|
__u16 i, j;
|
|
|
|
- pthread_spin_lock(&q_info->lock);
|
|
+ pthread_spin_lock(&q_info->rv_lock);
|
|
i = q_info->cq_head_index;
|
|
cqe = q_info->cq_base + i * sizeof(struct cqe);
|
|
|
|
if (q_info->cqc_phase == CQE_PHASE(cqe)) {
|
|
j = CQE_SQ_HEAD_INDEX(cqe);
|
|
if (j >= QM_Q_DEPTH) {
|
|
- pthread_spin_unlock(&q_info->lock);
|
|
+ pthread_spin_unlock(&q_info->rv_lock);
|
|
WD_DEV_ERR(qp->h_ctx, "CQE_SQ_HEAD_INDEX(%u) error!\n", j);
|
|
return -WD_EIO;
|
|
}
|
|
memcpy(resp, (void *)((uintptr_t)q_info->sq_base +
|
|
j * q_info->sqe_size), q_info->sqe_size);
|
|
} else {
|
|
- pthread_spin_unlock(&q_info->lock);
|
|
+ pthread_spin_unlock(&q_info->rv_lock);
|
|
return -WD_EAGAIN;
|
|
}
|
|
|
|
@@ -500,8 +512,8 @@ static int hisi_qm_recv_single(struct hisi_qm_queue_info *q_info, void *resp)
|
|
q_info->cq_head_index = i;
|
|
q_info->sq_head_index = i;
|
|
|
|
- q_info->used_num--;
|
|
- pthread_spin_unlock(&q_info->lock);
|
|
+ __atomic_sub_fetch(&q_info->used_num, 1, __ATOMIC_RELAXED);
|
|
+ pthread_spin_unlock(&q_info->rv_lock);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/include/hisi_qm_udrv.h b/include/hisi_qm_udrv.h
|
|
index 88758ac..92333ed 100644
|
|
--- a/include/hisi_qm_udrv.h
|
|
+++ b/include/hisi_qm_udrv.h
|
|
@@ -75,7 +75,8 @@ struct hisi_qm_queue_info {
|
|
__u16 hw_type;
|
|
__u32 idx;
|
|
bool cqc_phase;
|
|
- pthread_spinlock_t lock;
|
|
+ pthread_spinlock_t sd_lock;
|
|
+ pthread_spinlock_t rv_lock;
|
|
unsigned long region_size[UACCE_QFRT_MAX];
|
|
bool epoll_en;
|
|
};
|
|
--
|
|
2.27.0
|
|
|