Skip to content

Commit

Permalink
Merge patch series "mpi3mr: Support PCI Error Recovery"
Browse files Browse the repository at this point in the history
Sumit Saxena <sumit.saxena@broadcom.com> says:

This patch series contains the changes done in the driver to support
PCI error recovery. It is rework of older patch series from Ranjan
Kumar, see [1].

[1] https://lore.kernel.org/all/20231214205900.270488-1-ranjan.kumar@broadcom.com/

Link: https://lore.kernel.org/r/20240627101735.18286-1-sumit.saxena@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Martin K. Petersen committed Jul 5, 2024
2 parents 3443855 + cf82b9e commit 6cd48c8
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 19 deletions.
11 changes: 9 additions & 2 deletions drivers/scsi/mpi3mr/mpi3mr.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/aer.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -56,8 +57,8 @@ extern struct list_head mrioc_list;
extern int prot_mask;
extern atomic64_t event_counter;

#define MPI3MR_DRIVER_VERSION "8.9.1.0.50"
#define MPI3MR_DRIVER_RELDATE "14-May-2024"
#define MPI3MR_DRIVER_VERSION "8.9.1.0.51"
#define MPI3MR_DRIVER_RELDATE "29-May-2024"

#define MPI3MR_DRIVER_NAME "mpi3mr"
#define MPI3MR_DRIVER_LICENSE "GPL"
Expand Down Expand Up @@ -129,6 +130,7 @@ extern atomic64_t event_counter;
#define MPI3MR_PREPARE_FOR_RESET_TIMEOUT 180
#define MPI3MR_RESET_ACK_TIMEOUT 30
#define MPI3MR_MUR_TIMEOUT 120
#define MPI3MR_RESET_TIMEOUT 510

#define MPI3MR_WATCHDOG_INTERVAL 1000 /* in milli seconds */

