On Fri, Jun 09, 2023 at 04:01:42AM -0700, Selvin Xavier wrote: > From: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> > > Use jiffies based timewait instead of counting iteration for > commands that block for FW response. > > Also add a poll routine for control path commands. This is for > polling completion if the waiting commands timeout. This avoids cases > where the driver misses completion interrupts. > > Signed-off-by: Kashyap Desai <kashyap.desai@xxxxxxxxxxxx> > Signed-off-by: Selvin Xavier <selvin.xavier@xxxxxxxxxxxx> > --- > drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 65 +++++++++++++++++++++++------- > 1 file changed, 51 insertions(+), 14 deletions(-) > > diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c > index 66121fb..3b242cc 100644 > --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c > +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c > @@ -53,37 +53,74 @@ > > static void bnxt_qplib_service_creq(struct tasklet_struct *t); > > -/* Hardware communication channel */ > +/** > + * __wait_for_resp - Don't hold the cpu context and wait for response > + * @rcfw - rcfw channel instance of rdev > + * @cookie - cookie to track the command > + * > + * Wait for command completion in sleepable context. > + * > + * Returns: > + * 0 if command is completed by firmware. > + * Non zero error code for rest of the case. I don't see "return ret;" in this function. > + */ > static int __wait_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) > { > struct bnxt_qplib_cmdq_ctx *cmdq; > u16 cbit; > - int rc; > + int ret; > > cmdq = &rcfw->cmdq; > cbit = cookie % rcfw->cmdq_depth; > - rc = wait_event_timeout(cmdq->waitq, > - !test_bit(cbit, cmdq->cmdq_bitmap), > - msecs_to_jiffies(RCFW_CMD_WAIT_TIME_MS)); > - return rc ? 0 : -ETIMEDOUT; > + > + do { > + /* Non zero means command completed */ > + ret = wait_event_timeout(cmdq->waitq, > + !test_bit(cbit, cmdq->cmdq_bitmap), > + msecs_to_jiffies(10000)); Don't you need to check ret here? > + > + if (!test_bit(cbit, cmdq->cmdq_bitmap)) > + return 0; > + > + bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet); > + > + if (!test_bit(cbit, cmdq->cmdq_bitmap)) > + return 0; > + > + } while (true); > }; > > +/** > + * __block_for_resp - hold the cpu context and wait for response > + * @rcfw - rcfw channel instance of rdev > + * @cookie - cookie to track the command > + * > + * This function will hold the cpu (non-sleepable context) and > + * wait for command completion. Maximum holding interval is 8 second. > + * > + * Returns: > + * -ETIMEOUT if command is not completed in specific time interval. > + * 0 if command is completed by firmware. > + */ > static int __block_for_resp(struct bnxt_qplib_rcfw *rcfw, u16 cookie) > { > - u32 count = RCFW_BLOCKED_CMD_WAIT_COUNT; > - struct bnxt_qplib_cmdq_ctx *cmdq; > + struct bnxt_qplib_cmdq_ctx *cmdq = &rcfw->cmdq; > + unsigned long issue_time = 0; > u16 cbit; > > - cmdq = &rcfw->cmdq; > cbit = cookie % rcfw->cmdq_depth; > - if (!test_bit(cbit, cmdq->cmdq_bitmap)) > - goto done; > + issue_time = jiffies; > + > do { > udelay(1); > + > bnxt_qplib_service_creq(&rcfw->creq.creq_tasklet); > - } while (test_bit(cbit, cmdq->cmdq_bitmap) && --count); > -done: > - return count ? 0 : -ETIMEDOUT; > + if (!test_bit(cbit, cmdq->cmdq_bitmap)) > + return 0; > + > + } while (time_before(jiffies, issue_time + (8 * HZ))); > + > + return -ETIMEDOUT; > }; > > static int __send_message(struct bnxt_qplib_rcfw *rcfw, > -- > 2.5.5 >