Skip to content

Commit 02ca7da

Browse files
Ranjan Kumarmartinkpetersen
authored andcommitted
scsi: mpi3mr: ioctl timeout when disabling/enabling interrupt
As part of Task Management handling, the driver will disable and enable the MSIx index zero which belongs to the Admin reply queue. During this transition the driver loses some interrupts and this leads to Admin request and ioctl timeouts. After enabling the interrupts, poll the Admin reply queue to avoid timeouts. Signed-off-by: Ranjan Kumar <[email protected]> Signed-off-by: Sreekanth Reddy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 2850b23 commit 02ca7da

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

drivers/scsi/mpi3mr/mpi3mr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,7 @@ struct scmd_priv {
902902
* @admin_reply_ephase:Admin reply queue expected phase
903903
* @admin_reply_base: Admin reply queue base virtual address
904904
* @admin_reply_dma: Admin reply queue base dma address
905+
* @admin_reply_q_in_use: Queue is handled by poll/ISR
905906
* @ready_timeout: Controller ready timeout
906907
* @intr_info: Interrupt cookie pointer
907908
* @intr_info_count: Number of interrupt cookies
@@ -1055,6 +1056,7 @@ struct mpi3mr_ioc {
10551056
u8 admin_reply_ephase;
10561057
void *admin_reply_base;
10571058
dma_addr_t admin_reply_dma;
1059+
atomic_t admin_reply_q_in_use;
10581060

10591061
u32 ready_timeout;
10601062

@@ -1390,4 +1392,5 @@ void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc);
13901392
void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc);
13911393
void mpi3mr_flush_cmds_for_unrecovered_controller(struct mpi3mr_ioc *mrioc);
13921394
void mpi3mr_free_enclosure_list(struct mpi3mr_ioc *mrioc);
1395+
int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc);
13931396
#endif /*MPI3MR_H_INCLUDED*/

drivers/scsi/mpi3mr/mpi3mr_fw.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,20 +415,25 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc,
415415
le64_to_cpu(scsi_reply->sense_data_buffer_address));
416416
}
417417

418-
static int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
418+
int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
419419
{
420420
u32 exp_phase = mrioc->admin_reply_ephase;
421421
u32 admin_reply_ci = mrioc->admin_reply_ci;
422422
u32 num_admin_replies = 0;
423423
u64 reply_dma = 0;
424424
struct mpi3_default_reply_descriptor *reply_desc;
425425

426+
if (!atomic_add_unless(&mrioc->admin_reply_q_in_use, 1, 1))
427+
return 0;
428+
426429
reply_desc = (struct mpi3_default_reply_descriptor *)mrioc->admin_reply_base +
427430
admin_reply_ci;
428431

429432
if ((le16_to_cpu(reply_desc->reply_flags) &
430-
MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase)
433+
MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) {
434+
atomic_dec(&mrioc->admin_reply_q_in_use);
431435
return 0;
436+
}
432437

433438
do {
434439
if (mrioc->unrecoverable)
@@ -454,6 +459,7 @@ static int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc)
454459
writel(admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci);
455460
mrioc->admin_reply_ci = admin_reply_ci;
456461
mrioc->admin_reply_ephase = exp_phase;
462+
atomic_dec(&mrioc->admin_reply_q_in_use);
457463

458464
return num_admin_replies;
459465
}
@@ -2605,6 +2611,7 @@ static int mpi3mr_setup_admin_qpair(struct mpi3mr_ioc *mrioc)
26052611
mrioc->admin_reply_ci = 0;
26062612
mrioc->admin_reply_ephase = 1;
26072613
mrioc->admin_reply_base = NULL;
2614+
atomic_set(&mrioc->admin_reply_q_in_use, 0);
26082615

26092616
if (!mrioc->admin_req_base) {
26102617
mrioc->admin_req_base = dma_alloc_coherent(&mrioc->pdev->dev,
@@ -4155,6 +4162,7 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
41554162
memset(mrioc->admin_req_base, 0, mrioc->admin_req_q_sz);
41564163
if (mrioc->admin_reply_base)
41574164
memset(mrioc->admin_reply_base, 0, mrioc->admin_reply_q_sz);
4165+
atomic_set(&mrioc->admin_reply_q_in_use, 0);
41584166

41594167
if (mrioc->init_cmds.reply) {
41604168
memset(mrioc->init_cmds.reply, 0, sizeof(*mrioc->init_cmds.reply));

drivers/scsi/mpi3mr/mpi3mr_os.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3720,6 +3720,7 @@ int mpi3mr_issue_tm(struct mpi3mr_ioc *mrioc, u8 tm_type,
37203720
mpi3mr_poll_pend_io_completions(mrioc);
37213721
mpi3mr_ioc_enable_intr(mrioc);
37223722
mpi3mr_poll_pend_io_completions(mrioc);
3723+
mpi3mr_process_admin_reply_q(mrioc);
37233724
}
37243725
switch (tm_type) {
37253726
case MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET:

0 commit comments

Comments
 (0)