xref: /linux/block/elevator.c (revision 7ebdfaa52d15b947503f76474477f92854796d96)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  Block device elevator/IO-scheduler.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
51da177e4SLinus Torvalds  *
60fe23479SJens Axboe  * 30042000 Jens Axboe <axboe@kernel.dk> :
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Split the elevator a bit so that it is possible to choose a different
91da177e4SLinus Torvalds  * one or even write a new "plug in". There are three pieces:
101da177e4SLinus Torvalds  * - elevator_fn, inserts a new request in the queue list
111da177e4SLinus Torvalds  * - elevator_merge_fn, decides whether a new buffer can be merged with
121da177e4SLinus Torvalds  *   an existing request
131da177e4SLinus Torvalds  * - elevator_dequeue_fn, called when a request is taken off the active list
141da177e4SLinus Torvalds  *
151da177e4SLinus Torvalds  * 20082000 Dave Jones <davej@suse.de> :
161da177e4SLinus Torvalds  * Removed tests for max-bomb-segments, which was breaking elvtune
171da177e4SLinus Torvalds  *  when run without -bN
181da177e4SLinus Torvalds  *
191da177e4SLinus Torvalds  * Jens:
201da177e4SLinus Torvalds  * - Rework again to work with bio instead of buffer_heads
211da177e4SLinus Torvalds  * - loose bi_dev comparisons, partition handling is right now
221da177e4SLinus Torvalds  * - completely modularize elevator setup and teardown
231da177e4SLinus Torvalds  *
241da177e4SLinus Torvalds  */
251da177e4SLinus Torvalds #include <linux/kernel.h>
261da177e4SLinus Torvalds #include <linux/fs.h>
271da177e4SLinus Torvalds #include <linux/blkdev.h>
281da177e4SLinus Torvalds #include <linux/elevator.h>
291da177e4SLinus Torvalds #include <linux/bio.h>
301da177e4SLinus Torvalds #include <linux/module.h>
311da177e4SLinus Torvalds #include <linux/slab.h>
321da177e4SLinus Torvalds #include <linux/init.h>
331da177e4SLinus Torvalds #include <linux/compiler.h>
342056a782SJens Axboe #include <linux/blktrace_api.h>
359817064bSJens Axboe #include <linux/hash.h>
360835da67SJens Axboe #include <linux/uaccess.h>
37c8158819SLin Ming #include <linux/pm_runtime.h>
381da177e4SLinus Torvalds 
3955782138SLi Zefan #include <trace/events/block.h>
4055782138SLi Zefan 
41242f9dcbSJens Axboe #include "blk.h"
4272e06c25STejun Heo #include "blk-cgroup.h"
43242f9dcbSJens Axboe 
441da177e4SLinus Torvalds static DEFINE_SPINLOCK(elv_list_lock);
451da177e4SLinus Torvalds static LIST_HEAD(elv_list);
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds /*
489817064bSJens Axboe  * Merge hash stuff.
499817064bSJens Axboe  */
5083096ebfSTejun Heo #define rq_hash_key(rq)		(blk_rq_pos(rq) + blk_rq_sectors(rq))
519817064bSJens Axboe 
529817064bSJens Axboe /*
53da775265SJens Axboe  * Query io scheduler to see if the current process issuing bio may be
54da775265SJens Axboe  * merged with rq.
55da775265SJens Axboe  */
56da775265SJens Axboe static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
57da775265SJens Axboe {
58165125e1SJens Axboe 	struct request_queue *q = rq->q;
59b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
60da775265SJens Axboe 
6122f746e2STejun Heo 	if (e->type->ops.elevator_allow_merge_fn)
6222f746e2STejun Heo 		return e->type->ops.elevator_allow_merge_fn(q, rq, bio);
63da775265SJens Axboe 
64da775265SJens Axboe 	return 1;
65da775265SJens Axboe }
66da775265SJens Axboe 
67da775265SJens Axboe /*
681da177e4SLinus Torvalds  * can we safely merge with this request?
691da177e4SLinus Torvalds  */
70050c8ea8STejun Heo bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
711da177e4SLinus Torvalds {
72050c8ea8STejun Heo 	if (!blk_rq_merge_ok(rq, bio))
737ba1ba12SMartin K. Petersen 		return 0;
747ba1ba12SMartin K. Petersen 
75da775265SJens Axboe 	if (!elv_iosched_allow_merge(rq, bio))
76da775265SJens Axboe 		return 0;
77da775265SJens Axboe 
78da775265SJens Axboe 	return 1;
791da177e4SLinus Torvalds }
801da177e4SLinus Torvalds EXPORT_SYMBOL(elv_rq_merge_ok);
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds static struct elevator_type *elevator_find(const char *name)
831da177e4SLinus Torvalds {
84a22b169dSVasily Tarasov 	struct elevator_type *e;
851da177e4SLinus Torvalds 
8670cee26eSMatthias Kaehlcke 	list_for_each_entry(e, &elv_list, list) {
87a22b169dSVasily Tarasov 		if (!strcmp(e->elevator_name, name))
881da177e4SLinus Torvalds 			return e;
891da177e4SLinus Torvalds 	}
901da177e4SLinus Torvalds 
91a22b169dSVasily Tarasov 	return NULL;
92a22b169dSVasily Tarasov }
93a22b169dSVasily Tarasov 
941da177e4SLinus Torvalds static void elevator_put(struct elevator_type *e)
951da177e4SLinus Torvalds {
961da177e4SLinus Torvalds 	module_put(e->elevator_owner);
971da177e4SLinus Torvalds }
981da177e4SLinus Torvalds 
9921c3c5d2STejun Heo static struct elevator_type *elevator_get(const char *name, bool try_loading)
1001da177e4SLinus Torvalds {
1012824bc93STejun Heo 	struct elevator_type *e;
1021da177e4SLinus Torvalds 
1032a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
1042824bc93STejun Heo 
1052824bc93STejun Heo 	e = elevator_find(name);
10621c3c5d2STejun Heo 	if (!e && try_loading) {
107e1640949SJens Axboe 		spin_unlock(&elv_list_lock);
108490b94beSKees Cook 		request_module("%s-iosched", name);
109e1640949SJens Axboe 		spin_lock(&elv_list_lock);
110e1640949SJens Axboe 		e = elevator_find(name);
111e1640949SJens Axboe 	}
112e1640949SJens Axboe 
1132824bc93STejun Heo 	if (e && !try_module_get(e->elevator_owner))
1142824bc93STejun Heo 		e = NULL;
1152824bc93STejun Heo 
1162a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds 	return e;
1191da177e4SLinus Torvalds }
1201da177e4SLinus Torvalds 
121484fc254SWang Sheng-Hui static char chosen_elevator[ELV_NAME_MAX];
1221da177e4SLinus Torvalds 
1235f003976SNate Diller static int __init elevator_setup(char *str)
1241da177e4SLinus Torvalds {
125752a3b79SChuck Ebbert 	/*
126752a3b79SChuck Ebbert 	 * Be backwards-compatible with previous kernels, so users
127752a3b79SChuck Ebbert 	 * won't get the wrong elevator.
128752a3b79SChuck Ebbert 	 */
1291da177e4SLinus Torvalds 	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
1309b41046cSOGAWA Hirofumi 	return 1;
1311da177e4SLinus Torvalds }
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds __setup("elevator=", elevator_setup);
1341da177e4SLinus Torvalds 
135bb813f4cSTejun Heo /* called during boot to load the elevator chosen by the elevator param */
136bb813f4cSTejun Heo void __init load_default_elevator_module(void)
137bb813f4cSTejun Heo {
138bb813f4cSTejun Heo 	struct elevator_type *e;
139bb813f4cSTejun Heo 
140bb813f4cSTejun Heo 	if (!chosen_elevator[0])
141bb813f4cSTejun Heo 		return;
142bb813f4cSTejun Heo 
143bb813f4cSTejun Heo 	spin_lock(&elv_list_lock);
144bb813f4cSTejun Heo 	e = elevator_find(chosen_elevator);
145bb813f4cSTejun Heo 	spin_unlock(&elv_list_lock);
146bb813f4cSTejun Heo 
147bb813f4cSTejun Heo 	if (!e)
148bb813f4cSTejun Heo 		request_module("%s-iosched", chosen_elevator);
149bb813f4cSTejun Heo }
150bb813f4cSTejun Heo 
1513d1ab40fSAl Viro static struct kobj_type elv_ktype;
1523d1ab40fSAl Viro 
153d50235b7SJianpeng Ma struct elevator_queue *elevator_alloc(struct request_queue *q,
154165125e1SJens Axboe 				  struct elevator_type *e)
1553d1ab40fSAl Viro {
156b374d18aSJens Axboe 	struct elevator_queue *eq;
1579817064bSJens Axboe 
158c1b511ebSJoe Perches 	eq = kzalloc_node(sizeof(*eq), GFP_KERNEL, q->node);
1599817064bSJens Axboe 	if (unlikely(!eq))
1609817064bSJens Axboe 		goto err;
1619817064bSJens Axboe 
16222f746e2STejun Heo 	eq->type = e;
163f9cb074bSGreg Kroah-Hartman 	kobject_init(&eq->kobj, &elv_ktype);
1643d1ab40fSAl Viro 	mutex_init(&eq->sysfs_lock);
165242d98f0SSasha Levin 	hash_init(eq->hash);
1669817064bSJens Axboe 
1673d1ab40fSAl Viro 	return eq;
1689817064bSJens Axboe err:
1699817064bSJens Axboe 	kfree(eq);
1709817064bSJens Axboe 	elevator_put(e);
1719817064bSJens Axboe 	return NULL;
1723d1ab40fSAl Viro }
173d50235b7SJianpeng Ma EXPORT_SYMBOL(elevator_alloc);
1743d1ab40fSAl Viro 
1753d1ab40fSAl Viro static void elevator_release(struct kobject *kobj)
1763d1ab40fSAl Viro {
177b374d18aSJens Axboe 	struct elevator_queue *e;
1789817064bSJens Axboe 
179b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
18022f746e2STejun Heo 	elevator_put(e->type);
1813d1ab40fSAl Viro 	kfree(e);
1823d1ab40fSAl Viro }
1833d1ab40fSAl Viro 
184165125e1SJens Axboe int elevator_init(struct request_queue *q, char *name)
1851da177e4SLinus Torvalds {
1861da177e4SLinus Torvalds 	struct elevator_type *e = NULL;
187f8fc877dSTejun Heo 	int err;
1881da177e4SLinus Torvalds 
189eb1c160bSTomoki Sekiyama 	/*
190eb1c160bSTomoki Sekiyama 	 * q->sysfs_lock must be held to provide mutual exclusion between
191eb1c160bSTomoki Sekiyama 	 * elevator_switch() and here.
192eb1c160bSTomoki Sekiyama 	 */
193eb1c160bSTomoki Sekiyama 	lockdep_assert_held(&q->sysfs_lock);
194eb1c160bSTomoki Sekiyama 
1951abec4fdSMike Snitzer 	if (unlikely(q->elevator))
1961abec4fdSMike Snitzer 		return 0;
1971abec4fdSMike Snitzer 
198cb98fc8bSTejun Heo 	INIT_LIST_HEAD(&q->queue_head);
199cb98fc8bSTejun Heo 	q->last_merge = NULL;
200cb98fc8bSTejun Heo 	q->end_sector = 0;
201cb98fc8bSTejun Heo 	q->boundary_rq = NULL;
202cb98fc8bSTejun Heo 
2034eb166d9SJens Axboe 	if (name) {
20421c3c5d2STejun Heo 		e = elevator_get(name, true);
2054eb166d9SJens Axboe 		if (!e)
2061da177e4SLinus Torvalds 			return -EINVAL;
2074eb166d9SJens Axboe 	}
2081da177e4SLinus Torvalds 
20921c3c5d2STejun Heo 	/*
21021c3c5d2STejun Heo 	 * Use the default elevator specified by config boot param or
21121c3c5d2STejun Heo 	 * config option.  Don't try to load modules as we could be running
21221c3c5d2STejun Heo 	 * off async and request_module() isn't allowed from async.
21321c3c5d2STejun Heo 	 */
2144eb166d9SJens Axboe 	if (!e && *chosen_elevator) {
21521c3c5d2STejun Heo 		e = elevator_get(chosen_elevator, false);
2164eb166d9SJens Axboe 		if (!e)
2174eb166d9SJens Axboe 			printk(KERN_ERR "I/O scheduler %s not found\n",
2184eb166d9SJens Axboe 							chosen_elevator);
2194eb166d9SJens Axboe 	}
220248d5ca5SNate Diller 
2214eb166d9SJens Axboe 	if (!e) {
22221c3c5d2STejun Heo 		e = elevator_get(CONFIG_DEFAULT_IOSCHED, false);
2234eb166d9SJens Axboe 		if (!e) {
2244eb166d9SJens Axboe 			printk(KERN_ERR
2254eb166d9SJens Axboe 				"Default I/O scheduler not found. " \
2264eb166d9SJens Axboe 				"Using noop.\n");
22721c3c5d2STejun Heo 			e = elevator_get("noop", false);
2285f003976SNate Diller 		}
2294eb166d9SJens Axboe 	}
2305f003976SNate Diller 
231d50235b7SJianpeng Ma 	err = e->ops.elevator_init_fn(q, e);
232d32f6b57SSudip Mukherjee 	if (err)
233d32f6b57SSudip Mukherjee 		elevator_put(e);
234d32f6b57SSudip Mukherjee 	return err;
2351da177e4SLinus Torvalds }
2362e662b65SJens Axboe EXPORT_SYMBOL(elevator_init);
2372e662b65SJens Axboe 
238b374d18aSJens Axboe void elevator_exit(struct elevator_queue *e)
2391da177e4SLinus Torvalds {
2403d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
24122f746e2STejun Heo 	if (e->type->ops.elevator_exit_fn)
24222f746e2STejun Heo 		e->type->ops.elevator_exit_fn(e);
2433d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
2441da177e4SLinus Torvalds 
2453d1ab40fSAl Viro 	kobject_put(&e->kobj);
2461da177e4SLinus Torvalds }
2472e662b65SJens Axboe EXPORT_SYMBOL(elevator_exit);
2482e662b65SJens Axboe 
2499817064bSJens Axboe static inline void __elv_rqhash_del(struct request *rq)
2509817064bSJens Axboe {
251242d98f0SSasha Levin 	hash_del(&rq->hash);
252360f92c2SJens Axboe 	rq->cmd_flags &= ~REQ_HASHED;
2539817064bSJens Axboe }
2549817064bSJens Axboe 
255165125e1SJens Axboe static void elv_rqhash_del(struct request_queue *q, struct request *rq)
2569817064bSJens Axboe {
2579817064bSJens Axboe 	if (ELV_ON_HASH(rq))
2589817064bSJens Axboe 		__elv_rqhash_del(rq);
2599817064bSJens Axboe }
2609817064bSJens Axboe 
261165125e1SJens Axboe static void elv_rqhash_add(struct request_queue *q, struct request *rq)
2629817064bSJens Axboe {
263b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
2649817064bSJens Axboe 
2659817064bSJens Axboe 	BUG_ON(ELV_ON_HASH(rq));
266242d98f0SSasha Levin 	hash_add(e->hash, &rq->hash, rq_hash_key(rq));
267360f92c2SJens Axboe 	rq->cmd_flags |= REQ_HASHED;
2689817064bSJens Axboe }
2699817064bSJens Axboe 
270165125e1SJens Axboe static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
2719817064bSJens Axboe {
2729817064bSJens Axboe 	__elv_rqhash_del(rq);
2739817064bSJens Axboe 	elv_rqhash_add(q, rq);
2749817064bSJens Axboe }
2759817064bSJens Axboe 
276165125e1SJens Axboe static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
2779817064bSJens Axboe {
278b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
279b67bfe0dSSasha Levin 	struct hlist_node *next;
2809817064bSJens Axboe 	struct request *rq;
2819817064bSJens Axboe 
282ee89f812SLinus Torvalds 	hash_for_each_possible_safe(e->hash, rq, next, hash, offset) {
2839817064bSJens Axboe 		BUG_ON(!ELV_ON_HASH(rq));
2849817064bSJens Axboe 
2859817064bSJens Axboe 		if (unlikely(!rq_mergeable(rq))) {
2869817064bSJens Axboe 			__elv_rqhash_del(rq);
2879817064bSJens Axboe 			continue;
2889817064bSJens Axboe 		}
2899817064bSJens Axboe 
2909817064bSJens Axboe 		if (rq_hash_key(rq) == offset)
2919817064bSJens Axboe 			return rq;
2929817064bSJens Axboe 	}
2939817064bSJens Axboe 
2949817064bSJens Axboe 	return NULL;
2959817064bSJens Axboe }
2969817064bSJens Axboe 
2978922e16cSTejun Heo /*
2982e662b65SJens Axboe  * RB-tree support functions for inserting/lookup/removal of requests
2992e662b65SJens Axboe  * in a sorted RB tree.
3002e662b65SJens Axboe  */
301796d5116SJeff Moyer void elv_rb_add(struct rb_root *root, struct request *rq)
3022e662b65SJens Axboe {
3032e662b65SJens Axboe 	struct rb_node **p = &root->rb_node;
3042e662b65SJens Axboe 	struct rb_node *parent = NULL;
3052e662b65SJens Axboe 	struct request *__rq;
3062e662b65SJens Axboe 
3072e662b65SJens Axboe 	while (*p) {
3082e662b65SJens Axboe 		parent = *p;
3092e662b65SJens Axboe 		__rq = rb_entry(parent, struct request, rb_node);
3102e662b65SJens Axboe 
31183096ebfSTejun Heo 		if (blk_rq_pos(rq) < blk_rq_pos(__rq))
3122e662b65SJens Axboe 			p = &(*p)->rb_left;
313796d5116SJeff Moyer 		else if (blk_rq_pos(rq) >= blk_rq_pos(__rq))
3142e662b65SJens Axboe 			p = &(*p)->rb_right;
3152e662b65SJens Axboe 	}
3162e662b65SJens Axboe 
3172e662b65SJens Axboe 	rb_link_node(&rq->rb_node, parent, p);
3182e662b65SJens Axboe 	rb_insert_color(&rq->rb_node, root);
3192e662b65SJens Axboe }
3202e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_add);
3212e662b65SJens Axboe 
3222e662b65SJens Axboe void elv_rb_del(struct rb_root *root, struct request *rq)
3232e662b65SJens Axboe {
3242e662b65SJens Axboe 	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
3252e662b65SJens Axboe 	rb_erase(&rq->rb_node, root);
3262e662b65SJens Axboe 	RB_CLEAR_NODE(&rq->rb_node);
3272e662b65SJens Axboe }
3282e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_del);
3292e662b65SJens Axboe 
3302e662b65SJens Axboe struct request *elv_rb_find(struct rb_root *root, sector_t sector)
3312e662b65SJens Axboe {
3322e662b65SJens Axboe 	struct rb_node *n = root->rb_node;
3332e662b65SJens Axboe 	struct request *rq;
3342e662b65SJens Axboe 
3352e662b65SJens Axboe 	while (n) {
3362e662b65SJens Axboe 		rq = rb_entry(n, struct request, rb_node);
3372e662b65SJens Axboe 
33883096ebfSTejun Heo 		if (sector < blk_rq_pos(rq))
3392e662b65SJens Axboe 			n = n->rb_left;
34083096ebfSTejun Heo 		else if (sector > blk_rq_pos(rq))
3412e662b65SJens Axboe 			n = n->rb_right;
3422e662b65SJens Axboe 		else
3432e662b65SJens Axboe 			return rq;
3442e662b65SJens Axboe 	}
3452e662b65SJens Axboe 
3462e662b65SJens Axboe 	return NULL;
3472e662b65SJens Axboe }
3482e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_find);
3492e662b65SJens Axboe 
3502e662b65SJens Axboe /*
3518922e16cSTejun Heo  * Insert rq into dispatch queue of q.  Queue lock must be held on
352dbe7f76dSUwe Kleine-König  * entry.  rq is sort instead into the dispatch queue. To be used by
3532e662b65SJens Axboe  * specific elevators.
3548922e16cSTejun Heo  */
355165125e1SJens Axboe void elv_dispatch_sort(struct request_queue *q, struct request *rq)
3568922e16cSTejun Heo {
3578922e16cSTejun Heo 	sector_t boundary;
3588922e16cSTejun Heo 	struct list_head *entry;
3594eb166d9SJens Axboe 	int stop_flags;
3608922e16cSTejun Heo 
36106b86245STejun Heo 	if (q->last_merge == rq)
36206b86245STejun Heo 		q->last_merge = NULL;
3639817064bSJens Axboe 
3649817064bSJens Axboe 	elv_rqhash_del(q, rq);
3659817064bSJens Axboe 
36615853af9STejun Heo 	q->nr_sorted--;
36706b86245STejun Heo 
3681b47f531SJens Axboe 	boundary = q->end_sector;
36902e031cbSChristoph Hellwig 	stop_flags = REQ_SOFTBARRIER | REQ_STARTED;
3708922e16cSTejun Heo 	list_for_each_prev(entry, &q->queue_head) {
3718922e16cSTejun Heo 		struct request *pos = list_entry_rq(entry);
3728922e16cSTejun Heo 
37333659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_DISCARD) !=
37433659ebbSChristoph Hellwig 		    (pos->cmd_flags & REQ_DISCARD))
375e17fc0a1SDavid Woodhouse 			break;
376783660b2SJens Axboe 		if (rq_data_dir(rq) != rq_data_dir(pos))
377783660b2SJens Axboe 			break;
3784eb166d9SJens Axboe 		if (pos->cmd_flags & stop_flags)
3798922e16cSTejun Heo 			break;
38083096ebfSTejun Heo 		if (blk_rq_pos(rq) >= boundary) {
38183096ebfSTejun Heo 			if (blk_rq_pos(pos) < boundary)
3828922e16cSTejun Heo 				continue;
3838922e16cSTejun Heo 		} else {
38483096ebfSTejun Heo 			if (blk_rq_pos(pos) >= boundary)
3858922e16cSTejun Heo 				break;
3868922e16cSTejun Heo 		}
38783096ebfSTejun Heo 		if (blk_rq_pos(rq) >= blk_rq_pos(pos))
3888922e16cSTejun Heo 			break;
3898922e16cSTejun Heo 	}
3908922e16cSTejun Heo 
3918922e16cSTejun Heo 	list_add(&rq->queuelist, entry);
3928922e16cSTejun Heo }
3932e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_sort);
3942e662b65SJens Axboe 
3959817064bSJens Axboe /*
3962e662b65SJens Axboe  * Insert rq into dispatch queue of q.  Queue lock must be held on
3972e662b65SJens Axboe  * entry.  rq is added to the back of the dispatch queue. To be used by
3982e662b65SJens Axboe  * specific elevators.
3999817064bSJens Axboe  */
4009817064bSJens Axboe void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
4019817064bSJens Axboe {
4029817064bSJens Axboe 	if (q->last_merge == rq)
4039817064bSJens Axboe 		q->last_merge = NULL;
4049817064bSJens Axboe 
4059817064bSJens Axboe 	elv_rqhash_del(q, rq);
4069817064bSJens Axboe 
4079817064bSJens Axboe 	q->nr_sorted--;
4089817064bSJens Axboe 
4099817064bSJens Axboe 	q->end_sector = rq_end_sector(rq);
4109817064bSJens Axboe 	q->boundary_rq = rq;
4119817064bSJens Axboe 	list_add_tail(&rq->queuelist, &q->queue_head);
4129817064bSJens Axboe }
4132e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_add_tail);
4142e662b65SJens Axboe 
415165125e1SJens Axboe int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
4161da177e4SLinus Torvalds {
417b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
4189817064bSJens Axboe 	struct request *__rq;
41906b86245STejun Heo 	int ret;
42006b86245STejun Heo 
4219817064bSJens Axboe 	/*
422488991e2SAlan D. Brunelle 	 * Levels of merges:
423488991e2SAlan D. Brunelle 	 * 	nomerges:  No merges at all attempted
424488991e2SAlan D. Brunelle 	 * 	noxmerges: Only simple one-hit cache try
425488991e2SAlan D. Brunelle 	 * 	merges:	   All merge tries attempted
426488991e2SAlan D. Brunelle 	 */
427488991e2SAlan D. Brunelle 	if (blk_queue_nomerges(q))
428488991e2SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
429488991e2SAlan D. Brunelle 
430488991e2SAlan D. Brunelle 	/*
4319817064bSJens Axboe 	 * First try one-hit cache.
4329817064bSJens Axboe 	 */
433050c8ea8STejun Heo 	if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
434050c8ea8STejun Heo 		ret = blk_try_merge(q->last_merge, bio);
43506b86245STejun Heo 		if (ret != ELEVATOR_NO_MERGE) {
43606b86245STejun Heo 			*req = q->last_merge;
43706b86245STejun Heo 			return ret;
43806b86245STejun Heo 		}
43906b86245STejun Heo 	}
4401da177e4SLinus Torvalds 
441488991e2SAlan D. Brunelle 	if (blk_queue_noxmerges(q))
442ac9fafa1SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
443ac9fafa1SAlan D. Brunelle 
4449817064bSJens Axboe 	/*
4459817064bSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
4469817064bSJens Axboe 	 */
447*4f024f37SKent Overstreet 	__rq = elv_rqhash_find(q, bio->bi_iter.bi_sector);
4489817064bSJens Axboe 	if (__rq && elv_rq_merge_ok(__rq, bio)) {
4499817064bSJens Axboe 		*req = __rq;
4509817064bSJens Axboe 		return ELEVATOR_BACK_MERGE;
4519817064bSJens Axboe 	}
4529817064bSJens Axboe 
45322f746e2STejun Heo 	if (e->type->ops.elevator_merge_fn)
45422f746e2STejun Heo 		return e->type->ops.elevator_merge_fn(q, req, bio);
4551da177e4SLinus Torvalds 
4561da177e4SLinus Torvalds 	return ELEVATOR_NO_MERGE;
4571da177e4SLinus Torvalds }
4581da177e4SLinus Torvalds 
4595e84ea3aSJens Axboe /*
4605e84ea3aSJens Axboe  * Attempt to do an insertion back merge. Only check for the case where
4615e84ea3aSJens Axboe  * we can append 'rq' to an existing request, so we can throw 'rq' away
4625e84ea3aSJens Axboe  * afterwards.
4635e84ea3aSJens Axboe  *
4645e84ea3aSJens Axboe  * Returns true if we merged, false otherwise
4655e84ea3aSJens Axboe  */
4665e84ea3aSJens Axboe static bool elv_attempt_insert_merge(struct request_queue *q,
4675e84ea3aSJens Axboe 				     struct request *rq)
4685e84ea3aSJens Axboe {
4695e84ea3aSJens Axboe 	struct request *__rq;
470bee0393cSShaohua Li 	bool ret;
4715e84ea3aSJens Axboe 
4725e84ea3aSJens Axboe 	if (blk_queue_nomerges(q))
4735e84ea3aSJens Axboe 		return false;
4745e84ea3aSJens Axboe 
4755e84ea3aSJens Axboe 	/*
4765e84ea3aSJens Axboe 	 * First try one-hit cache.
4775e84ea3aSJens Axboe 	 */
4785e84ea3aSJens Axboe 	if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
4795e84ea3aSJens Axboe 		return true;
4805e84ea3aSJens Axboe 
4815e84ea3aSJens Axboe 	if (blk_queue_noxmerges(q))
4825e84ea3aSJens Axboe 		return false;
4835e84ea3aSJens Axboe 
484bee0393cSShaohua Li 	ret = false;
4855e84ea3aSJens Axboe 	/*
4865e84ea3aSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
4875e84ea3aSJens Axboe 	 */
488bee0393cSShaohua Li 	while (1) {
4895e84ea3aSJens Axboe 		__rq = elv_rqhash_find(q, blk_rq_pos(rq));
490bee0393cSShaohua Li 		if (!__rq || !blk_attempt_req_merge(q, __rq, rq))
491bee0393cSShaohua Li 			break;
4925e84ea3aSJens Axboe 
493bee0393cSShaohua Li 		/* The merged request could be merged with others, try again */
494bee0393cSShaohua Li 		ret = true;
495bee0393cSShaohua Li 		rq = __rq;
496bee0393cSShaohua Li 	}
497bee0393cSShaohua Li 
498bee0393cSShaohua Li 	return ret;
4995e84ea3aSJens Axboe }
5005e84ea3aSJens Axboe 
501165125e1SJens Axboe void elv_merged_request(struct request_queue *q, struct request *rq, int type)
5021da177e4SLinus Torvalds {
503b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5041da177e4SLinus Torvalds 
50522f746e2STejun Heo 	if (e->type->ops.elevator_merged_fn)
50622f746e2STejun Heo 		e->type->ops.elevator_merged_fn(q, rq, type);
50706b86245STejun Heo 
5082e662b65SJens Axboe 	if (type == ELEVATOR_BACK_MERGE)
5099817064bSJens Axboe 		elv_rqhash_reposition(q, rq);
5109817064bSJens Axboe 
51106b86245STejun Heo 	q->last_merge = rq;
5121da177e4SLinus Torvalds }
5131da177e4SLinus Torvalds 
514165125e1SJens Axboe void elv_merge_requests(struct request_queue *q, struct request *rq,
5151da177e4SLinus Torvalds 			     struct request *next)
5161da177e4SLinus Torvalds {
517b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5185e84ea3aSJens Axboe 	const int next_sorted = next->cmd_flags & REQ_SORTED;
5191da177e4SLinus Torvalds 
52022f746e2STejun Heo 	if (next_sorted && e->type->ops.elevator_merge_req_fn)
52122f746e2STejun Heo 		e->type->ops.elevator_merge_req_fn(q, rq, next);
52206b86245STejun Heo 
5239817064bSJens Axboe 	elv_rqhash_reposition(q, rq);
5249817064bSJens Axboe 
5255e84ea3aSJens Axboe 	if (next_sorted) {
5265e84ea3aSJens Axboe 		elv_rqhash_del(q, next);
5279817064bSJens Axboe 		q->nr_sorted--;
5285e84ea3aSJens Axboe 	}
5295e84ea3aSJens Axboe 
53006b86245STejun Heo 	q->last_merge = rq;
5311da177e4SLinus Torvalds }
5321da177e4SLinus Torvalds 
533812d4026SDivyesh Shah void elv_bio_merged(struct request_queue *q, struct request *rq,
534812d4026SDivyesh Shah 			struct bio *bio)
535812d4026SDivyesh Shah {
536812d4026SDivyesh Shah 	struct elevator_queue *e = q->elevator;
537812d4026SDivyesh Shah 
53822f746e2STejun Heo 	if (e->type->ops.elevator_bio_merged_fn)
53922f746e2STejun Heo 		e->type->ops.elevator_bio_merged_fn(q, rq, bio);
540812d4026SDivyesh Shah }
541812d4026SDivyesh Shah 
54247fafbc7SRafael J. Wysocki #ifdef CONFIG_PM
543c8158819SLin Ming static void blk_pm_requeue_request(struct request *rq)
544c8158819SLin Ming {
545c8158819SLin Ming 	if (rq->q->dev && !(rq->cmd_flags & REQ_PM))
546c8158819SLin Ming 		rq->q->nr_pending--;
547c8158819SLin Ming }
548c8158819SLin Ming 
549c8158819SLin Ming static void blk_pm_add_request(struct request_queue *q, struct request *rq)
550c8158819SLin Ming {
551c8158819SLin Ming 	if (q->dev && !(rq->cmd_flags & REQ_PM) && q->nr_pending++ == 0 &&
552c8158819SLin Ming 	    (q->rpm_status == RPM_SUSPENDED || q->rpm_status == RPM_SUSPENDING))
553c8158819SLin Ming 		pm_request_resume(q->dev);
554c8158819SLin Ming }
555c8158819SLin Ming #else
556c8158819SLin Ming static inline void blk_pm_requeue_request(struct request *rq) {}
557c8158819SLin Ming static inline void blk_pm_add_request(struct request_queue *q,
558c8158819SLin Ming 				      struct request *rq)
559c8158819SLin Ming {
560c8158819SLin Ming }
561c8158819SLin Ming #endif
562c8158819SLin Ming 
563165125e1SJens Axboe void elv_requeue_request(struct request_queue *q, struct request *rq)
5641da177e4SLinus Torvalds {
5651da177e4SLinus Torvalds 	/*
5661da177e4SLinus Torvalds 	 * it already went through dequeue, we need to decrement the
5671da177e4SLinus Torvalds 	 * in_flight count again
5681da177e4SLinus Torvalds 	 */
5698922e16cSTejun Heo 	if (blk_account_rq(rq)) {
5700a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
57133659ebbSChristoph Hellwig 		if (rq->cmd_flags & REQ_SORTED)
572cad97516SJens Axboe 			elv_deactivate_rq(q, rq);
5731da177e4SLinus Torvalds 	}
5741da177e4SLinus Torvalds 
5754aff5e23SJens Axboe 	rq->cmd_flags &= ~REQ_STARTED;
5761da177e4SLinus Torvalds 
577c8158819SLin Ming 	blk_pm_requeue_request(rq);
578c8158819SLin Ming 
579b710a480SJens Axboe 	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE);
5801da177e4SLinus Torvalds }
5811da177e4SLinus Torvalds 
58226308eabSJerome Marchand void elv_drain_elevator(struct request_queue *q)
58315853af9STejun Heo {
58415853af9STejun Heo 	static int printed;
585e3c78ca5STejun Heo 
586e3c78ca5STejun Heo 	lockdep_assert_held(q->queue_lock);
587e3c78ca5STejun Heo 
58822f746e2STejun Heo 	while (q->elevator->type->ops.elevator_dispatch_fn(q, 1))
58915853af9STejun Heo 		;
590e3c78ca5STejun Heo 	if (q->nr_sorted && printed++ < 10) {
59115853af9STejun Heo 		printk(KERN_ERR "%s: forced dispatching is broken "
59215853af9STejun Heo 		       "(nr_sorted=%u), please report this\n",
59322f746e2STejun Heo 		       q->elevator->type->elevator_name, q->nr_sorted);
59415853af9STejun Heo 	}
59515853af9STejun Heo }
59615853af9STejun Heo 
597b710a480SJens Axboe void __elv_add_request(struct request_queue *q, struct request *rq, int where)
5981da177e4SLinus Torvalds {
5995f3ea37cSArnaldo Carvalho de Melo 	trace_block_rq_insert(q, rq);
6002056a782SJens Axboe 
601c8158819SLin Ming 	blk_pm_add_request(q, rq);
602c8158819SLin Ming 
6031da177e4SLinus Torvalds 	rq->q = q;
6041da177e4SLinus Torvalds 
605b710a480SJens Axboe 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
606b710a480SJens Axboe 		/* barriers are scheduling boundary, update end_sector */
607e2a60da7SMartin K. Petersen 		if (rq->cmd_type == REQ_TYPE_FS) {
608b710a480SJens Axboe 			q->end_sector = rq_end_sector(rq);
609b710a480SJens Axboe 			q->boundary_rq = rq;
610b710a480SJens Axboe 		}
611b710a480SJens Axboe 	} else if (!(rq->cmd_flags & REQ_ELVPRIV) &&
6123aa72873SJens Axboe 		    (where == ELEVATOR_INSERT_SORT ||
6133aa72873SJens Axboe 		     where == ELEVATOR_INSERT_SORT_MERGE))
614b710a480SJens Axboe 		where = ELEVATOR_INSERT_BACK;
615b710a480SJens Axboe 
6168922e16cSTejun Heo 	switch (where) {
61728e7d184STejun Heo 	case ELEVATOR_INSERT_REQUEUE:
6188922e16cSTejun Heo 	case ELEVATOR_INSERT_FRONT:
6194aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
6208922e16cSTejun Heo 		list_add(&rq->queuelist, &q->queue_head);
6218922e16cSTejun Heo 		break;
6228922e16cSTejun Heo 
6238922e16cSTejun Heo 	case ELEVATOR_INSERT_BACK:
6244aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
62515853af9STejun Heo 		elv_drain_elevator(q);
6268922e16cSTejun Heo 		list_add_tail(&rq->queuelist, &q->queue_head);
6278922e16cSTejun Heo 		/*
6288922e16cSTejun Heo 		 * We kick the queue here for the following reasons.
6298922e16cSTejun Heo 		 * - The elevator might have returned NULL previously
6308922e16cSTejun Heo 		 *   to delay requests and returned them now.  As the
6318922e16cSTejun Heo 		 *   queue wasn't empty before this request, ll_rw_blk
6328922e16cSTejun Heo 		 *   won't run the queue on return, resulting in hang.
6338922e16cSTejun Heo 		 * - Usually, back inserted requests won't be merged
6348922e16cSTejun Heo 		 *   with anything.  There's no point in delaying queue
6358922e16cSTejun Heo 		 *   processing.
6368922e16cSTejun Heo 		 */
63724ecfbe2SChristoph Hellwig 		__blk_run_queue(q);
6388922e16cSTejun Heo 		break;
6398922e16cSTejun Heo 
6405e84ea3aSJens Axboe 	case ELEVATOR_INSERT_SORT_MERGE:
6415e84ea3aSJens Axboe 		/*
6425e84ea3aSJens Axboe 		 * If we succeed in merging this request with one in the
6435e84ea3aSJens Axboe 		 * queue already, we are done - rq has now been freed,
6445e84ea3aSJens Axboe 		 * so no need to do anything further.
6455e84ea3aSJens Axboe 		 */
6465e84ea3aSJens Axboe 		if (elv_attempt_insert_merge(q, rq))
6475e84ea3aSJens Axboe 			break;
6488922e16cSTejun Heo 	case ELEVATOR_INSERT_SORT:
649e2a60da7SMartin K. Petersen 		BUG_ON(rq->cmd_type != REQ_TYPE_FS);
6504aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SORTED;
65115853af9STejun Heo 		q->nr_sorted++;
6529817064bSJens Axboe 		if (rq_mergeable(rq)) {
6539817064bSJens Axboe 			elv_rqhash_add(q, rq);
6549817064bSJens Axboe 			if (!q->last_merge)
65506b86245STejun Heo 				q->last_merge = rq;
6569817064bSJens Axboe 		}
6579817064bSJens Axboe 
658ca23509fSTejun Heo 		/*
659ca23509fSTejun Heo 		 * Some ioscheds (cfq) run q->request_fn directly, so
660ca23509fSTejun Heo 		 * rq cannot be accessed after calling
661ca23509fSTejun Heo 		 * elevator_add_req_fn.
662ca23509fSTejun Heo 		 */
66322f746e2STejun Heo 		q->elevator->type->ops.elevator_add_req_fn(q, rq);
6648922e16cSTejun Heo 		break;
6658922e16cSTejun Heo 
666ae1b1539STejun Heo 	case ELEVATOR_INSERT_FLUSH:
667ae1b1539STejun Heo 		rq->cmd_flags |= REQ_SOFTBARRIER;
668ae1b1539STejun Heo 		blk_insert_flush(rq);
669ae1b1539STejun Heo 		break;
6708922e16cSTejun Heo 	default:
6718922e16cSTejun Heo 		printk(KERN_ERR "%s: bad insertion point %d\n",
67224c03d47SHarvey Harrison 		       __func__, where);
6738922e16cSTejun Heo 		BUG();
6748922e16cSTejun Heo 	}
6751da177e4SLinus Torvalds }
6762e662b65SJens Axboe EXPORT_SYMBOL(__elv_add_request);
6772e662b65SJens Axboe 
6787eaceaccSJens Axboe void elv_add_request(struct request_queue *q, struct request *rq, int where)
6791da177e4SLinus Torvalds {
6801da177e4SLinus Torvalds 	unsigned long flags;
6811da177e4SLinus Torvalds 
6821da177e4SLinus Torvalds 	spin_lock_irqsave(q->queue_lock, flags);
6837eaceaccSJens Axboe 	__elv_add_request(q, rq, where);
6841da177e4SLinus Torvalds 	spin_unlock_irqrestore(q->queue_lock, flags);
6851da177e4SLinus Torvalds }
6862e662b65SJens Axboe EXPORT_SYMBOL(elv_add_request);
6872e662b65SJens Axboe 
688165125e1SJens Axboe struct request *elv_latter_request(struct request_queue *q, struct request *rq)
6891da177e4SLinus Torvalds {
690b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6911da177e4SLinus Torvalds 
69222f746e2STejun Heo 	if (e->type->ops.elevator_latter_req_fn)
69322f746e2STejun Heo 		return e->type->ops.elevator_latter_req_fn(q, rq);
6941da177e4SLinus Torvalds 	return NULL;
6951da177e4SLinus Torvalds }
6961da177e4SLinus Torvalds 
697165125e1SJens Axboe struct request *elv_former_request(struct request_queue *q, struct request *rq)
6981da177e4SLinus Torvalds {
699b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7001da177e4SLinus Torvalds 
70122f746e2STejun Heo 	if (e->type->ops.elevator_former_req_fn)
70222f746e2STejun Heo 		return e->type->ops.elevator_former_req_fn(q, rq);
7031da177e4SLinus Torvalds 	return NULL;
7041da177e4SLinus Torvalds }
7051da177e4SLinus Torvalds 
706852c788fSTejun Heo int elv_set_request(struct request_queue *q, struct request *rq,
707852c788fSTejun Heo 		    struct bio *bio, gfp_t gfp_mask)
7081da177e4SLinus Torvalds {
709b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7101da177e4SLinus Torvalds 
71122f746e2STejun Heo 	if (e->type->ops.elevator_set_req_fn)
712852c788fSTejun Heo 		return e->type->ops.elevator_set_req_fn(q, rq, bio, gfp_mask);
7131da177e4SLinus Torvalds 	return 0;
7141da177e4SLinus Torvalds }
7151da177e4SLinus Torvalds 
716165125e1SJens Axboe void elv_put_request(struct request_queue *q, struct request *rq)
7171da177e4SLinus Torvalds {
718b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7191da177e4SLinus Torvalds 
72022f746e2STejun Heo 	if (e->type->ops.elevator_put_req_fn)
72122f746e2STejun Heo 		e->type->ops.elevator_put_req_fn(rq);
7221da177e4SLinus Torvalds }
7231da177e4SLinus Torvalds 
724165125e1SJens Axboe int elv_may_queue(struct request_queue *q, int rw)
7251da177e4SLinus Torvalds {
726b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7271da177e4SLinus Torvalds 
72822f746e2STejun Heo 	if (e->type->ops.elevator_may_queue_fn)
72922f746e2STejun Heo 		return e->type->ops.elevator_may_queue_fn(q, rw);
7301da177e4SLinus Torvalds 
7311da177e4SLinus Torvalds 	return ELV_MQUEUE_MAY;
7321da177e4SLinus Torvalds }
7331da177e4SLinus Torvalds 
734165125e1SJens Axboe void elv_completed_request(struct request_queue *q, struct request *rq)
7351da177e4SLinus Torvalds {
736b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7371da177e4SLinus Torvalds 
7381da177e4SLinus Torvalds 	/*
7391da177e4SLinus Torvalds 	 * request is released from the driver, io must be done
7401da177e4SLinus Torvalds 	 */
7418922e16cSTejun Heo 	if (blk_account_rq(rq)) {
7420a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
74333659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_SORTED) &&
74422f746e2STejun Heo 		    e->type->ops.elevator_completed_req_fn)
74522f746e2STejun Heo 			e->type->ops.elevator_completed_req_fn(q, rq);
7461bc691d3STejun Heo 	}
7478922e16cSTejun Heo }
7481da177e4SLinus Torvalds 
7493d1ab40fSAl Viro #define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
7503d1ab40fSAl Viro 
7513d1ab40fSAl Viro static ssize_t
7523d1ab40fSAl Viro elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
7533d1ab40fSAl Viro {
7543d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
755b374d18aSJens Axboe 	struct elevator_queue *e;
7563d1ab40fSAl Viro 	ssize_t error;
7573d1ab40fSAl Viro 
7583d1ab40fSAl Viro 	if (!entry->show)
7593d1ab40fSAl Viro 		return -EIO;
7603d1ab40fSAl Viro 
761b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
7623d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
76322f746e2STejun Heo 	error = e->type ? entry->show(e, page) : -ENOENT;
7643d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
7653d1ab40fSAl Viro 	return error;
7663d1ab40fSAl Viro }
7673d1ab40fSAl Viro 
7683d1ab40fSAl Viro static ssize_t
7693d1ab40fSAl Viro elv_attr_store(struct kobject *kobj, struct attribute *attr,
7703d1ab40fSAl Viro 	       const char *page, size_t length)
7713d1ab40fSAl Viro {
7723d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
773b374d18aSJens Axboe 	struct elevator_queue *e;
7743d1ab40fSAl Viro 	ssize_t error;
7753d1ab40fSAl Viro 
7763d1ab40fSAl Viro 	if (!entry->store)
7773d1ab40fSAl Viro 		return -EIO;
7783d1ab40fSAl Viro 
779b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
7803d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
78122f746e2STejun Heo 	error = e->type ? entry->store(e, page, length) : -ENOENT;
7823d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
7833d1ab40fSAl Viro 	return error;
7843d1ab40fSAl Viro }
7853d1ab40fSAl Viro 
78652cf25d0SEmese Revfy static const struct sysfs_ops elv_sysfs_ops = {
7873d1ab40fSAl Viro 	.show	= elv_attr_show,
7883d1ab40fSAl Viro 	.store	= elv_attr_store,
7893d1ab40fSAl Viro };
7903d1ab40fSAl Viro 
7913d1ab40fSAl Viro static struct kobj_type elv_ktype = {
7923d1ab40fSAl Viro 	.sysfs_ops	= &elv_sysfs_ops,
7933d1ab40fSAl Viro 	.release	= elevator_release,
7943d1ab40fSAl Viro };
7953d1ab40fSAl Viro 
7965a5bafdcSTejun Heo int elv_register_queue(struct request_queue *q)
7971da177e4SLinus Torvalds {
7985a5bafdcSTejun Heo 	struct elevator_queue *e = q->elevator;
7993d1ab40fSAl Viro 	int error;
8001da177e4SLinus Torvalds 
801b2d6db58SGreg Kroah-Hartman 	error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
8023d1ab40fSAl Viro 	if (!error) {
80322f746e2STejun Heo 		struct elv_fs_entry *attr = e->type->elevator_attrs;
8043d1ab40fSAl Viro 		if (attr) {
805e572ec7eSAl Viro 			while (attr->attr.name) {
806e572ec7eSAl Viro 				if (sysfs_create_file(&e->kobj, &attr->attr))
8073d1ab40fSAl Viro 					break;
808e572ec7eSAl Viro 				attr++;
8093d1ab40fSAl Viro 			}
8103d1ab40fSAl Viro 		}
8113d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_ADD);
812430c62fbSJens Axboe 		e->registered = 1;
8133d1ab40fSAl Viro 	}
8143d1ab40fSAl Viro 	return error;
8151da177e4SLinus Torvalds }
81601effb0dSMike Snitzer EXPORT_SYMBOL(elv_register_queue);
8171da177e4SLinus Torvalds 
818f8fc877dSTejun Heo void elv_unregister_queue(struct request_queue *q)
8191da177e4SLinus Torvalds {
820f8fc877dSTejun Heo 	if (q) {
821f8fc877dSTejun Heo 		struct elevator_queue *e = q->elevator;
822f8fc877dSTejun Heo 
8233d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_REMOVE);
8243d1ab40fSAl Viro 		kobject_del(&e->kobj);
825430c62fbSJens Axboe 		e->registered = 0;
8261da177e4SLinus Torvalds 	}
8271da177e4SLinus Torvalds }
82801effb0dSMike Snitzer EXPORT_SYMBOL(elv_unregister_queue);
8291da177e4SLinus Torvalds 
830e567bf71SJens Axboe int elv_register(struct elevator_type *e)
8311da177e4SLinus Torvalds {
8321ffb96c5SThibaut VARENE 	char *def = "";
8332a12dcd7SJens Axboe 
8343d3c2379STejun Heo 	/* create icq_cache if requested */
8353d3c2379STejun Heo 	if (e->icq_size) {
8363d3c2379STejun Heo 		if (WARN_ON(e->icq_size < sizeof(struct io_cq)) ||
8373d3c2379STejun Heo 		    WARN_ON(e->icq_align < __alignof__(struct io_cq)))
8383d3c2379STejun Heo 			return -EINVAL;
8393d3c2379STejun Heo 
8403d3c2379STejun Heo 		snprintf(e->icq_cache_name, sizeof(e->icq_cache_name),
8413d3c2379STejun Heo 			 "%s_io_cq", e->elevator_name);
8423d3c2379STejun Heo 		e->icq_cache = kmem_cache_create(e->icq_cache_name, e->icq_size,
8433d3c2379STejun Heo 						 e->icq_align, 0, NULL);
8443d3c2379STejun Heo 		if (!e->icq_cache)
8453d3c2379STejun Heo 			return -ENOMEM;
8463d3c2379STejun Heo 	}
8473d3c2379STejun Heo 
8483d3c2379STejun Heo 	/* register, don't allow duplicate names */
8492a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
8503d3c2379STejun Heo 	if (elevator_find(e->elevator_name)) {
8513d3c2379STejun Heo 		spin_unlock(&elv_list_lock);
8523d3c2379STejun Heo 		if (e->icq_cache)
8533d3c2379STejun Heo 			kmem_cache_destroy(e->icq_cache);
8543d3c2379STejun Heo 		return -EBUSY;
8553d3c2379STejun Heo 	}
8561da177e4SLinus Torvalds 	list_add_tail(&e->list, &elv_list);
8572a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
8581da177e4SLinus Torvalds 
8593d3c2379STejun Heo 	/* print pretty message */
8605f003976SNate Diller 	if (!strcmp(e->elevator_name, chosen_elevator) ||
8615f003976SNate Diller 			(!*chosen_elevator &&
8625f003976SNate Diller 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
8631ffb96c5SThibaut VARENE 				def = " (default)";
8641ffb96c5SThibaut VARENE 
8654eb166d9SJens Axboe 	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
8664eb166d9SJens Axboe 								def);
8673d3c2379STejun Heo 	return 0;
8681da177e4SLinus Torvalds }
8691da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_register);
8701da177e4SLinus Torvalds 
8711da177e4SLinus Torvalds void elv_unregister(struct elevator_type *e)
8721da177e4SLinus Torvalds {
8733d3c2379STejun Heo 	/* unregister */
8742a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
8751da177e4SLinus Torvalds 	list_del_init(&e->list);
8762a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
8773d3c2379STejun Heo 
8783d3c2379STejun Heo 	/*
8793d3c2379STejun Heo 	 * Destroy icq_cache if it exists.  icq's are RCU managed.  Make
8803d3c2379STejun Heo 	 * sure all RCU operations are complete before proceeding.
8813d3c2379STejun Heo 	 */
8823d3c2379STejun Heo 	if (e->icq_cache) {
8833d3c2379STejun Heo 		rcu_barrier();
8843d3c2379STejun Heo 		kmem_cache_destroy(e->icq_cache);
8853d3c2379STejun Heo 		e->icq_cache = NULL;
8863d3c2379STejun Heo 	}
8871da177e4SLinus Torvalds }
8881da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_unregister);
8891da177e4SLinus Torvalds 
8901da177e4SLinus Torvalds /*
8911da177e4SLinus Torvalds  * switch to new_e io scheduler. be careful not to introduce deadlocks -
8921da177e4SLinus Torvalds  * we don't free the old io scheduler, before we have allocated what we
8931da177e4SLinus Torvalds  * need for the new one. this way we have a chance of going back to the old
894cb98fc8bSTejun Heo  * one, if the new one fails init for some reason.
8951da177e4SLinus Torvalds  */
896165125e1SJens Axboe static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
8971da177e4SLinus Torvalds {
8985a5bafdcSTejun Heo 	struct elevator_queue *old = q->elevator;
8995a5bafdcSTejun Heo 	bool registered = old->registered;
900e8989faeSTejun Heo 	int err;
9011da177e4SLinus Torvalds 
9025a5bafdcSTejun Heo 	/*
9035a5bafdcSTejun Heo 	 * Turn on BYPASS and drain all requests w/ elevator private data.
9045a5bafdcSTejun Heo 	 * Block layer doesn't call into a quiesced elevator - all requests
9055a5bafdcSTejun Heo 	 * are directly put on the dispatch list without elevator data
9065a5bafdcSTejun Heo 	 * using INSERT_BACK.  All requests have SOFTBARRIER set and no
9075a5bafdcSTejun Heo 	 * merge happens either.
9085a5bafdcSTejun Heo 	 */
909d732580bSTejun Heo 	blk_queue_bypass_start(q);
910cb98fc8bSTejun Heo 
9115a5bafdcSTejun Heo 	/* unregister and clear all auxiliary data of the old elevator */
9125a5bafdcSTejun Heo 	if (registered)
913f8fc877dSTejun Heo 		elv_unregister_queue(q);
9145a5bafdcSTejun Heo 
9155a5bafdcSTejun Heo 	spin_lock_irq(q->queue_lock);
9165a5bafdcSTejun Heo 	ioc_clear_queue(q);
9175a5bafdcSTejun Heo 	spin_unlock_irq(q->queue_lock);
9185a5bafdcSTejun Heo 
9195a5bafdcSTejun Heo 	/* allocate, init and register new elevator */
920d50235b7SJianpeng Ma 	err = new_e->ops.elevator_init_fn(q, new_e);
921d50235b7SJianpeng Ma 	if (err)
9225a5bafdcSTejun Heo 		goto fail_init;
9235a5bafdcSTejun Heo 
9245a5bafdcSTejun Heo 	if (registered) {
9255a5bafdcSTejun Heo 		err = elv_register_queue(q);
9265dd531a0SJens Axboe 		if (err)
9271da177e4SLinus Torvalds 			goto fail_register;
928430c62fbSJens Axboe 	}
9291da177e4SLinus Torvalds 
9305a5bafdcSTejun Heo 	/* done, kill the old one and finish */
9315a5bafdcSTejun Heo 	elevator_exit(old);
932d732580bSTejun Heo 	blk_queue_bypass_end(q);
93375ad23bcSNick Piggin 
9345a5bafdcSTejun Heo 	blk_add_trace_msg(q, "elv switch: %s", new_e->elevator_name);
9354722dc52SAlan D. Brunelle 
9365dd531a0SJens Axboe 	return 0;
9371da177e4SLinus Torvalds 
9381da177e4SLinus Torvalds fail_register:
9395a5bafdcSTejun Heo 	elevator_exit(q->elevator);
9405a5bafdcSTejun Heo fail_init:
9415a5bafdcSTejun Heo 	/* switch failed, restore and re-register old elevator */
9425a5bafdcSTejun Heo 	q->elevator = old;
9431da177e4SLinus Torvalds 	elv_register_queue(q);
944d732580bSTejun Heo 	blk_queue_bypass_end(q);
94575ad23bcSNick Piggin 
9465dd531a0SJens Axboe 	return err;
9471da177e4SLinus Torvalds }
9481da177e4SLinus Torvalds 
9495dd531a0SJens Axboe /*
9505dd531a0SJens Axboe  * Switch this queue to the given IO scheduler.
9515dd531a0SJens Axboe  */
9527c8a3679STomoki Sekiyama static int __elevator_change(struct request_queue *q, const char *name)
9531da177e4SLinus Torvalds {
9541da177e4SLinus Torvalds 	char elevator_name[ELV_NAME_MAX];
9551da177e4SLinus Torvalds 	struct elevator_type *e;
9561da177e4SLinus Torvalds 
957cd43e26fSMartin K. Petersen 	if (!q->elevator)
9585dd531a0SJens Axboe 		return -ENXIO;
959cd43e26fSMartin K. Petersen 
960ee2e992cSLi Zefan 	strlcpy(elevator_name, name, sizeof(elevator_name));
96121c3c5d2STejun Heo 	e = elevator_get(strstrip(elevator_name), true);
9621da177e4SLinus Torvalds 	if (!e) {
9631da177e4SLinus Torvalds 		printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
9641da177e4SLinus Torvalds 		return -EINVAL;
9651da177e4SLinus Torvalds 	}
9661da177e4SLinus Torvalds 
96722f746e2STejun Heo 	if (!strcmp(elevator_name, q->elevator->type->elevator_name)) {
9682ca7d93bSNate Diller 		elevator_put(e);
9695dd531a0SJens Axboe 		return 0;
9702ca7d93bSNate Diller 	}
9711da177e4SLinus Torvalds 
9725dd531a0SJens Axboe 	return elevator_switch(q, e);
9735dd531a0SJens Axboe }
9747c8a3679STomoki Sekiyama 
9757c8a3679STomoki Sekiyama int elevator_change(struct request_queue *q, const char *name)
9767c8a3679STomoki Sekiyama {
9777c8a3679STomoki Sekiyama 	int ret;
9787c8a3679STomoki Sekiyama 
9797c8a3679STomoki Sekiyama 	/* Protect q->elevator from elevator_init() */
9807c8a3679STomoki Sekiyama 	mutex_lock(&q->sysfs_lock);
9817c8a3679STomoki Sekiyama 	ret = __elevator_change(q, name);
9827c8a3679STomoki Sekiyama 	mutex_unlock(&q->sysfs_lock);
9837c8a3679STomoki Sekiyama 
9847c8a3679STomoki Sekiyama 	return ret;
9857c8a3679STomoki Sekiyama }
9865dd531a0SJens Axboe EXPORT_SYMBOL(elevator_change);
9875dd531a0SJens Axboe 
9885dd531a0SJens Axboe ssize_t elv_iosched_store(struct request_queue *q, const char *name,
9895dd531a0SJens Axboe 			  size_t count)
9905dd531a0SJens Axboe {
9915dd531a0SJens Axboe 	int ret;
9925dd531a0SJens Axboe 
9935dd531a0SJens Axboe 	if (!q->elevator)
9941da177e4SLinus Torvalds 		return count;
9955dd531a0SJens Axboe 
9967c8a3679STomoki Sekiyama 	ret = __elevator_change(q, name);
9975dd531a0SJens Axboe 	if (!ret)
9985dd531a0SJens Axboe 		return count;
9995dd531a0SJens Axboe 
10005dd531a0SJens Axboe 	printk(KERN_ERR "elevator: switch to %s failed\n", name);
10015dd531a0SJens Axboe 	return ret;
10021da177e4SLinus Torvalds }
10031da177e4SLinus Torvalds 
1004165125e1SJens Axboe ssize_t elv_iosched_show(struct request_queue *q, char *name)
10051da177e4SLinus Torvalds {
1006b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
1007cd43e26fSMartin K. Petersen 	struct elevator_type *elv;
100870cee26eSMatthias Kaehlcke 	struct elevator_type *__e;
10091da177e4SLinus Torvalds 	int len = 0;
10101da177e4SLinus Torvalds 
1011e36f724bSMike Snitzer 	if (!q->elevator || !blk_queue_stackable(q))
1012cd43e26fSMartin K. Petersen 		return sprintf(name, "none\n");
1013cd43e26fSMartin K. Petersen 
101422f746e2STejun Heo 	elv = e->type;
1015cd43e26fSMartin K. Petersen 
10162a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
101770cee26eSMatthias Kaehlcke 	list_for_each_entry(__e, &elv_list, list) {
10181da177e4SLinus Torvalds 		if (!strcmp(elv->elevator_name, __e->elevator_name))
10191da177e4SLinus Torvalds 			len += sprintf(name+len, "[%s] ", elv->elevator_name);
10201da177e4SLinus Torvalds 		else
10211da177e4SLinus Torvalds 			len += sprintf(name+len, "%s ", __e->elevator_name);
10221da177e4SLinus Torvalds 	}
10232a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
10241da177e4SLinus Torvalds 
10251da177e4SLinus Torvalds 	len += sprintf(len+name, "\n");
10261da177e4SLinus Torvalds 	return len;
10271da177e4SLinus Torvalds }
10281da177e4SLinus Torvalds 
1029165125e1SJens Axboe struct request *elv_rb_former_request(struct request_queue *q,
1030165125e1SJens Axboe 				      struct request *rq)
10312e662b65SJens Axboe {
10322e662b65SJens Axboe 	struct rb_node *rbprev = rb_prev(&rq->rb_node);
10332e662b65SJens Axboe 
10342e662b65SJens Axboe 	if (rbprev)
10352e662b65SJens Axboe 		return rb_entry_rq(rbprev);
10362e662b65SJens Axboe 
10372e662b65SJens Axboe 	return NULL;
10382e662b65SJens Axboe }
10392e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_former_request);
10402e662b65SJens Axboe 
1041165125e1SJens Axboe struct request *elv_rb_latter_request(struct request_queue *q,
1042165125e1SJens Axboe 				      struct request *rq)
10432e662b65SJens Axboe {
10442e662b65SJens Axboe 	struct rb_node *rbnext = rb_next(&rq->rb_node);
10452e662b65SJens Axboe 
10462e662b65SJens Axboe 	if (rbnext)
10472e662b65SJens Axboe 		return rb_entry_rq(rbnext);
10482e662b65SJens Axboe 
10492e662b65SJens Axboe 	return NULL;
10502e662b65SJens Axboe }
10512e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_latter_request);
1052