Skip to contentSkip to conversation

move tasklist walk from cfq-iosched to elevator.c

PATCH In review Christoph Hellwig 2 participants 4 messages Aug 26, 2005 – Sep 19, 2005 Block layer

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 move tasklist walk from cfq-iosched to elevator.c

We're trying to get rid of as much as possible tasklist walks, or at least moving them to core code. This patch falls into the second category.

Instead of walking the tasklist in cfq-iosched move that into elv_unregister. The added benefit is that with this change the as ioscheduler might be might unloadable more easily aswell.

The new code uses read_lock instead of read_lock_irq because the tasklist_lock only needs irq disabling for writers.

drivers/block/cfq-iosched.c +1 -21
Index: linux-2.6/drivers/block/cfq-iosched.c
===================================================================
@@ -2609,28 +2609,8 @@
 
 static void __exit cfq_exit(void)
 {
-	struct task_struct *g, *p;
-	unsigned long flags;
-
-	read_lock_irqsave(&tasklist_lock, flags);
-
-	/*
-	 * iterate each process in the system, removing our io_context
-	 */
-	do_each_thread(g, p) {
-		struct io_context *ioc = p->io_context;
-
-		if (ioc && ioc->cic) {
-			ioc->cic->exit(ioc->cic);
-			cfq_free_io_context(ioc->cic);
-			ioc->cic = NULL;
-		}
-	} while_each_thread(g, p);
-
-	read_unlock_irqrestore(&tasklist_lock, flags);
-
-	cfq_slab_kill();
 	elv_unregister(&iosched_cfq);
+	cfq_slab_kill();
 }
 
 module_init(cfq_init);
