mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-25 00:52:45 -04:00
RDMA/erdma: Support non-sleeping erdma_post_cmd_wait()
Several scenarios require posting commands to the cmdq in a non-sleepable context. For example, the cm_alloc_msg() might call erdma_create_ah() while still holding a spinlock. So we add support for non-sleeping erdma_post_cmd_wait(). Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com> Signed-off-by: Boshi Yu <boshiyu@linux.alibaba.com> Link: https://patch.msgid.link/20241226084141.74823-4-boshiyu@linux.alibaba.com Signed-off-by: Leon Romanovsky <leon@kernel.org>
This commit is contained in:
committed by
Leon Romanovsky
parent
3761e0ad79
commit
26981e688c
@@ -182,7 +182,6 @@ int erdma_cmdq_init(struct erdma_dev *dev)
|
||||
int err;
|
||||
|
||||
cmdq->max_outstandings = ERDMA_CMDQ_MAX_OUTSTANDING;
|
||||
cmdq->use_event = false;
|
||||
|
||||
sema_init(&cmdq->credits, cmdq->max_outstandings);
|
||||
|
||||
@@ -223,8 +222,6 @@ err_destroy_sq:
|
||||
|
||||
void erdma_finish_cmdq_init(struct erdma_dev *dev)
|
||||
{
|
||||
/* after device init successfully, change cmdq to event mode. */
|
||||
dev->cmdq.use_event = true;
|
||||
arm_cmdq_cq(&dev->cmdq);
|
||||
}
|
||||
|
||||
@@ -312,8 +309,7 @@ static int erdma_poll_single_cmd_completion(struct erdma_cmdq *cmdq)
|
||||
/* Copy 16B comp data after cqe hdr to outer */
|
||||
be32_to_cpu_array(comp_wait->comp_data, cqe + 2, 4);
|
||||
|
||||
if (cmdq->use_event)
|
||||
complete(&comp_wait->wait_event);
|
||||
complete(&comp_wait->wait_event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -332,9 +328,6 @@ static void erdma_polling_cmd_completions(struct erdma_cmdq *cmdq)
|
||||
if (erdma_poll_single_cmd_completion(cmdq))
|
||||
break;
|
||||
|
||||
if (comp_num && cmdq->use_event)
|
||||
arm_cmdq_cq(cmdq);
|
||||
|
||||
spin_unlock_irqrestore(&cmdq->cq.lock, flags);
|
||||
}
|
||||
|
||||
@@ -342,8 +335,7 @@ void erdma_cmdq_completion_handler(struct erdma_cmdq *cmdq)
|
||||
{
|
||||
int got_event = 0;
|
||||
|
||||
if (!test_bit(ERDMA_CMDQ_STATE_OK_BIT, &cmdq->state) ||
|
||||
!cmdq->use_event)
|
||||
if (!test_bit(ERDMA_CMDQ_STATE_OK_BIT, &cmdq->state))
|
||||
return;
|
||||
|
||||
while (get_next_valid_eqe(&cmdq->eq)) {
|
||||
@@ -354,6 +346,7 @@ void erdma_cmdq_completion_handler(struct erdma_cmdq *cmdq)
|
||||
if (got_event) {
|
||||
cmdq->cq.cmdsn++;
|
||||
erdma_polling_cmd_completions(cmdq);
|
||||
arm_cmdq_cq(cmdq);
|
||||
}
|
||||
|
||||
notify_eq(&cmdq->eq);
|
||||
@@ -372,7 +365,7 @@ static int erdma_poll_cmd_completion(struct erdma_comp_wait *comp_ctx,
|
||||
if (time_is_before_jiffies(comp_timeout))
|
||||
return -ETIME;
|
||||
|
||||
msleep(20);
|
||||
udelay(20);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -403,7 +396,7 @@ void erdma_cmdq_build_reqhdr(u64 *hdr, u32 mod, u32 op)
|
||||
}
|
||||
|
||||
int erdma_post_cmd_wait(struct erdma_cmdq *cmdq, void *req, u32 req_size,
|
||||
u64 *resp0, u64 *resp1)
|
||||
u64 *resp0, u64 *resp1, bool sleepable)
|
||||
{
|
||||
struct erdma_comp_wait *comp_wait;
|
||||
int ret;
|
||||
@@ -411,7 +404,12 @@ int erdma_post_cmd_wait(struct erdma_cmdq *cmdq, void *req, u32 req_size,
|
||||
if (!test_bit(ERDMA_CMDQ_STATE_OK_BIT, &cmdq->state))
|
||||
return -ENODEV;
|
||||
|
||||
down(&cmdq->credits);
|
||||
if (!sleepable) {
|
||||
while (down_trylock(&cmdq->credits))
|
||||
;
|
||||
} else {
|
||||
down(&cmdq->credits);
|
||||
}
|
||||
|
||||
comp_wait = get_comp_wait(cmdq);
|
||||
if (IS_ERR(comp_wait)) {
|
||||
@@ -425,7 +423,7 @@ int erdma_post_cmd_wait(struct erdma_cmdq *cmdq, void *req, u32 req_size,
|
||||
push_cmdq_sqe(cmdq, req, req_size, comp_wait);
|
||||
spin_unlock(&cmdq->sq.lock);
|
||||
|
||||
if (cmdq->use_event)
|
||||
if (sleepable)
|
||||
ret = erdma_wait_cmd_completion(comp_wait, cmdq,
|
||||
ERDMA_CMDQ_TIMEOUT_MS);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user