[PATCH] stop elv_unregister() from rogering other iosched's data, fix locking
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
25975f863b
Коммит
e17a9489b4
|
@ -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 = {
|
||||||
.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)
|
||||||
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 = {
|
||||||
.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)
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
|
||||||
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)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче