Commit e17a9489 authored by Al Viro's avatar Al Viro

[PATCH] stop elv_unregister() from rogering other iosched's data, fix locking

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 25975f86
...@@ -195,6 +195,12 @@ static void free_as_io_context(struct as_io_context *aic) ...@@ -195,6 +195,12 @@ static void free_as_io_context(struct as_io_context *aic)
kfree(aic); kfree(aic);
} }
static void as_trim(struct io_context *ioc)
{
kfree(ioc->aic);
ioc->aic = NULL;
}
/* Called when the task exits */ /* Called when the task exits */
static void exit_as_io_context(struct as_io_context *aic) static void exit_as_io_context(struct as_io_context *aic)
{ {
...@@ -1860,6 +1866,7 @@ static struct elevator_type iosched_as = { ...@@ -1860,6 +1866,7 @@ static struct elevator_type iosched_as = {
.elevator_may_queue_fn = as_may_queue, .elevator_may_queue_fn = as_may_queue,
.elevator_init_fn = as_init_queue, .elevator_init_fn = as_init_queue,
.elevator_exit_fn = as_exit_queue, .elevator_exit_fn = as_exit_queue,
.trim = as_trim,
}, },
.elevator_ktype = &as_ktype, .elevator_ktype = &as_ktype,
......
...@@ -1211,6 +1211,13 @@ static void cfq_free_io_context(struct cfq_io_context *cic) ...@@ -1211,6 +1211,13 @@ static void cfq_free_io_context(struct cfq_io_context *cic)
kmem_cache_free(cfq_ioc_pool, cic); kmem_cache_free(cfq_ioc_pool, cic);
} }
static void cfq_trim(struct io_context *ioc)
{
ioc->set_ioprio = NULL;
if (ioc->cic)
cfq_free_io_context(ioc->cic);
}
/* /*
* Called with interrupts disabled * Called with interrupts disabled
*/ */
...@@ -2472,6 +2479,7 @@ static struct elevator_type iosched_cfq = { ...@@ -2472,6 +2479,7 @@ static struct elevator_type iosched_cfq = {
.elevator_may_queue_fn = cfq_may_queue, .elevator_may_queue_fn = cfq_may_queue,
.elevator_init_fn = cfq_init_queue, .elevator_init_fn = cfq_init_queue,
.elevator_exit_fn = cfq_exit_queue, .elevator_exit_fn = cfq_exit_queue,
.trim = cfq_trim,
}, },
.elevator_ktype = &cfq_ktype, .elevator_ktype = &cfq_ktype,
.elevator_name = "cfq", .elevator_name = "cfq",
......
...@@ -675,21 +675,15 @@ void elv_unregister(struct elevator_type *e) ...@@ -675,21 +675,15 @@ void elv_unregister(struct elevator_type *e)
/* /*
* Iterate every thread in the process to remove the io contexts. * Iterate every thread in the process to remove the io contexts.
*/ */
read_lock(&tasklist_lock); if (e->ops.trim) {
do_each_thread(g, p) { read_lock(&tasklist_lock);
struct io_context *ioc = p->io_context; do_each_thread(g, p) {
if (ioc && ioc->cic) { task_lock(p);
ioc->cic->exit(ioc->cic); e->ops.trim(p->io_context);
ioc->cic->dtor(ioc->cic); task_unlock(p);
ioc->cic = NULL; } while_each_thread(g, p);
} read_unlock(&tasklist_lock);
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); spin_lock_irq(&elv_list_lock);
list_del_init(&e->list); list_del_init(&e->list);
......
...@@ -48,6 +48,7 @@ struct elevator_ops ...@@ -48,6 +48,7 @@ struct elevator_ops
elevator_init_fn *elevator_init_fn; elevator_init_fn *elevator_init_fn;
elevator_exit_fn *elevator_exit_fn; elevator_exit_fn *elevator_exit_fn;
void (*trim)(struct io_context *);
}; };
#define ELV_NAME_MAX (16) #define ELV_NAME_MAX (16)
......
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