[dm-devel] multipath_busy() stalls IO due to scsi_host_is_busy()
Jun'ichi Nomura
j-nomura at ce.jp.nec.com
Thu May 17 09:09:57 UTC 2012
Hi,
On 05/16/12 21:28, Bernd Schubert wrote:
> Looking through the call chain, I see the underlying problem seems to be in scsi_host_is_busy().
>
>> static inline int scsi_host_is_busy(struct Scsi_Host *shost)
>> {
>> if ((shost->can_queue > 0 && shost->host_busy >= shost->can_queue) ||
>> shost->host_blocked || shost->host_self_blocked)
>> return 1;
>>
>> return 0;
>> }
multipath_busy() was introduced because, without that,
a request would be prematurely sent down to SCSI,
lose the chance of additional merges and result in
bad performance.
However, when it is target/host that is busy, I think dm should
send the request down and let SCSI, which has better knowledge
about the shared resource, do appropriate starvation control.
Could you try the attached patch?
---
Jun'ichi Nomura, NEC Corporation
If sdev is not busy but starget and/or host is busy,
it is better to accept a request from stacking driver.
Otherwise, the stacking device could be starved by other device
sharing the same target/host.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 5dfd749..0eb4602 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1378,16 +1378,13 @@ static int scsi_lld_busy(struct request_queue *q)
{
struct scsi_device *sdev = q->queuedata;
struct Scsi_Host *shost;
- struct scsi_target *starget;
if (!sdev)
return 0;
shost = sdev->host;
- starget = scsi_target(sdev);
- if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) ||
- scsi_target_is_busy(starget) || scsi_device_is_busy(sdev))
+ if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev))
return 1;
return 0;
More information about the dm-devel
mailing list