[PATCH] scsi: qla2xxx: reduce the time granularity of the qla2x00_eh_wait_on_command
If the cmd has not be returned after aborted by qla2x00_eh_abort, when qla2x00_eh_wait_on_command is invoked, it has to wait for it. However, the time is 1000ms at least currently. If there are a lot cmds need to be aborted, the delay could be long enough to lead to panic due to such as hung task, ocfs2 heartbeat, etc, just before scsi recovery work completes and get back the HBA. Change the granularity to 1ms, even though more context switches would be introduced, but it should be ok as it is not hot path. Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 15eaa6d..9ea4e02 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1064,7 +1064,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, static int qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) { -#define ABORT_POLLING_PERIOD 1000 +#define ABORT_POLLING_PERIOD 1 #define ABORT_WAIT_ITER((2 * 1000) / (ABORT_POLLING_PERIOD)) unsigned long wait_iter = ABORT_WAIT_ITER; scsi_qla_host_t *vha = shost_priv(cmd->device->host); -- 2.7.4
[PATCH] scsi: qla2xxx: reduce the time granularity of qla2x00_eh_wait_on_command
If the cmd has not be returned after aborted by qla2x00_eh_abort, we have to wait for it. However, the time is 1000ms at least currently. If there are a lot cmds need to be aborted, the delay could be long enough to lead to panic due to such as hung task, ocfs2 heartbeat, etc, just before scsi recovery works. Change the granularity to 1ms, even though more context switches would be introduced, but it should be ok as it is not hot path. Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 5c5dcca4..9f52ad9 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1072,7 +1072,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, static int qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) { -#define ABORT_POLLING_PERIOD 1000 +#define ABORT_POLLING_PERIOD 1 #define ABORT_WAIT_ITER((2 * 1000) / (ABORT_POLLING_PERIOD)) unsigned long wait_iter = ABORT_WAIT_ITER; scsi_qla_host_t *vha = shost_priv(cmd->device->host); -- 2.7.4
[PATCH] scsi: iscsi_tcp: set BDI_CAP_STABLE_WRITES when data digest enabled
iscsi tcp will first send out data, then calculate and send data digest. If we don't have BDI_CAP_STABLE_WRITES, the page cache will be written in spite of the on going writeback. Consequently, wrong digest will be got and sent to target. To fix this, set BDI_CAP_STABLE_WRITES when data digest is enabled in iscsi_tcp .slave_configure callback. Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/iscsi_tcp.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 6198559..261c686 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -954,6 +955,12 @@ static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev) static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) { + struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host); + struct iscsi_session *session = tcp_sw_host->session; + struct iscsi_conn *conn = session->leadconn; + + if (conn->datadgst_en) + sdev->request_queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); blk_queue_dma_alignment(sdev->request_queue, 0); return 0; -- 2.7.4
[PATCH V4] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
In scsi core, __scsi_queue_insert should just put request back on the queue and retry using the same command as before. However, for blk-mq, scsi_mq_requeue_cmd is employed here which will unprepare the request. To align with the semantics of __scsi_queue_insert, use blk_mq_requeue_request with kick_requeue_list == true and put the reference of scsi_device. Cc: Christoph Hellwig <h...@lst.de> Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> Reviewed-by: Bart Van Assche <bart.vanass...@wdc.com> --- Changelog: V3 -> V4: - modify the comment and make it more clearly V2 -> V3: - add comment to explain why we need a put_device in __scsi_queue_insert - add reviewed-by V1 -> V2: - add put_device on scsi_device->sdev_gendev drivers/scsi/scsi_lib.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a86df9c..6ce33f6 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -191,7 +191,19 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; if (q->mq_ops) { - scsi_mq_requeue_cmd(cmd); + /* +* Before a SCSI command is dispatched, +* get_device(>sdev_gendev) is called and the host, +* target and device busy counters are increased. Since +* requeuing a request causes these actions to be repeated and +* since scsi_device_unbusy() has already been called, +* put_device(>sdev_gendev) must still be called. Call +* put_device() after blk_mq_requeue_request() to avoid that +* removal of the SCSI device can start before requeueing has +* happened. +*/ + blk_mq_requeue_request(cmd->request, true); + put_device(>sdev_gendev); return; } spin_lock_irqsave(q->queue_lock, flags); -- 2.7.4
[PATCH V3] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
In scsi core, __scsi_queue_insert should just put request back on the queue and retry using the same command as before. However, for blk-mq, scsi_mq_requeue_cmd is employed here which will unprepare the request. To align with the semantics of __scsi_queue_insert, use blk_mq_requeue_request with kick_requeue_list == true and put the reference of scsi_device. Cc: Christoph Hellwig <h...@lst.de> Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> Reviewed-by: Bart Van Assche <bart.vanass...@wdc.com> --- Changelog: V2 -> V3: - add commit to explain why we need a put_device in __scsi_queue_insert - add reviewed-by V1 -> V2: - add put_device on scsi_device->sdev_gendev drivers/scsi/scsi_lib.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a86df9c..d2f1838 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -191,7 +191,13 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; if (q->mq_ops) { - scsi_mq_requeue_cmd(cmd); + /* +* scsi_device.sdev_gendev will be get every time in .get_budget and +* be put in scsi_end_request. Hence we need to put the reference +* here when we decide to requeue request. +*/ + blk_mq_requeue_request(cmd->request, true); + put_device(>sdev_gendev); return; } spin_lock_irqsave(q->queue_lock, flags); -- 2.7.4
[PATCH V2] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
In scsi core, __scsi_queue_insert should just put request back on the queue and retry using the same command as before. However, for blk-mq, scsi_mq_requeue_cmd is employed here which will unprepare the request. To align with the semantics of __scsi_queue_insert, use blk_mq_requeue_request with kick_requeue_list == true and put the reference of scsi_device. V1 -> V2: - add put_device on scsi_device->sdev_gendev Cc: Christoph Hellwig <h...@lst.de> Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/scsi_lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a86df9c..6fa7b0c 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -191,7 +191,8 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; if (q->mq_ops) { - scsi_mq_requeue_cmd(cmd); + blk_mq_requeue_request(cmd->request, true); + put_device(>sdev_gendev); return; } spin_lock_irqsave(q->queue_lock, flags); -- 2.7.4
[PATCH] scsi: core: fix two wrong indentation cases
No functional changes. Just fix two wrong indentation cases in scsi_finish_command and scsi_decide_disposition. Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/scsi.c | 2 +- drivers/scsi/scsi_error.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a7e4fba..4c60c26 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -231,7 +231,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "(result %x)\n", cmd->result)); good_bytes = scsi_bufflen(cmd); -if (!blk_rq_is_passthrough(cmd->request)) { + if (!blk_rq_is_passthrough(cmd->request)) { int old_good_bytes = good_bytes; drv = scsi_cmd_to_driver(cmd); if (drv->done) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index d042915..96066d1 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1888,7 +1888,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) } return FAILED; - maybe_retry: +maybe_retry: /* we requeue for retry because the error was retryable, and * the request was not marked fast fail. Note that above, -- 2.7.4
[PATCH] scsi: core: use blk_mq_requeue_request in __scsi_queue_insert
In scsi core, __scsi_queue_insert should just put request back on the queue and retry using the same command as before. However, for blk-mq, scsi_mq_requeue_cmd is employed here which will unprepare the request. To align with the semantics of __scsi_queue_insert, just use blk_mq_requeue_request with kick_requeue_list == true. Cc: Christoph Hellwig <h...@lst.de> Signed-off-by: Jianchao Wang <jianchao.w.w...@oracle.com> --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a86df9c..06d8110 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -191,7 +191,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) */ cmd->result = 0; if (q->mq_ops) { - scsi_mq_requeue_cmd(cmd); + blk_mq_requeue_request(cmd->request, true); return; } spin_lock_irqsave(q->queue_lock, flags); -- 2.7.4