xref: /linux/block/elevator.c (revision e8989fae38d9831c72b20375a206a919ca468c52)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  Block device elevator/IO-scheduler.
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
51da177e4SLinus Torvalds  *
60fe23479SJens Axboe  * 30042000 Jens Axboe <axboe@kernel.dk> :
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Split the elevator a bit so that it is possible to choose a different
91da177e4SLinus Torvalds  * one or even write a new "plug in". There are three pieces:
101da177e4SLinus Torvalds  * - elevator_fn, inserts a new request in the queue list
111da177e4SLinus Torvalds  * - elevator_merge_fn, decides whether a new buffer can be merged with
121da177e4SLinus Torvalds  *   an existing request
131da177e4SLinus Torvalds  * - elevator_dequeue_fn, called when a request is taken off the active list
141da177e4SLinus Torvalds  *
151da177e4SLinus Torvalds  * 20082000 Dave Jones <davej@suse.de> :
161da177e4SLinus Torvalds  * Removed tests for max-bomb-segments, which was breaking elvtune
171da177e4SLinus Torvalds  *  when run without -bN
181da177e4SLinus Torvalds  *
191da177e4SLinus Torvalds  * Jens:
201da177e4SLinus Torvalds  * - Rework again to work with bio instead of buffer_heads
211da177e4SLinus Torvalds  * - loose bi_dev comparisons, partition handling is right now
221da177e4SLinus Torvalds  * - completely modularize elevator setup and teardown
231da177e4SLinus Torvalds  *
241da177e4SLinus Torvalds  */
251da177e4SLinus Torvalds #include <linux/kernel.h>
261da177e4SLinus Torvalds #include <linux/fs.h>
271da177e4SLinus Torvalds #include <linux/blkdev.h>
281da177e4SLinus Torvalds #include <linux/elevator.h>
291da177e4SLinus Torvalds #include <linux/bio.h>
301da177e4SLinus Torvalds #include <linux/module.h>
311da177e4SLinus Torvalds #include <linux/slab.h>
321da177e4SLinus Torvalds #include <linux/init.h>
331da177e4SLinus Torvalds #include <linux/compiler.h>
342056a782SJens Axboe #include <linux/blktrace_api.h>
359817064bSJens Axboe #include <linux/hash.h>
360835da67SJens Axboe #include <linux/uaccess.h>
371da177e4SLinus Torvalds 
3855782138SLi Zefan #include <trace/events/block.h>
3955782138SLi Zefan 
40242f9dcbSJens Axboe #include "blk.h"
4172e06c25STejun Heo #include "blk-cgroup.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 
6522f746e2STejun Heo 	if (e->type->ops.elevator_allow_merge_fn)
6622f746e2STejun Heo 		return e->type->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  */
74050c8ea8STejun Heo bool elv_rq_merge_ok(struct request *rq, struct bio *bio)
751da177e4SLinus Torvalds {
76050c8ea8STejun Heo 	if (!blk_rq_merge_ok(rq, bio))
777ba1ba12SMartin K. Petersen 		return 0;
787ba1ba12SMartin K. Petersen 
79da775265SJens Axboe 	if (!elv_iosched_allow_merge(rq, bio))
80da775265SJens Axboe 		return 0;
81da775265SJens Axboe 
82da775265SJens Axboe 	return 1;
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds EXPORT_SYMBOL(elv_rq_merge_ok);
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds static struct elevator_type *elevator_find(const char *name)
871da177e4SLinus Torvalds {
88a22b169dSVasily Tarasov 	struct elevator_type *e;
891da177e4SLinus Torvalds 
9070cee26eSMatthias Kaehlcke 	list_for_each_entry(e, &elv_list, list) {
91a22b169dSVasily Tarasov 		if (!strcmp(e->elevator_name, name))
921da177e4SLinus Torvalds 			return e;
931da177e4SLinus Torvalds 	}
941da177e4SLinus Torvalds 
95a22b169dSVasily Tarasov 	return NULL;
96a22b169dSVasily Tarasov }
97a22b169dSVasily Tarasov 
981da177e4SLinus Torvalds static void elevator_put(struct elevator_type *e)
991da177e4SLinus Torvalds {
1001da177e4SLinus Torvalds 	module_put(e->elevator_owner);
1011da177e4SLinus Torvalds }
1021da177e4SLinus Torvalds 
1031da177e4SLinus Torvalds static struct elevator_type *elevator_get(const char *name)
1041da177e4SLinus Torvalds {
1052824bc93STejun Heo 	struct elevator_type *e;
1061da177e4SLinus Torvalds 
1072a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
1082824bc93STejun Heo 
1092824bc93STejun Heo 	e = elevator_find(name);
110e1640949SJens Axboe 	if (!e) {
111e1640949SJens Axboe 		spin_unlock(&elv_list_lock);
112490b94beSKees Cook 		request_module("%s-iosched", name);
113e1640949SJens Axboe 		spin_lock(&elv_list_lock);
114e1640949SJens Axboe 		e = elevator_find(name);
115e1640949SJens Axboe 	}
116e1640949SJens Axboe 
1172824bc93STejun Heo 	if (e && !try_module_get(e->elevator_owner))
1182824bc93STejun Heo 		e = NULL;
1192824bc93STejun Heo 
1202a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
1211da177e4SLinus Torvalds 
1221da177e4SLinus Torvalds 	return e;
1231da177e4SLinus Torvalds }
1241da177e4SLinus Torvalds 
125484fc254SWang Sheng-Hui static char chosen_elevator[ELV_NAME_MAX];
1261da177e4SLinus Torvalds 
1275f003976SNate Diller static int __init elevator_setup(char *str)
1281da177e4SLinus Torvalds {
129752a3b79SChuck Ebbert 	/*
130752a3b79SChuck Ebbert 	 * Be backwards-compatible with previous kernels, so users
131752a3b79SChuck Ebbert 	 * won't get the wrong elevator.
132752a3b79SChuck Ebbert 	 */
1331da177e4SLinus Torvalds 	strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
1349b41046cSOGAWA Hirofumi 	return 1;
1351da177e4SLinus Torvalds }
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds __setup("elevator=", elevator_setup);
1381da177e4SLinus Torvalds 
1393d1ab40fSAl Viro static struct kobj_type elv_ktype;
1403d1ab40fSAl Viro 
141b374d18aSJens Axboe static struct elevator_queue *elevator_alloc(struct request_queue *q,
142165125e1SJens Axboe 				  struct elevator_type *e)
1433d1ab40fSAl Viro {
144b374d18aSJens Axboe 	struct elevator_queue *eq;
1459817064bSJens Axboe 	int i;
1469817064bSJens Axboe 
147b374d18aSJens Axboe 	eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node);
1489817064bSJens Axboe 	if (unlikely(!eq))
1499817064bSJens Axboe 		goto err;
1509817064bSJens Axboe 
15122f746e2STejun Heo 	eq->type = e;
152f9cb074bSGreg Kroah-Hartman 	kobject_init(&eq->kobj, &elv_ktype);
1533d1ab40fSAl Viro 	mutex_init(&eq->sysfs_lock);
1549817064bSJens Axboe 
155b5deef90SJens Axboe 	eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
156b5deef90SJens Axboe 					GFP_KERNEL, q->node);
1579817064bSJens Axboe 	if (!eq->hash)
1589817064bSJens Axboe 		goto err;
1599817064bSJens Axboe 
1609817064bSJens Axboe 	for (i = 0; i < ELV_HASH_ENTRIES; i++)
1619817064bSJens Axboe 		INIT_HLIST_HEAD(&eq->hash[i]);
1629817064bSJens Axboe 
1633d1ab40fSAl Viro 	return eq;
1649817064bSJens Axboe err:
1659817064bSJens Axboe 	kfree(eq);
1669817064bSJens Axboe 	elevator_put(e);
1679817064bSJens Axboe 	return NULL;
1683d1ab40fSAl Viro }
1693d1ab40fSAl Viro 
1703d1ab40fSAl Viro static void elevator_release(struct kobject *kobj)
1713d1ab40fSAl Viro {
172b374d18aSJens Axboe 	struct elevator_queue *e;
1739817064bSJens Axboe 
174b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
17522f746e2STejun Heo 	elevator_put(e->type);
1769817064bSJens Axboe 	kfree(e->hash);
1773d1ab40fSAl Viro 	kfree(e);
1783d1ab40fSAl Viro }
1793d1ab40fSAl Viro 
180165125e1SJens Axboe int elevator_init(struct request_queue *q, char *name)
1811da177e4SLinus Torvalds {
1821da177e4SLinus Torvalds 	struct elevator_type *e = NULL;
183f8fc877dSTejun Heo 	int err;
1841da177e4SLinus Torvalds 
1851abec4fdSMike Snitzer 	if (unlikely(q->elevator))
1861abec4fdSMike Snitzer 		return 0;
1871abec4fdSMike Snitzer 
188cb98fc8bSTejun Heo 	INIT_LIST_HEAD(&q->queue_head);
189cb98fc8bSTejun Heo 	q->last_merge = NULL;
190cb98fc8bSTejun Heo 	q->end_sector = 0;
191cb98fc8bSTejun Heo 	q->boundary_rq = NULL;
192cb98fc8bSTejun Heo 
1934eb166d9SJens Axboe 	if (name) {
1944eb166d9SJens Axboe 		e = elevator_get(name);
1954eb166d9SJens Axboe 		if (!e)
1961da177e4SLinus Torvalds 			return -EINVAL;
1974eb166d9SJens Axboe 	}
1981da177e4SLinus Torvalds 
1994eb166d9SJens Axboe 	if (!e && *chosen_elevator) {
2004eb166d9SJens Axboe 		e = elevator_get(chosen_elevator);
2014eb166d9SJens Axboe 		if (!e)
2024eb166d9SJens Axboe 			printk(KERN_ERR "I/O scheduler %s not found\n",
2034eb166d9SJens Axboe 							chosen_elevator);
2044eb166d9SJens Axboe 	}
205248d5ca5SNate Diller 
2064eb166d9SJens Axboe 	if (!e) {
2074eb166d9SJens Axboe 		e = elevator_get(CONFIG_DEFAULT_IOSCHED);
2084eb166d9SJens Axboe 		if (!e) {
2094eb166d9SJens Axboe 			printk(KERN_ERR
2104eb166d9SJens Axboe 				"Default I/O scheduler not found. " \
2114eb166d9SJens Axboe 				"Using noop.\n");
212248d5ca5SNate Diller 			e = elevator_get("noop");
2135f003976SNate Diller 		}
2144eb166d9SJens Axboe 	}
2155f003976SNate Diller 
2165a5bafdcSTejun Heo 	q->elevator = elevator_alloc(q, e);
2175a5bafdcSTejun Heo 	if (!q->elevator)
2181da177e4SLinus Torvalds 		return -ENOMEM;
2191da177e4SLinus Torvalds 
220b2fab5acSTejun Heo 	err = e->ops.elevator_init_fn(q);
221f8fc877dSTejun Heo 	if (err) {
2225a5bafdcSTejun Heo 		kobject_put(&q->elevator->kobj);
223f8fc877dSTejun Heo 		return err;
224bc1c1169SJens Axboe 	}
2251da177e4SLinus Torvalds 
2261abec4fdSMike Snitzer 	return 0;
2271da177e4SLinus Torvalds }
2282e662b65SJens Axboe EXPORT_SYMBOL(elevator_init);
2292e662b65SJens Axboe 
230b374d18aSJens Axboe void elevator_exit(struct elevator_queue *e)
2311da177e4SLinus Torvalds {
2323d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
23322f746e2STejun Heo 	if (e->type->ops.elevator_exit_fn)
23422f746e2STejun Heo 		e->type->ops.elevator_exit_fn(e);
2353d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
2361da177e4SLinus Torvalds 
2373d1ab40fSAl Viro 	kobject_put(&e->kobj);
2381da177e4SLinus Torvalds }
2392e662b65SJens Axboe EXPORT_SYMBOL(elevator_exit);
2402e662b65SJens Axboe 
2419817064bSJens Axboe static inline void __elv_rqhash_del(struct request *rq)
2429817064bSJens Axboe {
2439817064bSJens Axboe 	hlist_del_init(&rq->hash);
2449817064bSJens Axboe }
2459817064bSJens Axboe 
246165125e1SJens Axboe static void elv_rqhash_del(struct request_queue *q, struct request *rq)
2479817064bSJens Axboe {
2489817064bSJens Axboe 	if (ELV_ON_HASH(rq))
2499817064bSJens Axboe 		__elv_rqhash_del(rq);
2509817064bSJens Axboe }
2519817064bSJens Axboe 
252165125e1SJens Axboe static void elv_rqhash_add(struct request_queue *q, struct request *rq)
2539817064bSJens Axboe {
254b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
2559817064bSJens Axboe 
2569817064bSJens Axboe 	BUG_ON(ELV_ON_HASH(rq));
2579817064bSJens Axboe 	hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
2589817064bSJens Axboe }
2599817064bSJens Axboe 
260165125e1SJens Axboe static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
2619817064bSJens Axboe {
2629817064bSJens Axboe 	__elv_rqhash_del(rq);
2639817064bSJens Axboe 	elv_rqhash_add(q, rq);
2649817064bSJens Axboe }
2659817064bSJens Axboe 
266165125e1SJens Axboe static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
2679817064bSJens Axboe {
268b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
2699817064bSJens Axboe 	struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
2709817064bSJens Axboe 	struct hlist_node *entry, *next;
2719817064bSJens Axboe 	struct request *rq;
2729817064bSJens Axboe 
2739817064bSJens Axboe 	hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
2749817064bSJens Axboe 		BUG_ON(!ELV_ON_HASH(rq));
2759817064bSJens Axboe 
2769817064bSJens Axboe 		if (unlikely(!rq_mergeable(rq))) {
2779817064bSJens Axboe 			__elv_rqhash_del(rq);
2789817064bSJens Axboe 			continue;
2799817064bSJens Axboe 		}
2809817064bSJens Axboe 
2819817064bSJens Axboe 		if (rq_hash_key(rq) == offset)
2829817064bSJens Axboe 			return rq;
2839817064bSJens Axboe 	}
2849817064bSJens Axboe 
2859817064bSJens Axboe 	return NULL;
2869817064bSJens Axboe }
2879817064bSJens Axboe 
2888922e16cSTejun Heo /*
2892e662b65SJens Axboe  * RB-tree support functions for inserting/lookup/removal of requests
2902e662b65SJens Axboe  * in a sorted RB tree.
2912e662b65SJens Axboe  */
292796d5116SJeff Moyer void elv_rb_add(struct rb_root *root, struct request *rq)
2932e662b65SJens Axboe {
2942e662b65SJens Axboe 	struct rb_node **p = &root->rb_node;
2952e662b65SJens Axboe 	struct rb_node *parent = NULL;
2962e662b65SJens Axboe 	struct request *__rq;
2972e662b65SJens Axboe 
2982e662b65SJens Axboe 	while (*p) {
2992e662b65SJens Axboe 		parent = *p;
3002e662b65SJens Axboe 		__rq = rb_entry(parent, struct request, rb_node);
3012e662b65SJens Axboe 
30283096ebfSTejun Heo 		if (blk_rq_pos(rq) < blk_rq_pos(__rq))
3032e662b65SJens Axboe 			p = &(*p)->rb_left;
304796d5116SJeff Moyer 		else if (blk_rq_pos(rq) >= blk_rq_pos(__rq))
3052e662b65SJens Axboe 			p = &(*p)->rb_right;
3062e662b65SJens Axboe 	}
3072e662b65SJens Axboe 
3082e662b65SJens Axboe 	rb_link_node(&rq->rb_node, parent, p);
3092e662b65SJens Axboe 	rb_insert_color(&rq->rb_node, root);
3102e662b65SJens Axboe }
3112e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_add);
3122e662b65SJens Axboe 
3132e662b65SJens Axboe void elv_rb_del(struct rb_root *root, struct request *rq)
3142e662b65SJens Axboe {
3152e662b65SJens Axboe 	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
3162e662b65SJens Axboe 	rb_erase(&rq->rb_node, root);
3172e662b65SJens Axboe 	RB_CLEAR_NODE(&rq->rb_node);
3182e662b65SJens Axboe }
3192e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_del);
3202e662b65SJens Axboe 
3212e662b65SJens Axboe struct request *elv_rb_find(struct rb_root *root, sector_t sector)
3222e662b65SJens Axboe {
3232e662b65SJens Axboe 	struct rb_node *n = root->rb_node;
3242e662b65SJens Axboe 	struct request *rq;
3252e662b65SJens Axboe 
3262e662b65SJens Axboe 	while (n) {
3272e662b65SJens Axboe 		rq = rb_entry(n, struct request, rb_node);
3282e662b65SJens Axboe 
32983096ebfSTejun Heo 		if (sector < blk_rq_pos(rq))
3302e662b65SJens Axboe 			n = n->rb_left;
33183096ebfSTejun Heo 		else if (sector > blk_rq_pos(rq))
3322e662b65SJens Axboe 			n = n->rb_right;
3332e662b65SJens Axboe 		else
3342e662b65SJens Axboe 			return rq;
3352e662b65SJens Axboe 	}
3362e662b65SJens Axboe 
3372e662b65SJens Axboe 	return NULL;
3382e662b65SJens Axboe }
3392e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_find);
3402e662b65SJens Axboe 
3412e662b65SJens Axboe /*
3428922e16cSTejun Heo  * Insert rq into dispatch queue of q.  Queue lock must be held on
343dbe7f76dSUwe Kleine-König  * entry.  rq is sort instead into the dispatch queue. To be used by
3442e662b65SJens Axboe  * specific elevators.
3458922e16cSTejun Heo  */
346165125e1SJens Axboe void elv_dispatch_sort(struct request_queue *q, struct request *rq)
3478922e16cSTejun Heo {
3488922e16cSTejun Heo 	sector_t boundary;
3498922e16cSTejun Heo 	struct list_head *entry;
3504eb166d9SJens Axboe 	int stop_flags;
3518922e16cSTejun Heo 
35206b86245STejun Heo 	if (q->last_merge == rq)
35306b86245STejun Heo 		q->last_merge = NULL;
3549817064bSJens Axboe 
3559817064bSJens Axboe 	elv_rqhash_del(q, rq);
3569817064bSJens Axboe 
35715853af9STejun Heo 	q->nr_sorted--;
35806b86245STejun Heo 
3591b47f531SJens Axboe 	boundary = q->end_sector;
36002e031cbSChristoph Hellwig 	stop_flags = REQ_SOFTBARRIER | REQ_STARTED;
3618922e16cSTejun Heo 	list_for_each_prev(entry, &q->queue_head) {
3628922e16cSTejun Heo 		struct request *pos = list_entry_rq(entry);
3638922e16cSTejun Heo 
36433659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_DISCARD) !=
36533659ebbSChristoph Hellwig 		    (pos->cmd_flags & REQ_DISCARD))
366e17fc0a1SDavid Woodhouse 			break;
367783660b2SJens Axboe 		if (rq_data_dir(rq) != rq_data_dir(pos))
368783660b2SJens Axboe 			break;
3694eb166d9SJens Axboe 		if (pos->cmd_flags & stop_flags)
3708922e16cSTejun Heo 			break;
37183096ebfSTejun Heo 		if (blk_rq_pos(rq) >= boundary) {
37283096ebfSTejun Heo 			if (blk_rq_pos(pos) < boundary)
3738922e16cSTejun Heo 				continue;
3748922e16cSTejun Heo 		} else {
37583096ebfSTejun Heo 			if (blk_rq_pos(pos) >= boundary)
3768922e16cSTejun Heo 				break;
3778922e16cSTejun Heo 		}
37883096ebfSTejun Heo 		if (blk_rq_pos(rq) >= blk_rq_pos(pos))
3798922e16cSTejun Heo 			break;
3808922e16cSTejun Heo 	}
3818922e16cSTejun Heo 
3828922e16cSTejun Heo 	list_add(&rq->queuelist, entry);
3838922e16cSTejun Heo }
3842e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_sort);
3852e662b65SJens Axboe 
3869817064bSJens Axboe /*
3872e662b65SJens Axboe  * Insert rq into dispatch queue of q.  Queue lock must be held on
3882e662b65SJens Axboe  * entry.  rq is added to the back of the dispatch queue. To be used by
3892e662b65SJens Axboe  * specific elevators.
3909817064bSJens Axboe  */
3919817064bSJens Axboe void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
3929817064bSJens Axboe {
3939817064bSJens Axboe 	if (q->last_merge == rq)
3949817064bSJens Axboe 		q->last_merge = NULL;
3959817064bSJens Axboe 
3969817064bSJens Axboe 	elv_rqhash_del(q, rq);
3979817064bSJens Axboe 
3989817064bSJens Axboe 	q->nr_sorted--;
3999817064bSJens Axboe 
4009817064bSJens Axboe 	q->end_sector = rq_end_sector(rq);
4019817064bSJens Axboe 	q->boundary_rq = rq;
4029817064bSJens Axboe 	list_add_tail(&rq->queuelist, &q->queue_head);
4039817064bSJens Axboe }
4042e662b65SJens Axboe EXPORT_SYMBOL(elv_dispatch_add_tail);
4052e662b65SJens Axboe 
406165125e1SJens Axboe int elv_merge(struct request_queue *q, struct request **req, struct bio *bio)
4071da177e4SLinus Torvalds {
408b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
4099817064bSJens Axboe 	struct request *__rq;
41006b86245STejun Heo 	int ret;
41106b86245STejun Heo 
4129817064bSJens Axboe 	/*
413488991e2SAlan D. Brunelle 	 * Levels of merges:
414488991e2SAlan D. Brunelle 	 * 	nomerges:  No merges at all attempted
415488991e2SAlan D. Brunelle 	 * 	noxmerges: Only simple one-hit cache try
416488991e2SAlan D. Brunelle 	 * 	merges:	   All merge tries attempted
417488991e2SAlan D. Brunelle 	 */
418488991e2SAlan D. Brunelle 	if (blk_queue_nomerges(q))
419488991e2SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
420488991e2SAlan D. Brunelle 
421488991e2SAlan D. Brunelle 	/*
4229817064bSJens Axboe 	 * First try one-hit cache.
4239817064bSJens Axboe 	 */
424050c8ea8STejun Heo 	if (q->last_merge && elv_rq_merge_ok(q->last_merge, bio)) {
425050c8ea8STejun Heo 		ret = blk_try_merge(q->last_merge, bio);
42606b86245STejun Heo 		if (ret != ELEVATOR_NO_MERGE) {
42706b86245STejun Heo 			*req = q->last_merge;
42806b86245STejun Heo 			return ret;
42906b86245STejun Heo 		}
43006b86245STejun Heo 	}
4311da177e4SLinus Torvalds 
432488991e2SAlan D. Brunelle 	if (blk_queue_noxmerges(q))
433ac9fafa1SAlan D. Brunelle 		return ELEVATOR_NO_MERGE;
434ac9fafa1SAlan D. Brunelle 
4359817064bSJens Axboe 	/*
4369817064bSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
4379817064bSJens Axboe 	 */
4389817064bSJens Axboe 	__rq = elv_rqhash_find(q, bio->bi_sector);
4399817064bSJens Axboe 	if (__rq && elv_rq_merge_ok(__rq, bio)) {
4409817064bSJens Axboe 		*req = __rq;
4419817064bSJens Axboe 		return ELEVATOR_BACK_MERGE;
4429817064bSJens Axboe 	}
4439817064bSJens Axboe 
44422f746e2STejun Heo 	if (e->type->ops.elevator_merge_fn)
44522f746e2STejun Heo 		return e->type->ops.elevator_merge_fn(q, req, bio);
4461da177e4SLinus Torvalds 
4471da177e4SLinus Torvalds 	return ELEVATOR_NO_MERGE;
4481da177e4SLinus Torvalds }
4491da177e4SLinus Torvalds 
4505e84ea3aSJens Axboe /*
4515e84ea3aSJens Axboe  * Attempt to do an insertion back merge. Only check for the case where
4525e84ea3aSJens Axboe  * we can append 'rq' to an existing request, so we can throw 'rq' away
4535e84ea3aSJens Axboe  * afterwards.
4545e84ea3aSJens Axboe  *
4555e84ea3aSJens Axboe  * Returns true if we merged, false otherwise
4565e84ea3aSJens Axboe  */
4575e84ea3aSJens Axboe static bool elv_attempt_insert_merge(struct request_queue *q,
4585e84ea3aSJens Axboe 				     struct request *rq)
4595e84ea3aSJens Axboe {
4605e84ea3aSJens Axboe 	struct request *__rq;
4615e84ea3aSJens Axboe 
4625e84ea3aSJens Axboe 	if (blk_queue_nomerges(q))
4635e84ea3aSJens Axboe 		return false;
4645e84ea3aSJens Axboe 
4655e84ea3aSJens Axboe 	/*
4665e84ea3aSJens Axboe 	 * First try one-hit cache.
4675e84ea3aSJens Axboe 	 */
4685e84ea3aSJens Axboe 	if (q->last_merge && blk_attempt_req_merge(q, q->last_merge, rq))
4695e84ea3aSJens Axboe 		return true;
4705e84ea3aSJens Axboe 
4715e84ea3aSJens Axboe 	if (blk_queue_noxmerges(q))
4725e84ea3aSJens Axboe 		return false;
4735e84ea3aSJens Axboe 
4745e84ea3aSJens Axboe 	/*
4755e84ea3aSJens Axboe 	 * See if our hash lookup can find a potential backmerge.
4765e84ea3aSJens Axboe 	 */
4775e84ea3aSJens Axboe 	__rq = elv_rqhash_find(q, blk_rq_pos(rq));
4785d381efbSJens Axboe 	if (__rq && blk_attempt_req_merge(q, __rq, rq))
4795d381efbSJens Axboe 		return true;
4805e84ea3aSJens Axboe 
4815d381efbSJens Axboe 	return false;
4825e84ea3aSJens Axboe }
4835e84ea3aSJens Axboe 
484165125e1SJens Axboe void elv_merged_request(struct request_queue *q, struct request *rq, int type)
4851da177e4SLinus Torvalds {
486b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
4871da177e4SLinus Torvalds 
48822f746e2STejun Heo 	if (e->type->ops.elevator_merged_fn)
48922f746e2STejun Heo 		e->type->ops.elevator_merged_fn(q, rq, type);
49006b86245STejun Heo 
4912e662b65SJens Axboe 	if (type == ELEVATOR_BACK_MERGE)
4929817064bSJens Axboe 		elv_rqhash_reposition(q, rq);
4939817064bSJens Axboe 
49406b86245STejun Heo 	q->last_merge = rq;
4951da177e4SLinus Torvalds }
4961da177e4SLinus Torvalds 
497165125e1SJens Axboe void elv_merge_requests(struct request_queue *q, struct request *rq,
4981da177e4SLinus Torvalds 			     struct request *next)
4991da177e4SLinus Torvalds {
500b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
5015e84ea3aSJens Axboe 	const int next_sorted = next->cmd_flags & REQ_SORTED;
5021da177e4SLinus Torvalds 
50322f746e2STejun Heo 	if (next_sorted && e->type->ops.elevator_merge_req_fn)
50422f746e2STejun Heo 		e->type->ops.elevator_merge_req_fn(q, rq, next);
50506b86245STejun Heo 
5069817064bSJens Axboe 	elv_rqhash_reposition(q, rq);
5079817064bSJens Axboe 
5085e84ea3aSJens Axboe 	if (next_sorted) {
5095e84ea3aSJens Axboe 		elv_rqhash_del(q, next);
5109817064bSJens Axboe 		q->nr_sorted--;
5115e84ea3aSJens Axboe 	}
5125e84ea3aSJens Axboe 
51306b86245STejun Heo 	q->last_merge = rq;
5141da177e4SLinus Torvalds }
5151da177e4SLinus Torvalds 
516812d4026SDivyesh Shah void elv_bio_merged(struct request_queue *q, struct request *rq,
517812d4026SDivyesh Shah 			struct bio *bio)
518812d4026SDivyesh Shah {
519812d4026SDivyesh Shah 	struct elevator_queue *e = q->elevator;
520812d4026SDivyesh Shah 
52122f746e2STejun Heo 	if (e->type->ops.elevator_bio_merged_fn)
52222f746e2STejun Heo 		e->type->ops.elevator_bio_merged_fn(q, rq, bio);
523812d4026SDivyesh Shah }
524812d4026SDivyesh Shah 
525165125e1SJens Axboe void elv_requeue_request(struct request_queue *q, struct request *rq)
5261da177e4SLinus Torvalds {
5271da177e4SLinus Torvalds 	/*
5281da177e4SLinus Torvalds 	 * it already went through dequeue, we need to decrement the
5291da177e4SLinus Torvalds 	 * in_flight count again
5301da177e4SLinus Torvalds 	 */
5318922e16cSTejun Heo 	if (blk_account_rq(rq)) {
5320a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
53333659ebbSChristoph Hellwig 		if (rq->cmd_flags & REQ_SORTED)
534cad97516SJens Axboe 			elv_deactivate_rq(q, rq);
5351da177e4SLinus Torvalds 	}
5361da177e4SLinus Torvalds 
5374aff5e23SJens Axboe 	rq->cmd_flags &= ~REQ_STARTED;
5381da177e4SLinus Torvalds 
539b710a480SJens Axboe 	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE);
5401da177e4SLinus Torvalds }
5411da177e4SLinus Torvalds 
54226308eabSJerome Marchand void elv_drain_elevator(struct request_queue *q)
54315853af9STejun Heo {
54415853af9STejun Heo 	static int printed;
545e3c78ca5STejun Heo 
546e3c78ca5STejun Heo 	lockdep_assert_held(q->queue_lock);
547e3c78ca5STejun Heo 
54822f746e2STejun Heo 	while (q->elevator->type->ops.elevator_dispatch_fn(q, 1))
54915853af9STejun Heo 		;
550e3c78ca5STejun Heo 	if (q->nr_sorted && printed++ < 10) {
55115853af9STejun Heo 		printk(KERN_ERR "%s: forced dispatching is broken "
55215853af9STejun Heo 		       "(nr_sorted=%u), please report this\n",
55322f746e2STejun Heo 		       q->elevator->type->elevator_name, q->nr_sorted);
55415853af9STejun Heo 	}
55515853af9STejun Heo }
55615853af9STejun Heo 
557b710a480SJens Axboe void __elv_add_request(struct request_queue *q, struct request *rq, int where)
5581da177e4SLinus Torvalds {
5595f3ea37cSArnaldo Carvalho de Melo 	trace_block_rq_insert(q, rq);
5602056a782SJens Axboe 
5611da177e4SLinus Torvalds 	rq->q = q;
5621da177e4SLinus Torvalds 
563b710a480SJens Axboe 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
564b710a480SJens Axboe 		/* barriers are scheduling boundary, update end_sector */
565b710a480SJens Axboe 		if (rq->cmd_type == REQ_TYPE_FS ||
566b710a480SJens Axboe 		    (rq->cmd_flags & REQ_DISCARD)) {
567b710a480SJens Axboe 			q->end_sector = rq_end_sector(rq);
568b710a480SJens Axboe 			q->boundary_rq = rq;
569b710a480SJens Axboe 		}
570b710a480SJens Axboe 	} else if (!(rq->cmd_flags & REQ_ELVPRIV) &&
5713aa72873SJens Axboe 		    (where == ELEVATOR_INSERT_SORT ||
5723aa72873SJens Axboe 		     where == ELEVATOR_INSERT_SORT_MERGE))
573b710a480SJens Axboe 		where = ELEVATOR_INSERT_BACK;
574b710a480SJens Axboe 
5758922e16cSTejun Heo 	switch (where) {
57628e7d184STejun Heo 	case ELEVATOR_INSERT_REQUEUE:
5778922e16cSTejun Heo 	case ELEVATOR_INSERT_FRONT:
5784aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
5798922e16cSTejun Heo 		list_add(&rq->queuelist, &q->queue_head);
5808922e16cSTejun Heo 		break;
5818922e16cSTejun Heo 
5828922e16cSTejun Heo 	case ELEVATOR_INSERT_BACK:
5834aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SOFTBARRIER;
58415853af9STejun Heo 		elv_drain_elevator(q);
5858922e16cSTejun Heo 		list_add_tail(&rq->queuelist, &q->queue_head);
5868922e16cSTejun Heo 		/*
5878922e16cSTejun Heo 		 * We kick the queue here for the following reasons.
5888922e16cSTejun Heo 		 * - The elevator might have returned NULL previously
5898922e16cSTejun Heo 		 *   to delay requests and returned them now.  As the
5908922e16cSTejun Heo 		 *   queue wasn't empty before this request, ll_rw_blk
5918922e16cSTejun Heo 		 *   won't run the queue on return, resulting in hang.
5928922e16cSTejun Heo 		 * - Usually, back inserted requests won't be merged
5938922e16cSTejun Heo 		 *   with anything.  There's no point in delaying queue
5948922e16cSTejun Heo 		 *   processing.
5958922e16cSTejun Heo 		 */
59624ecfbe2SChristoph Hellwig 		__blk_run_queue(q);
5978922e16cSTejun Heo 		break;
5988922e16cSTejun Heo 
5995e84ea3aSJens Axboe 	case ELEVATOR_INSERT_SORT_MERGE:
6005e84ea3aSJens Axboe 		/*
6015e84ea3aSJens Axboe 		 * If we succeed in merging this request with one in the
6025e84ea3aSJens Axboe 		 * queue already, we are done - rq has now been freed,
6035e84ea3aSJens Axboe 		 * so no need to do anything further.
6045e84ea3aSJens Axboe 		 */
6055e84ea3aSJens Axboe 		if (elv_attempt_insert_merge(q, rq))
6065e84ea3aSJens Axboe 			break;
6078922e16cSTejun Heo 	case ELEVATOR_INSERT_SORT:
60833659ebbSChristoph Hellwig 		BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
60933659ebbSChristoph Hellwig 		       !(rq->cmd_flags & REQ_DISCARD));
6104aff5e23SJens Axboe 		rq->cmd_flags |= REQ_SORTED;
61115853af9STejun Heo 		q->nr_sorted++;
6129817064bSJens Axboe 		if (rq_mergeable(rq)) {
6139817064bSJens Axboe 			elv_rqhash_add(q, rq);
6149817064bSJens Axboe 			if (!q->last_merge)
61506b86245STejun Heo 				q->last_merge = rq;
6169817064bSJens Axboe 		}
6179817064bSJens Axboe 
618ca23509fSTejun Heo 		/*
619ca23509fSTejun Heo 		 * Some ioscheds (cfq) run q->request_fn directly, so
620ca23509fSTejun Heo 		 * rq cannot be accessed after calling
621ca23509fSTejun Heo 		 * elevator_add_req_fn.
622ca23509fSTejun Heo 		 */
62322f746e2STejun Heo 		q->elevator->type->ops.elevator_add_req_fn(q, rq);
6248922e16cSTejun Heo 		break;
6258922e16cSTejun Heo 
626ae1b1539STejun Heo 	case ELEVATOR_INSERT_FLUSH:
627ae1b1539STejun Heo 		rq->cmd_flags |= REQ_SOFTBARRIER;
628ae1b1539STejun Heo 		blk_insert_flush(rq);
629ae1b1539STejun Heo 		break;
6308922e16cSTejun Heo 	default:
6318922e16cSTejun Heo 		printk(KERN_ERR "%s: bad insertion point %d\n",
63224c03d47SHarvey Harrison 		       __func__, where);
6338922e16cSTejun Heo 		BUG();
6348922e16cSTejun Heo 	}
6351da177e4SLinus Torvalds }
6362e662b65SJens Axboe EXPORT_SYMBOL(__elv_add_request);
6372e662b65SJens Axboe 
6387eaceaccSJens Axboe void elv_add_request(struct request_queue *q, struct request *rq, int where)
6391da177e4SLinus Torvalds {
6401da177e4SLinus Torvalds 	unsigned long flags;
6411da177e4SLinus Torvalds 
6421da177e4SLinus Torvalds 	spin_lock_irqsave(q->queue_lock, flags);
6437eaceaccSJens Axboe 	__elv_add_request(q, rq, where);
6441da177e4SLinus Torvalds 	spin_unlock_irqrestore(q->queue_lock, flags);
6451da177e4SLinus Torvalds }
6462e662b65SJens Axboe EXPORT_SYMBOL(elv_add_request);
6472e662b65SJens Axboe 
648165125e1SJens Axboe struct request *elv_latter_request(struct request_queue *q, struct request *rq)
6491da177e4SLinus Torvalds {
650b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6511da177e4SLinus Torvalds 
65222f746e2STejun Heo 	if (e->type->ops.elevator_latter_req_fn)
65322f746e2STejun Heo 		return e->type->ops.elevator_latter_req_fn(q, rq);
6541da177e4SLinus Torvalds 	return NULL;
6551da177e4SLinus Torvalds }
6561da177e4SLinus Torvalds 
657165125e1SJens Axboe struct request *elv_former_request(struct request_queue *q, struct request *rq)
6581da177e4SLinus Torvalds {
659b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6601da177e4SLinus Torvalds 
66122f746e2STejun Heo 	if (e->type->ops.elevator_former_req_fn)
66222f746e2STejun Heo 		return e->type->ops.elevator_former_req_fn(q, rq);
6631da177e4SLinus Torvalds 	return NULL;
6641da177e4SLinus Torvalds }
6651da177e4SLinus Torvalds 
666165125e1SJens Axboe int elv_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
6671da177e4SLinus Torvalds {
668b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6691da177e4SLinus Torvalds 
67022f746e2STejun Heo 	if (e->type->ops.elevator_set_req_fn)
67122f746e2STejun Heo 		return e->type->ops.elevator_set_req_fn(q, rq, gfp_mask);
6721da177e4SLinus Torvalds 	return 0;
6731da177e4SLinus Torvalds }
6741da177e4SLinus Torvalds 
675165125e1SJens Axboe void elv_put_request(struct request_queue *q, struct request *rq)
6761da177e4SLinus Torvalds {
677b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6781da177e4SLinus Torvalds 
67922f746e2STejun Heo 	if (e->type->ops.elevator_put_req_fn)
68022f746e2STejun Heo 		e->type->ops.elevator_put_req_fn(rq);
6811da177e4SLinus Torvalds }
6821da177e4SLinus Torvalds 
683165125e1SJens Axboe int elv_may_queue(struct request_queue *q, int rw)
6841da177e4SLinus Torvalds {
685b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
6861da177e4SLinus Torvalds 
68722f746e2STejun Heo 	if (e->type->ops.elevator_may_queue_fn)
68822f746e2STejun Heo 		return e->type->ops.elevator_may_queue_fn(q, rw);
6891da177e4SLinus Torvalds 
6901da177e4SLinus Torvalds 	return ELV_MQUEUE_MAY;
6911da177e4SLinus Torvalds }
6921da177e4SLinus Torvalds 
69311914a53SMike Anderson void elv_abort_queue(struct request_queue *q)
69411914a53SMike Anderson {
69511914a53SMike Anderson 	struct request *rq;
69611914a53SMike Anderson 
697ae1b1539STejun Heo 	blk_abort_flushes(q);
698ae1b1539STejun Heo 
69911914a53SMike Anderson 	while (!list_empty(&q->queue_head)) {
70011914a53SMike Anderson 		rq = list_entry_rq(q->queue_head.next);
70111914a53SMike Anderson 		rq->cmd_flags |= REQ_QUIET;
7025f3ea37cSArnaldo Carvalho de Melo 		trace_block_rq_abort(q, rq);
70353c663ceSKiyoshi Ueda 		/*
70453c663ceSKiyoshi Ueda 		 * Mark this request as started so we don't trigger
70553c663ceSKiyoshi Ueda 		 * any debug logic in the end I/O path.
70653c663ceSKiyoshi Ueda 		 */
70753c663ceSKiyoshi Ueda 		blk_start_request(rq);
70840cbbb78STejun Heo 		__blk_end_request_all(rq, -EIO);
70911914a53SMike Anderson 	}
71011914a53SMike Anderson }
71111914a53SMike Anderson EXPORT_SYMBOL(elv_abort_queue);
71211914a53SMike Anderson 
713165125e1SJens Axboe void elv_completed_request(struct request_queue *q, struct request *rq)
7141da177e4SLinus Torvalds {
715b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
7161da177e4SLinus Torvalds 
7171da177e4SLinus Torvalds 	/*
7181da177e4SLinus Torvalds 	 * request is released from the driver, io must be done
7191da177e4SLinus Torvalds 	 */
7208922e16cSTejun Heo 	if (blk_account_rq(rq)) {
7210a7ae2ffSJens Axboe 		q->in_flight[rq_is_sync(rq)]--;
72233659ebbSChristoph Hellwig 		if ((rq->cmd_flags & REQ_SORTED) &&
72322f746e2STejun Heo 		    e->type->ops.elevator_completed_req_fn)
72422f746e2STejun Heo 			e->type->ops.elevator_completed_req_fn(q, rq);
7251bc691d3STejun Heo 	}
7268922e16cSTejun Heo }
7271da177e4SLinus Torvalds 
7283d1ab40fSAl Viro #define to_elv(atr) container_of((atr), struct elv_fs_entry, attr)
7293d1ab40fSAl Viro 
7303d1ab40fSAl Viro static ssize_t
7313d1ab40fSAl Viro elv_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
7323d1ab40fSAl Viro {
7333d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
734b374d18aSJens Axboe 	struct elevator_queue *e;
7353d1ab40fSAl Viro 	ssize_t error;
7363d1ab40fSAl Viro 
7373d1ab40fSAl Viro 	if (!entry->show)
7383d1ab40fSAl Viro 		return -EIO;
7393d1ab40fSAl Viro 
740b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
7413d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
74222f746e2STejun Heo 	error = e->type ? entry->show(e, page) : -ENOENT;
7433d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
7443d1ab40fSAl Viro 	return error;
7453d1ab40fSAl Viro }
7463d1ab40fSAl Viro 
7473d1ab40fSAl Viro static ssize_t
7483d1ab40fSAl Viro elv_attr_store(struct kobject *kobj, struct attribute *attr,
7493d1ab40fSAl Viro 	       const char *page, size_t length)
7503d1ab40fSAl Viro {
7513d1ab40fSAl Viro 	struct elv_fs_entry *entry = to_elv(attr);
752b374d18aSJens Axboe 	struct elevator_queue *e;
7533d1ab40fSAl Viro 	ssize_t error;
7543d1ab40fSAl Viro 
7553d1ab40fSAl Viro 	if (!entry->store)
7563d1ab40fSAl Viro 		return -EIO;
7573d1ab40fSAl Viro 
758b374d18aSJens Axboe 	e = container_of(kobj, struct elevator_queue, kobj);
7593d1ab40fSAl Viro 	mutex_lock(&e->sysfs_lock);
76022f746e2STejun Heo 	error = e->type ? entry->store(e, page, length) : -ENOENT;
7613d1ab40fSAl Viro 	mutex_unlock(&e->sysfs_lock);
7623d1ab40fSAl Viro 	return error;
7633d1ab40fSAl Viro }
7643d1ab40fSAl Viro 
76552cf25d0SEmese Revfy static const struct sysfs_ops elv_sysfs_ops = {
7663d1ab40fSAl Viro 	.show	= elv_attr_show,
7673d1ab40fSAl Viro 	.store	= elv_attr_store,
7683d1ab40fSAl Viro };
7693d1ab40fSAl Viro 
7703d1ab40fSAl Viro static struct kobj_type elv_ktype = {
7713d1ab40fSAl Viro 	.sysfs_ops	= &elv_sysfs_ops,
7723d1ab40fSAl Viro 	.release	= elevator_release,
7733d1ab40fSAl Viro };
7743d1ab40fSAl Viro 
7755a5bafdcSTejun Heo int elv_register_queue(struct request_queue *q)
7761da177e4SLinus Torvalds {
7775a5bafdcSTejun Heo 	struct elevator_queue *e = q->elevator;
7783d1ab40fSAl Viro 	int error;
7791da177e4SLinus Torvalds 
780b2d6db58SGreg Kroah-Hartman 	error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
7813d1ab40fSAl Viro 	if (!error) {
78222f746e2STejun Heo 		struct elv_fs_entry *attr = e->type->elevator_attrs;
7833d1ab40fSAl Viro 		if (attr) {
784e572ec7eSAl Viro 			while (attr->attr.name) {
785e572ec7eSAl Viro 				if (sysfs_create_file(&e->kobj, &attr->attr))
7863d1ab40fSAl Viro 					break;
787e572ec7eSAl Viro 				attr++;
7883d1ab40fSAl Viro 			}
7893d1ab40fSAl Viro 		}
7903d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_ADD);
791430c62fbSJens Axboe 		e->registered = 1;
7923d1ab40fSAl Viro 	}
7933d1ab40fSAl Viro 	return error;
7941da177e4SLinus Torvalds }
79501effb0dSMike Snitzer EXPORT_SYMBOL(elv_register_queue);
7961da177e4SLinus Torvalds 
797f8fc877dSTejun Heo void elv_unregister_queue(struct request_queue *q)
7981da177e4SLinus Torvalds {
799f8fc877dSTejun Heo 	if (q) {
800f8fc877dSTejun Heo 		struct elevator_queue *e = q->elevator;
801f8fc877dSTejun Heo 
8023d1ab40fSAl Viro 		kobject_uevent(&e->kobj, KOBJ_REMOVE);
8033d1ab40fSAl Viro 		kobject_del(&e->kobj);
804430c62fbSJens Axboe 		e->registered = 0;
8051da177e4SLinus Torvalds 	}
8061da177e4SLinus Torvalds }
80701effb0dSMike Snitzer EXPORT_SYMBOL(elv_unregister_queue);
8081da177e4SLinus Torvalds 
8093d3c2379STejun Heo int elv_register(struct elevator_type *e)
8101da177e4SLinus Torvalds {
8111ffb96c5SThibaut VARENE 	char *def = "";
8122a12dcd7SJens Axboe 
8133d3c2379STejun Heo 	/* create icq_cache if requested */
8143d3c2379STejun Heo 	if (e->icq_size) {
8153d3c2379STejun Heo 		if (WARN_ON(e->icq_size < sizeof(struct io_cq)) ||
8163d3c2379STejun Heo 		    WARN_ON(e->icq_align < __alignof__(struct io_cq)))
8173d3c2379STejun Heo 			return -EINVAL;
8183d3c2379STejun Heo 
8193d3c2379STejun Heo 		snprintf(e->icq_cache_name, sizeof(e->icq_cache_name),
8203d3c2379STejun Heo 			 "%s_io_cq", e->elevator_name);
8213d3c2379STejun Heo 		e->icq_cache = kmem_cache_create(e->icq_cache_name, e->icq_size,
8223d3c2379STejun Heo 						 e->icq_align, 0, NULL);
8233d3c2379STejun Heo 		if (!e->icq_cache)
8243d3c2379STejun Heo 			return -ENOMEM;
8253d3c2379STejun Heo 	}
8263d3c2379STejun Heo 
8273d3c2379STejun Heo 	/* register, don't allow duplicate names */
8282a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
8293d3c2379STejun Heo 	if (elevator_find(e->elevator_name)) {
8303d3c2379STejun Heo 		spin_unlock(&elv_list_lock);
8313d3c2379STejun Heo 		if (e->icq_cache)
8323d3c2379STejun Heo 			kmem_cache_destroy(e->icq_cache);
8333d3c2379STejun Heo 		return -EBUSY;
8343d3c2379STejun Heo 	}
8351da177e4SLinus Torvalds 	list_add_tail(&e->list, &elv_list);
8362a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
8371da177e4SLinus Torvalds 
8383d3c2379STejun Heo 	/* print pretty message */
8395f003976SNate Diller 	if (!strcmp(e->elevator_name, chosen_elevator) ||
8405f003976SNate Diller 			(!*chosen_elevator &&
8415f003976SNate Diller 			 !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED)))
8421ffb96c5SThibaut VARENE 				def = " (default)";
8431ffb96c5SThibaut VARENE 
8444eb166d9SJens Axboe 	printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name,
8454eb166d9SJens Axboe 								def);
8463d3c2379STejun Heo 	return 0;
8471da177e4SLinus Torvalds }
8481da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_register);
8491da177e4SLinus Torvalds 
8501da177e4SLinus Torvalds void elv_unregister(struct elevator_type *e)
8511da177e4SLinus Torvalds {
8523d3c2379STejun Heo 	/* unregister */
8532a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
8541da177e4SLinus Torvalds 	list_del_init(&e->list);
8552a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
8563d3c2379STejun Heo 
8573d3c2379STejun Heo 	/*
8583d3c2379STejun Heo 	 * Destroy icq_cache if it exists.  icq's are RCU managed.  Make
8593d3c2379STejun Heo 	 * sure all RCU operations are complete before proceeding.
8603d3c2379STejun Heo 	 */
8613d3c2379STejun Heo 	if (e->icq_cache) {
8623d3c2379STejun Heo 		rcu_barrier();
8633d3c2379STejun Heo 		kmem_cache_destroy(e->icq_cache);
8643d3c2379STejun Heo 		e->icq_cache = NULL;
8653d3c2379STejun Heo 	}
8661da177e4SLinus Torvalds }
8671da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(elv_unregister);
8681da177e4SLinus Torvalds 
8691da177e4SLinus Torvalds /*
8701da177e4SLinus Torvalds  * switch to new_e io scheduler. be careful not to introduce deadlocks -
8711da177e4SLinus Torvalds  * we don't free the old io scheduler, before we have allocated what we
8721da177e4SLinus Torvalds  * need for the new one. this way we have a chance of going back to the old
873cb98fc8bSTejun Heo  * one, if the new one fails init for some reason.
8741da177e4SLinus Torvalds  */
875165125e1SJens Axboe static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
8761da177e4SLinus Torvalds {
8775a5bafdcSTejun Heo 	struct elevator_queue *old = q->elevator;
8785a5bafdcSTejun Heo 	bool registered = old->registered;
879*e8989faeSTejun Heo 	int err;
8801da177e4SLinus Torvalds 
8815a5bafdcSTejun Heo 	/*
8825a5bafdcSTejun Heo 	 * Turn on BYPASS and drain all requests w/ elevator private data.
8835a5bafdcSTejun Heo 	 * Block layer doesn't call into a quiesced elevator - all requests
8845a5bafdcSTejun Heo 	 * are directly put on the dispatch list without elevator data
8855a5bafdcSTejun Heo 	 * using INSERT_BACK.  All requests have SOFTBARRIER set and no
8865a5bafdcSTejun Heo 	 * merge happens either.
8875a5bafdcSTejun Heo 	 */
888d732580bSTejun Heo 	blk_queue_bypass_start(q);
889cb98fc8bSTejun Heo 
8905a5bafdcSTejun Heo 	/* unregister and clear all auxiliary data of the old elevator */
8915a5bafdcSTejun Heo 	if (registered)
892f8fc877dSTejun Heo 		elv_unregister_queue(q);
8935a5bafdcSTejun Heo 
8945a5bafdcSTejun Heo 	spin_lock_irq(q->queue_lock);
8955a5bafdcSTejun Heo 	ioc_clear_queue(q);
8965a5bafdcSTejun Heo 	spin_unlock_irq(q->queue_lock);
8975a5bafdcSTejun Heo 
898*e8989faeSTejun Heo 	blkg_destroy_all(q, false);
89972e06c25STejun Heo 
9005a5bafdcSTejun Heo 	/* allocate, init and register new elevator */
9015a5bafdcSTejun Heo 	err = -ENOMEM;
9025a5bafdcSTejun Heo 	q->elevator = elevator_alloc(q, new_e);
9035a5bafdcSTejun Heo 	if (!q->elevator)
9045a5bafdcSTejun Heo 		goto fail_init;
9055a5bafdcSTejun Heo 
906b2fab5acSTejun Heo 	err = new_e->ops.elevator_init_fn(q);
9075a5bafdcSTejun Heo 	if (err) {
9085a5bafdcSTejun Heo 		kobject_put(&q->elevator->kobj);
9095a5bafdcSTejun Heo 		goto fail_init;
9105a5bafdcSTejun Heo 	}
9115a5bafdcSTejun Heo 
9125a5bafdcSTejun Heo 	if (registered) {
9135a5bafdcSTejun Heo 		err = elv_register_queue(q);
9145dd531a0SJens Axboe 		if (err)
9151da177e4SLinus Torvalds 			goto fail_register;
916430c62fbSJens Axboe 	}
9171da177e4SLinus Torvalds 
9185a5bafdcSTejun Heo 	/* done, kill the old one and finish */
9195a5bafdcSTejun Heo 	elevator_exit(old);
920d732580bSTejun Heo 	blk_queue_bypass_end(q);
92175ad23bcSNick Piggin 
9225a5bafdcSTejun Heo 	blk_add_trace_msg(q, "elv switch: %s", new_e->elevator_name);
9234722dc52SAlan D. Brunelle 
9245dd531a0SJens Axboe 	return 0;
9251da177e4SLinus Torvalds 
9261da177e4SLinus Torvalds fail_register:
9275a5bafdcSTejun Heo 	elevator_exit(q->elevator);
9285a5bafdcSTejun Heo fail_init:
9295a5bafdcSTejun Heo 	/* switch failed, restore and re-register old elevator */
9305a5bafdcSTejun Heo 	q->elevator = old;
9311da177e4SLinus Torvalds 	elv_register_queue(q);
932d732580bSTejun Heo 	blk_queue_bypass_end(q);
93375ad23bcSNick Piggin 
9345dd531a0SJens Axboe 	return err;
9351da177e4SLinus Torvalds }
9361da177e4SLinus Torvalds 
9375dd531a0SJens Axboe /*
9385dd531a0SJens Axboe  * Switch this queue to the given IO scheduler.
9395dd531a0SJens Axboe  */
9405dd531a0SJens Axboe int elevator_change(struct request_queue *q, const char *name)
9411da177e4SLinus Torvalds {
9421da177e4SLinus Torvalds 	char elevator_name[ELV_NAME_MAX];
9431da177e4SLinus Torvalds 	struct elevator_type *e;
9441da177e4SLinus Torvalds 
945cd43e26fSMartin K. Petersen 	if (!q->elevator)
9465dd531a0SJens Axboe 		return -ENXIO;
947cd43e26fSMartin K. Petersen 
948ee2e992cSLi Zefan 	strlcpy(elevator_name, name, sizeof(elevator_name));
9498c279598SKOSAKI Motohiro 	e = elevator_get(strstrip(elevator_name));
9501da177e4SLinus Torvalds 	if (!e) {
9511da177e4SLinus Torvalds 		printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
9521da177e4SLinus Torvalds 		return -EINVAL;
9531da177e4SLinus Torvalds 	}
9541da177e4SLinus Torvalds 
95522f746e2STejun Heo 	if (!strcmp(elevator_name, q->elevator->type->elevator_name)) {
9562ca7d93bSNate Diller 		elevator_put(e);
9575dd531a0SJens Axboe 		return 0;
9582ca7d93bSNate Diller 	}
9591da177e4SLinus Torvalds 
9605dd531a0SJens Axboe 	return elevator_switch(q, e);
9615dd531a0SJens Axboe }
9625dd531a0SJens Axboe EXPORT_SYMBOL(elevator_change);
9635dd531a0SJens Axboe 
9645dd531a0SJens Axboe ssize_t elv_iosched_store(struct request_queue *q, const char *name,
9655dd531a0SJens Axboe 			  size_t count)
9665dd531a0SJens Axboe {
9675dd531a0SJens Axboe 	int ret;
9685dd531a0SJens Axboe 
9695dd531a0SJens Axboe 	if (!q->elevator)
9701da177e4SLinus Torvalds 		return count;
9715dd531a0SJens Axboe 
9725dd531a0SJens Axboe 	ret = elevator_change(q, name);
9735dd531a0SJens Axboe 	if (!ret)
9745dd531a0SJens Axboe 		return count;
9755dd531a0SJens Axboe 
9765dd531a0SJens Axboe 	printk(KERN_ERR "elevator: switch to %s failed\n", name);
9775dd531a0SJens Axboe 	return ret;
9781da177e4SLinus Torvalds }
9791da177e4SLinus Torvalds 
980165125e1SJens Axboe ssize_t elv_iosched_show(struct request_queue *q, char *name)
9811da177e4SLinus Torvalds {
982b374d18aSJens Axboe 	struct elevator_queue *e = q->elevator;
983cd43e26fSMartin K. Petersen 	struct elevator_type *elv;
98470cee26eSMatthias Kaehlcke 	struct elevator_type *__e;
9851da177e4SLinus Torvalds 	int len = 0;
9861da177e4SLinus Torvalds 
987e36f724bSMike Snitzer 	if (!q->elevator || !blk_queue_stackable(q))
988cd43e26fSMartin K. Petersen 		return sprintf(name, "none\n");
989cd43e26fSMartin K. Petersen 
99022f746e2STejun Heo 	elv = e->type;
991cd43e26fSMartin K. Petersen 
9922a12dcd7SJens Axboe 	spin_lock(&elv_list_lock);
99370cee26eSMatthias Kaehlcke 	list_for_each_entry(__e, &elv_list, list) {
9941da177e4SLinus Torvalds 		if (!strcmp(elv->elevator_name, __e->elevator_name))
9951da177e4SLinus Torvalds 			len += sprintf(name+len, "[%s] ", elv->elevator_name);
9961da177e4SLinus Torvalds 		else
9971da177e4SLinus Torvalds 			len += sprintf(name+len, "%s ", __e->elevator_name);
9981da177e4SLinus Torvalds 	}
9992a12dcd7SJens Axboe 	spin_unlock(&elv_list_lock);
10001da177e4SLinus Torvalds 
10011da177e4SLinus Torvalds 	len += sprintf(len+name, "\n");
10021da177e4SLinus Torvalds 	return len;
10031da177e4SLinus Torvalds }
10041da177e4SLinus Torvalds 
1005165125e1SJens Axboe struct request *elv_rb_former_request(struct request_queue *q,
1006165125e1SJens Axboe 				      struct request *rq)
10072e662b65SJens Axboe {
10082e662b65SJens Axboe 	struct rb_node *rbprev = rb_prev(&rq->rb_node);
10092e662b65SJens Axboe 
10102e662b65SJens Axboe 	if (rbprev)
10112e662b65SJens Axboe 		return rb_entry_rq(rbprev);
10122e662b65SJens Axboe 
10132e662b65SJens Axboe 	return NULL;
10142e662b65SJens Axboe }
10152e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_former_request);
10162e662b65SJens Axboe 
1017165125e1SJens Axboe struct request *elv_rb_latter_request(struct request_queue *q,
1018165125e1SJens Axboe 				      struct request *rq)
10192e662b65SJens Axboe {
10202e662b65SJens Axboe 	struct rb_node *rbnext = rb_next(&rq->rb_node);
10212e662b65SJens Axboe 
10222e662b65SJens Axboe 	if (rbnext)
10232e662b65SJens Axboe 		return rb_entry_rq(rbnext);
10242e662b65SJens Axboe 
10252e662b65SJens Axboe 	return NULL;
10262e662b65SJens Axboe }
10272e662b65SJens Axboe EXPORT_SYMBOL(elv_rb_latter_request);
1028