Commit 2ccbb008 authored by Christoph Hellwig's avatar Christoph Hellwig

scsi: only maintain target_blocked if the driver has a target queue limit

This saves us an atomic operation for each I/O submission and completion
for the usual case where the driver doesn't set a per-target can_queue
value.  Only a few iscsi hardware offload drivers set the per-target
can_queue value at the moment.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarWebb Scales <webbnh@hp.com>
Acked-by: default avatarJens Axboe <axboe@kernel.dk>
Tested-by: default avatarBart Van Assche <bvanassche@acm.org>
Tested-by: default avatarRobert Elliott <elliott@hp.com>
parent cd9070c9
...@@ -295,7 +295,8 @@ void scsi_device_unbusy(struct scsi_device *sdev) ...@@ -295,7 +295,8 @@ void scsi_device_unbusy(struct scsi_device *sdev)
unsigned long flags; unsigned long flags;
atomic_dec(&shost->host_busy); atomic_dec(&shost->host_busy);
atomic_dec(&starget->target_busy); if (starget->can_queue > 0)
atomic_dec(&starget->target_busy);
if (unlikely(scsi_host_in_recovery(shost) && if (unlikely(scsi_host_in_recovery(shost) &&
(shost->host_failed || shost->host_eh_scheduled))) { (shost->host_failed || shost->host_eh_scheduled))) {
...@@ -364,11 +365,12 @@ static inline bool scsi_device_is_busy(struct scsi_device *sdev) ...@@ -364,11 +365,12 @@ static inline bool scsi_device_is_busy(struct scsi_device *sdev)
static inline bool scsi_target_is_busy(struct scsi_target *starget) static inline bool scsi_target_is_busy(struct scsi_target *starget)
{ {
if (starget->can_queue > 0 && if (starget->can_queue > 0) {
atomic_read(&starget->target_busy) >= starget->can_queue) if (atomic_read(&starget->target_busy) >= starget->can_queue)
return true; return true;
if (atomic_read(&starget->target_blocked) > 0) if (atomic_read(&starget->target_blocked) > 0)
return true; return true;
}
return false; return false;
} }
...@@ -1309,6 +1311,9 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost, ...@@ -1309,6 +1311,9 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
} }
if (starget->can_queue <= 0)
return 1;
busy = atomic_inc_return(&starget->target_busy) - 1; busy = atomic_inc_return(&starget->target_busy) - 1;
if (atomic_read(&starget->target_blocked) > 0) { if (atomic_read(&starget->target_blocked) > 0) {
if (busy) if (busy)
...@@ -1324,7 +1329,7 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost, ...@@ -1324,7 +1329,7 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
"unblocking target at zero depth\n")); "unblocking target at zero depth\n"));
} }
if (starget->can_queue > 0 && busy >= starget->can_queue) if (busy >= starget->can_queue)
goto starved; goto starved;
return 1; return 1;
...@@ -1334,7 +1339,8 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost, ...@@ -1334,7 +1339,8 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
list_move_tail(&sdev->starved_entry, &shost->starved_list); list_move_tail(&sdev->starved_entry, &shost->starved_list);
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
out_dec: out_dec:
atomic_dec(&starget->target_busy); if (starget->can_queue > 0)
atomic_dec(&starget->target_busy);
return 0; return 0;
} }
...@@ -1455,7 +1461,8 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) ...@@ -1455,7 +1461,8 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
*/ */
atomic_inc(&sdev->device_busy); atomic_inc(&sdev->device_busy);
atomic_inc(&shost->host_busy); atomic_inc(&shost->host_busy);
atomic_inc(&starget->target_busy); if (starget->can_queue > 0)
atomic_inc(&starget->target_busy);
blk_complete_request(req); blk_complete_request(req);
} }
...@@ -1624,7 +1631,8 @@ static void scsi_request_fn(struct request_queue *q) ...@@ -1624,7 +1631,8 @@ static void scsi_request_fn(struct request_queue *q)
return; return;
host_not_ready: host_not_ready:
atomic_dec(&scsi_target(sdev)->target_busy); if (scsi_target(sdev)->can_queue > 0)
atomic_dec(&scsi_target(sdev)->target_busy);
not_ready: not_ready:
/* /*
* lock q, handle tag, requeue req, and decrement device_busy. We * lock q, handle tag, requeue req, and decrement device_busy. We
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment