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)
class_device_put(&shost->class_dev);
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)
struct scsi_device *sdev = cmd->device;
struct Scsi_Host *shost = sdev->host;
struct scsi_request *sreq;
unsigned long flags;
scsi_host_busy_dec_and_test(shost, 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);
scsi_device_unbusy(sdev);
/*
* Clear the flags which say that the device/host is no longer
......
......@@ -44,6 +44,16 @@
#define BUS_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.
* @scmd: scmd to run eh on.
......@@ -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);
shost->in_recovery = 1;
shost->host_failed++;
if (shost->host_busy == shost->host_failed) {
up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
" thread\n"));
}
scsi_eh_wakeup(shost);
spin_unlock_irqrestore(shost->host_lock, flags);
return 1;
}
......
......@@ -95,7 +95,6 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
unsigned long flags;
SCSI_LOG_MLQUEUE(1,
printk("Inserting command %p into mlqueue\n", cmd));
......@@ -134,10 +133,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
* Decrement the counters, since these commands are no longer
* active on the host/device.
*/
spin_lock_irqsave(device->request_queue->queue_lock, flags);
device->device_busy--;
spin_unlock_irqrestore(device->request_queue->queue_lock, flags);
scsi_host_busy_dec_and_test(host, device);
scsi_device_unbusy(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)
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,
* and call blk_run_queue for all the scsi_devices on the 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 */
extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
......@@ -77,11 +73,13 @@ extern void scsi_exit_devinfo(void);
extern void scsi_times_out(struct scsi_cmnd *cmd);
extern void scsi_error_handler(void *host);
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);
/* scsi_lib.c */
extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
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 void scsi_next_command(struct scsi_cmnd *cmd);
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