xref: /linux/block/elevator.c (revision 01effb0dc1451fad55925873ffbfb88fa4eadce0)
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>
34cb98fc8bSTejun Heo #include <linux/delay.h>
352056a782SJens Axboe #include <linux/blktrace_api.h>
369817064bSJens Axboe #include <linux/hash.h>
370835da67SJens Axboe #include <linux/uaccess.h>
381da177e4SLinus Torvalds 
3955782138SLi Zefan #include <trace/events/block.h>
4055782138SLi Zefan 
41242f9dcbSJens Axboe #include "blk.h"
42242f9dcbSJens Axboe 
431da177e4SLinus Torvalds static DEFINE_SPINLOCK(elv_list_lock);
441da177e4SLinus Torvalds static LIST_HEAD(elv_list);
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds /*
479817064bSJens Axboe  * Merge hash stuff.
489817064bSJens Axboe  */
499817064bSJens Axboe static const int elv_hash_shift = 6;
509817064bSJens Axboe #define ELV_HASH_BLOCK(sec)	((sec) >> 3)
514eb166d9SJens Axboe #define ELV_HASH_FN(sec)	\
524eb166d9SJens Axboe 		(hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift))
539817064bSJens Axboe #define ELV_HASH_ENTRIES	(1 << elv_hash_shift)
5483096ebfSTejun Heo #define rq_hash_key(rq)		(blk_rq_pos(rq) + blk_rq_sectors(rq))
559817064bSJens Axboe 
569817064bSJens Axboe /*
57da775265SJens Axboe  * Query io scheduler to see if the current process issuing bio may be
58da775265SJens Axboe  * merged with rq.
59da775265SJens Axboe  */
60da775265SJens Axboe static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
61da775265SJens Axboe {
62165125e1SJens Axboe 	struct request_queue *q = rq->q;
63b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
64da775265SJens Axboe 
65da775265SJens Axboe 	if (e->ops->elevator_allow_merge_fn)
66da775265SJens Axboe 		return e->ops->elevator_allow_merge_fn(q, rq, bio);
67da775265SJens Axboe 
68da775265SJens Axboe 	return 1;
69da775265SJens Axboe }
70da775265SJens Axboe 
71da775265SJens Axboe /*
721da177e4SLinus Torvalds  * can we safely merge with this request?
731da177e4SLinus Torvalds  */
7472ed0bf6SAdrian Bunk int elv_rq_merge_ok(struct request *rq, struct bio *bio)
751da177e4SLinus Torvalds {
761da177e4SLinus Torvalds 	if (!rq_mergeable(rq))
771da177e4SLinus Torvalds 		return 0;
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds 	/*
80e17fc0a1SDavid Woodhouse 	 * Don't merge file system requests and discard requests
81e17fc0a1SDavid Woodhouse 	 */
821f98a13fSJens Axboe 	if (bio_rw_flagged(bio, BIO_RW_DISCARD) !=
831f98a13fSJens Axboe 	    bio_rw_flagged(rq->bio, BIO_RW_DISCARD))
84e17fc0a1SDavid Woodhouse 		return 0;
85e17fc0a1SDavid Woodhouse 
86e17fc0a1SDavid Woodhouse 	/*
871da177e4SLinus Torvalds 	 * different data direction or already started, don't merge
881da177e4SLinus Torvalds 	 */
891da177e4SLinus Torvalds 	if (bio_data_dir(bio) != rq_data_dir(rq))
901da177e4SLinus Torvalds 		return 0;
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds 	/*
93da775265SJens Axboe 	 * must be same device and not a special request
941da177e4SLinus Torvalds 	 */
95bb4067e3SJens Axboe 	if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
961da177e4SLinus Torvalds 		return 0;
97da775265SJens Axboe 
987ba1ba12SMartin K. Petersen 	/*
997ba1ba12SMartin K. Petersen 	 * only merge integrity protected bio into ditto rq
1007ba1ba12SMartin K. Petersen 	 */
1017ba1ba12SMartin K. Petersen 	if (bio_integrity(bio) != blk_integrity_rq(rq))
1027ba1ba12SMartin K. Petersen 		return 0;
1037ba1ba12SMartin K. Petersen 
104da775265SJens Axboe 	if (!elv_iosched_allow_merge(rq, bio))
105da775265SJens Axboe 		return 0;
106da775265SJens Axboe 
107da775265SJens Axboe 	return 1;
1081da177e4SLinus Torvalds }
1091da177e4SLinus Torvalds EXPORT_SYMBOL(elv_rq_merge_ok);
1101da177e4SLinus Torvalds 
111769db45bSCoywolf Qi Hunt static inline int elv_try_merge(struct request *__rq, struct bio *bio)
1121da177e4SLinus Torvalds {
1131da177e4SLinus Torvalds 	int ret = ELEVATOR_NO_MERGE;
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds 	/*
1161da177e4SLinus Torvalds 	 * we can merge and sequence is ok, check if it's possible
1171da177e4SLinus Torvalds 	 */
1181da177e4SLinus Torvalds 	if (elv_rq_merge_ok(__rq, bio)) {
11983096ebfSTejun Heo 		if (blk_rq_pos(__rq) + blk_rq_sectors(__rq) == bio->bi_sector)
1201da177e4SLinus Torvalds 			ret = ELEVATOR_BACK_MERGE;
12183096ebfSTejun Heo 		else if (blk_rq_pos(__rq) - bio_sectors(bio) == bio->bi_sector)
1221da177e4SLinus Torvalds 			ret = ELEVATOR_FRONT_MERGE;
1231da177e4SLinus Torvalds 	}
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	return ret;
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds static struct elevator_type *elevator_find(const char *name)
1291da177e4SLinus Torvalds {
130a22b169dSVasily Tarasov 	struct elevator_type *e;
1311da177e4SLinus Torvalds 
13270cee26eSMatthias Kaehlcke 	list_for_each_entry(e, &elv_list, list) {
133a22b169dSVasily Tarasov 		if (!strcmp(e->elevator_name, name))
1341da177e4SLinus Torvalds 			return e;
1351da177e4SLinus Torvalds 	}
1361da177e4SLinus Torvalds 
137a22b169dSVasily Tarasov 	return NULL;
138a22b169dSVasily Tarasov }
139a22b169dSVasily Tarasov 
1401da177e4SLinus Torvalds static void elevator_put(struct elevator_type *e)
1411da177e4SLinus Torvalds {
1421da177e4SLinus Torvalds 	module_put(e->elevator_owner);
1431da177e4SLinus Torvalds }
1441da177e4SLinus Torvalds 
1451da177e4SLinus Torvalds static struct elevator_type *elevator_get(const char *name)
1461da177e4SLinus Torvalds {
1472824bc93STejun Heo 	struct elevator_type *e;
1481da177e4SLinus Torvalds 
1492a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
1502824bc93STejun Heo 
1512824bc93STejun Heo 	e = elevator_find(name);
152e1640949SJens Axboe 	if (!e) {
153e1640949SJens Axboe 		char elv[ELV_NAME_MAX + strlen("-iosched")];
154e1640949SJens Axboe 
155e1640949SJens Axboe 		spin_unlock(&elv_list_lock);
156e1640949SJens Axboe 
157a506aedcSwzt.wzt@gmail.com 		snprintf(elv, sizeof(elv), "%s-iosched", name);
158e1640949SJens Axboe 
159e180f594Smaximilian attems 		request_module("%s", elv);
160e1640949SJens Axboe 		spin_lock(&elv_list_lock);
161e1640949SJens Axboe 		e = elevator_find(name);
162e1640949SJens Axboe 	}
163e1640949SJens Axboe 
1642824bc93STejun Heo 	if (e && !try_module_get(e->elevator_owner))
1652824bc93STejun Heo 		e = NULL;
1662824bc93STejun Heo 
1672a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds 	return e;
1701da177e4SLinus Torvalds }
1711da177e4SLinus Torvalds 
172165125e1SJens Axboe static void *elevator_init_queue(struct request_queue *q,
173165125e1SJens Axboe 				 struct elevator_queue *eq)
1741da177e4SLinus Torvalds {
175bb37b94cSJens Axboe 	return eq->ops->elevator_init_fn(q);
176bc1c1169SJens Axboe }
1771da177e4SLinus Torvalds 
178165125e1SJens Axboe static void elevator_attach(struct request_queue *q, struct elevator_queue *eq,
179bc1c1169SJens Axboe 			   void *data)
180bc1c1169SJens Axboe {
1811da177e4SLinus Torvalds 	q->elevator = eq;
182bc1c1169SJens Axboe 	eq->elevator_data = data;
1831da177e4SLinus Torvalds }
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds static char chosen_elevator[16];
1861da177e4SLinus Torvalds 
1875f003976SNate Diller static int __init elevator_setup(char *str)
1881da177e4SLinus Torvalds {
189752a3b79SChuck Ebbert 	/*
190752a3b79SChuck Ebbert 	 * Be backwards-compatible with previous kernels, so users
191752a3b79SChuck Ebbert 	 * won't get the wrong elevator.
192752a3b79SChuck Ebbert 	 */
1931da177e4SLinus Torvalds 	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
1949b41046cSOGAWA Hirofumi 	return 1;
1951da177e4SLinus Torvalds }
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds __setup("elevator=", elevator_setup);
1981da177e4SLinus Torvalds 
1993d1ab40fSAl Viro static struct kobj_type elv_ktype;
2003d1ab40fSAl Viro 
201b374d18aSJens Axboe static struct elevator_queue *elevator_alloc(struct request_queue *q,
202165125e1SJens Axboe 				  struct elevator_type *e)
2033d1ab40fSAl Viro {
204b374d18aSJens Axboe 	struct elevator_queue *eq;
2059817064bSJens Axboe 	int i;
2069817064bSJens Axboe 
207b374d18aSJens Axboe 	eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node);
2089817064bSJens Axboe 	if (unlikely(!eq))
2099817064bSJens Axboe 		goto err;
2109817064bSJens Axboe 
2113d1ab40fSAl Viro 	eq->ops = &e->ops;
2123d1ab40fSAl Viro 	eq->elevator_type = e;
213f9cb074bSGreg Kroah-Hartman 	kobject_init(&eq->kobj, &elv_ktype);
2143d1ab40fSAl Viro 	mutex_init(&eq->sysfs_lock);
2159817064bSJens Axboe 
216b5deef90SJens Axboe 	eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
217b5deef90SJens Axboe 					GFP_KERNEL, q->node);
2189817064bSJens Axboe 	if (!eq->hash)
2199817064bSJens Axboe 		goto err;
2209817064bSJens Axboe 
2219817064bSJens Axboe 	for (i = 0; i < ELV_HASH_ENTRIES; i++)
2229817064bSJens Axboe 		INIT_HLIST_HEAD(&eq->hash[i]);
2239817064bSJens Axboe 
2243d1ab40fSAl Viro 	return eq;
2259817064bSJens Axboe err:
2269817064bSJens Axboe 	kfree(eq);
2279817064bSJens Axboe 	elevator_put(e);
2289817064bSJens Axboe 	return NULL;
2293d1ab40fSAl Viro }
2303d1ab40fSAl Viro 
2313d1ab40fSAl Viro static void elevator_release(struct kobject *kobj)
2323d1ab40fSAl Viro {
233b374d18aSJens Axboe 	struct elevator_queue *e;
2349817064bSJens Axboe 
235b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
2363d1ab40fSAl Viro 	elevator_put(e->elevator_type);
2379817064bSJens Axboe 	kfree(e->hash);
2383d1ab40fSAl Viro 	kfree(e);
2393d1ab40fSAl Viro }
2403d1ab40fSAl Viro 
241165125e1SJens Axboe int elevator_init(struct request_queue *q, char *name)
2421da177e4SLinus Torvalds {
2431da177e4SLinus Torvalds 	struct elevator_type *e = NULL;
2441da177e4SLinus Torvalds 	struct elevator_queue *eq;
2451da177e4SLinus Torvalds 	int ret = 0;
246bc1c1169SJens Axboe 	void *data;
2471da177e4SLinus Torvalds 
248cb98fc8bSTejun Heo 	INIT_LIST_HEAD(&q->queue_head);
249cb98fc8bSTejun Heo 	q->last_merge = NULL;
250cb98fc8bSTejun Heo 	q->end_sector = 0;
251cb98fc8bSTejun Heo 	q->boundary_rq = NULL;
252cb98fc8bSTejun Heo 
2534eb166d9SJens Axboe 	if (name) {
2544eb166d9SJens Axboe 		e = elevator_get(name);
2554eb166d9SJens Axboe 		if (!e)
2561da177e4SLinus Torvalds 			return -EINVAL;
2574eb166d9SJens Axboe 	}
2581da177e4SLinus Torvalds 
2594eb166d9SJens Axboe 	if (!e && *chosen_elevator) {
2604eb166d9SJens Axboe 		e = elevator_get(chosen_elevator);
2614eb166d9SJens Axboe 		if (!e)
2624eb166d9SJens Axboe 			printk(KERN_ERR "I/O scheduler %s not found\n",
2634eb166d9SJens Axboe 							chosen_elevator);
2644eb166d9SJens Axboe 	}
265248d5ca5SNate Diller 
2664eb166d9SJens Axboe 	if (!e) {
2674eb166d9SJens Axboe 		e = elevator_get(CONFIG_DEFAULT_IOSCHED);
2684eb166d9SJens Axboe 		if (!e) {
2694eb166d9SJens Axboe 			printk(KERN_ERR
2704eb166d9SJens Axboe 				"Default I/O scheduler not found. " \
2714eb166d9SJens Axboe 				"Using noop.\n");
272248d5ca5SNate Diller 			e = elevator_get("noop");
2735f003976SNate Diller 		}
2744eb166d9SJens Axboe 	}
2755f003976SNate Diller 
276b5deef90SJens Axboe 	eq = elevator_alloc(q, e);
2773d1ab40fSAl Viro 	if (!eq)
2781da177e4SLinus Torvalds 		return -ENOMEM;
2791da177e4SLinus Torvalds 
280bc1c1169SJens Axboe 	data = elevator_init_queue(q, eq);
281bc1c1169SJens Axboe 	if (!data) {
2823d1ab40fSAl Viro 		kobject_put(&eq->kobj);
283bc1c1169SJens Axboe 		return -ENOMEM;
284bc1c1169SJens Axboe 	}
2851da177e4SLinus Torvalds 
286bc1c1169SJens Axboe 	elevator_attach(q, eq, data);
2871da177e4SLinus Torvalds 	return ret;
2881da177e4SLinus Torvalds }
2892e662b65SJens Axboe EXPORT_SYMBOL(elevator_init);
2902e662b65SJens Axboe 
291b374d18aSJens Axboe void elevator_exit(struct elevator_queue *e)
2921da177e4SLinus Torvalds {
2933d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
2941da177e4SLinus Torvalds 	if (e->ops->elevator_exit_fn)
2951da177e4SLinus Torvalds 		e->ops->elevator_exit_fn(e);
2963d1ab40fSAl Viro 	e->ops = NULL;
2973d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
2981da177e4SLinus Torvalds 
2993d1ab40fSAl Viro 	kobject_put(&e->kobj);
3001da177e4SLinus Torvalds }
3012e662b65SJens Axboe EXPORT_SYMBOL(elevator_exit);
3022e662b65SJens Axboe 
3039817064bSJens Axboe static inline void __elv_rqhash_del(struct request *rq)
3049817064bSJens Axboe {
3059817064bSJens Axboe 	hlist_del_init(&rq->hash);
3069817064bSJens Axboe }
3079817064bSJens Axboe 
308165125e1SJens Axboe static void elv_rqhash_del(struct request_queue *q, struct request *rq)
3099817064bSJens Axboe {
3109817064bSJens Axboe 	if (ELV_ON_HASH(rq))
3119817064bSJens Axboe 		__elv_rqhash_del(rq);
3129817064bSJens Axboe }
3139817064bSJens Axboe 
314165125e1SJens Axboe static void elv_rqhash_add(struct request_queue *q, struct request *rq)
3159817064bSJens Axboe {
316b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
3179817064bSJens Axboe 
3189817064bSJens Axboe 	BUG_ON(ELV_ON_HASH(rq));
3199817064bSJens Axboe 	hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
3209817064bSJens Axboe }
3219817064bSJens Axboe 
322165125e1SJens Axboe static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
3239817064bSJens Axboe {
3249817064bSJens Axboe 	__elv_rqhash_del(rq);
3259817064bSJens Axboe 	elv_rqhash_add(q, rq);
3269817064bSJens Axboe }
3279817064bSJens Axboe 
328165125e1SJens Axboe static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
3299817064bSJens Axboe {
330b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
3319817064bSJens Axboe 	struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
3329817064bSJens Axboe 	struct hlist_node *entry, *next;
3339817064bSJens Axboe 	struct request *rq;
3349817064bSJens Axboe 
3359817064bSJens Axboe 	hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
3369817064bSJens Axboe 		BUG_ON(!ELV_ON_HASH(rq));
3379817064bSJens Axboe 
3389817064bSJens Axboe 		if (unlikely(!rq_mergeable(rq))) {
3399817064bSJens Axboe 			__elv_rqhash_del(rq);
3409817064bSJens Axboe 			continue;
3419817064bSJens Axboe 		}
3429817064bSJens Axboe 
3439817064bSJens Axboe 		if (rq_hash_key(rq) == offset)
3449817064bSJens Axboe 			return rq;
3459817064bSJens Axboe 	}
3469817064bSJens Axboe 
3479817064bSJens Axboe 	return NULL;
3489817064bSJens Axboe }
3499817064bSJens Axboe 
3508922e16cSTejun Heo /*
3512e662b65SJens Axboe  * RB-tree support functions for inserting/lookup/removal of requests
3522e662b65SJens Axboe  * in a sorted RB tree.
3532e662b65SJens Axboe  */
3542e662b65SJens Axboe struct request *elv_rb_add(struct rb_root *root, struct request *rq)
3552e662b65SJens Axboe {
3562e662b65SJens Axboe 	struct rb_node **p = &root->rb_node;
3572e662b65SJens Axboe 	struct rb_node *parent = NULL;
3582e662b65SJens Axboe 	struct request *__rq;
3592e662b65SJens Axboe 
3602e662b65SJens Axboe 	while (*p) {
3612e662b65SJens Axboe 		parent = *p;
3622e662b65SJens Axboe 		__rq = rb_entry(parent, struct request, rb_node);
3632e662b65SJens Axboe 
36483096ebfSTejun Heo 		if (blk_rq_pos(rq) < blk_rq_pos(__rq))
3652e662b65SJens Axboe 			p = &(*p)->rb_left;
36683096ebfSTejun Heo 		else if (blk_rq_pos(rq) > blk_rq_pos(__rq))
3672e662b65SJens Axboe 			p = &(*p)->rb_right;
3682e662b65SJens Axboe 		else
3692e662b65SJens Axboe 			return __rq;
3702e662b65SJens Axboe 	}
3712e662b65SJens Axboe 
3722e662b65SJens Axboe 	rb_link_node(&rq->rb_node, parent, p);
3732e662b65SJens Axboe 	rb_insert_color(&rq->rb_node, root);
3742e662b65SJens Axboe 	return NULL;
3752e662b65SJens Axboe }
3762e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_add);
3772e662b65SJens Axboe 
3782e662b65SJens Axboe void elv_rb_del(struct rb_root *root, struct request *rq)
3792e662b65SJens Axboe {
3802e662b65SJens Axboe 	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
3812e662b65SJens Axboe 	rb_erase(&rq->rb_node, root);
3822e662b65SJens Axboe 	RB_CLEAR_NODE(&rq->rb_node);
3832e662b65SJens Axboe }
3842e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_del);
3852e662b65SJens Axboe 
3862e662b65SJens Axboe struct request *elv_rb_find(struct rb_root *root, sector_t sector)
3872e662b65SJens Axboe {
3882e662b65SJens Axboe 	struct rb_node *n = root->rb_node;
3892e662b65SJens Axboe 	struct request *rq;
3902e662b65SJens Axboe 
3912e662b65SJens Axboe 	while (n) {
3922e662b65SJens Axboe 		rq = rb_entry(n, struct request, rb_node);
3932e662b65SJens Axboe 
39483096ebfSTejun Heo 		if (sector < blk_rq_pos(rq))
3952e662b65SJens Axboe 			n = n->rb_left;
39683096ebfSTejun Heo 		else if (sector > blk_rq_pos(rq))
3972e662b65SJens Axboe 			n = n->rb_right;
3982e662b65SJens Axboe 		else
3992e662b65SJens Axboe 			return rq;
4002e662b65SJens Axboe 	}
4012e662b65SJens Axboe 
4022e662b65SJens Axboe 	return NULL;
4032e662b65SJens Axboe }
4042e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_find);
4052e662b65SJens Axboe 
4062e662b65SJens Axboe /*
4078922e16cSTejun Heo  * Insert rq into dispatch queue of q.  Queue lock must be held on
408dbe7f76dSUwe Kleine-König  * entry.  rq is sort instead into the dispatch queue. To be used by
4092e662b65SJens Axboe  * specific elevators.
4108922e16cSTejun Heo  */
411165125e1SJens Axboe void elv_dispatch_sort(struct request_queue *q, struct request *rq)
4128922e16cSTejun Heo {
4138922e16cSTejun Heo 	sector_t boundary;
4148922e16cSTejun Heo 	struct list_head *entry;
4154eb166d9SJens Axboe 	int stop_flags;
4168922e16cSTejun Heo 
41706b86245STejun Heo 	if (q->last_merge == rq)
41806b86245STejun Heo 		q->last_merge = NULL;
4199817064bSJens Axboe 
4209817064bSJens Axboe 	elv_rqhash_del(q, rq);
4219817064bSJens Axboe 
42215853af9STejun Heo 	q->nr_sorted--;
42306b86245STejun Heo 
4241b47f531SJens Axboe 	boundary = q->end_sector;
4254eb166d9SJens Axboe 	stop_flags = REQ_SOFTBARRIER | REQ_HARDBARRIER | REQ_STARTED;
4268922e16cSTejun Heo 	list_for_each_prev(entry, &q->queue_head) {
4278922e16cSTejun Heo 		struct request *pos = list_entry_rq(entry);
4288922e16cSTejun Heo 
429e17fc0a1SDavid Woodhouse 		if (blk_discard_rq(rq) != blk_discard_rq(pos))
430e17fc0a1SDavid Woodhouse 			break;
431783660b2SJens Axboe 		if (rq_data_dir(rq) != rq_data_dir(pos))
432783660b2SJens Axboe 			break;
4334eb166d9SJens Axboe 		if (pos->cmd_flags & stop_flags)
4348922e16cSTejun Heo 			break;
43583096ebfSTejun Heo 		if (blk_rq_pos(rq) >= boundary) {
43683096ebfSTejun Heo 			if (blk_rq_pos(pos) < boundary)
4378922e16cSTejun Heo 				continue;
4388922e16cSTejun Heo 		} else {
43983096ebfSTejun Heo 			if (blk_rq_pos(pos) >= boundary)
4408922e16cSTejun Heo 				break;
4418922e16cSTejun Heo 		}
44283096ebfSTejun Heo 		if (blk_rq_pos(rq) >= blk_rq_pos(pos))
4438922e16cSTejun Heo 			break;
4448922e16cSTejun Heo 	}
4458922e16cSTejun Heo 
4468922e16cSTejun Heo 	list_add(&rq->queuelist, entry);
4478922e16cSTejun Heo }
4482e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_sort);
4492e662b65SJens Axboe 
4509817064bSJens Axboe /*
4512e662b65SJens Axboe  * Insert rq into dispatch queue of q.  Queue lock must be held on
4522e662b65SJens Axboe  * entry.  rq is added to the back of the dispatch queue. To be used by
4532e662b65SJens Axboe  * specific elevators.
4549817064bSJens Axboe  */
4559817064bSJens Axboe void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
4569817064bSJens Axboe {
4579817064bSJens Axboe 	if (q->last_merge == rq)
4589817064bSJens Axboe 		q->last_merge = NULL;
4599817064bSJens Axboe 
4609817064bSJens Axboe 	elv_rqhash_del(q, rq);
4619817064bSJens Axboe 
4629817064bSJens Axboe 	q->nr_sorted--;
4639817064bSJens Axboe 
4649817064bSJens Axboe 	q->end_sector = rq_end_sector(rq);
4659817064bSJens Axboe 	q->boundary_rq = rq;
4669817064bSJens Axboe 	list_add_tail(&rq->queuelist, &q->queue_head);
4679817064bSJens Axboe }
4682e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_add_tail);
4692e662b65SJens Axboe 
470165125e1SJens Axboe int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
4711da177e4SLinus Torvalds {
472b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
4739817064bSJens Axboe 	struct request *__rq;
47406b86245STejun Heo 	int ret;
47506b86245STejun Heo 
4769817064bSJens Axboe 	/*
477488991e2SAlan D. Brunelle 	 * Levels of merges:
478488991e2SAlan D. Brunelle 	 * 	nomerges:  No merges at all attempted
479488991e2SAlan D. Brunelle 	 * 	noxmerges: Only simple one-hit cache try
480488991e2SAlan D. Brunelle 	 * 	merges:	   All merge tries attempted
481488991e2SAlan D. Brunelle 	 */
482488991e2SAlan D. Brunelle 	if (blk_queue_nomerges(q))
483488991e2SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
484488991e2SAlan D. Brunelle 
485488991e2SAlan D. Brunelle 	/*
4869817064bSJens Axboe 	 * First try one-hit cache.
4879817064bSJens Axboe 	 */
48806b86245STejun Heo 	if (q->last_merge) {
48906b86245STejun Heo 		ret = elv_try_merge(q->last_merge, bio);
49006b86245STejun Heo 		if (ret != ELEVATOR_NO_MERGE) {
49106b86245STejun Heo 			*req = q->last_merge;
49206b86245STejun Heo 			return ret;
49306b86245STejun Heo 		}
49406b86245STejun Heo 	}
4951da177e4SLinus Torvalds 
496488991e2SAlan D. Brunelle 	if (blk_queue_noxmerges(q))
497ac9fafa1SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
498ac9fafa1SAlan D. Brunelle 
4999817064bSJens Axboe 	/*
5009817064bSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
5019817064bSJens Axboe 	 */
5029817064bSJens Axboe 	__rq = elv_rqhash_find(q, bio->bi_sector);
5039817064bSJens Axboe 	if (__rq && elv_rq_merge_ok(__rq, bio)) {
5049817064bSJens Axboe 		*req = __rq;
5059817064bSJens Axboe 		return ELEVATOR_BACK_MERGE;
5069817064bSJens Axboe 	}
5079817064bSJens Axboe 
5081da177e4SLinus Torvalds 	if (e->ops->elevator_merge_fn)
5091da177e4SLinus Torvalds 		return e->ops->elevator_merge_fn(q, req, bio);
5101da177e4SLinus Torvalds 
5111da177e4SLinus Torvalds 	return ELEVATOR_NO_MERGE;
5121da177e4SLinus Torvalds }
5131da177e4SLinus Torvalds 
514165125e1SJens Axboe void elv_merged_request(struct request_queue *q, struct request *rq, int type)
5151da177e4SLinus Torvalds {
516b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5171da177e4SLinus Torvalds 
5181da177e4SLinus Torvalds 	if (e->ops->elevator_merged_fn)
5192e662b65SJens Axboe 		e->ops->elevator_merged_fn(q, rq, type);
52006b86245STejun Heo 
5212e662b65SJens Axboe 	if (type == ELEVATOR_BACK_MERGE)
5229817064bSJens Axboe 		elv_rqhash_reposition(q, rq);
5239817064bSJens Axboe 
52406b86245STejun Heo 	q->last_merge = rq;
5251da177e4SLinus Torvalds }
5261da177e4SLinus Torvalds 
527165125e1SJens Axboe void elv_merge_requests(struct request_queue *q, struct request *rq,
5281da177e4SLinus Torvalds 			     struct request *next)
5291da177e4SLinus Torvalds {
530b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5311da177e4SLinus Torvalds 
5321da177e4SLinus Torvalds 	if (e->ops->elevator_merge_req_fn)
5331da177e4SLinus Torvalds 		e->ops->elevator_merge_req_fn(q, rq, next);
53406b86245STejun Heo 
5359817064bSJens Axboe 	elv_rqhash_reposition(q, rq);
5369817064bSJens Axboe 	elv_rqhash_del(q, next);
5379817064bSJens Axboe 
5389817064bSJens Axboe 	q->nr_sorted--;
53906b86245STejun Heo 	q->last_merge = rq;
5401da177e4SLinus Torvalds }
5411da177e4SLinus Torvalds 
542812d4026SDivyesh Shah void elv_bio_merged(struct request_queue *q, struct request *rq,
543812d4026SDivyesh Shah 			struct bio *bio)
544812d4026SDivyesh Shah {
545812d4026SDivyesh Shah 	struct elevator_queue *e = q->elevator;
546812d4026SDivyesh Shah 
547812d4026SDivyesh Shah 	if (e->ops->elevator_bio_merged_fn)
548812d4026SDivyesh Shah 		e->ops->elevator_bio_merged_fn(q, rq, bio);
549812d4026SDivyesh Shah }
550812d4026SDivyesh Shah 
551165125e1SJens Axboe void elv_requeue_request(struct request_queue *q, struct request *rq)
5521da177e4SLinus Torvalds {
5531da177e4SLinus Torvalds 	/*
5541da177e4SLinus Torvalds 	 * it already went through dequeue, we need to decrement the
5551da177e4SLinus Torvalds 	 * in_flight count again
5561da177e4SLinus Torvalds 	 */
5578922e16cSTejun Heo 	if (blk_account_rq(rq)) {
5580a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
559cad97516SJens Axboe 		if (blk_sorted_rq(rq))
560cad97516SJens Axboe 			elv_deactivate_rq(q, rq);
5611da177e4SLinus Torvalds 	}
5621da177e4SLinus Torvalds 
5634aff5e23SJens Axboe 	rq->cmd_flags &= ~REQ_STARTED;
5641da177e4SLinus Torvalds 
56530e9656cSTejun Heo 	elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
5661da177e4SLinus Torvalds }
5671da177e4SLinus Torvalds 
56826308eabSJerome Marchand void elv_drain_elevator(struct request_queue *q)
56915853af9STejun Heo {
57015853af9STejun Heo 	static int printed;
57115853af9STejun Heo 	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
57215853af9STejun Heo 		;
57315853af9STejun Heo 	if (q->nr_sorted == 0)
57415853af9STejun Heo 		return;
57515853af9STejun Heo 	if (printed++ < 10) {
57615853af9STejun Heo 		printk(KERN_ERR "%s: forced dispatching is broken "
57715853af9STejun Heo 		       "(nr_sorted=%u), please report this\n",
57815853af9STejun Heo 		       q->elevator->elevator_type->elevator_name, q->nr_sorted);
57915853af9STejun Heo 	}
58015853af9STejun Heo }
58115853af9STejun Heo 
5826c7e8ceeSJens Axboe /*
5836c7e8ceeSJens Axboe  * Call with queue lock held, interrupts disabled
5846c7e8ceeSJens Axboe  */
585f600abe2SJens Axboe void elv_quiesce_start(struct request_queue *q)
5866c7e8ceeSJens Axboe {
587cd43e26fSMartin K. Petersen 	if (!q->elevator)
588cd43e26fSMartin K. Petersen 		return;
589cd43e26fSMartin K. Petersen 
5906c7e8ceeSJens Axboe 	queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
5916c7e8ceeSJens Axboe 
5926c7e8ceeSJens Axboe 	/*
5936c7e8ceeSJens Axboe 	 * make sure we don't have any requests in flight
5946c7e8ceeSJens Axboe 	 */
5956c7e8ceeSJens Axboe 	elv_drain_elevator(q);
5966c7e8ceeSJens Axboe 	while (q->rq.elvpriv) {
597a7f55792STejun Heo 		__blk_run_queue(q);
5986c7e8ceeSJens Axboe 		spin_unlock_irq(q->queue_lock);
5996c7e8ceeSJens Axboe 		msleep(10);
6006c7e8ceeSJens Axboe 		spin_lock_irq(q->queue_lock);
6016c7e8ceeSJens Axboe 		elv_drain_elevator(q);
6026c7e8ceeSJens Axboe 	}
6036c7e8ceeSJens Axboe }
6046c7e8ceeSJens Axboe 
605f600abe2SJens Axboe void elv_quiesce_end(struct request_queue *q)
6066c7e8ceeSJens Axboe {
6076c7e8ceeSJens Axboe 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
6086c7e8ceeSJens Axboe }
6096c7e8ceeSJens Axboe 
610165125e1SJens Axboe void elv_insert(struct request_queue *q, struct request *rq, int where)
6111da177e4SLinus Torvalds {
612797e7dbbSTejun Heo 	struct list_head *pos;
613797e7dbbSTejun Heo 	unsigned ordseq;
614dac07ec1SJens Axboe 	int unplug_it = 1;
615797e7dbbSTejun Heo 
6165f3ea37cSArnaldo Carvalho de Melo 	trace_block_rq_insert(q, rq);
6172056a782SJens Axboe 
6181da177e4SLinus Torvalds 	rq->q = q;
6191da177e4SLinus Torvalds 
6208922e16cSTejun Heo 	switch (where) {
6218922e16cSTejun Heo 	case ELEVATOR_INSERT_FRONT:
6224aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
6238922e16cSTejun Heo 
6248922e16cSTejun Heo 		list_add(&rq->queuelist, &q->queue_head);
6258922e16cSTejun Heo 		break;
6268922e16cSTejun Heo 
6278922e16cSTejun Heo 	case ELEVATOR_INSERT_BACK:
6284aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
62915853af9STejun Heo 		elv_drain_elevator(q);
6308922e16cSTejun Heo 		list_add_tail(&rq->queuelist, &q->queue_head);
6318922e16cSTejun Heo 		/*
6328922e16cSTejun Heo 		 * We kick the queue here for the following reasons.
6338922e16cSTejun Heo 		 * - The elevator might have returned NULL previously
6348922e16cSTejun Heo 		 *   to delay requests and returned them now.  As the
6358922e16cSTejun Heo 		 *   queue wasn't empty before this request, ll_rw_blk
6368922e16cSTejun Heo 		 *   won't run the queue on return, resulting in hang.
6378922e16cSTejun Heo 		 * - Usually, back inserted requests won't be merged
6388922e16cSTejun Heo 		 *   with anything.  There's no point in delaying queue
6398922e16cSTejun Heo 		 *   processing.
6408922e16cSTejun Heo 		 */
641a7f55792STejun Heo 		__blk_run_queue(q);
6428922e16cSTejun Heo 		break;
6438922e16cSTejun Heo 
6448922e16cSTejun Heo 	case ELEVATOR_INSERT_SORT:
645e17fc0a1SDavid Woodhouse 		BUG_ON(!blk_fs_request(rq) && !blk_discard_rq(rq));
6464aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SORTED;
64715853af9STejun Heo 		q->nr_sorted++;
6489817064bSJens Axboe 		if (rq_mergeable(rq)) {
6499817064bSJens Axboe 			elv_rqhash_add(q, rq);
6509817064bSJens Axboe 			if (!q->last_merge)
65106b86245STejun Heo 				q->last_merge = rq;
6529817064bSJens Axboe 		}
6539817064bSJens Axboe 
654ca23509fSTejun Heo 		/*
655ca23509fSTejun Heo 		 * Some ioscheds (cfq) run q->request_fn directly, so
656ca23509fSTejun Heo 		 * rq cannot be accessed after calling
657ca23509fSTejun Heo 		 * elevator_add_req_fn.
658ca23509fSTejun Heo 		 */
659ca23509fSTejun Heo 		q->elevator->ops->elevator_add_req_fn(q, rq);
6608922e16cSTejun Heo 		break;
6618922e16cSTejun Heo 
662797e7dbbSTejun Heo 	case ELEVATOR_INSERT_REQUEUE:
663797e7dbbSTejun Heo 		/*
664797e7dbbSTejun Heo 		 * If ordered flush isn't in progress, we do front
665797e7dbbSTejun Heo 		 * insertion; otherwise, requests should be requeued
666797e7dbbSTejun Heo 		 * in ordseq order.
667797e7dbbSTejun Heo 		 */
6684aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
669797e7dbbSTejun Heo 
67095543179SLinas Vepstas 		/*
67195543179SLinas Vepstas 		 * Most requeues happen because of a busy condition,
67295543179SLinas Vepstas 		 * don't force unplug of the queue for that case.
67395543179SLinas Vepstas 		 */
67495543179SLinas Vepstas 		unplug_it = 0;
67595543179SLinas Vepstas 
676797e7dbbSTejun Heo 		if (q->ordseq == 0) {
677797e7dbbSTejun Heo 			list_add(&rq->queuelist, &q->queue_head);
678797e7dbbSTejun Heo 			break;
679797e7dbbSTejun Heo 		}
680797e7dbbSTejun Heo 
681797e7dbbSTejun Heo 		ordseq = blk_ordered_req_seq(rq);
682797e7dbbSTejun Heo 
683797e7dbbSTejun Heo 		list_for_each(pos, &q->queue_head) {
684797e7dbbSTejun Heo 			struct request *pos_rq = list_entry_rq(pos);
685797e7dbbSTejun Heo 			if (ordseq <= blk_ordered_req_seq(pos_rq))
686797e7dbbSTejun Heo 				break;
687797e7dbbSTejun Heo 		}
688797e7dbbSTejun Heo 
689797e7dbbSTejun Heo 		list_add_tail(&rq->queuelist, pos);
690797e7dbbSTejun Heo 		break;
691797e7dbbSTejun Heo 
6928922e16cSTejun Heo 	default:
6938922e16cSTejun Heo 		printk(KERN_ERR "%s: bad insertion point %d\n",
69424c03d47SHarvey Harrison 		       __func__, where);
6958922e16cSTejun Heo 		BUG();
6968922e16cSTejun Heo 	}
6971da177e4SLinus Torvalds 
698dac07ec1SJens Axboe 	if (unplug_it && blk_queue_plugged(q)) {
6991faa16d2SJens Axboe 		int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
7000a7ae2ffSJens Axboe 				- queue_in_flight(q);
7011da177e4SLinus Torvalds 
702c374f127STejun Heo  		if (nrq >= q->unplug_thresh)
7031da177e4SLinus Torvalds 			__generic_unplug_device(q);
7041da177e4SLinus Torvalds 	}
7051da177e4SLinus Torvalds }
7061da177e4SLinus Torvalds 
707165125e1SJens Axboe void __elv_add_request(struct request_queue *q, struct request *rq, int where,
70830e9656cSTejun Heo 		       int plug)
70930e9656cSTejun Heo {
71030e9656cSTejun Heo 	if (q->ordcolor)
7114aff5e23SJens Axboe 		rq->cmd_flags |= REQ_ORDERED_COLOR;
71230e9656cSTejun Heo 
7134aff5e23SJens Axboe 	if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
71430e9656cSTejun Heo 		/*
71530e9656cSTejun Heo 		 * toggle ordered color
71630e9656cSTejun Heo 		 */
71730e9656cSTejun Heo 		if (blk_barrier_rq(rq))
71830e9656cSTejun Heo 			q->ordcolor ^= 1;
71930e9656cSTejun Heo 
72030e9656cSTejun Heo 		/*
72130e9656cSTejun Heo 		 * barriers implicitly indicate back insertion
72230e9656cSTejun Heo 		 */
72330e9656cSTejun Heo 		if (where == ELEVATOR_INSERT_SORT)
72430e9656cSTejun Heo 			where = ELEVATOR_INSERT_BACK;
72530e9656cSTejun Heo 
72630e9656cSTejun Heo 		/*
72730e9656cSTejun Heo 		 * this request is scheduling boundary, update
72830e9656cSTejun Heo 		 * end_sector
72930e9656cSTejun Heo 		 */
730e17fc0a1SDavid Woodhouse 		if (blk_fs_request(rq) || blk_discard_rq(rq)) {
73130e9656cSTejun Heo 			q->end_sector = rq_end_sector(rq);
73230e9656cSTejun Heo 			q->boundary_rq = rq;
73330e9656cSTejun Heo 		}
7344eb166d9SJens Axboe 	} else if (!(rq->cmd_flags & REQ_ELVPRIV) &&
7354eb166d9SJens Axboe 		    where == ELEVATOR_INSERT_SORT)
73630e9656cSTejun Heo 		where = ELEVATOR_INSERT_BACK;
73730e9656cSTejun Heo 
73830e9656cSTejun Heo 	if (plug)
73930e9656cSTejun Heo 		blk_plug_device(q);
74030e9656cSTejun Heo 
74130e9656cSTejun Heo 	elv_insert(q, rq, where);
74230e9656cSTejun Heo }
7432e662b65SJens Axboe EXPORT_SYMBOL(__elv_add_request);
7442e662b65SJens Axboe 
745165125e1SJens Axboe void elv_add_request(struct request_queue *q, struct request *rq, int where,
7461da177e4SLinus Torvalds 		     int plug)
7471da177e4SLinus Torvalds {
7481da177e4SLinus Torvalds 	unsigned long flags;
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	spin_lock_irqsave(q->queue_lock, flags);
7511da177e4SLinus Torvalds 	__elv_add_request(q, rq, where, plug);
7521da177e4SLinus Torvalds 	spin_unlock_irqrestore(q->queue_lock, flags);
7531da177e4SLinus Torvalds }
7542e662b65SJens Axboe EXPORT_SYMBOL(elv_add_request);
7552e662b65SJens Axboe 
756165125e1SJens Axboe int elv_queue_empty(struct request_queue *q)
7571da177e4SLinus Torvalds {
758b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7591da177e4SLinus Torvalds 
7608922e16cSTejun Heo 	if (!list_empty(&q->queue_head))
7618922e16cSTejun Heo 		return 0;
7628922e16cSTejun Heo 
7631da177e4SLinus Torvalds 	if (e->ops->elevator_queue_empty_fn)
7641da177e4SLinus Torvalds 		return e->ops->elevator_queue_empty_fn(q);
7651da177e4SLinus Torvalds 
7668922e16cSTejun Heo 	return 1;
7671da177e4SLinus Torvalds }
7682e662b65SJens Axboe EXPORT_SYMBOL(elv_queue_empty);
7692e662b65SJens Axboe 
770165125e1SJens Axboe struct request *elv_latter_request(struct request_queue *q, struct request *rq)
7711da177e4SLinus Torvalds {
772b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7731da177e4SLinus Torvalds 
7741da177e4SLinus Torvalds 	if (e->ops->elevator_latter_req_fn)
7751da177e4SLinus Torvalds 		return e->ops->elevator_latter_req_fn(q, rq);
7761da177e4SLinus Torvalds 	return NULL;
7771da177e4SLinus Torvalds }
7781da177e4SLinus Torvalds 
779165125e1SJens Axboe struct request *elv_former_request(struct request_queue *q, struct request *rq)
7801da177e4SLinus Torvalds {
781b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7821da177e4SLinus Torvalds 
7831da177e4SLinus Torvalds 	if (e->ops->elevator_former_req_fn)
7841da177e4SLinus Torvalds 		return e->ops->elevator_former_req_fn(q, rq);
7851da177e4SLinus Torvalds 	return NULL;
7861da177e4SLinus Torvalds }
7871da177e4SLinus Torvalds 
788165125e1SJens Axboe int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
7891da177e4SLinus Torvalds {
790b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7911da177e4SLinus Torvalds 
7921da177e4SLinus Torvalds 	if (e->ops->elevator_set_req_fn)
793cb78b285SJens Axboe 		return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
7941da177e4SLinus Torvalds 
7951da177e4SLinus Torvalds 	rq->elevator_private = NULL;
7961da177e4SLinus Torvalds 	return 0;
7971da177e4SLinus Torvalds }
7981da177e4SLinus Torvalds 
799165125e1SJens Axboe void elv_put_request(struct request_queue *q, struct request *rq)
8001da177e4SLinus Torvalds {
801b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8021da177e4SLinus Torvalds 
8031da177e4SLinus Torvalds 	if (e->ops->elevator_put_req_fn)
804bb37b94cSJens Axboe 		e->ops->elevator_put_req_fn(rq);
8051da177e4SLinus Torvalds }
8061da177e4SLinus Torvalds 
807165125e1SJens Axboe int elv_may_queue(struct request_queue *q, int rw)
8081da177e4SLinus Torvalds {
809b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8101da177e4SLinus Torvalds 
8111da177e4SLinus Torvalds 	if (e->ops->elevator_may_queue_fn)
812cb78b285SJens Axboe 		return e->ops->elevator_may_queue_fn(q, rw);
8131da177e4SLinus Torvalds 
8141da177e4SLinus Torvalds 	return ELV_MQUEUE_MAY;
8151da177e4SLinus Torvalds }
8161da177e4SLinus Torvalds 
81711914a53SMike Anderson void elv_abort_queue(struct request_queue *q)
81811914a53SMike Anderson {
81911914a53SMike Anderson 	struct request *rq;
82011914a53SMike Anderson 
82111914a53SMike Anderson 	while (!list_empty(&q->queue_head)) {
82211914a53SMike Anderson 		rq = list_entry_rq(q->queue_head.next);
82311914a53SMike Anderson 		rq->cmd_flags |= REQ_QUIET;
8245f3ea37cSArnaldo Carvalho de Melo 		trace_block_rq_abort(q, rq);
82553c663ceSKiyoshi Ueda 		/*
82653c663ceSKiyoshi Ueda 		 * Mark this request as started so we don't trigger
82753c663ceSKiyoshi Ueda 		 * any debug logic in the end I/O path.
82853c663ceSKiyoshi Ueda 		 */
82953c663ceSKiyoshi Ueda 		blk_start_request(rq);
83040cbbb78STejun Heo 		__blk_end_request_all(rq, -EIO);
83111914a53SMike Anderson 	}
83211914a53SMike Anderson }
83311914a53SMike Anderson EXPORT_SYMBOL(elv_abort_queue);
83411914a53SMike Anderson 
835165125e1SJens Axboe void elv_completed_request(struct request_queue *q, struct request *rq)
8361da177e4SLinus Torvalds {
837b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8381da177e4SLinus Torvalds 
8391da177e4SLinus Torvalds 	/*
8401da177e4SLinus Torvalds 	 * request is released from the driver, io must be done
8411da177e4SLinus Torvalds 	 */
8428922e16cSTejun Heo 	if (blk_account_rq(rq)) {
8430a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
8441bc691d3STejun Heo 		if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
8451bc691d3STejun Heo 			e->ops->elevator_completed_req_fn(q, rq);
8461bc691d3STejun Heo 	}
847797e7dbbSTejun Heo 
848797e7dbbSTejun Heo 	/*
849797e7dbbSTejun Heo 	 * Check if the queue is waiting for fs requests to be
850797e7dbbSTejun Heo 	 * drained for flush sequence.
851797e7dbbSTejun Heo 	 */
8521bc691d3STejun Heo 	if (unlikely(q->ordseq)) {
8538f11b3e9STejun Heo 		struct request *next = NULL;
8548f11b3e9STejun Heo 
8558f11b3e9STejun Heo 		if (!list_empty(&q->queue_head))
8568f11b3e9STejun Heo 			next = list_entry_rq(q->queue_head.next);
8578f11b3e9STejun Heo 
8580a7ae2ffSJens Axboe 		if (!queue_in_flight(q) &&
859797e7dbbSTejun Heo 		    blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
8608f11b3e9STejun Heo 		    (!next || blk_ordered_req_seq(next) > QUEUE_ORDSEQ_DRAIN)) {
861797e7dbbSTejun Heo 			blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
862a7f55792STejun Heo 			__blk_run_queue(q);
863797e7dbbSTejun Heo 		}
8641da177e4SLinus Torvalds 	}
8658922e16cSTejun Heo }
8661da177e4SLinus Torvalds 
8673d1ab40fSAl Viro #define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
8683d1ab40fSAl Viro 
8693d1ab40fSAl Viro static ssize_t
8703d1ab40fSAl Viro elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
8713d1ab40fSAl Viro {
8723d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
873b374d18aSJens Axboe 	struct elevator_queue *e;
8743d1ab40fSAl Viro 	ssize_t error;
8753d1ab40fSAl Viro 
8763d1ab40fSAl Viro 	if (!entry->show)
8773d1ab40fSAl Viro 		return -EIO;
8783d1ab40fSAl Viro 
879b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8803d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8813d1ab40fSAl Viro 	error = e->ops ? entry->show(e, page) : -ENOENT;
8823d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
8833d1ab40fSAl Viro 	return error;
8843d1ab40fSAl Viro }
8853d1ab40fSAl Viro 
8863d1ab40fSAl Viro static ssize_t
8873d1ab40fSAl Viro elv_attr_store(struct kobject *kobj, struct attribute *attr,
8883d1ab40fSAl Viro 	       const char *page, size_t length)
8893d1ab40fSAl Viro {
8903d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
891b374d18aSJens Axboe 	struct elevator_queue *e;
8923d1ab40fSAl Viro 	ssize_t error;
8933d1ab40fSAl Viro 
8943d1ab40fSAl Viro 	if (!entry->store)
8953d1ab40fSAl Viro 		return -EIO;
8963d1ab40fSAl Viro 
897b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8983d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8993d1ab40fSAl Viro 	error = e->ops ? entry->store(e, page, length) : -ENOENT;
9003d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
9013d1ab40fSAl Viro 	return error;
9023d1ab40fSAl Viro }
9033d1ab40fSAl Viro 
90452cf25d0SEmese Revfy static const struct sysfs_ops elv_sysfs_ops = {
9053d1ab40fSAl Viro 	.show	= elv_attr_show,
9063d1ab40fSAl Viro 	.store	= elv_attr_store,
9073d1ab40fSAl Viro };
9083d1ab40fSAl Viro 
9093d1ab40fSAl Viro static struct kobj_type elv_ktype = {
9103d1ab40fSAl Viro 	.sysfs_ops	= &elv_sysfs_ops,
9113d1ab40fSAl Viro 	.release	= elevator_release,
9123d1ab40fSAl Viro };
9133d1ab40fSAl Viro 
9141da177e4SLinus Torvalds int elv_register_queue(struct request_queue *q)
9151da177e4SLinus Torvalds {
916b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
9173d1ab40fSAl Viro 	int error;
9181da177e4SLinus Torvalds 
919b2d6db58SGreg Kroah-Hartman 	error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
9203d1ab40fSAl Viro 	if (!error) {
921e572ec7eSAl Viro 		struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
9223d1ab40fSAl Viro 		if (attr) {
923e572ec7eSAl Viro 			while (attr->attr.name) {
924e572ec7eSAl Viro 				if (sysfs_create_file(&e->kobj, &attr->attr))
9253d1ab40fSAl Viro 					break;
926e572ec7eSAl Viro 				attr++;
9273d1ab40fSAl Viro 			}
9283d1ab40fSAl Viro 		}
9293d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_ADD);
9303d1ab40fSAl Viro 	}
9313d1ab40fSAl Viro 	return error;
9321da177e4SLinus Torvalds }
933*01effb0dSMike Snitzer EXPORT_SYMBOL(elv_register_queue);
9341da177e4SLinus Torvalds 
935b374d18aSJens Axboe static void __elv_unregister_queue(struct elevator_queue *e)
9361da177e4SLinus Torvalds {
9373d1ab40fSAl Viro 	kobject_uevent(&e->kobj, KOBJ_REMOVE);
9383d1ab40fSAl Viro 	kobject_del(&e->kobj);
9391da177e4SLinus Torvalds }
940bc1c1169SJens Axboe 
941bc1c1169SJens Axboe void elv_unregister_queue(struct request_queue *q)
942bc1c1169SJens Axboe {
943bc1c1169SJens Axboe 	if (q)
944bc1c1169SJens Axboe 		__elv_unregister_queue(q->elevator);
9451da177e4SLinus Torvalds }
946*01effb0dSMike Snitzer EXPORT_SYMBOL(elv_unregister_queue);
9471da177e4SLinus Torvalds 
9482fdd82bdSAdrian Bunk void elv_register(struct elevator_type *e)
9491da177e4SLinus Torvalds {
9501ffb96c5SThibaut VARENE 	char *def = "";
9512a12dcd7SJens Axboe 
9522a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
953ce524497SEric Sesterhenn 	BUG_ON(elevator_find(e->elevator_name));
9541da177e4SLinus Torvalds 	list_add_tail(&e->list, &elv_list);
9552a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9561da177e4SLinus Torvalds 
9575f003976SNate Diller 	if (!strcmp(e->elevator_name, chosen_elevator) ||
9585f003976SNate Diller 			(!*chosen_elevator &&
9595f003976SNate Diller 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
9601ffb96c5SThibaut VARENE 				def = " (default)";
9611ffb96c5SThibaut VARENE 
9624eb166d9SJens Axboe 	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
9634eb166d9SJens Axboe 								def);
9641da177e4SLinus Torvalds }
9651da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_register);
9661da177e4SLinus Torvalds 
9671da177e4SLinus Torvalds void elv_unregister(struct elevator_type *e)
9681da177e4SLinus Torvalds {
96983521d3eSChristoph Hellwig 	struct task_struct *g, *p;
97083521d3eSChristoph Hellwig 
97183521d3eSChristoph Hellwig 	/*
97283521d3eSChristoph Hellwig 	 * Iterate every thread in the process to remove the io contexts.
97383521d3eSChristoph Hellwig 	 */
974e17a9489SAl Viro 	if (e->ops.trim) {
97583521d3eSChristoph Hellwig 		read_lock(&tasklist_lock);
97683521d3eSChristoph Hellwig 		do_each_thread(g, p) {
977e17a9489SAl Viro 			task_lock(p);
9782d8f6131SOleg Nesterov 			if (p->io_context)
979e17a9489SAl Viro 				e->ops.trim(p->io_context);
980e17a9489SAl Viro 			task_unlock(p);
98183521d3eSChristoph Hellwig 		} while_each_thread(g, p);
98283521d3eSChristoph Hellwig 		read_unlock(&tasklist_lock);
983e17a9489SAl Viro 	}
98483521d3eSChristoph Hellwig 
9852a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
9861da177e4SLinus Torvalds 	list_del_init(&e->list);
9872a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9881da177e4SLinus Torvalds }
9891da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_unregister);
9901da177e4SLinus Torvalds 
9911da177e4SLinus Torvalds /*
9921da177e4SLinus Torvalds  * switch to new_e io scheduler. be careful not to introduce deadlocks -
9931da177e4SLinus Torvalds  * we don't free the old io scheduler, before we have allocated what we
9941da177e4SLinus Torvalds  * need for the new one. this way we have a chance of going back to the old
995cb98fc8bSTejun Heo  * one, if the new one fails init for some reason.
9961da177e4SLinus Torvalds  */
997165125e1SJens Axboe static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
9981da177e4SLinus Torvalds {
999b374d18aSJens Axboe 	struct elevator_queue *old_elevator, *e;
1000bc1c1169SJens Axboe 	void *data;
10011da177e4SLinus Torvalds 
1002cb98fc8bSTejun Heo 	/*
1003cb98fc8bSTejun Heo 	 * Allocate new elevator
1004cb98fc8bSTejun Heo 	 */
1005b5deef90SJens Axboe 	e = elevator_alloc(q, new_e);
10061da177e4SLinus Torvalds 	if (!e)
10073d1ab40fSAl Viro 		return 0;
10081da177e4SLinus Torvalds 
1009bc1c1169SJens Axboe 	data = elevator_init_queue(q, e);
1010bc1c1169SJens Axboe 	if (!data) {
1011bc1c1169SJens Axboe 		kobject_put(&e->kobj);
1012bc1c1169SJens Axboe 		return 0;
1013bc1c1169SJens Axboe 	}
1014bc1c1169SJens Axboe 
10151da177e4SLinus Torvalds 	/*
1016cb98fc8bSTejun Heo 	 * Turn on BYPASS and drain all requests w/ elevator private data
10171da177e4SLinus Torvalds 	 */
1018cb98fc8bSTejun Heo 	spin_lock_irq(q->queue_lock);
1019f600abe2SJens Axboe 	elv_quiesce_start(q);
1020cb98fc8bSTejun Heo 
10211da177e4SLinus Torvalds 	/*
1022bc1c1169SJens Axboe 	 * Remember old elevator.
10231da177e4SLinus Torvalds 	 */
10241da177e4SLinus Torvalds 	old_elevator = q->elevator;
10251da177e4SLinus Torvalds 
10261da177e4SLinus Torvalds 	/*
10271da177e4SLinus Torvalds 	 * attach and start new elevator
10281da177e4SLinus Torvalds 	 */
1029bc1c1169SJens Axboe 	elevator_attach(q, e, data);
1030bc1c1169SJens Axboe 
1031bc1c1169SJens Axboe 	spin_unlock_irq(q->queue_lock);
1032bc1c1169SJens Axboe 
1033bc1c1169SJens Axboe 	__elv_unregister_queue(old_elevator);
10341da177e4SLinus Torvalds 
10351da177e4SLinus Torvalds 	if (elv_register_queue(q))
10361da177e4SLinus Torvalds 		goto fail_register;
10371da177e4SLinus Torvalds 
10381da177e4SLinus Torvalds 	/*
1039cb98fc8bSTejun Heo 	 * finally exit old elevator and turn off BYPASS.
10401da177e4SLinus Torvalds 	 */
10411da177e4SLinus Torvalds 	elevator_exit(old_elevator);
104275ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
1043f600abe2SJens Axboe 	elv_quiesce_end(q);
104475ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
104575ad23bcSNick Piggin 
10464722dc52SAlan D. Brunelle 	blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
10474722dc52SAlan D. Brunelle 
10483d1ab40fSAl Viro 	return 1;
10491da177e4SLinus Torvalds 
10501da177e4SLinus Torvalds fail_register:
10511da177e4SLinus Torvalds 	/*
10521da177e4SLinus Torvalds 	 * switch failed, exit the new io scheduler and reattach the old
10531da177e4SLinus Torvalds 	 * one again (along with re-adding the sysfs dir)
10541da177e4SLinus Torvalds 	 */
10551da177e4SLinus Torvalds 	elevator_exit(e);
10561da177e4SLinus Torvalds 	q->elevator = old_elevator;
10571da177e4SLinus Torvalds 	elv_register_queue(q);
105875ad23bcSNick Piggin 
105975ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
106075ad23bcSNick Piggin 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
106175ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
106275ad23bcSNick Piggin 
10633d1ab40fSAl Viro 	return 0;
10641da177e4SLinus Torvalds }
10651da177e4SLinus Torvalds 
1066165125e1SJens Axboe ssize_t elv_iosched_store(struct request_queue *q, const char *name,
1067165125e1SJens Axboe 			  size_t count)
10681da177e4SLinus Torvalds {
10691da177e4SLinus Torvalds 	char elevator_name[ELV_NAME_MAX];
10701da177e4SLinus Torvalds 	struct elevator_type *e;
10711da177e4SLinus Torvalds 
1072cd43e26fSMartin K. Petersen 	if (!q->elevator)
1073cd43e26fSMartin K. Petersen 		return count;
1074cd43e26fSMartin K. Petersen 
1075ee2e992cSLi Zefan 	strlcpy(elevator_name, name, sizeof(elevator_name));
10768c279598SKOSAKI Motohiro 	e = elevator_get(strstrip(elevator_name));
10771da177e4SLinus Torvalds 	if (!e) {
10781da177e4SLinus Torvalds 		printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
10791da177e4SLinus Torvalds 		return -EINVAL;
10801da177e4SLinus Torvalds 	}
10811da177e4SLinus Torvalds 
10822ca7d93bSNate Diller 	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
10832ca7d93bSNate Diller 		elevator_put(e);
10841da177e4SLinus Torvalds 		return count;
10852ca7d93bSNate Diller 	}
10861da177e4SLinus Torvalds 
10873d1ab40fSAl Viro 	if (!elevator_switch(q, e))
10884eb166d9SJens Axboe 		printk(KERN_ERR "elevator: switch to %s failed\n",
10894eb166d9SJens Axboe 							elevator_name);
10901da177e4SLinus Torvalds 	return count;
10911da177e4SLinus Torvalds }
10921da177e4SLinus Torvalds 
1093165125e1SJens Axboe ssize_t elv_iosched_show(struct request_queue *q, char *name)
10941da177e4SLinus Torvalds {
1095b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
1096cd43e26fSMartin K. Petersen 	struct elevator_type *elv;
109770cee26eSMatthias Kaehlcke 	struct elevator_type *__e;
10981da177e4SLinus Torvalds 	int len = 0;
10991da177e4SLinus Torvalds 
1100cd43e26fSMartin K. Petersen 	if (!q->elevator)
1101cd43e26fSMartin K. Petersen 		return sprintf(name, "none\n");
1102cd43e26fSMartin K. Petersen 
1103cd43e26fSMartin K. Petersen 	elv = e->elevator_type;
1104cd43e26fSMartin K. Petersen 
11052a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
110670cee26eSMatthias Kaehlcke 	list_for_each_entry(__e, &elv_list, list) {
11071da177e4SLinus Torvalds 		if (!strcmp(elv->elevator_name, __e->elevator_name))
11081da177e4SLinus Torvalds 			len += sprintf(name+len, "[%s] ", elv->elevator_name);
11091da177e4SLinus Torvalds 		else
11101da177e4SLinus Torvalds 			len += sprintf(name+len, "%s ", __e->elevator_name);
11111da177e4SLinus Torvalds 	}
11122a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
11131da177e4SLinus Torvalds 
11141da177e4SLinus Torvalds 	len += sprintf(len+name, "\n");
11151da177e4SLinus Torvalds 	return len;
11161da177e4SLinus Torvalds }
11171da177e4SLinus Torvalds 
1118165125e1SJens Axboe struct request *elv_rb_former_request(struct request_queue *q,
1119165125e1SJens Axboe 				      struct request *rq)
11202e662b65SJens Axboe {
11212e662b65SJens Axboe 	struct rb_node *rbprev = rb_prev(&rq->rb_node);
11222e662b65SJens Axboe 
11232e662b65SJens Axboe 	if (rbprev)
11242e662b65SJens Axboe 		return rb_entry_rq(rbprev);
11252e662b65SJens Axboe 
11262e662b65SJens Axboe 	return NULL;
11272e662b65SJens Axboe }
11282e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_former_request);
11292e662b65SJens Axboe 
1130165125e1SJens Axboe struct request *elv_rb_latter_request(struct request_queue *q,
1131165125e1SJens Axboe 				      struct request *rq)
11322e662b65SJens Axboe {
11332e662b65SJens Axboe 	struct rb_node *rbnext = rb_next(&rq->rb_node);
11342e662b65SJens Axboe 
11352e662b65SJens Axboe 	if (rbnext)
11362e662b65SJens Axboe 		return rb_entry_rq(rbnext);
11372e662b65SJens Axboe 
11382e662b65SJens Axboe 	return NULL;
11392e662b65SJens Axboe }
11402e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_latter_request);
1141