Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e17a9489 authored by Al Viro's avatar Al Viro
Browse files

[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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -195,6 +195,12 @@ static void free_as_io_context(struct as_io_context *aic)
	kfree(aic);
}

static void as_trim(struct io_context *ioc)
{
	kfree(ioc->aic);
	ioc->aic = NULL;
}

/* Called when the task exits */
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_init_fn =		as_init_queue,
		.elevator_exit_fn =		as_exit_queue,
		.trim =				as_trim,
	},

	.elevator_ktype = &as_ktype,
+8 −0
Original line number Diff line number Diff line
@@ -1211,6 +1211,13 @@ static void cfq_free_io_context(struct cfq_io_context *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
 */
@@ -2472,6 +2479,7 @@ static struct elevator_type iosched_cfq = {
		.elevator_may_queue_fn =	cfq_may_queue,
		.elevator_init_fn =		cfq_init_queue,
		.elevator_exit_fn =		cfq_exit_queue,
		.trim =				cfq_trim,
	},
	.elevator_ktype =	&cfq_ktype,
	.elevator_name =	"cfq",
+9 −15
Original line number Diff line number Diff line
@@ -675,21 +675,15 @@ void elv_unregister(struct elevator_type *e)
	/*
	 * Iterate every thread in the process to remove the io contexts.
	 */
	if (e->ops.trim) {
		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;
		}
			task_lock(p);
			e->ops.trim(p->io_context);
			task_unlock(p);
		} while_each_thread(g, p);
		read_unlock(&tasklist_lock);
	}

	spin_lock_irq(&elv_list_lock);
	list_del_init(&e->list);
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct elevator_ops

	elevator_init_fn *elevator_init_fn;
	elevator_exit_fn *elevator_exit_fn;
	void (*trim)(struct io_context *);
};

#define ELV_NAME_MAX	(16)