xref: /linux/block/elevator.c (revision 24ecfbe27f65563909b14492afda2f1c21f7c044)
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 
11673c10101SJens 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 
42473c10101SJens Axboe 	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
42573c10101SJens 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 
5245e84ea3aSJens Axboe /*
5255e84ea3aSJens Axboe  * Attempt to do an insertion back merge. Only check for the case where
5265e84ea3aSJens Axboe  * we can append 'rq' to an existing request, so we can throw 'rq' away
5275e84ea3aSJens Axboe  * afterwards.
5285e84ea3aSJens Axboe  *
5295e84ea3aSJens Axboe  * Returns true if we merged, false otherwise
5305e84ea3aSJens Axboe  */
5315e84ea3aSJens Axboe static bool elv_attempt_insert_merge(struct request_queue *q,
5325e84ea3aSJens Axboe 				     struct request *rq)
5335e84ea3aSJens Axboe {
5345e84ea3aSJens Axboe 	struct request *__rq;
5355e84ea3aSJens Axboe 
5365e84ea3aSJens Axboe 	if (blk_queue_nomerges(q))
5375e84ea3aSJens Axboe 		return false;
5385e84ea3aSJens Axboe 
5395e84ea3aSJens Axboe 	/*
5405e84ea3aSJens Axboe 	 * First try one-hit cache.
5415e84ea3aSJens Axboe 	 */
5425e84ea3aSJens Axboe 	if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
5435e84ea3aSJens Axboe 		return true;
5445e84ea3aSJens Axboe 
5455e84ea3aSJens Axboe 	if (blk_queue_noxmerges(q))
5465e84ea3aSJens Axboe 		return false;
5475e84ea3aSJens Axboe 
5485e84ea3aSJens Axboe 	/*
5495e84ea3aSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
5505e84ea3aSJens Axboe 	 */
5515e84ea3aSJens Axboe 	__rq = elv_rqhash_find(q, blk_rq_pos(rq));
5525e84ea3aSJens Axboe 	if (__rq && blk_attempt_req_merge(q, __rq, rq))
5535e84ea3aSJens Axboe 		return true;
5545e84ea3aSJens Axboe 
5555e84ea3aSJens Axboe 	return false;
5565e84ea3aSJens Axboe }
5575e84ea3aSJens Axboe 
558165125e1SJens Axboe void elv_merged_request(struct request_queue *q, struct request *rq, int type)
5591da177e4SLinus Torvalds {
560b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5611da177e4SLinus Torvalds 
5621da177e4SLinus Torvalds 	if (e->ops->elevator_merged_fn)
5632e662b65SJens Axboe 		e->ops->elevator_merged_fn(q, rq, type);
56406b86245STejun Heo 
5652e662b65SJens Axboe 	if (type == ELEVATOR_BACK_MERGE)
5669817064bSJens Axboe 		elv_rqhash_reposition(q, rq);
5679817064bSJens Axboe 
56806b86245STejun Heo 	q->last_merge = rq;
5691da177e4SLinus Torvalds }
5701da177e4SLinus Torvalds 
571165125e1SJens Axboe void elv_merge_requests(struct request_queue *q, struct request *rq,
5721da177e4SLinus Torvalds 			     struct request *next)
5731da177e4SLinus Torvalds {
574b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5755e84ea3aSJens Axboe 	const int next_sorted = next->cmd_flags & REQ_SORTED;
5761da177e4SLinus Torvalds 
5775e84ea3aSJens Axboe 	if (next_sorted && e->ops->elevator_merge_req_fn)
5781da177e4SLinus Torvalds 		e->ops->elevator_merge_req_fn(q, rq, next);
57906b86245STejun Heo 
5809817064bSJens Axboe 	elv_rqhash_reposition(q, rq);
5819817064bSJens Axboe 
5825e84ea3aSJens Axboe 	if (next_sorted) {
5835e84ea3aSJens Axboe 		elv_rqhash_del(q, next);
5849817064bSJens Axboe 		q->nr_sorted--;
5855e84ea3aSJens Axboe 	}
5865e84ea3aSJens Axboe 
58706b86245STejun Heo 	q->last_merge = rq;
5881da177e4SLinus Torvalds }
5891da177e4SLinus Torvalds 
590812d4026SDivyesh Shah void elv_bio_merged(struct request_queue *q, struct request *rq,
591812d4026SDivyesh Shah 			struct bio *bio)
592812d4026SDivyesh Shah {
593812d4026SDivyesh Shah 	struct elevator_queue *e = q->elevator;
594812d4026SDivyesh Shah 
595812d4026SDivyesh Shah 	if (e->ops->elevator_bio_merged_fn)
596812d4026SDivyesh Shah 		e->ops->elevator_bio_merged_fn(q, rq, bio);
597812d4026SDivyesh Shah }
598812d4026SDivyesh Shah 
599165125e1SJens Axboe void elv_requeue_request(struct request_queue *q, struct request *rq)
6001da177e4SLinus Torvalds {
6011da177e4SLinus Torvalds 	/*
6021da177e4SLinus Torvalds 	 * it already went through dequeue, we need to decrement the
6031da177e4SLinus Torvalds 	 * in_flight count again
6041da177e4SLinus Torvalds 	 */
6058922e16cSTejun Heo 	if (blk_account_rq(rq)) {
6060a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
60733659ebbSChristoph Hellwig 		if (rq->cmd_flags & REQ_SORTED)
608cad97516SJens Axboe 			elv_deactivate_rq(q, rq);
6091da177e4SLinus Torvalds 	}
6101da177e4SLinus Torvalds 
6114aff5e23SJens Axboe 	rq->cmd_flags &= ~REQ_STARTED;
6121da177e4SLinus Torvalds 
613b710a480SJens Axboe 	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE);
6141da177e4SLinus Torvalds }
6151da177e4SLinus Torvalds 
61626308eabSJerome Marchand void elv_drain_elevator(struct request_queue *q)
61715853af9STejun Heo {
61815853af9STejun Heo 	static int printed;
61915853af9STejun Heo 	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
62015853af9STejun Heo 		;
62115853af9STejun Heo 	if (q->nr_sorted == 0)
62215853af9STejun Heo 		return;
62315853af9STejun Heo 	if (printed++ < 10) {
62415853af9STejun Heo 		printk(KERN_ERR "%s: forced dispatching is broken "
62515853af9STejun Heo 		       "(nr_sorted=%u), please report this\n",
62615853af9STejun Heo 		       q->elevator->elevator_type->elevator_name, q->nr_sorted);
62715853af9STejun Heo 	}
62815853af9STejun Heo }
62915853af9STejun Heo 
6306c7e8ceeSJens Axboe /*
6316c7e8ceeSJens Axboe  * Call with queue lock held, interrupts disabled
6326c7e8ceeSJens Axboe  */
633f600abe2SJens Axboe void elv_quiesce_start(struct request_queue *q)
6346c7e8ceeSJens Axboe {
635cd43e26fSMartin K. Petersen 	if (!q->elevator)
636cd43e26fSMartin K. Petersen 		return;
637cd43e26fSMartin K. Petersen 
6386c7e8ceeSJens Axboe 	queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
6396c7e8ceeSJens Axboe 
6406c7e8ceeSJens Axboe 	/*
6416c7e8ceeSJens Axboe 	 * make sure we don't have any requests in flight
6426c7e8ceeSJens Axboe 	 */
6436c7e8ceeSJens Axboe 	elv_drain_elevator(q);
6446c7e8ceeSJens Axboe 	while (q->rq.elvpriv) {
645*24ecfbe2SChristoph Hellwig 		__blk_run_queue(q);
6466c7e8ceeSJens Axboe 		spin_unlock_irq(q->queue_lock);
6476c7e8ceeSJens Axboe 		msleep(10);
6486c7e8ceeSJens Axboe 		spin_lock_irq(q->queue_lock);
6496c7e8ceeSJens Axboe 		elv_drain_elevator(q);
6506c7e8ceeSJens Axboe 	}
6516c7e8ceeSJens Axboe }
6526c7e8ceeSJens Axboe 
653f600abe2SJens Axboe void elv_quiesce_end(struct request_queue *q)
6546c7e8ceeSJens Axboe {
6556c7e8ceeSJens Axboe 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
6566c7e8ceeSJens Axboe }
6576c7e8ceeSJens Axboe 
658b710a480SJens Axboe void __elv_add_request(struct request_queue *q, struct request *rq, int where)
6591da177e4SLinus Torvalds {
6605f3ea37cSArnaldo Carvalho de Melo 	trace_block_rq_insert(q, rq);
6612056a782SJens Axboe 
6621da177e4SLinus Torvalds 	rq->q = q;
6631da177e4SLinus Torvalds 
664b710a480SJens Axboe 	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
665b710a480SJens Axboe 
666b710a480SJens Axboe 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
667b710a480SJens Axboe 		/* barriers are scheduling boundary, update end_sector */
668b710a480SJens Axboe 		if (rq->cmd_type == REQ_TYPE_FS ||
669b710a480SJens Axboe 		    (rq->cmd_flags & REQ_DISCARD)) {
670b710a480SJens Axboe 			q->end_sector = rq_end_sector(rq);
671b710a480SJens Axboe 			q->boundary_rq = rq;
672b710a480SJens Axboe 		}
673b710a480SJens Axboe 	} else if (!(rq->cmd_flags & REQ_ELVPRIV) &&
674b710a480SJens Axboe 		    where == ELEVATOR_INSERT_SORT)
675b710a480SJens Axboe 		where = ELEVATOR_INSERT_BACK;
676b710a480SJens Axboe 
6778922e16cSTejun Heo 	switch (where) {
67828e7d184STejun Heo 	case ELEVATOR_INSERT_REQUEUE:
6798922e16cSTejun Heo 	case ELEVATOR_INSERT_FRONT:
6804aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
6818922e16cSTejun Heo 		list_add(&rq->queuelist, &q->queue_head);
6828922e16cSTejun Heo 		break;
6838922e16cSTejun Heo 
6848922e16cSTejun Heo 	case ELEVATOR_INSERT_BACK:
6854aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
68615853af9STejun Heo 		elv_drain_elevator(q);
6878922e16cSTejun Heo 		list_add_tail(&rq->queuelist, &q->queue_head);
6888922e16cSTejun Heo 		/*
6898922e16cSTejun Heo 		 * We kick the queue here for the following reasons.
6908922e16cSTejun Heo 		 * - The elevator might have returned NULL previously
6918922e16cSTejun Heo 		 *   to delay requests and returned them now.  As the
6928922e16cSTejun Heo 		 *   queue wasn't empty before this request, ll_rw_blk
6938922e16cSTejun Heo 		 *   won't run the queue on return, resulting in hang.
6948922e16cSTejun Heo 		 * - Usually, back inserted requests won't be merged
6958922e16cSTejun Heo 		 *   with anything.  There's no point in delaying queue
6968922e16cSTejun Heo 		 *   processing.
6978922e16cSTejun Heo 		 */
698*24ecfbe2SChristoph Hellwig 		__blk_run_queue(q);
6998922e16cSTejun Heo 		break;
7008922e16cSTejun Heo 
7015e84ea3aSJens Axboe 	case ELEVATOR_INSERT_SORT_MERGE:
7025e84ea3aSJens Axboe 		/*
7035e84ea3aSJens Axboe 		 * If we succeed in merging this request with one in the
7045e84ea3aSJens Axboe 		 * queue already, we are done - rq has now been freed,
7055e84ea3aSJens Axboe 		 * so no need to do anything further.
7065e84ea3aSJens Axboe 		 */
7075e84ea3aSJens Axboe 		if (elv_attempt_insert_merge(q, rq))
7085e84ea3aSJens Axboe 			break;
7098922e16cSTejun Heo 	case ELEVATOR_INSERT_SORT:
71033659ebbSChristoph Hellwig 		BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
71133659ebbSChristoph Hellwig 		       !(rq->cmd_flags & REQ_DISCARD));
7124aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SORTED;
71315853af9STejun Heo 		q->nr_sorted++;
7149817064bSJens Axboe 		if (rq_mergeable(rq)) {
7159817064bSJens Axboe 			elv_rqhash_add(q, rq);
7169817064bSJens Axboe 			if (!q->last_merge)
71706b86245STejun Heo 				q->last_merge = rq;
7189817064bSJens Axboe 		}
7199817064bSJens Axboe 
720ca23509fSTejun Heo 		/*
721ca23509fSTejun Heo 		 * Some ioscheds (cfq) run q->request_fn directly, so
722ca23509fSTejun Heo 		 * rq cannot be accessed after calling
723ca23509fSTejun Heo 		 * elevator_add_req_fn.
724ca23509fSTejun Heo 		 */
725ca23509fSTejun Heo 		q->elevator->ops->elevator_add_req_fn(q, rq);
7268922e16cSTejun Heo 		break;
7278922e16cSTejun Heo 
728ae1b1539STejun Heo 	case ELEVATOR_INSERT_FLUSH:
729ae1b1539STejun Heo 		rq->cmd_flags |= REQ_SOFTBARRIER;
730ae1b1539STejun Heo 		blk_insert_flush(rq);
731ae1b1539STejun Heo 		break;
7328922e16cSTejun Heo 	default:
7338922e16cSTejun Heo 		printk(KERN_ERR "%s: bad insertion point %d\n",
73424c03d47SHarvey Harrison 		       __func__, where);
7358922e16cSTejun Heo 		BUG();
7368922e16cSTejun Heo 	}
7371da177e4SLinus Torvalds }
7382e662b65SJens Axboe EXPORT_SYMBOL(__elv_add_request);
7392e662b65SJens Axboe 
7407eaceaccSJens Axboe void elv_add_request(struct request_queue *q, struct request *rq, int where)
7411da177e4SLinus Torvalds {
7421da177e4SLinus Torvalds 	unsigned long flags;
7431da177e4SLinus Torvalds 
7441da177e4SLinus Torvalds 	spin_lock_irqsave(q->queue_lock, flags);
7457eaceaccSJens Axboe 	__elv_add_request(q, rq, where);
7461da177e4SLinus Torvalds 	spin_unlock_irqrestore(q->queue_lock, flags);
7471da177e4SLinus Torvalds }
7482e662b65SJens Axboe EXPORT_SYMBOL(elv_add_request);
7492e662b65SJens Axboe 
750165125e1SJens Axboe struct request *elv_latter_request(struct request_queue *q, struct request *rq)
7511da177e4SLinus Torvalds {
752b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7531da177e4SLinus Torvalds 
7541da177e4SLinus Torvalds 	if (e->ops->elevator_latter_req_fn)
7551da177e4SLinus Torvalds 		return e->ops->elevator_latter_req_fn(q, rq);
7561da177e4SLinus Torvalds 	return NULL;
7571da177e4SLinus Torvalds }
7581da177e4SLinus Torvalds 
759165125e1SJens Axboe struct request *elv_former_request(struct request_queue *q, struct request *rq)
7601da177e4SLinus Torvalds {
761b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7621da177e4SLinus Torvalds 
7631da177e4SLinus Torvalds 	if (e->ops->elevator_former_req_fn)
7641da177e4SLinus Torvalds 		return e->ops->elevator_former_req_fn(q, rq);
7651da177e4SLinus Torvalds 	return NULL;
7661da177e4SLinus Torvalds }
7671da177e4SLinus Torvalds 
768165125e1SJens Axboe int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
7691da177e4SLinus Torvalds {
770b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	if (e->ops->elevator_set_req_fn)
773cb78b285SJens Axboe 		return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
7741da177e4SLinus Torvalds 
775c186794dSMike Snitzer 	rq->elevator_private[0] = NULL;
7761da177e4SLinus Torvalds 	return 0;
7771da177e4SLinus Torvalds }
7781da177e4SLinus Torvalds 
779165125e1SJens Axboe void elv_put_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_put_req_fn)
784bb37b94cSJens Axboe 		e->ops->elevator_put_req_fn(rq);
7851da177e4SLinus Torvalds }
7861da177e4SLinus Torvalds 
787165125e1SJens Axboe int elv_may_queue(struct request_queue *q, int rw)
7881da177e4SLinus Torvalds {
789b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7901da177e4SLinus Torvalds 
7911da177e4SLinus Torvalds 	if (e->ops->elevator_may_queue_fn)
792cb78b285SJens Axboe 		return e->ops->elevator_may_queue_fn(q, rw);
7931da177e4SLinus Torvalds 
7941da177e4SLinus Torvalds 	return ELV_MQUEUE_MAY;
7951da177e4SLinus Torvalds }
7961da177e4SLinus Torvalds 
79711914a53SMike Anderson void elv_abort_queue(struct request_queue *q)
79811914a53SMike Anderson {
79911914a53SMike Anderson 	struct request *rq;
80011914a53SMike Anderson 
801ae1b1539STejun Heo 	blk_abort_flushes(q);
802ae1b1539STejun Heo 
80311914a53SMike Anderson 	while (!list_empty(&q->queue_head)) {
80411914a53SMike Anderson 		rq = list_entry_rq(q->queue_head.next);
80511914a53SMike Anderson 		rq->cmd_flags |= REQ_QUIET;
8065f3ea37cSArnaldo Carvalho de Melo 		trace_block_rq_abort(q, rq);
80753c663ceSKiyoshi Ueda 		/*
80853c663ceSKiyoshi Ueda 		 * Mark this request as started so we don't trigger
80953c663ceSKiyoshi Ueda 		 * any debug logic in the end I/O path.
81053c663ceSKiyoshi Ueda 		 */
81153c663ceSKiyoshi Ueda 		blk_start_request(rq);
81240cbbb78STejun Heo 		__blk_end_request_all(rq, -EIO);
81311914a53SMike Anderson 	}
81411914a53SMike Anderson }
81511914a53SMike Anderson EXPORT_SYMBOL(elv_abort_queue);
81611914a53SMike Anderson 
817165125e1SJens Axboe void elv_completed_request(struct request_queue *q, struct request *rq)
8181da177e4SLinus Torvalds {
819b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8201da177e4SLinus Torvalds 
8211da177e4SLinus Torvalds 	/*
8221da177e4SLinus Torvalds 	 * request is released from the driver, io must be done
8231da177e4SLinus Torvalds 	 */
8248922e16cSTejun Heo 	if (blk_account_rq(rq)) {
8250a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
82633659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_SORTED) &&
82733659ebbSChristoph Hellwig 		    e->ops->elevator_completed_req_fn)
8281bc691d3STejun Heo 			e->ops->elevator_completed_req_fn(q, rq);
8291bc691d3STejun Heo 	}
8308922e16cSTejun Heo }
8311da177e4SLinus Torvalds 
8323d1ab40fSAl Viro #define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
8333d1ab40fSAl Viro 
8343d1ab40fSAl Viro static ssize_t
8353d1ab40fSAl Viro elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
8363d1ab40fSAl Viro {
8373d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
838b374d18aSJens Axboe 	struct elevator_queue *e;
8393d1ab40fSAl Viro 	ssize_t error;
8403d1ab40fSAl Viro 
8413d1ab40fSAl Viro 	if (!entry->show)
8423d1ab40fSAl Viro 		return -EIO;
8433d1ab40fSAl Viro 
844b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8453d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8463d1ab40fSAl Viro 	error = e->ops ? entry->show(e, page) : -ENOENT;
8473d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
8483d1ab40fSAl Viro 	return error;
8493d1ab40fSAl Viro }
8503d1ab40fSAl Viro 
8513d1ab40fSAl Viro static ssize_t
8523d1ab40fSAl Viro elv_attr_store(struct kobject *kobj, struct attribute *attr,
8533d1ab40fSAl Viro 	       const char *page, size_t length)
8543d1ab40fSAl Viro {
8553d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
856b374d18aSJens Axboe 	struct elevator_queue *e;
8573d1ab40fSAl Viro 	ssize_t error;
8583d1ab40fSAl Viro 
8593d1ab40fSAl Viro 	if (!entry->store)
8603d1ab40fSAl Viro 		return -EIO;
8613d1ab40fSAl Viro 
862b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
8633d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
8643d1ab40fSAl Viro 	error = e->ops ? entry->store(e, page, length) : -ENOENT;
8653d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
8663d1ab40fSAl Viro 	return error;
8673d1ab40fSAl Viro }
8683d1ab40fSAl Viro 
86952cf25d0SEmese Revfy static const struct sysfs_ops elv_sysfs_ops = {
8703d1ab40fSAl Viro 	.show	= elv_attr_show,
8713d1ab40fSAl Viro 	.store	= elv_attr_store,
8723d1ab40fSAl Viro };
8733d1ab40fSAl Viro 
8743d1ab40fSAl Viro static struct kobj_type elv_ktype = {
8753d1ab40fSAl Viro 	.sysfs_ops	= &elv_sysfs_ops,
8763d1ab40fSAl Viro 	.release	= elevator_release,
8773d1ab40fSAl Viro };
8783d1ab40fSAl Viro 
8791da177e4SLinus Torvalds int elv_register_queue(struct request_queue *q)
8801da177e4SLinus Torvalds {
881b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
8823d1ab40fSAl Viro 	int error;
8831da177e4SLinus Torvalds 
884b2d6db58SGreg Kroah-Hartman 	error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
8853d1ab40fSAl Viro 	if (!error) {
886e572ec7eSAl Viro 		struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
8873d1ab40fSAl Viro 		if (attr) {
888e572ec7eSAl Viro 			while (attr->attr.name) {
889e572ec7eSAl Viro 				if (sysfs_create_file(&e->kobj, &attr->attr))
8903d1ab40fSAl Viro 					break;
891e572ec7eSAl Viro 				attr++;
8923d1ab40fSAl Viro 			}
8933d1ab40fSAl Viro 		}
8943d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_ADD);
895430c62fbSJens Axboe 		e->registered = 1;
8963d1ab40fSAl Viro 	}
8973d1ab40fSAl Viro 	return error;
8981da177e4SLinus Torvalds }
89901effb0dSMike Snitzer EXPORT_SYMBOL(elv_register_queue);
9001da177e4SLinus Torvalds 
901b374d18aSJens Axboe static void __elv_unregister_queue(struct elevator_queue *e)
9021da177e4SLinus Torvalds {
9033d1ab40fSAl Viro 	kobject_uevent(&e->kobj, KOBJ_REMOVE);
9043d1ab40fSAl Viro 	kobject_del(&e->kobj);
905430c62fbSJens Axboe 	e->registered = 0;
9061da177e4SLinus Torvalds }
907bc1c1169SJens Axboe 
908bc1c1169SJens Axboe void elv_unregister_queue(struct request_queue *q)
909bc1c1169SJens Axboe {
910bc1c1169SJens Axboe 	if (q)
911bc1c1169SJens Axboe 		__elv_unregister_queue(q->elevator);
9121da177e4SLinus Torvalds }
91301effb0dSMike Snitzer EXPORT_SYMBOL(elv_unregister_queue);
9141da177e4SLinus Torvalds 
9152fdd82bdSAdrian Bunk void elv_register(struct elevator_type *e)
9161da177e4SLinus Torvalds {
9171ffb96c5SThibaut VARENE 	char *def = "";
9182a12dcd7SJens Axboe 
9192a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
920ce524497SEric Sesterhenn 	BUG_ON(elevator_find(e->elevator_name));
9211da177e4SLinus Torvalds 	list_add_tail(&e->list, &elv_list);
9222a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9231da177e4SLinus Torvalds 
9245f003976SNate Diller 	if (!strcmp(e->elevator_name, chosen_elevator) ||
9255f003976SNate Diller 			(!*chosen_elevator &&
9265f003976SNate Diller 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
9271ffb96c5SThibaut VARENE 				def = " (default)";
9281ffb96c5SThibaut VARENE 
9294eb166d9SJens Axboe 	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
9304eb166d9SJens Axboe 								def);
9311da177e4SLinus Torvalds }
9321da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_register);
9331da177e4SLinus Torvalds 
9341da177e4SLinus Torvalds void elv_unregister(struct elevator_type *e)
9351da177e4SLinus Torvalds {
93683521d3eSChristoph Hellwig 	struct task_struct *g, *p;
93783521d3eSChristoph Hellwig 
93883521d3eSChristoph Hellwig 	/*
93983521d3eSChristoph Hellwig 	 * Iterate every thread in the process to remove the io contexts.
94083521d3eSChristoph Hellwig 	 */
941e17a9489SAl Viro 	if (e->ops.trim) {
94283521d3eSChristoph Hellwig 		read_lock(&tasklist_lock);
94383521d3eSChristoph Hellwig 		do_each_thread(g, p) {
944e17a9489SAl Viro 			task_lock(p);
9452d8f6131SOleg Nesterov 			if (p->io_context)
946e17a9489SAl Viro 				e->ops.trim(p->io_context);
947e17a9489SAl Viro 			task_unlock(p);
94883521d3eSChristoph Hellwig 		} while_each_thread(g, p);
94983521d3eSChristoph Hellwig 		read_unlock(&tasklist_lock);
950e17a9489SAl Viro 	}
95183521d3eSChristoph Hellwig 
9522a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
9531da177e4SLinus Torvalds 	list_del_init(&e->list);
9542a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
9551da177e4SLinus Torvalds }
9561da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_unregister);
9571da177e4SLinus Torvalds 
9581da177e4SLinus Torvalds /*
9591da177e4SLinus Torvalds  * switch to new_e io scheduler. be careful not to introduce deadlocks -
9601da177e4SLinus Torvalds  * we don't free the old io scheduler, before we have allocated what we
9611da177e4SLinus Torvalds  * need for the new one. this way we have a chance of going back to the old
962cb98fc8bSTejun Heo  * one, if the new one fails init for some reason.
9631da177e4SLinus Torvalds  */
964165125e1SJens Axboe static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
9651da177e4SLinus Torvalds {
966b374d18aSJens Axboe 	struct elevator_queue *old_elevator, *e;
967bc1c1169SJens Axboe 	void *data;
9685dd531a0SJens Axboe 	int err;
9691da177e4SLinus Torvalds 
970cb98fc8bSTejun Heo 	/*
971cb98fc8bSTejun Heo 	 * Allocate new elevator
972cb98fc8bSTejun Heo 	 */
973b5deef90SJens Axboe 	e = elevator_alloc(q, new_e);
9741da177e4SLinus Torvalds 	if (!e)
9755dd531a0SJens Axboe 		return -ENOMEM;
9761da177e4SLinus Torvalds 
977bc1c1169SJens Axboe 	data = elevator_init_queue(q, e);
978bc1c1169SJens Axboe 	if (!data) {
979bc1c1169SJens Axboe 		kobject_put(&e->kobj);
9805dd531a0SJens Axboe 		return -ENOMEM;
981bc1c1169SJens Axboe 	}
982bc1c1169SJens Axboe 
9831da177e4SLinus Torvalds 	/*
984cb98fc8bSTejun Heo 	 * Turn on BYPASS and drain all requests w/ elevator private data
9851da177e4SLinus Torvalds 	 */
986cb98fc8bSTejun Heo 	spin_lock_irq(q->queue_lock);
987f600abe2SJens Axboe 	elv_quiesce_start(q);
988cb98fc8bSTejun Heo 
9891da177e4SLinus Torvalds 	/*
990bc1c1169SJens Axboe 	 * Remember old elevator.
9911da177e4SLinus Torvalds 	 */
9921da177e4SLinus Torvalds 	old_elevator = q->elevator;
9931da177e4SLinus Torvalds 
9941da177e4SLinus Torvalds 	/*
9951da177e4SLinus Torvalds 	 * attach and start new elevator
9961da177e4SLinus Torvalds 	 */
997bc1c1169SJens Axboe 	elevator_attach(q, e, data);
998bc1c1169SJens Axboe 
999bc1c1169SJens Axboe 	spin_unlock_irq(q->queue_lock);
1000bc1c1169SJens Axboe 
1001430c62fbSJens Axboe 	if (old_elevator->registered) {
1002bc1c1169SJens Axboe 		__elv_unregister_queue(old_elevator);
10031da177e4SLinus Torvalds 
10045dd531a0SJens Axboe 		err = elv_register_queue(q);
10055dd531a0SJens Axboe 		if (err)
10061da177e4SLinus Torvalds 			goto fail_register;
1007430c62fbSJens Axboe 	}
10081da177e4SLinus Torvalds 
10091da177e4SLinus Torvalds 	/*
1010cb98fc8bSTejun Heo 	 * finally exit old elevator and turn off BYPASS.
10111da177e4SLinus Torvalds 	 */
10121da177e4SLinus Torvalds 	elevator_exit(old_elevator);
101375ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
1014f600abe2SJens Axboe 	elv_quiesce_end(q);
101575ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
101675ad23bcSNick Piggin 
10174722dc52SAlan D. Brunelle 	blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
10184722dc52SAlan D. Brunelle 
10195dd531a0SJens Axboe 	return 0;
10201da177e4SLinus Torvalds 
10211da177e4SLinus Torvalds fail_register:
10221da177e4SLinus Torvalds 	/*
10231da177e4SLinus Torvalds 	 * switch failed, exit the new io scheduler and reattach the old
10241da177e4SLinus Torvalds 	 * one again (along with re-adding the sysfs dir)
10251da177e4SLinus Torvalds 	 */
10261da177e4SLinus Torvalds 	elevator_exit(e);
10271da177e4SLinus Torvalds 	q->elevator = old_elevator;
10281da177e4SLinus Torvalds 	elv_register_queue(q);
102975ad23bcSNick Piggin 
103075ad23bcSNick Piggin 	spin_lock_irq(q->queue_lock);
103175ad23bcSNick Piggin 	queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
103275ad23bcSNick Piggin 	spin_unlock_irq(q->queue_lock);
103375ad23bcSNick Piggin 
10345dd531a0SJens Axboe 	return err;
10351da177e4SLinus Torvalds }
10361da177e4SLinus Torvalds 
10375dd531a0SJens Axboe /*
10385dd531a0SJens Axboe  * Switch this queue to the given IO scheduler.
10395dd531a0SJens Axboe  */
10405dd531a0SJens Axboe int elevator_change(struct request_queue *q, const char *name)
10411da177e4SLinus Torvalds {
10421da177e4SLinus Torvalds 	char elevator_name[ELV_NAME_MAX];
10431da177e4SLinus Torvalds 	struct elevator_type *e;
10441da177e4SLinus Torvalds 
1045cd43e26fSMartin K. Petersen 	if (!q->elevator)
10465dd531a0SJens Axboe 		return -ENXIO;
1047cd43e26fSMartin K. Petersen 
1048ee2e992cSLi Zefan 	strlcpy(elevator_name, name, sizeof(elevator_name));
10498c279598SKOSAKI Motohiro 	e = elevator_get(strstrip(elevator_name));
10501da177e4SLinus Torvalds 	if (!e) {
10511da177e4SLinus Torvalds 		printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
10521da177e4SLinus Torvalds 		return -EINVAL;
10531da177e4SLinus Torvalds 	}
10541da177e4SLinus Torvalds 
10552ca7d93bSNate Diller 	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
10562ca7d93bSNate Diller 		elevator_put(e);
10575dd531a0SJens Axboe 		return 0;
10582ca7d93bSNate Diller 	}
10591da177e4SLinus Torvalds 
10605dd531a0SJens Axboe 	return elevator_switch(q, e);
10615dd531a0SJens Axboe }
10625dd531a0SJens Axboe EXPORT_SYMBOL(elevator_change);
10635dd531a0SJens Axboe 
10645dd531a0SJens Axboe ssize_t elv_iosched_store(struct request_queue *q, const char *name,
10655dd531a0SJens Axboe 			  size_t count)
10665dd531a0SJens Axboe {
10675dd531a0SJens Axboe 	int ret;
10685dd531a0SJens Axboe 
10695dd531a0SJens Axboe 	if (!q->elevator)
10701da177e4SLinus Torvalds 		return count;
10715dd531a0SJens Axboe 
10725dd531a0SJens Axboe 	ret = elevator_change(q, name);
10735dd531a0SJens Axboe 	if (!ret)
10745dd531a0SJens Axboe 		return count;
10755dd531a0SJens Axboe 
10765dd531a0SJens Axboe 	printk(KERN_ERR "elevator: switch to %s failed\n", name);
10775dd531a0SJens Axboe 	return ret;
10781da177e4SLinus Torvalds }
10791da177e4SLinus Torvalds 
1080165125e1SJens Axboe ssize_t elv_iosched_show(struct request_queue *q, char *name)
10811da177e4SLinus Torvalds {
1082b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
1083cd43e26fSMartin K. Petersen 	struct elevator_type *elv;
108470cee26eSMatthias Kaehlcke 	struct elevator_type *__e;
10851da177e4SLinus Torvalds 	int len = 0;
10861da177e4SLinus Torvalds 
1087e36f724bSMike Snitzer 	if (!q->elevator || !blk_queue_stackable(q))
1088cd43e26fSMartin K. Petersen 		return sprintf(name, "none\n");
1089cd43e26fSMartin K. Petersen 
1090cd43e26fSMartin K. Petersen 	elv = e->elevator_type;
1091cd43e26fSMartin K. Petersen 
10922a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
109370cee26eSMatthias Kaehlcke 	list_for_each_entry(__e, &elv_list, list) {
10941da177e4SLinus Torvalds 		if (!strcmp(elv->elevator_name, __e->elevator_name))
10951da177e4SLinus Torvalds 			len += sprintf(name+len, "[%s] ", elv->elevator_name);
10961da177e4SLinus Torvalds 		else
10971da177e4SLinus Torvalds 			len += sprintf(name+len, "%s ", __e->elevator_name);
10981da177e4SLinus Torvalds 	}
10992a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
11001da177e4SLinus Torvalds 
11011da177e4SLinus Torvalds 	len += sprintf(len+name, "\n");
11021da177e4SLinus Torvalds 	return len;
11031da177e4SLinus Torvalds }
11041da177e4SLinus Torvalds 
1105165125e1SJens Axboe struct request *elv_rb_former_request(struct request_queue *q,
1106165125e1SJens Axboe 				      struct request *rq)
11072e662b65SJens Axboe {
11082e662b65SJens Axboe 	struct rb_node *rbprev = rb_prev(&rq->rb_node);
11092e662b65SJens Axboe 
11102e662b65SJens Axboe 	if (rbprev)
11112e662b65SJens Axboe 		return rb_entry_rq(rbprev);
11122e662b65SJens Axboe 
11132e662b65SJens Axboe 	return NULL;
11142e662b65SJens Axboe }
11152e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_former_request);
11162e662b65SJens Axboe 
1117165125e1SJens Axboe struct request *elv_rb_latter_request(struct request_queue *q,
1118165125e1SJens Axboe 				      struct request *rq)
11192e662b65SJens Axboe {
11202e662b65SJens Axboe 	struct rb_node *rbnext = rb_next(&rq->rb_node);
11212e662b65SJens Axboe 
11222e662b65SJens Axboe 	if (rbnext)
11232e662b65SJens Axboe 		return rb_entry_rq(rbnext);
11242e662b65SJens Axboe 
11252e662b65SJens Axboe 	return NULL;
11262e662b65SJens Axboe }
11272e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_latter_request);
1128