drivers/block/elevator.c +21 -0
Index: linux-2.6/drivers/block/elevator.c
===================================================================
@@ -572,6 +572,27 @@
 
 void elv_unregister(struct elevator_type *e)
 {
+	struct task_struct *g, *p;
+
+	/*
+	 * Iterate every thread in the process to remove the io contexts.
+	 */
+	read_lock(&tasklist_lock);
+	do_each_thread(g, p) {
+		struct io_context *ioc = p->io_context;
+		if (ioc && ioc->cic) {
+			ioc->cic->exit(ioc->cic);
+			ioc->cic->dtor(ioc->cic);
+			ioc->cic = NULL;
+		}
+		if (ioc && ioc->aic) {
+			ioc->aic->exit(ioc->aic);
+			ioc->aic->dtor(ioc->aic);
+			ioc->aic = NULL;
+		}
+	} while_each_thread(g, p);
+	read_unlock(&tasklist_lock);
+
 	spin_lock_irq(&elv_list_lock);
 	list_del_init(&e->list);
 	spin_unlock_irq(&elv_list_lock);
#1 lore raw
Quoted 10 lines · Christoph Hellwig

We're trying to get rid of as much as possible tasklist walks, or at least moving them to core code. This patch falls into the second category.

Instead of walking the tasklist in cfq-iosched move that into elv_unregister. The added benefit is that with this change the as ioscheduler might be might unloadable more easily aswell.

The new code uses read_lock instead of read_lock_irq because the tasklist_lock only needs irq disabling for writers.

Looks innocent enough, fine with me. 'as' will need additional work to be unloadable, but it wont break anything since it's running with an elevated module count right now anyways.

Signature · 1 line
Jens Axboe
#2 lore raw
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig

We're trying to get rid of as much as possible tasklist walks, or at least moving them to core code. This patch falls into the second category.

Instead of walking the tasklist in cfq-iosched move that into elv_unregister. The added benefit is that with this change the as ioscheduler might be might unloadable more easily aswell.

Quoted 6 lines
Quoted 2 lines

The new code uses read_lock instead of read_lock_irq because the tasklist_lock only needs irq disabling for writers.

Looks innocent enough, fine with me. 'as' will need additional work to be unloadable, but it wont break anything since it's running with an elevated module count right now anyways.

any chance to send this on to akpm?

drivers/block/as-iosched.c +1 -1
Index: linux-2.6/drivers/block/as-iosched.c
===================================================================
@@ -2119,8 +2119,8 @@
 
 static void __exit as_exit(void)
 {
-	kmem_cache_destroy(arq_pool);
 	elv_unregister(&iosched_as);
+	kmem_cache_destroy(arq_pool);
 }
 
 module_init(as_init);
drivers/block/cfq-iosched.c +1 -21
Index: linux-2.6/drivers/block/cfq-iosched.c
===================================================================
@@ -2609,28 +2609,8 @@
 
 static void __exit cfq_exit(void)
 {
-	struct task_struct *g, *p;
-	unsigned long flags;
-
-	read_lock_irqsave(&tasklist_lock, flags);
-
-	/*
-	 * iterate each process in the system, removing our io_context
-	 */
-	do_each_thread(g, p) {
-		struct io_context *ioc = p->io_context;
-
-		if (ioc && ioc->cic) {
-			ioc->cic->exit(ioc->cic);
-			cfq_free_io_context(ioc->cic);
-			ioc->cic = NULL;
-		}
-	} while_each_thread(g, p);
-
-	read_unlock_irqrestore(&tasklist_lock, flags);
-
-	cfq_slab_kill();
 	elv_unregister(&iosched_cfq);
+	cfq_slab_kill();
 }
 
 module_init(cfq_init);
drivers/block/elevator.c +21 -0
Index: linux-2.6/drivers/block/elevator.c
===================================================================
@@ -572,6 +572,27 @@
 
 void elv_unregister(struct elevator_type *e)
 {
+	struct task_struct *g, *p;
+
+	/*
+	 * Iterate every thread in the process to remove the io contexts.
+	 */
+	read_lock(&tasklist_lock);
+	do_each_thread(g, p) {
+		struct io_context *ioc = p->io_context;
+		if (ioc && ioc->cic) {
+			ioc->cic->exit(ioc->cic);
+			ioc->cic->dtor(ioc->cic);
+			ioc->cic = NULL;
+		}
+		if (ioc && ioc->aic) {
+			ioc->aic->exit(ioc->aic);
+			ioc->aic->dtor(ioc->aic);
+			ioc->aic = NULL;
+		}
+	} while_each_thread(g, p);
+	read_unlock(&tasklist_lock);
+
 	spin_lock_irq(&elv_list_lock);
 	list_del_init(&e->list);
 	spin_unlock_irq(&elv_list_lock);
#3 lore raw
Quoted 10 lines · Christoph Hellwig
Quoted 9 lines · Jens Axboe
Quoted 8 lines · Christoph Hellwig

We're trying to get rid of as much as possible tasklist walks, or at least moving them to core code. This patch falls into the second category.

Instead of walking the tasklist in cfq-iosched move that into elv_unregister. The added benefit is that with this change the as ioscheduler might be might unloadable more easily aswell.

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

The new code uses read_lock instead of read_lock_irq because the tasklist_lock only needs irq disabling for writers.

Looks innocent enough, fine with me. 'as' will need additional work to be unloadable, but it wont break anything since it's running with an elevated module count right now anyways.

any chance to send this on to akpm?

Sure, already ack'ed it and I thought akpm was cc'ed on the mail. Anyways, andrew can you add this? Thanks!

Quoted 83 lines

Index: linux-2.6/drivers/block/as-iosched.c
===================================================================

drivers/block/as-iosched.c +1 -1
@@ -2119,8 +2119,8 @@
 
 static void __exit as_exit(void)
 {
-	kmem_cache_destroy(arq_pool);
 	elv_unregister(&iosched_as);
+	kmem_cache_destroy(arq_pool);
 }
 
 module_init(as_init);

Index: linux-2.6/drivers/block/cfq-iosched.c
===================================================================

drivers/block/cfq-iosched.c +1 -21
@@ -2609,28 +2609,8 @@
 
 static void __exit cfq_exit(void)
 {
-	struct task_struct *g, *p;
-	unsigned long flags;
-
-	read_lock_irqsave(&tasklist_lock, flags);
-
-	/*
-	 * iterate each process in the system, removing our io_context
-	 */
-	do_each_thread(g, p) {
-		struct io_context *ioc = p->io_context;
-
-		if (ioc && ioc->cic) {
-			ioc->cic->exit(ioc->cic);
-			cfq_free_io_context(ioc->cic);
-			ioc->cic = NULL;
-		}
-	} while_each_thread(g, p);
-
-	read_unlock_irqrestore(&tasklist_lock, flags);
-
-	cfq_slab_kill();
 	elv_unregister(&iosched_cfq);
+	cfq_slab_kill();
 }
 
 module_init(cfq_init);

Index: linux-2.6/drivers/block/elevator.c
===================================================================

drivers/block/elevator.c +21 -0
@@ -572,6 +572,27 @@
 
 void elv_unregister(struct elevator_type *e)
 {
+	struct task_struct *g, *p;
+
+	/*
+	 * Iterate every thread in the process to remove the io contexts.
+	 */
+	read_lock(&tasklist_lock);
+	do_each_thread(g, p) {
+		struct io_context *ioc = p->io_context;
+		if (ioc && ioc->cic) {
+			ioc->cic->exit(ioc->cic);
+			ioc->cic->dtor(ioc->cic);
+			ioc->cic = NULL;
+		}
+		if (ioc && ioc->aic) {
+			ioc->aic->exit(ioc->aic);
+			ioc->aic->dtor(ioc->aic);
+			ioc->aic = NULL;
+		}
+	} while_each_thread(g, p);
+	read_unlock(&tasklist_lock);
+
 	spin_lock_irq(&elv_list_lock);
 	list_del_init(&e->list);
 	spin_unlock_irq(&elv_list_lock);
Signature · 1 line
Jens Axboe