Commit 92905e51 authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] cleanup device_busy/host_busy handling

- scsi_host_busy_inc isn't used anymore (and uses broken locking rules),
  kill it.
- scsi_host_busy_dec_and_test gets replace by scsi_device_unbusy that
  also cares for sdev->device_busty.
- there's a new helper, scsi_eh_wakeup, shared by scsi_device_unbusy
  and some EH code.
parent b18cc974
...@@ -289,29 +289,3 @@ void scsi_host_put(struct Scsi_Host *shost) ...@@ -289,29 +289,3 @@ void scsi_host_put(struct Scsi_Host *shost)
class_device_put(&shost->class_dev); class_device_put(&shost->class_dev);
put_device(&shost->host_gendev); put_device(&shost->host_gendev);
} }
void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
{
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy++;
sdev->device_busy++;
spin_unlock_irqrestore(shost->host_lock, flags);
}
void scsi_host_busy_dec_and_test(struct Scsi_Host *shost, Scsi_Device *sdev)
{
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
if (shost->in_recovery && shost->host_failed &&
(shost->host_busy == shost->host_failed))
{
up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
" thread\n"));
}
spin_unlock_irqrestore(shost->host_lock, flags);
}
...@@ -733,16 +733,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) ...@@ -733,16 +733,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
struct scsi_device *sdev = cmd->device; struct scsi_device *sdev = cmd->device;
struct Scsi_Host *shost = sdev->host; struct Scsi_Host *shost = sdev->host;
struct scsi_request *sreq; struct scsi_request *sreq;
unsigned long flags;
scsi_host_busy_dec_and_test(shost, sdev);
/* scsi_device_unbusy(sdev);
* XXX(hch): We really want a nice helper for this..
*/
spin_lock_irqsave(&sdev->sdev_lock, flags);
sdev->device_busy--;
spin_unlock_irqrestore(&sdev->sdev_lock, flags);
/* /*
* Clear the flags which say that the device/host is no longer * Clear the flags which say that the device/host is no longer
......
...@@ -44,6 +44,16 @@ ...@@ -44,6 +44,16 @@
#define BUS_RESET_SETTLE_TIME 10*HZ #define BUS_RESET_SETTLE_TIME 10*HZ
#define HOST_RESET_SETTLE_TIME 10*HZ #define HOST_RESET_SETTLE_TIME 10*HZ
/* called with shost->host_lock held */
void scsi_eh_wakeup(struct Scsi_Host *shost)
{
if (shost->host_busy == shost->host_failed) {
up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5,
printk("Waking error handler thread\n"));
}
}
/** /**
* scsi_eh_scmd_add - add scsi cmd to error handling. * scsi_eh_scmd_add - add scsi cmd to error handling.
* @scmd: scmd to run eh on. * @scmd: scmd to run eh on.
...@@ -76,14 +86,8 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag) ...@@ -76,14 +86,8 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
shost->in_recovery = 1; shost->in_recovery = 1;
shost->host_failed++; shost->host_failed++;
if (shost->host_busy == shost->host_failed) { scsi_eh_wakeup(shost);
up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
" thread\n"));
}
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
return 1; return 1;
} }
......
...@@ -95,7 +95,6 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) ...@@ -95,7 +95,6 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{ {
struct Scsi_Host *host = cmd->device->host; struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device; struct scsi_device *device = cmd->device;
unsigned long flags;
SCSI_LOG_MLQUEUE(1, SCSI_LOG_MLQUEUE(1,
printk("Inserting command %p into mlqueue\n", cmd)); printk("Inserting command %p into mlqueue\n", cmd));
...@@ -134,10 +133,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) ...@@ -134,10 +133,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
* Decrement the counters, since these commands are no longer * Decrement the counters, since these commands are no longer
* active on the host/device. * active on the host/device.
*/ */
spin_lock_irqsave(device->request_queue->queue_lock, flags); scsi_device_unbusy(device);
device->device_busy--;
spin_unlock_irqrestore(device->request_queue->queue_lock, flags);
scsi_host_busy_dec_and_test(host, device);
/* /*
* Insert this command at the head of the queue for it's device. * Insert this command at the head of the queue for it's device.
...@@ -314,6 +310,21 @@ void scsi_setup_cmd_retry(struct scsi_cmnd *cmd) ...@@ -314,6 +310,21 @@ void scsi_setup_cmd_retry(struct scsi_cmnd *cmd)
cmd->underflow = cmd->old_underflow; cmd->underflow = cmd->old_underflow;
} }
void scsi_device_unbusy(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
if (unlikely(shost->in_recovery && shost->host_failed))
scsi_eh_wakeup(shost);
spin_unlock(shost->host_lock);
spin_lock(&sdev->sdev_lock);
sdev->device_busy--;
spin_unlock_irqrestore(&sdev->sdev_lock, flags);
}
/* /*
* Called for single_lun devices on IO completion. Clear starget_sdev_user, * Called for single_lun devices on IO completion. Clear starget_sdev_user,
* and call blk_run_queue for all the scsi_devices on the target - * and call blk_run_queue for all the scsi_devices on the target -
......
...@@ -52,10 +52,6 @@ struct scsi_target { ...@@ -52,10 +52,6 @@ struct scsi_target {
}; };
/* hosts.c */
extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
/* scsi.c */ /* scsi.c */
extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
extern int scsi_setup_command_freelist(struct Scsi_Host *shost); extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
...@@ -77,11 +73,13 @@ extern void scsi_exit_devinfo(void); ...@@ -77,11 +73,13 @@ extern void scsi_exit_devinfo(void);
extern void scsi_times_out(struct scsi_cmnd *cmd); extern void scsi_times_out(struct scsi_cmnd *cmd);
extern void scsi_error_handler(void *host); extern void scsi_error_handler(void *host);
extern int scsi_decide_disposition(struct scsi_cmnd *cmd); extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
extern void scsi_eh_wakeup(struct Scsi_Host *shost);
extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
/* scsi_lib.c */ /* scsi_lib.c */
extern int scsi_maybe_unblock_host(struct scsi_device *sdev); extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd); extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
extern void scsi_device_unbusy(struct scsi_device *sdev);
extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
extern void scsi_next_command(struct scsi_cmnd *cmd); extern void scsi_next_command(struct scsi_cmnd *cmd);
extern void scsi_run_host_queues(struct Scsi_Host *shost); extern void scsi_run_host_queues(struct Scsi_Host *shost);
......
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