---
 drivers/dma/dmatest.c              |    6 +---
 drivers/media/video/videobuf-dvb.c |    5 +--
 drivers/usb/atm/ueagle-atm.c       |    4 ---
 include/linux/kthread.h            |    2 -
 kernel/kthread.c                   |   48 ++++++++++---------------------------
 5 files changed, 19 insertions(+), 46 deletions(-)

diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -332,12 +332,10 @@ static void dmatest_cleanup_channel(stru
 {
 	struct dmatest_thread	*thread;
 	struct dmatest_thread	*_thread;
-	int			ret;
 
 	list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
-		ret = kthread_stop(thread->task);
-		pr_debug("dmatest: thread %s exited with status %d\n",
-				thread->task->comm, ret);
+		kthread_stop(thread->task);
+		pr_debug("dmatest: thread %s exited\n", thread->task->comm);
 		list_del(&thread->node);
 		kfree(thread);
 	}
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -121,16 +121,15 @@ static int videobuf_dvb_stop_feed(struct
 {
 	struct dvb_demux *demux  = feed->demux;
 	struct videobuf_dvb *dvb = demux->priv;
-	int err = 0;
 
 	mutex_lock(&dvb->lock);
 	dvb->nfeeds--;
 	if (0 == dvb->nfeeds  &&  NULL != dvb->thread) {
-		err = kthread_stop(dvb->thread);
+		kthread_stop(dvb->thread);
 		dvb->thread = NULL;
 	}
 	mutex_unlock(&dvb->lock);
-	return err;
+	return 0;
 }
 
 static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -2189,10 +2189,8 @@ err0:
  */
 static void uea_stop(struct uea_softc *sc)
 {
-	int ret;
 	uea_enters(INS_TO_USBDEV(sc));
-	ret = kthread_stop(sc->kthread);
-	uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
+	kthread_stop(sc->kthread);
 
 	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
 
diff --git a/include/linux/kthread.h b/include/linux/kthread.h
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -28,7 +28,7 @@ struct task_struct *kthread_create(int (
 })
 
 void kthread_bind(struct task_struct *k, unsigned int cpu);
-int kthread_stop(struct task_struct *k);
+void kthread_stop(struct task_struct *k);
 int kthread_should_stop(void);
 
 int kthreadd(void *unused);
diff --git a/kernel/kthread.c b/kernel/kthread.c
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -38,18 +38,6 @@ struct kthread_create_info
 	struct list_head list;
 };
 
-struct kthread_stop_info
-{
-	struct task_struct *k;
-	int err;
-	struct completion done;
-};
-
-/* Thread stopping is done by setthing this var: lock serializes
- * multiple kthread_stop calls. */
-static DEFINE_MUTEX(kthread_stop_lock);
-static struct kthread_stop_info kthread_stop_info;
-
 /**
  * kthread_should_stop - should this kthread return now?
  *
@@ -59,7 +47,7 @@ static struct kthread_stop_info kthread_
  */
 int kthread_should_stop(void)
 {
-	return (kthread_stop_info.k == current);
+	return signal_pending(current);
 }
 EXPORT_SYMBOL(kthread_should_stop);
 
@@ -68,26 +56,22 @@ static int kthread(void *_create)
 	struct kthread_create_info *create = _create;
 	int (*threadfn)(void *data);
 	void *data;
-	int ret = -EINTR;
 
 	/* Copy data: it's on kthread's stack */
 	threadfn = create->threadfn;
 	data = create->data;
 
+	/* We let SIGKILL stop us. */
+	allow_signal(SIGKILL);
+
 	/* OK, tell user we're spawned, wait for stop or wakeup */
-	__set_current_state(TASK_UNINTERRUPTIBLE);
+	__set_current_state(TASK_INTERRUPTIBLE);
 	create->result = current;
 	complete(&create->started);
 	schedule();
 
-	if (!kthread_should_stop())
-		ret = threadfn(data);
-
-	/* It might have exited on its own, w/o kthread_stop.  Check. */
-	if (kthread_should_stop()) {
-		kthread_stop_info.err = ret;
-		complete(&kthread_stop_info.done);
-	}
+	if (!signal_pending())
+		threadfn(data);
 	return 0;
 }
 
@@ -95,8 +79,8 @@ static void create_kthread(struct kthrea
 {
 	int pid;
 
-	/* We want our own signal handler (we take no signals by default). */
-	pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES | SIGCHLD);
+	/* We want our own signal handler (we take SIGKILL). */
+	pid = kernel_thread(kthread, create, CLONE_FS | CLONE_FILES);
 	if (pid < 0)
 		create->result = ERR_PTR(pid);
 	else
@@ -118,8 +102,7 @@ static void create_kthread(struct kthrea
  * argument. @threadfn() can either call do_exit() directly if it is a
  * standalone thread for which noone will call kthread_stop(), or
  * return when 'kthread_should_stop()' is true (which means
- * kthread_stop() has been called).  The return value should be zero
- * or a negative error number; it will be passed to kthread_stop().
+ * kthread_stop() has been called).  The return value is ignored.
  *
  * Returns a task_struct or ERR_PTR(-ENOMEM).
  */
@@ -189,18 +172,13 @@ EXPORT_SYMBOL(kthread_bind);
  * kthread_stop - stop a thread created by kthread_create().
  * @k: thread created by kthread_create().
  *
- * Sets kthread_should_stop() for @k to return true, wakes it, and
- * waits for it to exit.  Your threadfn() must not call do_exit()
- * itself if you use this function!  This can also be called after
+ * Sends a KILL signal to the thread.  This can also be called after
  * kthread_create() instead of calling wake_up_process(): the thread
  * will exit without calling threadfn().
- *
- * Returns the result of threadfn(), or %-EINTR if wake_up_process()
- * was never called.
  */
-int kthread_stop(struct task_struct *k)
+void kthread_stop(struct task_struct *k)
 {
-	int ret;
+	do
 
 	mutex_lock(&kthread_stop_lock);
 
