mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 17:30:53 +07:00
[SCSI] Fix thread termination for the SCSI error handle
From: Alan Stern <stern@rowland.harvard.edu> This patch (as561) fixes the error handler's thread-exit code. The kthread_stop call won't wake the thread from a down_interruptible, so the patch gets rid of the semaphore and simply does set_current_state(TASK_INTERRUPTIBLE); Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Modified to simplify the termination loop and correct the sleep condition. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
939647ee30
commit
3ed7a4704b
@ -50,7 +50,7 @@
|
||||
void scsi_eh_wakeup(struct Scsi_Host *shost)
|
||||
{
|
||||
if (shost->host_busy == shost->host_failed) {
|
||||
up(shost->eh_wait);
|
||||
wake_up_process(shost->ehandler);
|
||||
SCSI_LOG_ERROR_RECOVERY(5,
|
||||
printk("Waking error handler thread\n"));
|
||||
}
|
||||
@ -70,7 +70,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (shost->eh_wait == NULL)
|
||||
if (!shost->ehandler)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
@ -1591,40 +1591,31 @@ int scsi_error_handler(void *data)
|
||||
{
|
||||
struct Scsi_Host *shost = (struct Scsi_Host *) data;
|
||||
int rtn;
|
||||
DECLARE_MUTEX_LOCKED(sem);
|
||||
|
||||
current->flags |= PF_NOFREEZE;
|
||||
shost->eh_wait = &sem;
|
||||
|
||||
|
||||
/*
|
||||
* Wake up the thread that created us.
|
||||
* Note - we always use TASK_INTERRUPTIBLE even if the module
|
||||
* was loaded as part of the kernel. The reason is that
|
||||
* UNINTERRUPTIBLE would cause this thread to be counted in
|
||||
* the load average as a running process, and an interruptible
|
||||
* wait doesn't.
|
||||
*/
|
||||
SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
|
||||
" scsi_eh_%d\n",shost->host_no));
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* If we get a signal, it means we are supposed to go
|
||||
* away and die. This typically happens if the user is
|
||||
* trying to unload a module.
|
||||
*/
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d"
|
||||
" sleeping\n",shost->host_no));
|
||||
|
||||
/*
|
||||
* Note - we always use down_interruptible with the semaphore
|
||||
* even if the module was loaded as part of the kernel. The
|
||||
* reason is that down() will cause this thread to be counted
|
||||
* in the load average as a running process, and down
|
||||
* interruptible doesn't. Given that we need to allow this
|
||||
* thread to die if the driver was loaded as a module, using
|
||||
* semaphores isn't unreasonable.
|
||||
*/
|
||||
down_interruptible(&sem);
|
||||
if (kthread_should_stop())
|
||||
break;
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
while (!kthread_should_stop()) {
|
||||
if (shost->host_failed == 0 ||
|
||||
shost->host_failed != shost->host_busy) {
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d"
|
||||
" sleeping\n",
|
||||
shost->host_no));
|
||||
schedule();
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
continue;
|
||||
}
|
||||
|
||||
__set_current_state(TASK_RUNNING);
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
|
||||
" scsi_eh_%d waking"
|
||||
" up\n",shost->host_no));
|
||||
@ -1651,7 +1642,7 @@ int scsi_error_handler(void *data)
|
||||
* which are still online.
|
||||
*/
|
||||
scsi_restart_operations(shost);
|
||||
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
}
|
||||
|
||||
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
|
||||
@ -1660,7 +1651,7 @@ int scsi_error_handler(void *data)
|
||||
/*
|
||||
* Make sure that nobody tries to wake us up again.
|
||||
*/
|
||||
shost->eh_wait = NULL;
|
||||
shost->ehandler = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -467,8 +467,6 @@ struct Scsi_Host {
|
||||
|
||||
struct list_head eh_cmd_q;
|
||||
struct task_struct * ehandler; /* Error recovery thread. */
|
||||
struct semaphore * eh_wait; /* The error recovery thread waits
|
||||
on this. */
|
||||
struct semaphore * eh_action; /* Wait for specific actions on the
|
||||
host. */
|
||||
unsigned int eh_active:1; /* Indicates the eh thread is awake and active if
|
||||
|
Loading…
Reference in New Issue
Block a user