xref: /linux/block/elevator.c (revision 73c101011926c5832e6e141682180c4debe2cf45)
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 	 */
827b6d91daSChristoph Hellwig 	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
83e17fc0a1SDavid Woodhouse 		return 0;
84e17fc0a1SDavid Woodhouse 
85e17fc0a1SDavid Woodhouse 	/*
868d57a98cSAdrian Hunter 	 * Don't merge discard requests and secure discard requests
878d57a98cSAdrian Hunter 	 */
888d57a98cSAdrian Hunter 	if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
898d57a98cSAdrian Hunter 		return 0;
908d57a98cSAdrian Hunter 
918d57a98cSAdrian Hunter 	/*
921da177e4SLinus Torvalds 	 * different data direction or already started, don't merge
931da177e4SLinus Torvalds 	 */
941da177e4SLinus Torvalds 	if (bio_data_dir(bio) != rq_data_dir(rq))
951da177e4SLinus Torvalds 		return 0;
961da177e4SLinus Torvalds 
971da177e4SLinus Torvalds 	/*
98da775265SJens Axboe 	 * must be same device and not a special request
991da177e4SLinus Torvalds 	 */
100bb4067e3SJens Axboe 	if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
1011da177e4SLinus Torvalds 		return 0;
102da775265SJens Axboe 
1037ba1ba12SMartin K. Petersen 	/*
1047ba1ba12SMartin K. Petersen 	 * only merge integrity protected bio into ditto rq
1057ba1ba12SMartin K. Petersen 	 */
1067ba1ba12SMartin K. Petersen 	if (bio_integrity(bio) != blk_integrity_rq(rq))
1077ba1ba12SMartin K. Petersen 		return 0;
1087ba1ba12SMartin K. Petersen 
109da775265SJens Axboe 	if (!elv_iosched_allow_merge(rq, bio))
110da775265SJens Axboe 		return 0;
111da775265SJens Axboe 
112da775265SJens Axboe 	return 1;
1131da177e4SLinus Torvalds }
1141da177e4SLinus Torvalds EXPORT_SYMBOL(elv_rq_merge_ok);
1151da177e4SLinus Torvalds 
116*73c10101SJens Axboe int elv_try_merge(struct request *__rq, struct bio *bio)
1171da177e4SLinus Torvalds {
1181da177e4SLinus Torvalds 	int ret = ELEVATOR_NO_MERGE;
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds 	/*
1211da177e4SLinus Torvalds 	 * we can merge and sequence is ok, check if it's possible
1221da177e4SLinus Torvalds 	 */
1231da177e4SLinus Torvalds 	if (elv_rq_merge_ok(__rq, bio)) {
12483096ebfSTejun Heo 		if (blk_rq_pos(__rq) + blk_rq_sectors(__rq) == bio->bi_sector)
1251da177e4SLinus Torvalds 			ret = ELEVATOR_BACK_MERGE;
12683096ebfSTejun Heo 		else if (blk_rq_pos(__rq) - bio_sectors(bio) == bio->bi_sector)
1271da177e4SLinus Torvalds 			ret = ELEVATOR_FRONT_MERGE;
1281da177e4SLinus Torvalds 	}
1291da177e4SLinus Torvalds 
1301da177e4SLinus Torvalds 	return ret;
1311da177e4SLinus Torvalds }
1321da177e4SLinus Torvalds 
1331da177e4SLinus Torvalds static struct elevator_type *elevator_find(const char *name)
1341da177e4SLinus Torvalds {
135a22b169dSVasily Tarasov 	struct elevator_type *e;
1361da177e4SLinus Torvalds 
13770cee26eSMatthias Kaehlcke 	list_for_each_entry(e, &elv_list, list) {
138a22b169dSVasily Tarasov 		if (!strcmp(e->elevator_name, name))
1391da177e4SLinus Torvalds 			return e;
1401da177e4SLinus Torvalds 	}
1411da177e4SLinus Torvalds 
142a22b169dSVasily Tarasov 	return NULL;
143a22b169dSVasily Tarasov }
144a22b169dSVasily Tarasov 
1451da177e4SLinus Torvalds static void elevator_put(struct elevator_type *e)
1461da177e4SLinus Torvalds {
1471da177e4SLinus Torvalds 	module_put(e->elevator_owner);
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds static struct elevator_type *elevator_get(const char *name)
1511da177e4SLinus Torvalds {
1522824bc93STejun Heo 	struct elevator_type *e;
1531da177e4SLinus Torvalds 
1542a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
1552824bc93STejun Heo 
1562824bc93STejun Heo 	e = elevator_find(name);
157e1640949SJens Axboe 	if (!e) {
158e1640949SJens Axboe 		char elv[ELV_NAME_MAX + strlen("-iosched")];
159e1640949SJens Axboe 
160e1640949SJens Axboe 		spin_unlock(&elv_list_lock);
161e1640949SJens Axboe 
162a506aedcSwzt.wzt@gmail.com 		snprintf(elv, sizeof(elv), "%s-iosched", name);
163e1640949SJens Axboe 
164e180f594Smaximilian attems 		request_module("%s", elv);
165e1640949SJens Axboe 		spin_lock(&elv_list_lock);
166e1640949SJens Axboe 		e = elevator_find(name);
167e1640949SJens Axboe 	}
168e1640949SJens Axboe 
1692824bc93STejun Heo 	if (e && !try_module_get(e->elevator_owner))
1702824bc93STejun Heo 		e = NULL;
1712824bc93STejun Heo 
1722a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	return e;
1751da177e4SLinus Torvalds }
1761da177e4SLinus Torvalds 
177165125e1SJens Axboe static void *elevator_init_queue(struct request_queue *q,
178165125e1SJens Axboe 				 struct elevator_queue *eq)
1791da177e4SLinus Torvalds {
180bb37b94cSJens Axboe 	return eq->ops->elevator_init_fn(q);
181bc1c1169SJens Axboe }
1821da177e4SLinus Torvalds 
183165125e1SJens Axboe static void elevator_attach(struct request_queue *q, struct elevator_queue *eq,
184bc1c1169SJens Axboe 			   void *data)
185bc1c1169SJens Axboe {
1861da177e4SLinus Torvalds 	q->elevator = eq;
187bc1c1169SJens Axboe 	eq->elevator_data = data;
1881da177e4SLinus Torvalds }
1891da177e4SLinus Torvalds 
1901da177e4SLinus Torvalds static char chosen_elevator[16];
1911da177e4SLinus Torvalds 
1925f003976SNate Diller static int __init elevator_setup(char *str)
1931da177e4SLinus Torvalds {
194752a3b79SChuck Ebbert 	/*
195752a3b79SChuck Ebbert 	 * Be backwards-compatible with previous kernels, so users
196752a3b79SChuck Ebbert 	 * won't get the wrong elevator.
197752a3b79SChuck Ebbert 	 */
1981da177e4SLinus Torvalds 	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
1999b41046cSOGAWA Hirofumi 	return 1;
2001da177e4SLinus Torvalds }
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds __setup("elevator=", elevator_setup);
2031da177e4SLinus Torvalds 
2043d1ab40fSAl Viro static struct kobj_type elv_ktype;
2053d1ab40fSAl Viro 
206b374d18aSJens Axboe static struct elevator_queue *elevator_alloc(struct request_queue *q,
207165125e1SJens Axboe 				  struct elevator_type *e)
2083d1ab40fSAl Viro {
209b374d18aSJens Axboe 	struct elevator_queue *eq;
2109817064bSJens Axboe 	int i;
2119817064bSJens Axboe 
212b374d18aSJens Axboe 	eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node);
2139817064bSJens Axboe 	if (unlikely(!eq))
2149817064bSJens Axboe 		goto err;
2159817064bSJens Axboe 
2163d1ab40fSAl Viro 	eq->ops = &e->ops;
2173d1ab40fSAl Viro 	eq->elevator_type = e;
218f9cb074bSGreg Kroah-Hartman 	kobject_init(&eq->kobj, &elv_ktype);
2193d1ab40fSAl Viro 	mutex_init(&eq->sysfs_lock);
2209817064bSJens Axboe 
221b5deef90SJens Axboe 	eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
222b5deef90SJens Axboe 					GFP_KERNEL, q->node);
2239817064bSJens Axboe 	if (!eq->hash)
2249817064bSJens Axboe 		goto err;
2259817064bSJens Axboe 
2269817064bSJens Axboe 	for (i = 0; i < ELV_HASH_ENTRIES; i++)
2279817064bSJens Axboe 		INIT_HLIST_HEAD(&eq->hash[i]);
2289817064bSJens Axboe 
2293d1ab40fSAl Viro 	return eq;
2309817064bSJens Axboe err:
2319817064bSJens Axboe 	kfree(eq);
2329817064bSJens Axboe 	elevator_put(e);
2339817064bSJens Axboe 	return NULL;
2343d1ab40fSAl Viro }
2353d1ab40fSAl Viro 
2363d1ab40fSAl Viro static void elevator_release(struct kobject *kobj)
2373d1ab40fSAl Viro {
238b374d18aSJens Axboe 	struct elevator_queue *e;
2399817064bSJens Axboe 
240b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
2413d1ab40fSAl Viro 	elevator_put(e->elevator_type);
2429817064bSJens Axboe 	kfree(e->hash);
2433d1ab40fSAl Viro 	kfree(e);
2443d1ab40fSAl Viro }
2453d1ab40fSAl Viro 
246165125e1SJens Axboe int elevator_init(struct request_queue *q, char *name)
2471da177e4SLinus Torvalds {
2481da177e4SLinus Torvalds 	struct elevator_type *e = NULL;
2491da177e4SLinus Torvalds 	struct elevator_queue *eq;
250bc1c1169SJens Axboe 	void *data;
2511da177e4SLinus Torvalds 
2521abec4fdSMike Snitzer 	if (unlikely(q->elevator))
2531abec4fdSMike Snitzer 		return 0;
2541abec4fdSMike Snitzer 
255cb98fc8bSTejun Heo 	INIT_LIST_HEAD(&q->queue_head);
256cb98fc8bSTejun Heo 	q->last_merge = NULL;
257cb98fc8bSTejun Heo 	q->end_sector = 0;
258cb98fc8bSTejun Heo 	q->boundary_rq = NULL;
259cb98fc8bSTejun Heo 
2604eb166d9SJens Axboe 	if (name) {
2614eb166d9SJens Axboe 		e = elevator_get(name);
2624eb166d9SJens Axboe 		if (!e)
2631da177e4SLinus Torvalds 			return -EINVAL;
2644eb166d9SJens Axboe 	}
2651da177e4SLinus Torvalds 
2664eb166d9SJens Axboe 	if (!e && *chosen_elevator) {
2674eb166d9SJens Axboe 		e = elevator_get(chosen_elevator);
2684eb166d9SJens Axboe 		if (!e)
2694eb166d9SJens Axboe 			printk(KERN_ERR "I/O scheduler %s not found\n",
2704eb166d9SJens Axboe 							chosen_elevator);
2714eb166d9SJens Axboe 	}
272248d5ca5SNate Diller 
2734eb166d9SJens Axboe 	if (!e) {
2744eb166d9SJens Axboe 		e = elevator_get(CONFIG_DEFAULT_IOSCHED);
2754eb166d9SJens Axboe 		if (!e) {
2764eb166d9SJens Axboe 			printk(KERN_ERR
2774eb166d9SJens Axboe 				"Default I/O scheduler not found. " \
2784eb166d9SJens Axboe 				"Using noop.\n");
279248d5ca5SNate Diller 			e = elevator_get("noop");
2805f003976SNate Diller 		}
2814eb166d9SJens Axboe 	}
2825f003976SNate Diller 
283b5deef90SJens Axboe 	eq = elevator_alloc(q, e);
2843d1ab40fSAl Viro 	if (!eq)
2851da177e4SLinus Torvalds 		return -ENOMEM;
2861da177e4SLinus Torvalds 
287bc1c1169SJens Axboe 	data = elevator_init_queue(q, eq);
288bc1c1169SJens Axboe 	if (!data) {
2893d1ab40fSAl Viro 		kobject_put(&eq->kobj);
290bc1c1169SJens Axboe 		return -ENOMEM;
291bc1c1169SJens Axboe 	}
2921da177e4SLinus Torvalds 
293bc1c1169SJens Axboe 	elevator_attach(q, eq, data);
2941abec4fdSMike Snitzer 	return 0;
2951da177e4SLinus Torvalds }
2962e662b65SJens Axboe EXPORT_SYMBOL(elevator_init);
2972e662b65SJens Axboe 
298b374d18aSJens Axboe void elevator_exit(struct elevator_queue *e)
2991da177e4SLinus Torvalds {
3003d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
3011da177e4SLinus Torvalds 	if (e->ops->elevator_exit_fn)
3021da177e4SLinus Torvalds 		e->ops->elevator_exit_fn(e);
3033d1ab40fSAl Viro 	e->ops = NULL;
3043d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
3051da177e4SLinus Torvalds 
3063d1ab40fSAl Viro 	kobject_put(&e->kobj);
3071da177e4SLinus Torvalds }
3082e662b65SJens Axboe EXPORT_SYMBOL(elevator_exit);
3092e662b65SJens Axboe 
3109817064bSJens Axboe static inline void __elv_rqhash_del(struct request *rq)
3119817064bSJens Axboe {
3129817064bSJens Axboe 	hlist_del_init(&rq->hash);
3139817064bSJens Axboe }
3149817064bSJens Axboe 
315165125e1SJens Axboe static void elv_rqhash_del(struct request_queue *q, struct request *rq)
3169817064bSJens Axboe {
3179817064bSJens Axboe 	if (ELV_ON_HASH(rq))
3189817064bSJens Axboe 		__elv_rqhash_del(rq);
3199817064bSJens Axboe }
3209817064bSJens Axboe 
321165125e1SJens Axboe static void elv_rqhash_add(struct request_queue *q, struct request *rq)
3229817064bSJens Axboe {
323b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
3249817064bSJens Axboe 
3259817064bSJens Axboe 	BUG_ON(ELV_ON_HASH(rq));
3269817064bSJens Axboe 	hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
3279817064bSJens Axboe }
3289817064bSJens Axboe 
329165125e1SJens Axboe static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
3309817064bSJens Axboe {
3319817064bSJens Axboe 	__elv_rqhash_del(rq);
3329817064bSJens Axboe 	elv_rqhash_add(q, rq);
3339817064bSJens Axboe }
3349817064bSJens Axboe 
335165125e1SJens Axboe static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
3369817064bSJens Axboe {
337b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
3389817064bSJens Axboe 	struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
3399817064bSJens Axboe 	struct hlist_node *entry, *next;
3409817064bSJens Axboe 	struct request *rq;
3419817064bSJens Axboe 
3429817064bSJens Axboe 	hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
3439817064bSJens Axboe 		BUG_ON(!ELV_ON_HASH(rq));
3449817064bSJens Axboe 
3459817064bSJens Axboe 		if (unlikely(!rq_mergeable(rq))) {
3469817064bSJens Axboe 			__elv_rqhash_del(rq);
3479817064bSJens Axboe 			continue;
3489817064bSJens Axboe 		}
3499817064bSJens Axboe 
3509817064bSJens Axboe 		if (rq_hash_key(rq) == offset)
3519817064bSJens Axboe 			return rq;
3529817064bSJens Axboe 	}
3539817064bSJens Axboe 
3549817064bSJens Axboe 	return NULL;
3559817064bSJens Axboe }
3569817064bSJens Axboe 
3578922e16cSTejun Heo /*
3582e662b65SJens Axboe  * RB-tree support functions for inserting/lookup/removal of requests
3592e662b65SJens Axboe  * in a sorted RB tree.
3602e662b65SJens Axboe  */
3612e662b65SJens Axboe struct request *elv_rb_add(struct rb_root *root, struct request *rq)
3622e662b65SJens Axboe {
3632e662b65SJens Axboe 	struct rb_node **p = &root->rb_node;
3642e662b65SJens Axboe 	struct rb_node *parent = NULL;
3652e662b65SJens Axboe 	struct request *__rq;
3662e662b65SJens Axboe 
3672e662b65SJens Axboe 	while (*p) {
3682e662b65SJens Axboe 		parent = *p;
3692e662b65SJens Axboe 		__rq = rb_entry(parent, struct request, rb_node);
3702e662b65SJens Axboe 
37183096ebfSTejun Heo 		if (blk_rq_pos(rq) < blk_rq_pos(__rq))
3722e662b65SJens Axboe 			p = &(*p)->rb_left;
37383096ebfSTejun Heo 		else if (blk_rq_pos(rq) > blk_rq_pos(__rq))
3742e662b65SJens Axboe 			p = &(*p)->rb_right;
3752e662b65SJens Axboe 		else
3762e662b65SJens Axboe 			return __rq;
3772e662b65SJens Axboe 	}
3782e662b65SJens Axboe 
3792e662b65SJens Axboe 	rb_link_node(&rq->rb_node, parent, p);
3802e662b65SJens Axboe 	rb_insert_color(&rq->rb_node, root);
3812e662b65SJens Axboe 	return NULL;
3822e662b65SJens Axboe }
3832e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_add);
3842e662b65SJens Axboe 
3852e662b65SJens Axboe void elv_rb_del(struct rb_root *root, struct request *rq)
3862e662b65SJens Axboe {
3872e662b65SJens Axboe 	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
3882e662b65SJens Axboe 	rb_erase(&rq->rb_node, root);
3892e662b65SJens Axboe 	RB_CLEAR_NODE(&rq->rb_node);
3902e662b65SJens Axboe }
3912e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_del);
3922e662b65SJens Axboe 
3932e662b65SJens Axboe struct request *elv_rb_find(struct rb_root *root, sector_t sector)
3942e662b65SJens Axboe {
3952e662b65SJens Axboe 	struct rb_node *n = root->rb_node;
3962e662b65SJens Axboe 	struct request *rq;
3972e662b65SJens Axboe 
3982e662b65SJens Axboe 	while (n) {
3992e662b65SJens Axboe 		rq = rb_entry(n, struct request, rb_node);
4002e662b65SJens Axboe 
40183096ebfSTejun Heo 		if (sector < blk_rq_pos(rq))
4022e662b65SJens Axboe 			n = n->rb_left;
40383096ebfSTejun Heo 		else if (sector > blk_rq_pos(rq))
4042e662b65SJens Axboe 			n = n->rb_right;
4052e662b65SJens Axboe 		else
4062e662b65SJens Axboe 			return rq;
4072e662b65SJens Axboe 	}
4082e662b65SJens Axboe 
4092e662b65SJens Axboe 	return NULL;
4102e662b65SJens Axboe }
4112e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_find);
4122e662b65SJens Axboe 
4132e662b65SJens Axboe /*
4148922e16cSTejun Heo  * Insert rq into dispatch queue of q.  Queue lock must be held on
415dbe7f76dSUwe Kleine-König  * entry.  rq is sort instead into the dispatch queue. To be used by
4162e662b65SJens Axboe  * specific elevators.
4178922e16cSTejun Heo  */
418165125e1SJens Axboe void elv_dispatch_sort(struct request_queue *q, struct request *rq)
4198922e16cSTejun Heo {
4208922e16cSTejun Heo 	sector_t boundary;
4218922e16cSTejun Heo 	struct list_head *entry;
4224eb166d9SJens Axboe 	int stop_flags;
4238922e16cSTejun Heo 
424*73c10101SJens Axboe 	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
425*73c10101SJens Axboe 
42606b86245STejun Heo 	if (q->last_merge == rq)
42706b86245STejun Heo 		q->last_merge = NULL;
4289817064bSJens Axboe 
4299817064bSJens Axboe 	elv_rqhash_del(q, rq);
4309817064bSJens Axboe 
43115853af9STejun Heo 	q->nr_sorted--;
43206b86245STejun Heo 
4331b47f531SJens Axboe 	boundary = q->end_sector;
43402e031cbSChristoph Hellwig 	stop_flags = REQ_SOFTBARRIER | REQ_STARTED;
4358922e16cSTejun Heo 	list_for_each_prev(entry, &q->queue_head) {
4368922e16cSTejun Heo 		struct request *pos = list_entry_rq(entry);
4378922e16cSTejun Heo 
43833659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_DISCARD) !=
43933659ebbSChristoph Hellwig 		    (pos->cmd_flags & REQ_DISCARD))
440e17fc0a1SDavid Woodhouse 			break;
441783660b2SJens Axboe 		if (rq_data_dir(rq) != rq_data_dir(pos))
442783660b2SJens Axboe 			break;
4434eb166d9SJens Axboe 		if (pos->cmd_flags & stop_flags)
4448922e16cSTejun Heo 			break;
44583096ebfSTejun Heo 		if (blk_rq_pos(rq) >= boundary) {
44683096ebfSTejun Heo 			if (blk_rq_pos(pos) < boundary)
4478922e16cSTejun Heo 				continue;
4488922e16cSTejun Heo 		} else {
44983096ebfSTejun Heo 			if (blk_rq_pos(pos) >= boundary)
4508922e16cSTejun Heo 				break;
4518922e16cSTejun Heo 		}
45283096ebfSTejun Heo 		if (blk_rq_pos(rq) >= blk_rq_pos(pos))
4538922e16cSTejun Heo 			break;
4548922e16cSTejun Heo 	}
4558922e16cSTejun Heo 
4568922e16cSTejun Heo 	list_add(&rq->queuelist, entry);
4578922e16cSTejun Heo }
4582e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_sort);
4592e662b65SJens Axboe 
4609817064bSJens Axboe /*
4612e662b65SJens Axboe  * Insert rq into dispatch queue of q.  Queue lock must be held on
4622e662b65SJens Axboe  * entry.  rq is added to the back of the dispatch queue. To be used by
4632e662b65SJens Axboe  * specific elevators.
4649817064bSJens Axboe  */
4659817064bSJens Axboe void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
4669817064bSJens Axboe {
4679817064bSJens Axboe 	if (q->last_merge == rq)
4689817064bSJens Axboe 		q->last_merge = NULL;
4699817064bSJens Axboe 
4709817064bSJens Axboe 	elv_rqhash_del(q, rq);
4719817064bSJens Axboe 
4729817064bSJens Axboe 	q->nr_sorted--;
4739817064bSJens Axboe 
4749817064bSJens Axboe 	q->end_sector = rq_end_sector(rq);
4759817064bSJens Axboe 	q->boundary_rq = rq;
4769817064bSJens Axboe 	list_add_tail(&rq->queuelist, &q->queue_head);
4779817064bSJens Axboe }
4782e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_add_tail);
4792e662b65SJens Axboe 
480165125e1SJens Axboe int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
4811da177e4SLinus Torvalds {
482b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
4839817064bSJens Axboe 	struct request *__rq;
48406b86245STejun Heo 	int ret;
48506b86245STejun Heo 
4869817064bSJens Axboe 	/*
487488991e2SAlan D. Brunelle 	 * Levels of merges:
488488991e2SAlan D. Brunelle 	 * 	nomerges:  No merges at all attempted
489488991e2SAlan D. Brunelle 	 * 	noxmerges: Only simple one-hit cache try
490488991e2SAlan D. Brunelle 	 * 	merges:	   All merge tries attempted
491488991e2SAlan D. Brunelle 	 */
492488991e2SAlan D. Brunelle 	if (blk_queue_nomerges(q))
493488991e2SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
494488991e2SAlan D. Brunelle 
495488991e2SAlan D. Brunelle 	/*
4969817064bSJens Axboe 	 * First try one-hit cache.
4979817064bSJens Axboe 	 */
49806b86245STejun Heo 	if (q->last_merge) {
49906b86245STejun Heo 		ret = elv_try_merge(q->last_merge, bio);
50006b86245STejun Heo 		if (ret != ELEVATOR_NO_MERGE) {
50106b86245STejun Heo 			*req = q->last_merge;
50206b86245STejun Heo 			return ret;
50306b86245STejun Heo 		}
50406b86245STejun Heo 	}
5051da177e4SLinus Torvalds 
506488991e2SAlan D. Brunelle 	if (blk_queue_noxmerges(q))
507ac9fafa1SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
508ac9fafa1SAlan D. Brunelle 
5099817064bSJens Axboe 	/*
5109817064bSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
5119817064bSJens Axboe 	 */
5129817064bSJens Axboe 	__rq = elv_rqhash_find(q, bio->bi_sector);
5139817064bSJens Axboe 	if (__rq && elv_rq_merge_ok(__rq, bio)) {
5149817064bSJens Axboe 		*req = __rq;
5159817064bSJens Axboe 		return ELEVATOR_BACK_MERGE;
5169817064bSJens Axboe 	}
5179817064bSJens Axboe 
5181da177e4SLinus Torvalds 	if (e->ops->elevator_merge_fn)
5191da177e4SLinus Torvalds 		return e->ops->elevator_merge_fn(q, req, bio);
5201da177e4SLinus Torvalds 
5211da177e4SLinus Torvalds 	return ELEVATOR_NO_MERGE;
5221da177e4SLinus Torvalds }
5231da177e4SLinus Torvalds 
524165125e1SJens Axboe void elv_merged_request(struct request_queue *q, struct request *rq, int type)
5251da177e4SLinus Torvalds {
526b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5271da177e4SLinus Torvalds 
5281da177e4SLinus Torvalds 	if (e->ops->elevator_merged_fn)
5292e662b65SJens Axboe 		e->ops->elevator_merged_fn(q, rq, type);
53006b86245STejun Heo 
5312e662b65SJens Axboe 	if (type == ELEVATOR_BACK_MERGE)
5329817064bSJens Axboe 		elv_rqhash_reposition(q, rq);
5339817064bSJens Axboe 
53406b86245STejun Heo 	q->last_merge = rq;
5351da177e4SLinus Torvalds }
5361da177e4SLinus Torvalds 
537165125e1SJens Axboe void elv_merge_requests(struct request_queue *q, struct request *rq,
5381da177e4SLinus Torvalds 			     struct request *next)
5391da177e4SLinus Torvalds {
540b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5411da177e4SLinus Torvalds 
5421da177e4SLinus Torvalds 	if (e->ops->elevator_merge_req_fn)
5431da177e4SLinus Torvalds 		e->ops->elevator_merge_req_fn(q, rq, next);
54406b86245STejun Heo 
5459817064bSJens Axboe 	elv_rqhash_reposition(q, rq);
5469817064bSJens Axboe 	elv_rqhash_del(q, next);
5479817064bSJens Axboe 
5489817064bSJens Axboe 	q->nr_sorted--;
54906b86245STejun Heo 	q->last_merge = rq;
5501da177e4SLinus Torvalds }
5511da177e4SLinus Torvalds 
552812d4026SDivyesh Shah void elv_bio_merged(struct request_queue *q, struct request *rq,
553812d4026SDivyesh Shah 			struct bio *bio)
554812d4026SDivyesh Shah {
555812d4026SDivyesh Shah 	struct elevator_queue *e = q->elevator;
556812d4026SDivyesh Shah 
557812d4026SDivyesh Shah 	if (e->ops->elevator_bio_merged_fn)
558812d4026SDivyesh Shah 		e->ops->elevator_bio_merged_fn(q, rq, bio);
559812d4026SDivyesh Shah }
560812d4026SDivyesh Shah 
561165125e1SJens Axboe void elv_requeue_request(struct request_queue *q, struct request *rq)
5621da177e4SLinus Torvalds {
5631da177e4SLinus Torvalds 	/*
5641da177e4SLinus Torvalds 	 * it already went through dequeue, we need to decrement the
5651da177e4SLinus Torvalds 	 * in_flight count again
5661da177e4SLinus Torvalds 	 */
5678922e16cSTejun Heo 	if (blk_account_rq(rq)) {
5680a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
56933659ebbSChristoph Hellwig 		if (rq->cmd_flags & REQ_SORTED)
570cad97516SJens Axboe 			elv_deactivate_rq(q, rq);
5711da177e4SLinus Torvalds 	}
5721da177e4SLinus Torvalds 
5734aff5e23SJens Axboe 	rq->cmd_flags &= ~REQ_STARTED;
5741da177e4SLinus Torvalds 
57530e9656cSTejun Heo 	elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE);
5761da177e4SLinus Torvalds }
5771da177e4SLinus Torvalds 
57826308eabSJerome Marchand void elv_drain_elevator(struct request_queue *q)
57915853af9STejun Heo {
58015853af9STejun Heo 	static int printed;
58115853af9STejun Heo 	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
58215853af9STejun Heo 		;
58315853af9STejun Heo 	if (q->nr_sorted == 0)
58415853af9STejun Heo 		return;
58515853af9STejun Heo 	if (printed++ < 10) {
58615853af9STejun Heo 		printk(KERN_ERR "%s: forced dispatching is broken "
58715853af9STejun Heo 		       "(nr_sorted=%u), please report this\n",
58815853af9STejun Heo 		       q->elevator->elevator_type->elevator_name, q->nr_sorted);
58915853af9STejun Heo 	}
59015853af9STejun Heo }
59115853af9STejun Heo 
5926c7e8ceeSJens Axboe /*
5936c7e8ceeSJens Axboe  * Call with queue lock held, interrupts disabled
5946c7e8ceeSJens Axboe  */
595f600abe2SJens Axboe void elv_quiesce_start(struct request_queue *q)
5966c7e8ceeSJens Axboe {
597cd43e26fSMartin K. Petersen 	if (!q->elevator)
598cd43e26fSMartin K. Petersen 		return;
599cd43e26fSMartin K. Petersen 
6006c7e8ceeSJens Axboe 	queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
6016c7e8ceeSJens Axboe 
6026c7e8ceeSJens Axboe 	/*
6036c7e8ceeSJens Axboe 	 * make sure we don't have any requests in flight
6046c7e8ceeSJens Axboe 	 */
6056c7e8ceeSJens Axboe 	elv_drain_elevator(q);
6066c7e8ceeSJens Axboe 	while (q->rq.elvpriv) {
607a7f55792STejun Heo 		__blk_run_queue(q);
6086c7e8ceeSJens Axboe 		spin_unlock_irq(q->queue_lock);
6096c7e8ceeSJens Axboe 		msleep(10);
6106c7e8ceeSJens Axboe 		spin_lock_irq(q->queue_lock);
6116c7e8ceeSJens Axboe 		elv_drain_elevator(q);
6126c7e8ceeSJens Axboe 	}
6136c7e8ceeSJens Axboe }
6146c7e8ceeSJens Axboe 
615f600abe2SJens Axboe void elv_quiesce_end(struct request_queue *q)
6166c7e8ceeSJens Axboe {
6176c7e8ceeSJens Axboe 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
6186c7e8ceeSJens Axboe }
6196c7e8ceeSJens Axboe 
620165125e1SJens Axboe void elv_insert(struct request_queue *q, struct request *rq, int where)
6211da177e4SLinus Torvalds {
622dac07ec1SJens Axboe 	int unplug_it = 1;
623797e7dbbSTejun Heo 
6245f3ea37cSArnaldo Carvalho de Melo 	trace_block_rq_insert(q, rq);
6252056a782SJens Axboe 
6261da177e4SLinus Torvalds 	rq->q = q;
6271da177e4SLinus Torvalds 
6288922e16cSTejun Heo 	switch (where) {
62928e7d184STejun Heo 	case ELEVATOR_INSERT_REQUEUE:
63028e7d184STejun Heo 		/*
63128e7d184STejun Heo 		 * Most requeues happen because of a busy condition,
63228e7d184STejun Heo 		 * don't force unplug of the queue for that case.
63328e7d184STejun Heo 		 * Clear unplug_it and fall through.
63428e7d184STejun Heo 		 */
63528e7d184STejun Heo 		unplug_it = 0;
63628e7d184STejun Heo 
6378922e16cSTejun Heo 	case ELEVATOR_INSERT_FRONT:
6384aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
6398922e16cSTejun Heo 		list_add(&rq->queuelist, &q->queue_head);
6408922e16cSTejun Heo 		break;
6418922e16cSTejun Heo 
6428922e16cSTejun Heo 	case ELEVATOR_INSERT_BACK:
6434aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
64415853af9STejun Heo 		elv_drain_elevator(q);
6458922e16cSTejun Heo 		list_add_tail(&rq->queuelist, &q->queue_head);
6468922e16cSTejun Heo 		/*
6478922e16cSTejun Heo 		 * We kick the queue here for the following reasons.
6488922e16cSTejun Heo 		 * - The elevator might have returned NULL previously
6498922e16cSTejun Heo 		 *   to delay requests and returned them now.  As the
6508922e16cSTejun Heo 		 *   queue wasn't empty before this request, ll_rw_blk
6518922e16cSTejun Heo 		 *   won't run the queue on return, resulting in hang.
6528922e16cSTejun Heo 		 * - Usually, back inserted requests won't be merged
6538922e16cSTejun Heo 		 *   with anything.  There's no point in delaying queue
6548922e16cSTejun Heo 		 *   processing.
6558922e16cSTejun Heo 		 */
656a7f55792STejun Heo 		__blk_run_queue(q);
6578922e16cSTejun Heo 		break;
6588922e16cSTejun Heo 
6598922e16cSTejun Heo 	case ELEVATOR_INSERT_SORT:
66033659ebbSChristoph Hellwig 		BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
66133659ebbSChristoph Hellwig 		       !(rq->cmd_flags & REQ_DISCARD));
6624aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SORTED;
66315853af9STejun Heo 		q->nr_sorted++;
6649817064bSJens Axboe 		if (rq_mergeable(rq)) {
6659817064bSJens Axboe 			elv_rqhash_add(q, rq);
6669817064bSJens Axboe 			if (!q->last_merge)
66706b86245STejun Heo 				q->last_merge = rq;
6689817064bSJens Axboe 		}
6699817064bSJens Axboe 
670ca23509fSTejun Heo 		/*
671ca23509fSTejun Heo 		 * Some ioscheds (cfq) run q->request_fn directly, so
672ca23509fSTejun Heo 		 * rq cannot be accessed after calling
673ca23509fSTejun Heo 		 * elevator_add_req_fn.
674ca23509fSTejun Heo 		 */
675ca23509fSTejun Heo 		q->elevator->ops->elevator_add_req_fn(q, rq);
6768922e16cSTejun Heo 		break;
6778922e16cSTejun Heo 
678ae1b1539STejun Heo 	case ELEVATOR_INSERT_FLUSH:
679ae1b1539STejun Heo 		rq->cmd_flags |= REQ_SOFTBARRIER;
680ae1b1539STejun Heo 		blk_insert_flush(rq);
681ae1b1539STejun Heo 		break;
682ae1b1539STejun Heo 
6838922e16cSTejun Heo 	default:
6848922e16cSTejun Heo 		printk(KERN_ERR "%s: bad insertion point %d\n",
68524c03d47SHarvey Harrison 		       __func__, where);
6868922e16cSTejun Heo 		BUG();
6878922e16cSTejun Heo 	}
6881da177e4SLinus Torvalds 
689dac07ec1SJens Axboe 	if (unplug_it && blk_queue_plugged(q)) {
6901faa16d2SJens Axboe 		int nrq = q->rq.count[BLK_RW_SYNC] + q->rq.count[BLK_RW_ASYNC]
6910a7ae2ffSJens Axboe 				- queue_in_flight(q);
6921da177e4SLinus Torvalds 
693c374f127STejun Heo  		if (nrq >= q->unplug_thresh)
6941da177e4SLinus Torvalds 			__generic_unplug_device(q);
6951da177e4SLinus Torvalds 	}
6961da177e4SLinus Torvalds }
6971da177e4SLinus Torvalds 
698165125e1SJens Axboe void __elv_add_request(struct request_queue *q, struct request *rq, int where,
69930e9656cSTejun Heo 		       int plug)
70030e9656cSTejun Heo {
701*73c10101SJens Axboe 	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
702*73c10101SJens Axboe 
70302e031cbSChristoph Hellwig 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
70428e7d184STejun Heo 		/* barriers are scheduling boundary, update end_sector */
70533659ebbSChristoph Hellwig 		if (rq->cmd_type == REQ_TYPE_FS ||
70633659ebbSChristoph Hellwig 		    (rq->cmd_flags & REQ_DISCARD)) {
70730e9656cSTejun Heo 			q->end_sector = rq_end_sector(rq);
70830e9656cSTejun Heo 			q->boundary_rq = rq;
70930e9656cSTejun Heo 		}
7104eb166d9SJens Axboe 	} else if (!(rq->cmd_flags & REQ_ELVPRIV) &&
7114eb166d9SJens Axboe 		    where == ELEVATOR_INSERT_SORT)
71230e9656cSTejun Heo 		where = ELEVATOR_INSERT_BACK;
71330e9656cSTejun Heo 
71430e9656cSTejun Heo 	if (plug)
71530e9656cSTejun Heo 		blk_plug_device(q);
71630e9656cSTejun Heo 
71730e9656cSTejun Heo 	elv_insert(q, rq, where);
71830e9656cSTejun Heo }
7192e662b65SJens Axboe EXPORT_SYMBOL(__elv_add_request);
7202e662b65SJens Axboe 
721165125e1SJens Axboe void elv_add_request(struct request_queue *q, struct request *rq, int where,
7221da177e4SLinus Torvalds 		     int plug)
7231da177e4SLinus Torvalds {
7241da177e4SLinus Torvalds 	unsigned long flags;
7251da177e4SLinus Torvalds 
7261da177e4SLinus Torvalds 	spin_lock_irqsave(q->queue_lock, flags);
7271da177e4SLinus Torvalds 	__elv_add_request(q, rq, where, plug);
7281da177e4SLinus Torvalds 	spin_unlock_irqrestore(q->queue_lock, flags);
7291da177e4SLinus Torvalds }
7302e662b65SJens Axboe EXPORT_SYMBOL(elv_add_request);
7312e662b65SJens Axboe 
732165125e1SJens Axboe int elv_queue_empty(struct request_queue *q)
7331da177e4SLinus Torvalds {
734b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7351da177e4SLinus Torvalds 
7368922e16cSTejun Heo 	if (!list_empty(&q->queue_head))
7378922e16cSTejun Heo 		return 0;
7388922e16cSTejun Heo 
7391da177e4SLinus Torvalds 	if (e->ops->elevator_queue_empty_fn)
7401da177e4SLinus Torvalds 		return e->ops->elevator_queue_empty_fn(q);
7411da177e4SLinus Torvalds 
7428922e16cSTejun Heo 	return 1;
7431da177e4SLinus Torvalds }
7442e662b65SJens Axboe EXPORT_SYMBOL(elv_queue_empty);
7452e662b65SJens Axboe 
746165125e1SJens Axboe struct request *elv_latter_request(struct request_queue *q, struct request *rq)
7471da177e4SLinus Torvalds {
748b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7491da177e4SLinus Torvalds 
7501da177e4SLinus Torvalds 	if (e->ops->elevator_latter_req_fn)
7511da177e4SLinus Torvalds 		return e->ops->elevator_latter_req_fn(q, rq);
7521da177e4SLinus Torvalds 	return NULL;
7531da177e4SLinus Torvalds }
7541da177e4SLinus Torvalds 
755165125e1SJens Axboe struct request *elv_former_request(struct request_queue *q, struct request *rq)
7561da177e4SLinus Torvalds {
757b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7581da177e4SLinus Torvalds 
7591da177e4SLinus Torvalds 	if (e->ops->elevator_former_req_fn)
7601da177e4SLinus Torvalds 		return e->ops->elevator_former_req_fn(q, rq);
7611da177e4SLinus Torvalds 	return NULL;
7621da177e4SLinus Torvalds }
7631da177e4SLinus Torvalds 
764165125e1SJens Axboe int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
7651da177e4SLinus Torvalds {
766b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	if (e->ops->elevator_set_req_fn)
769cb78b285SJens Axboe 		return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
7701da177e4SLinus Torvalds 
771c186794dSMike Snitzer 	rq->elevator_private[0] = NULL;
7721da177e4SLinus Torvalds 	return 0;
7731da177e4SLinus Torvalds }
7741da177e4SLinus Torvalds 
775165125e1SJens Axboe void elv_put_request(struct request_queue *q, struct request *rq)
7761da177e4SLinus Torvalds {
777b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7781da177e4SLinus Torvalds 
7791da177e4SLinus Torvalds 	if (e->ops->elevator_put_req_fn)
780bb37b94cSJens Axboe 		e->ops->elevator_put_req_fn(rq);
7811da177e4SLinus Torvalds }
7821da177e4SLinus Torvalds 
783165125e1SJens Axboe int elv_may_queue(struct request_queue *q, int rw)
7841da177e4SLinus Torvalds {
785b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7861da177e4SLinus Torvalds 
7871da177e4SLinus Torvalds 	if (e->ops->elevator_may_queue_fn)
788cb78b285SJens Axboe 		return e->ops->elevator_may_queue_fn(q, rw);
7891da177e4SLinus Torvalds 
7901da177e4SLinus Torvalds 	return ELV_MQUEUE_MAY;
7911da177e4SLinus Torvalds }
7921da177e4SLinus Torvalds 
79311914a53SMike Anderson void elv_abort_queue(struct request_queue *q)
79411914a53SMike Anderson {
79511914a53SMike Anderson 	struct request *rq;
79611914a53SMike Anderson 
797ae1b1539STejun Heo 	blk_abort_flushes(q);
798ae1b1539STejun Heo 
79911914a53SMike Anderson 	while (!list_empty(&q->queue_head)) {
80011914a53SMike Anderson 		rq = list_entry_rq(q->queue_head.next);
80111914a53SMike Anderson 		rq->cmd_flags |= REQ_QUIET;
8025f3ea37cSArnaldo Carvalho de Melo 		trace_block_rq_abort(q, rq);
80353c663ceSKiyoshi Ueda 		/*
80453c663ceSKiyoshi Ueda 		 * Mark this request as started so we don't trigger
80553c663ceSKiyoshi Ueda 		 * any debug logic in the end I/O path.
80653c663ceSKiyoshi Ueda 		 */
80753c663ceSKiyoshi Ueda 		blk_start_request(rq);
80840cbbb78STejun Heo 		__blk_end_request_all(rq, -EIO);
80911914a53SMike Anderson 	}
81011914a53SMike Anderson }
81111914a53SMike Anderson EXPORT_SYMBOL(elv_abort_queue);
81211914a53SMike Anderson 
813165125e1SJens Axboe void elv_completed_request(struct request_queue *q, struct request *rq)
8141da177e4SLinus Torvalds {
815b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8161da177e4SLinus Torvalds 
8171da177e4SLinus Torvalds 	/*
8181da177e4SLinus Torvalds 	 * request is released from the driver, io must be done
8191da177e4SLinus Torvalds 	 */
8208922e16cSTejun Heo 	if (blk_account_rq(rq)) {
8210a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
82233659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_SORTED) &&
82333659ebbSChristoph Hellwig 		    e->ops->elevator_completed_req_fn)
8241bc691d3STejun Heo 			e->ops->elevator_completed_req_fn(q, rq);
8251bc691d3STejun Heo 	}
8268922e16cSTejun Heo }
8271da177e4SLinus Torvalds 
8283d1ab40fSAl Viro #define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
8293d1ab40fSAl Viro 
8303d1ab40fSAl Viro static ssize_t
8313d1ab40fSAl Viro elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
8323d1ab40fSAl Viro {
8333d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
834b374d18aSJens Axboe 	struct elevator_queue *e;
8353d1ab40fSAl Viro 	ssize_t error;
8363d1ab40fSAl Viro 
8373d1ab40fSAl Viro 	if (!entry->show)
8383d1ab40fSAl Viro 		return -EIO;
8393d1ab40fSAl Viro 
840b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8413d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8423d1ab40fSAl Viro 	error = e->ops ? entry->show(e, page) : -ENOENT;
8433d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
8443d1ab40fSAl Viro 	return error;
8453d1ab40fSAl Viro }
8463d1ab40fSAl Viro 
8473d1ab40fSAl Viro static ssize_t
8483d1ab40fSAl Viro elv_attr_store(struct kobject *kobj, struct attribute *attr,
8493d1ab40fSAl Viro 	       const char *page, size_t length)
8503d1ab40fSAl Viro {
8513d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
852b374d18aSJens Axboe 	struct elevator_queue *e;
8533d1ab40fSAl Viro 	ssize_t error;
8543d1ab40fSAl Viro 
8553d1ab40fSAl Viro 	if (!entry->store)
8563d1ab40fSAl Viro 		return -EIO;
8573d1ab40fSAl Viro 
858b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8593d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8603d1ab40fSAl Viro 	error = e->ops ? entry->store(e, page, length) : -ENOENT;
8613d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
8623d1ab40fSAl Viro 	return error;
8633d1ab40fSAl Viro }
8643d1ab40fSAl Viro 
86552cf25d0SEmese Revfy static const struct sysfs_ops elv_sysfs_ops = {
8663d1ab40fSAl Viro 	.show	= elv_attr_show,
8673d1ab40fSAl Viro 	.store	= elv_attr_store,
8683d1ab40fSAl Viro };
8693d1ab40fSAl Viro 
8703d1ab40fSAl Viro static struct kobj_type elv_ktype = {
8713d1ab40fSAl Viro 	.sysfs_ops	= &elv_sysfs_ops,
8723d1ab40fSAl Viro 	.release	= elevator_release,
8733d1ab40fSAl Viro };
8743d1ab40fSAl Viro 
8751da177e4SLinus Torvalds int elv_register_queue(struct request_queue *q)
8761da177e4SLinus Torvalds {
877b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8783d1ab40fSAl Viro 	int error;
8791da177e4SLinus Torvalds 
880b2d6db58SGreg Kroah-Hartman 	error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
8813d1ab40fSAl Viro 	if (!error) {
882e572ec7eSAl Viro 		struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
8833d1ab40fSAl Viro 		if (attr) {
884e572ec7eSAl Viro 			while (attr->attr.name) {
885e572ec7eSAl Viro 				if (sysfs_create_file(&e->kobj, &attr->attr))
8863d1ab40fSAl Viro 					break;
887e572ec7eSAl Viro 				attr++;
8883d1ab40fSAl Viro 			}
8893d1ab40fSAl Viro 		}
8903d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_ADD);
891430c62fbSJens Axboe 		e->registered = 1;
8923d1ab40fSAl Viro 	}
8933d1ab40fSAl Viro 	return error;
8941da177e4SLinus Torvalds }
89501effb0dSMike Snitzer EXPORT_SYMBOL(elv_register_queue);
8961da177e4SLinus Torvalds 
897b374d18aSJens Axboe static void __elv_unregister_queue(struct elevator_queue *e)
8981da177e4SLinus Torvalds {
8993d1ab40fSAl Viro 	kobject_uevent(&e->kobj, KOBJ_REMOVE);
9003d1ab40fSAl Viro 	kobject_del(&e->kobj);
901430c62fbSJens Axboe 	e->registered = 0;
9021da177e4SLinus Torvalds }
903bc1c1169SJens Axboe 
904bc1c1169SJens Axboe void elv_unregister_queue(struct request_queue *q)
905bc1c1169SJens Axboe {
906bc1c1169SJens Axboe 	if (q)
907bc1c1169SJens Axboe 		__elv_unregister_queue(q->elevator);
9081da177e4SLinus Torvalds }
90901effb0dSMike Snitzer EXPORT_SYMBOL(elv_unregister_queue);
9101da177e4SLinus Torvalds 
9112fdd82bdSAdrian Bunk void elv_register(struct elevator_type *e)
9121da177e4SLinus Torvalds {
9131ffb96c5SThibaut VARENE 	char *def = "";
9142a12dcd7SJens Axboe 
9152a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
916ce524497SEric Sesterhenn 	BUG_ON(elevator_find(e->elevator_name));
9171da177e4SLinus Torvalds 	list_add_tail(&e->list, &elv_list);
9182a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9191da177e4SLinus Torvalds 
9205f003976SNate Diller 	if (!strcmp(e->elevator_name, chosen_elevator) ||
9215f003976SNate Diller 			(!*chosen_elevator &&
9225f003976SNate Diller 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
9231ffb96c5SThibaut VARENE 				def = " (default)";
9241ffb96c5SThibaut VARENE 
9254eb166d9SJens Axboe 	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
9264eb166d9SJens Axboe 								def);
9271da177e4SLinus Torvalds }
9281da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_register);
9291da177e4SLinus Torvalds 
9301da177e4SLinus Torvalds void elv_unregister(struct elevator_type *e)
9311da177e4SLinus Torvalds {
93283521d3eSChristoph Hellwig 	struct task_struct *g, *p;
93383521d3eSChristoph Hellwig 
93483521d3eSChristoph Hellwig 	/*
93583521d3eSChristoph Hellwig 	 * Iterate every thread in the process to remove the io contexts.
93683521d3eSChristoph Hellwig 	 */
937e17a9489SAl Viro 	if (e->ops.trim) {
93883521d3eSChristoph Hellwig 		read_lock(&tasklist_lock);
93983521d3eSChristoph Hellwig 		do_each_thread(g, p) {
940e17a9489SAl Viro 			task_lock(p);
9412d8f6131SOleg Nesterov 			if (p->io_context)
942e17a9489SAl Viro 				e->ops.trim(p->io_context);
943e17a9489SAl Viro 			task_unlock(p);
94483521d3eSChristoph Hellwig 		} while_each_thread(g, p);
94583521d3eSChristoph Hellwig 		read_unlock(&tasklist_lock);
946e17a9489SAl Viro 	}
94783521d3eSChristoph Hellwig 
9482a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
9491da177e4SLinus Torvalds 	list_del_init(&e->list);
9502a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9511da177e4SLinus Torvalds }
9521da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_unregister);
9531da177e4SLinus Torvalds 
9541da177e4SLinus Torvalds /*
9551da177e4SLinus Torvalds  * switch to new_e io scheduler. be careful not to introduce deadlocks -
9561da177e4SLinus Torvalds  * we don't free the old io scheduler, before we have allocated what we
9571da177e4SLinus Torvalds  * need for the new one. this way we have a chance of going back to the old
958cb98fc8bSTejun Heo  * one, if the new one fails init for some reason.
9591da177e4SLinus Torvalds  */
960165125e1SJens Axboe static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
9611da177e4SLinus Torvalds {
962b374d18aSJens Axboe 	struct elevator_queue *old_elevator, *e;
963bc1c1169SJens Axboe 	void *data;
9645dd531a0SJens Axboe 	int err;
9651da177e4SLinus Torvalds 
966cb98fc8bSTejun Heo 	/*
967cb98fc8bSTejun Heo 	 * Allocate new elevator
968cb98fc8bSTejun Heo 	 */
969b5deef90SJens Axboe 	e = elevator_alloc(q, new_e);
9701da177e4SLinus Torvalds 	if (!e)
9715dd531a0SJens Axboe 		return -ENOMEM;
9721da177e4SLinus Torvalds 
973bc1c1169SJens Axboe 	data = elevator_init_queue(q, e);
974bc1c1169SJens Axboe 	if (!data) {
975bc1c1169SJens Axboe 		kobject_put(&e->kobj);
9765dd531a0SJens Axboe 		return -ENOMEM;
977bc1c1169SJens Axboe 	}
978bc1c1169SJens Axboe 
9791da177e4SLinus Torvalds 	/*
980cb98fc8bSTejun Heo 	 * Turn on BYPASS and drain all requests w/ elevator private data
9811da177e4SLinus Torvalds 	 */
982cb98fc8bSTejun Heo 	spin_lock_irq(q->queue_lock);
983f600abe2SJens Axboe 	elv_quiesce_start(q);
984cb98fc8bSTejun Heo 
9851da177e4SLinus Torvalds 	/*
986bc1c1169SJens Axboe 	 * Remember old elevator.
9871da177e4SLinus Torvalds 	 */
9881da177e4SLinus Torvalds 	old_elevator = q->elevator;
9891da177e4SLinus Torvalds 
9901da177e4SLinus Torvalds 	/*
9911da177e4SLinus Torvalds 	 * attach and start new elevator
9921da177e4SLinus Torvalds 	 */
993bc1c1169SJens Axboe 	elevator_attach(q, e, data);
994bc1c1169SJens Axboe 
995bc1c1169SJens Axboe 	spin_unlock_irq(q->queue_lock);
996bc1c1169SJens Axboe 
997430c62fbSJens Axboe 	if (old_elevator->registered) {
998bc1c1169SJens Axboe 		__elv_unregister_queue(old_elevator);
9991da177e4SLinus Torvalds 
10005dd531a0SJens Axboe 		err = elv_register_queue(q);
10015dd531a0SJens Axboe 		if (err)
10021da177e4SLinus Torvalds 			goto fail_register;
1003430c62fbSJens Axboe 	}
10041da177e4SLinus Torvalds 
10051da177e4SLinus Torvalds 	/*
1006cb98fc8bSTejun Heo 	 * finally exit old elevator and turn off BYPASS.
10071da177e4SLinus Torvalds 	 */
10081da177e4SLinus Torvalds 	elevator_exit(old_elevator);
100975ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
1010f600abe2SJens Axboe 	elv_quiesce_end(q);
101175ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
101275ad23bcSNick Piggin 
10134722dc52SAlan D. Brunelle 	blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
10144722dc52SAlan D. Brunelle 
10155dd531a0SJens Axboe 	return 0;
10161da177e4SLinus Torvalds 
10171da177e4SLinus Torvalds fail_register:
10181da177e4SLinus Torvalds 	/*
10191da177e4SLinus Torvalds 	 * switch failed, exit the new io scheduler and reattach the old
10201da177e4SLinus Torvalds 	 * one again (along with re-adding the sysfs dir)
10211da177e4SLinus Torvalds 	 */
10221da177e4SLinus Torvalds 	elevator_exit(e);
10231da177e4SLinus Torvalds 	q->elevator = old_elevator;
10241da177e4SLinus Torvalds 	elv_register_queue(q);
102575ad23bcSNick Piggin 
102675ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
102775ad23bcSNick Piggin 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
102875ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
102975ad23bcSNick Piggin 
10305dd531a0SJens Axboe 	return err;
10311da177e4SLinus Torvalds }
10321da177e4SLinus Torvalds 
10335dd531a0SJens Axboe /*
10345dd531a0SJens Axboe  * Switch this queue to the given IO scheduler.
10355dd531a0SJens Axboe  */
10365dd531a0SJens Axboe int elevator_change(struct request_queue *q, const char *name)
10371da177e4SLinus Torvalds {
10381da177e4SLinus Torvalds 	char elevator_name[ELV_NAME_MAX];
10391da177e4SLinus Torvalds 	struct elevator_type *e;
10401da177e4SLinus Torvalds 
1041cd43e26fSMartin K. Petersen 	if (!q->elevator)
10425dd531a0SJens Axboe 		return -ENXIO;
1043cd43e26fSMartin K. Petersen 
1044ee2e992cSLi Zefan 	strlcpy(elevator_name, name, sizeof(elevator_name));
10458c279598SKOSAKI Motohiro 	e = elevator_get(strstrip(elevator_name));
10461da177e4SLinus Torvalds 	if (!e) {
10471da177e4SLinus Torvalds 		printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
10481da177e4SLinus Torvalds 		return -EINVAL;
10491da177e4SLinus Torvalds 	}
10501da177e4SLinus Torvalds 
10512ca7d93bSNate Diller 	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
10522ca7d93bSNate Diller 		elevator_put(e);
10535dd531a0SJens Axboe 		return 0;
10542ca7d93bSNate Diller 	}
10551da177e4SLinus Torvalds 
10565dd531a0SJens Axboe 	return elevator_switch(q, e);
10575dd531a0SJens Axboe }
10585dd531a0SJens Axboe EXPORT_SYMBOL(elevator_change);
10595dd531a0SJens Axboe 
10605dd531a0SJens Axboe ssize_t elv_iosched_store(struct request_queue *q, const char *name,
10615dd531a0SJens Axboe 			  size_t count)
10625dd531a0SJens Axboe {
10635dd531a0SJens Axboe 	int ret;
10645dd531a0SJens Axboe 
10655dd531a0SJens Axboe 	if (!q->elevator)
10661da177e4SLinus Torvalds 		return count;
10675dd531a0SJens Axboe 
10685dd531a0SJens Axboe 	ret = elevator_change(q, name);
10695dd531a0SJens Axboe 	if (!ret)
10705dd531a0SJens Axboe 		return count;
10715dd531a0SJens Axboe 
10725dd531a0SJens Axboe 	printk(KERN_ERR "elevator: switch to %s failed\n", name);
10735dd531a0SJens Axboe 	return ret;
10741da177e4SLinus Torvalds }
10751da177e4SLinus Torvalds 
1076165125e1SJens Axboe ssize_t elv_iosched_show(struct request_queue *q, char *name)
10771da177e4SLinus Torvalds {
1078b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
1079cd43e26fSMartin K. Petersen 	struct elevator_type *elv;
108070cee26eSMatthias Kaehlcke 	struct elevator_type *__e;
10811da177e4SLinus Torvalds 	int len = 0;
10821da177e4SLinus Torvalds 
1083e36f724bSMike Snitzer 	if (!q->elevator || !blk_queue_stackable(q))
1084cd43e26fSMartin K. Petersen 		return sprintf(name, "none\n");
1085cd43e26fSMartin K. Petersen 
1086cd43e26fSMartin K. Petersen 	elv = e->elevator_type;
1087cd43e26fSMartin K. Petersen 
10882a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
108970cee26eSMatthias Kaehlcke 	list_for_each_entry(__e, &elv_list, list) {
10901da177e4SLinus Torvalds 		if (!strcmp(elv->elevator_name, __e->elevator_name))
10911da177e4SLinus Torvalds 			len += sprintf(name+len, "[%s] ", elv->elevator_name);
10921da177e4SLinus Torvalds 		else
10931da177e4SLinus Torvalds 			len += sprintf(name+len, "%s ", __e->elevator_name);
10941da177e4SLinus Torvalds 	}
10952a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
10961da177e4SLinus Torvalds 
10971da177e4SLinus Torvalds 	len += sprintf(len+name, "\n");
10981da177e4SLinus Torvalds 	return len;
10991da177e4SLinus Torvalds }
11001da177e4SLinus Torvalds 
1101165125e1SJens Axboe struct request *elv_rb_former_request(struct request_queue *q,
1102165125e1SJens Axboe 				      struct request *rq)
11032e662b65SJens Axboe {
11042e662b65SJens Axboe 	struct rb_node *rbprev = rb_prev(&rq->rb_node);
11052e662b65SJens Axboe 
11062e662b65SJens Axboe 	if (rbprev)
11072e662b65SJens Axboe 		return rb_entry_rq(rbprev);
11082e662b65SJens Axboe 
11092e662b65SJens Axboe 	return NULL;
11102e662b65SJens Axboe }
11112e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_former_request);
11122e662b65SJens Axboe 
1113165125e1SJens Axboe struct request *elv_rb_latter_request(struct request_queue *q,
1114165125e1SJens Axboe 				      struct request *rq)
11152e662b65SJens Axboe {
11162e662b65SJens Axboe 	struct rb_node *rbnext = rb_next(&rq->rb_node);
11172e662b65SJens Axboe 
11182e662b65SJens Axboe 	if (rbnext)
11192e662b65SJens Axboe 		return rb_entry_rq(rbnext);
11202e662b65SJens Axboe 
11212e662b65SJens Axboe 	return NULL;
11222e662b65SJens Axboe }
11232e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_latter_request);
1124