[RFC] [PATCH] UBI: convert to kthread API

Alexander Schmidt alexs at linux.vnet.ibm.com
Tue Feb 27 08:50:40 EST 2007


Hi Artem

UBI should use the kthread API, which makes completions and signal
handling go away.

I took Christoph on CC, I hope he has some comments on this.

Regards,
Alex

Signed-off-by: Alexander Schmidt <alexs at linux.vnet.ibm.com>
---
 drivers/mtd/ubi/background.c |   71 ++++++++++---------------------------------
 drivers/mtd/ubi/build.c      |    4 --
 drivers/mtd/ubi/ubi.h        |    5 ---
 3 files changed, 18 insertions(+), 62 deletions(-)

--- dedekind-ubi-2.6.orig/drivers/mtd/ubi/background.c
+++ dedekind-ubi-2.6/drivers/mtd/ubi/background.c
@@ -27,6 +27,7 @@
  */
 
 #include <linux/freezer.h>
+#include <linux/kthread.h>
 #include "ubi.h"
 
 /* Background thread name pattern */
@@ -160,23 +161,6 @@ void ubi_bgt_disable(struct ubi_info *ub
 }
 
 /**
- * ubi_bgt_kill_thread - kill the background thread.
- *
- * @ubi: the UBI device description object
- *
- * This function kills the background thread for UBI device defined by @ubi.
- * This function also makes sure all the pending tasks are done.
- */
-void ubi_bgt_kill_thread(struct ubi_info *ubi)
-{
-	dbg_bgt("disable \"%s\"", ubi->bgt.bgt_name);
-	if (ubi->bgt.task) {
-		send_sig(SIGKILL, ubi->bgt.task, 1);
-		wait_for_completion(&ubi->bgt.thread_stop);
-	}
-}
-
-/**
  * ubi_bgt_do_work - do one pending work.
  *
  * @ubi: the UBI device description object
@@ -235,46 +219,22 @@ static int ubi_thread(void *u)
 	int failures = 0;
 	struct ubi_info *ubi = u;
 
-	daemonize(ubi->bgt.bgt_name);
-	allow_signal(SIGKILL);
-	allow_signal(SIGSTOP);
-
 	ubi_msg("background thread \"%s\" started, PID %d",
 		ubi->bgt.bgt_name, current->pid);
 
-	ubi->bgt.task = current;
-	complete(&ubi->bgt.thread_start);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule();
-
 	for (;;) {
-		cond_resched();
-
 		if (unlikely(!ubi->bgt.enabled) ||
 			     list_empty(&ubi->bgt.pending_works)) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 		}
 
+		if (kthread_should_stop())
+			goto out;
+
 		if (try_to_freeze())
 			continue;
 
-		while (signal_pending(current)) {
-			siginfo_t info;
-			unsigned long nr;
-
-			nr = dequeue_signal_lock(current, &current->blocked,
-						 &info);
-			if (nr == SIGKILL)
-				goto out;
-			if (nr == SIGSTOP) {
-				ubi->bgt.enabled = !ubi->bgt.enabled;
-				ubi_msg("%s the background thread",
-					ubi->bgt.enabled ? "enable" :
-							   "disable");
-			}
-		}
-
 		spin_lock(&ubi->bgt.lock);
 		while (ubi->bgt.pending_works_count > 0 &&
 		       likely(ubi->bgt.enabled)) {
@@ -297,7 +257,6 @@ static int ubi_thread(void *u)
 					ubi_msg("%d consecutive failures, "
 						"disable the background thread",
 						BGT_MAX_FAILURES);
-					ubi_bgt_disable(ubi);
 					ubi_eba_ro_mode(ubi);
 					break;
 				} else
@@ -307,6 +266,8 @@ static int ubi_thread(void *u)
 			spin_lock(&ubi->bgt.lock);
 		}
 		spin_unlock(&ubi->bgt.lock);
+
+		cond_resched();
 	}
 
 out:
@@ -330,7 +291,7 @@ out:
 	}
 	spin_unlock(&ubi->bgt.lock);
 
-	complete_and_exit(&ubi->bgt.thread_stop, 0);
+	return 0;
 }
 
 /**
@@ -344,12 +305,9 @@ out:
 int ubi_bgt_init(struct ubi_info *ubi)
 {
 	int err;
-	pid_t pid;
 
 	dbg_bgt("initialize the UBI background thread unit");
 
-	init_completion(&ubi->bgt.thread_start);
-	init_completion(&ubi->bgt.thread_stop);
 	INIT_LIST_HEAD(&ubi->bgt.pending_works);
 	spin_lock_init(&ubi->bgt.lock);
 	mutex_init(&ubi->bgt.wrk_mutex);
@@ -359,14 +317,15 @@ int ubi_bgt_init(struct ubi_info *ubi)
 		return -ENOMEM;
 	sprintf(ubi->bgt.bgt_name, BGT_NAME_PATTERN, ubi->ubi_num);
 
-	pid = kernel_thread(ubi_thread, ubi, CLONE_FS | CLONE_FILES);
-	if (pid < 0) {
-		err = pid;
-		ubi_err("cannot spawn \"%s\", error %d", ubi->bgt.bgt_name, err);
+	ubi->bgt.task = kthread_create(ubi_thread, ubi, ubi->bgt.bgt_name);
+	if (IS_ERR(ubi->bgt.task)) {
+		err = PTR_ERR(ubi->bgt.task);
+		ubi_err("cannot spawn \"%s\", error %d", ubi->bgt.bgt_name,
+			err);
 		goto out_name;
 	}
 
-	wait_for_completion(&ubi->bgt.thread_start);
+	wake_up_process(ubi->bgt.task);
 	dbg_bgt("the UBI background thread unit is initialized");
 	return 0;
 
@@ -382,6 +341,10 @@ out_name:
  */
 void ubi_bgt_close(struct ubi_info *ubi)
 {
+	dbg_bgt("disable \"%s\"", ubi->bgt.bgt_name);
+	if (ubi->bgt.task)
+		kthread_stop(ubi->bgt.task);
+
 	dbg_bgt("close the UBI background thread unit");
 
 	ubi_assert(!ubi->bgt.enabled);
--- dedekind-ubi-2.6.orig/drivers/mtd/ubi/build.c
+++ dedekind-ubi-2.6/drivers/mtd/ubi/build.c
@@ -123,12 +123,11 @@ static void detach_mtd_dev(struct ubi_in
 
 	dbg_bld("detaching mtd%d from ubi%d", mtd_num, ubi_num);
 
-	ubi_bgt_kill_thread(ubi);
+	ubi_bgt_close(ubi);
 	ubi_uif_close(ubi);
 	ubi_eba_close(ubi);
 	ubi_wl_close(ubi);
 	ubi_vmt_close(ubi);
-	ubi_bgt_close(ubi);
 	ubi_io_close(ubi);
 	kfree(ubis[ubi_num]);
 	ubis[ubi_num] = NULL;
@@ -276,7 +275,6 @@ out_detach:
 	ubi_wl_close(ubi);
 	ubi_vmt_close(ubi);
 out_bgt:
-	ubi_bgt_kill_thread(ubi);
 	ubi_bgt_close(ubi);
 out_io:
 	ubi_io_close(ubi);
--- dedekind-ubi-2.6.orig/drivers/mtd/ubi/ubi.h
+++ dedekind-ubi-2.6/drivers/mtd/ubi/ubi.h
@@ -239,8 +239,6 @@ struct ubi_bgt_work {
  * @enabled: if the background thread is enabled
  * @task: a pointer to the &struct task_struct of the background thread
  * @bgt_name: the background thread name
- * @thread_start: used to synchronize with starting of the background thread
- * @thread_stop: used to synchronize with killing of the background thread
  * @wrk_mutex: serializes execution if background works
  */
 struct ubi_bgt_info {
@@ -251,8 +249,6 @@ struct ubi_bgt_info {
 	int enabled;                      /* public  */
 	struct task_struct *task;         /* private */
 	char *bgt_name;                   /* public  */
-	struct completion thread_start;   /* private */
-	struct completion thread_stop;    /* private */
 	struct mutex wrk_mutex;           /* private */
 };
 
@@ -551,7 +547,6 @@ int ubi_bgt_reschedule(struct ubi_info *
 int ubi_bgt_do_work(struct ubi_info *ubi);
 int ubi_bgt_enable(struct ubi_info *ubi);
 void ubi_bgt_disable(struct ubi_info *ubi);
-void ubi_bgt_kill_thread(struct ubi_info *ubi);
 int ubi_bgt_init(struct ubi_info *ubi);
 void ubi_bgt_close(struct ubi_info *ubi);
 




More information about the linux-mtd mailing list