summaryrefslogtreecommitdiff
path: root/drivers/block/elevator.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2005-10-30 15:01:39 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 17:37:17 -0800
commit83521d3eb8dd2dfb04dd78b4733e9766f61bb47e (patch)
treee372f6bef5205c12024512f3b1df5a76df7f0fba /drivers/block/elevator.c
parenta8db2db1e6a8d323d87a67c5391d48fe2b97faf5 (diff)
downloadlwn-83521d3eb8dd2dfb04dd78b4733e9766f61bb47e.tar.gz
lwn-83521d3eb8dd2dfb04dd78b4733e9766f61bb47e.zip
[PATCH] cfq-iosched: move tasklist walk 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. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block/elevator.c')
-rw-r--r--drivers/block/elevator.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
index 55621d5c5774..58e881bfd189 100644
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -642,6 +642,27 @@ EXPORT_SYMBOL_GPL(elv_register);
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);