anolis: scsi: add a proc interface to cancel scsi eh reset

ANBZ: #555

In case of multi-disk usecase, scsi layer would pause HBA if I/O error
or timeout occurs, and the error handler is triggeerd to recover HBA with
the following operations,

Abort the command.
  Reset the device.
    Reset the bus.
      Reset the host.

If all of the above fail, the device will be set to the offline state.

The problem is that the process(30s * 5) maybe too long.  Given that
the disk error state is just around 2%, we decide to offer an knob to
report errors immediately instead so that applications can deal with
disk errors more gracefully.

Signed-off-by: Zhenghua Jia <jiazhenghua@linux.alibaba.com>
Reviewed-by: Liu Bo <bo.liu@linux.alibaba.com>
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
This commit is contained in:
Zhenghua Jia 2019-01-29 11:18:07 +08:00 committed by Qiao Ma
parent 857f77c44b
commit 21ddbb572f
3 changed files with 20 additions and 2 deletions

View File

@ -2074,6 +2074,8 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
spin_unlock_irqrestore(shost->host_lock, flags);
}
int scsi_cancel_eh_reset;
/**
* scsi_eh_ready_devs - check device ready state and recover if not.
* @shost: host to be recovered.
@ -2084,13 +2086,18 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost,
struct list_head *work_q,
struct list_head *done_q)
{
if (!scsi_eh_stu(shost, work_q, done_q))
if (!scsi_eh_stu(shost, work_q, done_q)) {
if (scsi_cancel_eh_reset) {
scsi_eh_offline_sdevs(work_q, done_q);
return;
}
if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
if (!scsi_eh_target_reset(shost, work_q, done_q))
if (!scsi_eh_bus_reset(shost, work_q, done_q))
if (!scsi_eh_host_reset(shost, work_q, done_q))
scsi_eh_offline_sdevs(work_q,
done_q);
}
}
EXPORT_SYMBOL_GPL(scsi_eh_ready_devs);

View File

@ -8,16 +8,26 @@
#include <linux/kernel.h>
#include <linux/sysctl.h>
#include <scsi/scsi_eh.h>
#include "scsi_logging.h"
#include "scsi_priv.h"
static struct ctl_table scsi_table[] = {
{ .procname = "logging_level",
.data = &scsi_logging_level,
.maxlen = sizeof(scsi_logging_level),
.mode = 0644,
.proc_handler = proc_dointvec },
{ .procname = "scsi_cancel_eh_reset",
.data = &scsi_cancel_eh_reset,
.maxlen = sizeof(scsi_cancel_eh_reset),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
{ }
};

View File

@ -51,5 +51,6 @@ extern void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,
extern void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd,
struct scsi_eh_save *ses);
extern int scsi_cancel_eh_reset;
#endif /* _SCSI_SCSI_EH_H */