Expand Down Expand Up @@ -517,6 +519,7 @@ struct mpi3mr_throttle_group_info {

/* HBA port flags */
#define MPI3MR_HBA_PORT_FLAG_DIRTY 0x01
#define MPI3MR_HBA_PORT_FLAG_NEW 0x02

/* IOCTL data transfer sge*/
#define MPI3MR_NUM_IOCTL_SGE 256
Expand Down Expand Up @@ -1153,6 +1156,8 @@ struct scmd_priv {
* @trace_release_trigger_active: Trace trigger active flag
* @fw_release_trigger_active: Fw release trigger active flag
* @snapdump_trigger_active: Snapdump trigger active flag
* @pci_err_recovery: PCI error recovery in progress
* @block_on_pci_err: Block IO during PCI error recovery
*/
struct mpi3mr_ioc {
struct list_head list;
Expand Down Expand Up @@ -1353,6 +1358,8 @@ struct mpi3mr_ioc {
bool snapdump_trigger_active;
bool trace_release_trigger_active;
bool fw_release_trigger_active;
bool pci_err_recovery;
bool block_on_pci_err;
};

/**
Expand Down
10 changes: 7 additions & 3 deletions drivers/scsi/mpi3mr/mpi3mr_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ static int mpi3mr_bsg_pel_abort(struct mpi3mr_ioc *mrioc)
dprint_bsg_err(mrioc, "%s: reset in progress\n", __func__);
return -1;
}
if (mrioc->stop_bsgs) {
if (mrioc->stop_bsgs || mrioc->block_on_pci_err) {
dprint_bsg_err(mrioc, "%s: bsgs are blocked\n", __func__);
return -1;
}
Expand Down Expand Up @@ -1492,6 +1492,9 @@ static long mpi3mr_bsg_adp_reset(struct mpi3mr_ioc *mrioc,
goto out;
}

if (mrioc->unrecoverable || mrioc->block_on_pci_err)
return -EINVAL;

sg_copy_to_buffer(job->request_payload.sg_list,
job->request_payload.sg_cnt,
&adpreset, sizeof(adpreset));
Expand Down Expand Up @@ -2575,7 +2578,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
mutex_unlock(&mrioc->bsg_cmds.mutex);
goto out;
}
if (mrioc->stop_bsgs) {
if (mrioc->stop_bsgs || mrioc->block_on_pci_err) {
dprint_bsg_err(mrioc, "%s: bsgs are blocked\n", __func__);
rval = -EAGAIN;
mutex_unlock(&mrioc->bsg_cmds.mutex);
Expand Down Expand Up @@ -3108,7 +3111,8 @@ adp_state_show(struct device *dev, struct device_attribute *attr,
ioc_state = mpi3mr_get_iocstate(mrioc);
if (ioc_state == MRIOC_STATE_UNRECOVERABLE)
adp_state = MPI3MR_BSG_ADPSTATE_UNRECOVERABLE;
else if ((mrioc->reset_in_progress) || (mrioc->stop_bsgs))
else if (mrioc->reset_in_progress || mrioc->stop_bsgs ||
mrioc->block_on_pci_err)
adp_state = MPI3MR_BSG_ADPSTATE_IN_RESET;
else if (ioc_state == MRIOC_STATE_FAULT)
adp_state = MPI3MR_BSG_ADPSTATE_FAULT;
Expand Down
22 changes: 17 additions & 5 deletions drivers/scsi/mpi3mr/mpi3mr_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ int mpi3mr_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
mrioc = (struct mpi3mr_ioc *)shost->hostdata;

if ((mrioc->reset_in_progress || mrioc->prepare_for_reset ||
mrioc->unrecoverable))
mrioc->unrecoverable || mrioc->pci_err_recovery))
return 0;

num_entries = mpi3mr_process_op_reply_q(mrioc,
Expand Down Expand Up @@ -1693,6 +1693,12 @@ int mpi3mr_admin_request_post(struct mpi3mr_ioc *mrioc, void *admin_req,
retval = -EAGAIN;
goto out;
}
if (mrioc->pci_err_recovery) {
ioc_err(mrioc, "admin request queue submission failed due to pci error recovery in progress\n");
retval = -EAGAIN;
goto out;
}

areq_entry = (u8 *)mrioc->admin_req_base +
(areq_pi * MPI3MR_ADMIN_REQ_FRAME_SZ);
memset(areq_entry, 0, MPI3MR_ADMIN_REQ_FRAME_SZ);
Expand Down Expand Up @@ -2363,6 +2369,11 @@ int mpi3mr_op_request_post(struct mpi3mr_ioc *mrioc,
retval = -EAGAIN;
goto out;
}
if (mrioc->pci_err_recovery) {
ioc_err(mrioc, "operational request queue submission failed due to pci error recovery in progress\n");
retval = -EAGAIN;
goto out;
}

segment_base_addr = segments[pi / op_req_q->segment_qd].segment;
req_entry = (u8 *)segment_base_addr +
Expand Down Expand Up @@ -2627,7 +2638,7 @@ static void mpi3mr_watchdog_work(struct work_struct *work)
union mpi3mr_trigger_data trigger_data;
u16 reset_reason = MPI3MR_RESET_FROM_FAULT_WATCH;

if (mrioc->reset_in_progress)
if (mrioc->reset_in_progress || mrioc->pci_err_recovery)
return;

if (!mrioc->unrecoverable && !pci_device_is_present(mrioc->pdev)) {
Expand Down Expand Up @@ -4268,7 +4279,7 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume)
goto out_failed_noretry;
}

if (is_resume) {
if (is_resume || mrioc->block_on_pci_err) {
dprint_reset(mrioc, "setting up single ISR\n");
retval = mpi3mr_setup_isr(mrioc, 1);
if (retval) {
Expand Down Expand Up @@ -4319,7 +4330,7 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume)
goto out_failed;
}

if (is_resume) {
if (is_resume || mrioc->block_on_pci_err) {
dprint_reset(mrioc, "setting up multiple ISR\n");
retval = mpi3mr_setup_isr(mrioc, 0);
if (retval) {
Expand Down Expand Up @@ -4807,7 +4818,8 @@ void mpi3mr_cleanup_ioc(struct mpi3mr_ioc *mrioc)

ioc_state = mpi3mr_get_iocstate(mrioc);

if ((!mrioc->unrecoverable) && (!mrioc->reset_in_progress) &&
if (!mrioc->unrecoverable && !mrioc->reset_in_progress &&
!mrioc->pci_err_recovery &&
(ioc_state == MRIOC_STATE_READY)) {
if (mpi3mr_issue_and_process_mur(mrioc,
MPI3MR_RESET_FROM_CTLR_CLEANUP))
Expand Down
Loading

0 comments on commit 6cd48c8

Please sign in to comment.