aboutsummaryrefslogtreecommitdiffstats
path: root/block/cfq-iosched.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/cfq-iosched.c')
-rw-r--r--block/cfq-iosched.c86
1 files changed, 3 insertions, 83 deletions
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 3a3aee08ec5f..1b803c0c90f1 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -41,16 +41,6 @@ static DEFINE_SPINLOCK(cfq_exit_lock);
41#define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT) 41#define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT)
42#define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash) 42#define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash)
43 43
44/*
45 * for the hash of crq inside the cfqq
46 */
47#define CFQ_MHASH_SHIFT 6
48#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3)
49#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT)
50#define CFQ_MHASH_FN(sec) hash_long(CFQ_MHASH_BLOCK(sec), CFQ_MHASH_SHIFT)
51#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
52#define list_entry_hash(ptr) hlist_entry((ptr), struct cfq_rq, hash)
53
54#define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list) 44#define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list)
55#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist) 45#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist)
56 46
@@ -112,11 +102,6 @@ struct cfq_data {
112 */ 102 */
113 struct hlist_head *cfq_hash; 103 struct hlist_head *cfq_hash;
114 104
115 /*
116 * global crq hash for all queues
117 */
118 struct hlist_head *crq_hash;
119
120 mempool_t *crq_pool; 105 mempool_t *crq_pool;
121 106
122 int rq_in_driver; 107 int rq_in_driver;
@@ -203,7 +188,6 @@ struct cfq_rq {
203 struct rb_node rb_node; 188 struct rb_node rb_node;
204 sector_t rb_key; 189 sector_t rb_key;
205 struct request *request; 190 struct request *request;
206 struct hlist_node hash;
207 191
208 struct cfq_queue *cfq_queue; 192 struct cfq_queue *cfq_queue;
209 struct cfq_io_context *io_context; 193 struct cfq_io_context *io_context;
@@ -272,42 +256,6 @@ static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
272static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask); 256static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask);
273 257
274/* 258/*
275 * lots of deadline iosched dupes, can be abstracted later...
276 */
277static inline void cfq_del_crq_hash(struct cfq_rq *crq)
278{
279 hlist_del_init(&crq->hash);
280}
281
282static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
283{
284 const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
285
286 hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]);
287}
288
289static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
290{
291 struct hlist_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
292 struct hlist_node *entry, *next;
293
294 hlist_for_each_safe(entry, next, hash_list) {
295 struct cfq_rq *crq = list_entry_hash(entry);
296 struct request *__rq = crq->request;
297
298 if (!rq_mergeable(__rq)) {
299 cfq_del_crq_hash(crq);
300 continue;
301 }
302
303 if (rq_hash_key(__rq) == offset)
304 return __rq;
305 }
306
307 return NULL;
308}
309
310/*
311 * scheduler run of queue, if there are requests pending and no one in the 259 * scheduler run of queue, if there are requests pending and no one in the
312 * driver that will restart queueing 260 * driver that will restart queueing
313 */ 261 */
@@ -677,7 +625,6 @@ static void cfq_remove_request(struct request *rq)
677 625
678 list_del_init(&rq->queuelist); 626 list_del_init(&rq->queuelist);
679 cfq_del_crq_rb(crq); 627 cfq_del_crq_rb(crq);
680 cfq_del_crq_hash(crq);
681} 628}
682 629
683static int 630static int
@@ -685,34 +632,20 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
685{ 632{
686 struct cfq_data *cfqd = q->elevator->elevator_data; 633 struct cfq_data *cfqd = q->elevator->elevator_data;
687 struct request *__rq; 634 struct request *__rq;
688 int ret;
689
690 __rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
691 if (__rq && elv_rq_merge_ok(__rq, bio)) {
692 ret = ELEVATOR_BACK_MERGE;
693 goto out;
694 }
695 635
696 __rq = cfq_find_rq_fmerge(cfqd, bio); 636 __rq = cfq_find_rq_fmerge(cfqd, bio);
697 if (__rq && elv_rq_merge_ok(__rq, bio)) { 637 if (__rq && elv_rq_merge_ok(__rq, bio)) {
698 ret = ELEVATOR_FRONT_MERGE; 638 *req = __rq;
699 goto out; 639 return ELEVATOR_FRONT_MERGE;
700 } 640 }
701 641
702 return ELEVATOR_NO_MERGE; 642 return ELEVATOR_NO_MERGE;
703out:
704 *req = __rq;
705 return ret;
706} 643}
707 644
708static void cfq_merged_request(request_queue_t *q, struct request *req) 645static void cfq_merged_request(request_queue_t *q, struct request *req)
709{ 646{
710 struct cfq_data *cfqd = q->elevator->elevator_data;
711 struct cfq_rq *crq = RQ_DATA(req); 647 struct cfq_rq *crq = RQ_DATA(req);
712 648
713 cfq_del_crq_hash(crq);
714 cfq_add_crq_hash(cfqd, crq);
715
716 if (rq_rb_key(req) != crq->rb_key) { 649 if (rq_rb_key(req) != crq->rb_key) {
717 struct cfq_queue *cfqq = crq->cfq_queue; 650 struct cfq_queue *cfqq = crq->cfq_queue;
718 651
@@ -1825,9 +1758,6 @@ static void cfq_insert_request(request_queue_t *q, struct request *rq)
1825 1758
1826 list_add_tail(&rq->queuelist, &cfqq->fifo); 1759 list_add_tail(&rq->queuelist, &cfqq->fifo);
1827 1760
1828 if (rq_mergeable(rq))
1829 cfq_add_crq_hash(cfqd, crq);
1830
1831 cfq_crq_enqueued(cfqd, cfqq, crq); 1761 cfq_crq_enqueued(cfqd, cfqq, crq);
1832} 1762}
1833 1763
@@ -2055,7 +1985,6 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
2055 RB_CLEAR_NODE(&crq->rb_node); 1985 RB_CLEAR_NODE(&crq->rb_node);
2056 crq->rb_key = 0; 1986 crq->rb_key = 0;
2057 crq->request = rq; 1987 crq->request = rq;
2058 INIT_HLIST_NODE(&crq->hash);
2059 crq->cfq_queue = cfqq; 1988 crq->cfq_queue = cfqq;
2060 crq->io_context = cic; 1989 crq->io_context = cic;
2061 1990
@@ -2221,7 +2150,6 @@ static void cfq_exit_queue(elevator_t *e)
2221 cfq_shutdown_timer_wq(cfqd); 2150 cfq_shutdown_timer_wq(cfqd);
2222 2151
2223 mempool_destroy(cfqd->crq_pool); 2152 mempool_destroy(cfqd->crq_pool);
2224 kfree(cfqd->crq_hash);
2225 kfree(cfqd->cfq_hash); 2153 kfree(cfqd->cfq_hash);
2226 kfree(cfqd); 2154 kfree(cfqd);
2227} 2155}
@@ -2246,20 +2174,14 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
2246 INIT_LIST_HEAD(&cfqd->empty_list); 2174 INIT_LIST_HEAD(&cfqd->empty_list);
2247 INIT_LIST_HEAD(&cfqd->cic_list); 2175 INIT_LIST_HEAD(&cfqd->cic_list);
2248 2176
2249 cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
2250 if (!cfqd->crq_hash)
2251 goto out_crqhash;
2252
2253 cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL); 2177 cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
2254 if (!cfqd->cfq_hash) 2178 if (!cfqd->cfq_hash)
2255 goto out_cfqhash; 2179 goto out_crqhash;
2256 2180
2257 cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool); 2181 cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool);
2258 if (!cfqd->crq_pool) 2182 if (!cfqd->crq_pool)
2259 goto out_crqpool; 2183 goto out_crqpool;
2260 2184
2261 for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
2262 INIT_HLIST_HEAD(&cfqd->crq_hash[i]);
2263 for (i = 0; i < CFQ_QHASH_ENTRIES; i++) 2185 for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
2264 INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); 2186 INIT_HLIST_HEAD(&cfqd->cfq_hash[i]);
2265 2187
@@ -2289,8 +2211,6 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e)
2289 return cfqd; 2211 return cfqd;
2290out_crqpool: 2212out_crqpool:
2291 kfree(cfqd->cfq_hash); 2213 kfree(cfqd->cfq_hash);
2292out_cfqhash:
2293 kfree(cfqd->crq_hash);
2294out_crqhash: 2214out_crqhash:
2295 kfree(cfqd); 2215 kfree(cfqd);
2296 return NULL; 2216 return NULL;