Commit dabae96e authored by James Bottomley's avatar James Bottomley Committed by James Bottomley

remove SCSI's use of signals for killing the error handler thread

- change the eh_notify semaphore to a completion
- add complete_and_exit() to the thread
- use a host structure flag to signal thread death instead of the signal
parent e18106d2
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/completion.h>
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
...@@ -335,10 +336,10 @@ void scsi_unregister(struct Scsi_Host *shost) ...@@ -335,10 +336,10 @@ void scsi_unregister(struct Scsi_Host *shost)
* Next, kill the kernel error recovery thread for this host. * Next, kill the kernel error recovery thread for this host.
*/ */
if (shost->ehandler) { if (shost->ehandler) {
DECLARE_MUTEX_LOCKED(sem); DECLARE_COMPLETION(sem);
shost->eh_notify = &sem; shost->eh_notify = &sem;
send_sig(SIGPWR, shost->ehandler, 1); up(shost->eh_wait);
down(&sem); wait_for_completion(&sem);
shost->eh_notify = NULL; shost->eh_notify = NULL;
} }
...@@ -368,7 +369,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) ...@@ -368,7 +369,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
{ {
struct Scsi_Host *shost, *shost_scr; struct Scsi_Host *shost, *shost_scr;
int gfp_mask; int gfp_mask;
DECLARE_MUTEX_LOCKED(sem); DECLARE_COMPLETION(sem);
/* Check to see if this host has any error handling facilities */ /* Check to see if this host has any error handling facilities */
if(shost_tp->eh_strategy_handler == NULL && if(shost_tp->eh_strategy_handler == NULL &&
...@@ -464,7 +465,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) ...@@ -464,7 +465,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
* Now wait for the kernel error thread to initialize itself * Now wait for the kernel error thread to initialize itself
* as it might be needed when we scan the bus. * as it might be needed when we scan the bus.
*/ */
down(&sem); wait_for_completion(&sem);
shost->eh_notify = NULL; shost->eh_notify = NULL;
shost->hostt->present++; shost->hostt->present++;
......
...@@ -381,11 +381,12 @@ struct Scsi_Host ...@@ -381,11 +381,12 @@ struct Scsi_Host
struct task_struct * ehandler; /* Error recovery thread. */ struct task_struct * ehandler; /* Error recovery thread. */
struct semaphore * eh_wait; /* The error recovery thread waits on struct semaphore * eh_wait; /* The error recovery thread waits on
this. */ this. */
struct semaphore * eh_notify; /* wait for eh to begin */ struct completion * eh_notify; /* wait for eh to begin or end */
struct semaphore * eh_action; /* Wait for specific actions on the struct semaphore * eh_action; /* Wait for specific actions on the
host. */ host. */
unsigned int eh_active:1; /* Indicates the eh thread is awake and active if unsigned int eh_active:1; /* Indicates the eh thread is awake and active if
this is true. */ this is true. */
unsigned int eh_kill:1; /* set when killing the eh thread */
wait_queue_head_t host_wait; wait_queue_head_t host_wait;
Scsi_Host_Template * hostt; Scsi_Host_Template * hostt;
atomic_t host_active; /* commands checked out */ atomic_t host_active; /* commands checked out */
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h>
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
...@@ -41,24 +42,6 @@ ...@@ -41,24 +42,6 @@
#include <scsi/scsi_ioctl.h> /* grr */ #include <scsi/scsi_ioctl.h> /* grr */
/*
* We must always allow SHUTDOWN_SIGS. Even if we are not a module,
* the host drivers that we are using may be loaded as modules, and
* when we unload these, we need to ensure that the error handler thread
* can be shut down.
*
* Note - when we unload a module, we send a SIGHUP. We mustn't
* enable SIGTERM, as this is how the init shuts things down when you
* go to single-user mode. For that matter, init also sends SIGKILL,
* so we mustn't enable that one either. We use SIGHUP instead. Other
* options would be SIGPWR, I suppose.
*
* Changed behavior 1/1/2003 - it turns out, that SIGHUP can get sent
* to error handlers from a process responsible for their creation.
* To sidestep that issue, we now use SIGPWR as suggested above.
*/
#define SHUTDOWN_SIGS (sigmask(SIGPWR))
#ifdef DEBUG #ifdef DEBUG
#define SENSE_TIMEOUT SCSI_TIMEOUT #define SENSE_TIMEOUT SCSI_TIMEOUT
#else #else
...@@ -1593,12 +1576,10 @@ void scsi_error_handler(void *data) ...@@ -1593,12 +1576,10 @@ void scsi_error_handler(void *data)
int rtn; int rtn;
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
/* spin_lock_irq(&current->sig->siglock);
* We only listen to signals if the HA was loaded as a module. sigfillset(&current->blocked);
* If the HA was compiled into the kernel, then we don't listen recalc_sigpending();
* to any signals. spin_unlock_irq(&current->sig->siglock);
*/
siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
lock_kernel(); lock_kernel();
...@@ -1624,7 +1605,7 @@ void scsi_error_handler(void *data) ...@@ -1624,7 +1605,7 @@ void scsi_error_handler(void *data)
*/ */
SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of scsi_eh_%d\n",shost->host_no)); SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of scsi_eh_%d\n",shost->host_no));
up(shost->eh_notify); complete(shost->eh_notify);
while (1) { while (1) {
/* /*
...@@ -1644,7 +1625,7 @@ void scsi_error_handler(void *data) ...@@ -1644,7 +1625,7 @@ void scsi_error_handler(void *data)
* semaphores isn't unreasonable. * semaphores isn't unreasonable.
*/ */
down_interruptible(&sem); down_interruptible(&sem);
if (signal_pending(current)) if (shost->eh_kill)
break; break;
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d waking up\n",shost->host_no)); SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d waking up\n",shost->host_no));
...@@ -1695,13 +1676,9 @@ void scsi_error_handler(void *data) ...@@ -1695,13 +1676,9 @@ void scsi_error_handler(void *data)
/* /*
* If anyone is waiting for us to exit (i.e. someone trying to unload * If anyone is waiting for us to exit (i.e. someone trying to unload
* a driver), then wake up that process to let them know we are on * a driver), then wake up that process to let them know we are on
* the way out the door. This may be overkill - I *think* that we * the way out the door.
* could probably just unload the driver and send the signal, and when
* the error handling thread wakes up that it would just exit without
* needing to touch any memory associated with the driver itself.
*/ */
if (shost->eh_notify != NULL) complete_and_exit(shost->eh_notify, 0);
up(shost->eh_notify);
} }
/** /**
......
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