aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-21 03:03:38 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-21 03:03:38 -0500
commit4604096768d3be37ee1a05aee424aceed3e1b56f (patch)
tree56010e180bb32be7e57971e4bb617c28d0d09099
parent8df8bb4adf7e4abb48d29dc16c29eda40a64afed (diff)
parent126ec9a676f601818dc3a85af0552b146410d888 (diff)
Merge branch 'for-linus' of git://brick.kernel.dk/data/git/linux-2.6-block
* 'for-linus' of git://brick.kernel.dk/data/git/linux-2.6-block: [PATCH] block: document io scheduler allow_merge_fn hook [PATCH] cfq-iosched: don't allow sync merges across queues [PATCH] Fixup blk_rq_unmap_user() API [PATCH] __blk_rq_unmap_user() fails to return error [PATCH] __blk_rq_map_user() doesn't need to grab the queue_lock [PATCH] Remove queue merging hooks [PATCH] ->nr_sectors and ->hard_nr_sectors are not used for BLOCK_PC requests [PATCH] cciss: fix XFER_READ/XFER_WRITE in do_cciss_request [PATCH] cciss: set default raid level when reading geometry fails
-rw-r--r--Documentation/block/biodoc.txt7
-rw-r--r--block/cfq-iosched.c33
-rw-r--r--block/elevator.c26
-rw-r--r--block/ll_rw_blk.c67
-rw-r--r--block/scsi_ioctl.c3
-rw-r--r--drivers/block/cciss.c3
-rw-r--r--drivers/cdrom/cdrom.c3
-rw-r--r--drivers/scsi/scsi_lib.c4
-rw-r--r--include/linux/blkdev.h14
-rw-r--r--include/linux/elevator.h3
10 files changed, 107 insertions, 56 deletions
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index c6c9a9c10d7f..3adaace328a6 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -946,6 +946,13 @@ elevator_merged_fn called when a request in the scheduler has been
946 scheduler for example, to reposition the request 946 scheduler for example, to reposition the request
947 if its sorting order has changed. 947 if its sorting order has changed.
948 948
949elevator_allow_merge_fn called whenever the block layer determines
950 that a bio can be merged into an existing
951 request safely. The io scheduler may still
952 want to stop a merge at this point if it
953 results in some sort of conflict internally,
954 this hook allows it to do that.
955
949elevator_dispatch_fn fills the dispatch queue with ready requests. 956elevator_dispatch_fn fills the dispatch queue with ready requests.
950 I/O schedulers are free to postpone requests by 957 I/O schedulers are free to postpone requests by
951 not filling the dispatch queue unless @force 958 not filling the dispatch queue unless @force
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 533a2938ffd6..9fc5eafa6c0e 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -568,6 +568,38 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
568 cfq_remove_request(next); 568 cfq_remove_request(next);
569} 569}
570 570
571static int cfq_allow_merge(request_queue_t *q, struct request *rq,
572 struct bio *bio)
573{
574 struct cfq_data *cfqd = q->elevator->elevator_data;
575 const int rw = bio_data_dir(bio);
576 struct cfq_queue *cfqq;
577 pid_t key;
578
579 /*
580 * If bio is async or a write, always allow merge
581 */
582 if (!bio_sync(bio) || rw == WRITE)
583 return 1;
584
585 /*
586 * bio is sync. if request is not, disallow.
587 */
588 if (!rq_is_sync(rq))
589 return 0;
590
591 /*
592 * Ok, both bio and request are sync. Allow merge if they are
593 * from the same queue.
594 */
595 key = cfq_queue_pid(current, rw, 1);
596 cfqq = cfq_find_cfq_hash(cfqd, key, current->ioprio);
597 if (cfqq != RQ_CFQQ(rq))
598 return 0;
599
600 return 1;
601}
602
571static inline void 603static inline void
572__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) 604__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
573{ 605{
@@ -2125,6 +2157,7 @@ static struct elevator_type iosched_cfq = {
2125 .elevator_merge_fn = cfq_merge, 2157 .elevator_merge_fn = cfq_merge,
2126 .elevator_merged_fn = cfq_merged_request, 2158 .elevator_merged_fn = cfq_merged_request,
2127 .elevator_merge_req_fn = cfq_merged_requests, 2159 .elevator_merge_req_fn = cfq_merged_requests,
2160 .elevator_allow_merge_fn = cfq_allow_merge,
2128 .elevator_dispatch_fn = cfq_dispatch_requests, 2161 .elevator_dispatch_fn = cfq_dispatch_requests,
2129 .elevator_add_req_fn = cfq_insert_request, 2162 .elevator_add_req_fn = cfq_insert_request,
2130 .elevator_activate_req_fn = cfq_activate_request, 2163 .elevator_activate_req_fn = cfq_activate_request,
diff --git a/block/elevator.c b/block/elevator.c
index c0063f345c5d..62c7a3069d3a 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -51,6 +51,21 @@ static const int elv_hash_shift = 6;
51#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) 51#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
52 52
53/* 53/*
54 * Query io scheduler to see if the current process issuing bio may be
55 * merged with rq.
56 */
57static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
58{
59 request_queue_t *q = rq->q;
60 elevator_t *e = q->elevator;
61
62 if (e->ops->elevator_allow_merge_fn)
63 return e->ops->elevator_allow_merge_fn(q, rq, bio);
64
65 return 1;
66}
67
68/*
54 * can we safely merge with this request? 69 * can we safely merge with this request?
55 */ 70 */
56inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) 71inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
@@ -65,12 +80,15 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
65 return 0; 80 return 0;
66 81
67 /* 82 /*
68 * same device and no special stuff set, merge is ok 83 * must be same device and not a special request
69 */ 84 */
70 if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special) 85 if (rq->rq_disk != bio->bi_bdev->bd_disk || !rq->special)
71 return 1; 86 return 0;
72 87
73 return 0; 88 if (!elv_iosched_allow_merge(rq, bio))
89 return 0;
90
91 return 1;
74} 92}
75EXPORT_SYMBOL(elv_rq_merge_ok); 93EXPORT_SYMBOL(elv_rq_merge_ok);
76 94
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 79807dbc306e..e07c079e07e6 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1405,8 +1405,7 @@ static inline int ll_new_hw_segment(request_queue_t *q,
1405 return 1; 1405 return 1;
1406} 1406}
1407 1407
1408static int ll_back_merge_fn(request_queue_t *q, struct request *req, 1408int ll_back_merge_fn(request_queue_t *q, struct request *req, struct bio *bio)
1409 struct bio *bio)
1410{ 1409{
1411 unsigned short max_sectors; 1410 unsigned short max_sectors;
1412 int len; 1411 int len;
@@ -1442,6 +1441,7 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req,
1442 1441
1443 return ll_new_hw_segment(q, req, bio); 1442 return ll_new_hw_segment(q, req, bio);
1444} 1443}
1444EXPORT_SYMBOL(ll_back_merge_fn);
1445 1445
1446static int ll_front_merge_fn(request_queue_t *q, struct request *req, 1446static int ll_front_merge_fn(request_queue_t *q, struct request *req,
1447 struct bio *bio) 1447 struct bio *bio)
@@ -1912,9 +1912,6 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
1912 } 1912 }
1913 1913
1914 q->request_fn = rfn; 1914 q->request_fn = rfn;
1915 q->back_merge_fn = ll_back_merge_fn;
1916 q->front_merge_fn = ll_front_merge_fn;
1917 q->merge_requests_fn = ll_merge_requests_fn;
1918 q->prep_rq_fn = NULL; 1915 q->prep_rq_fn = NULL;
1919 q->unplug_fn = generic_unplug_device; 1916 q->unplug_fn = generic_unplug_device;
1920 q->queue_flags = (1 << QUEUE_FLAG_CLUSTER); 1917 q->queue_flags = (1 << QUEUE_FLAG_CLUSTER);
@@ -2350,40 +2347,29 @@ static int __blk_rq_map_user(request_queue_t *q, struct request *rq,
2350 else 2347 else
2351 bio = bio_copy_user(q, uaddr, len, reading); 2348 bio = bio_copy_user(q, uaddr, len, reading);
2352 2349
2353 if (IS_ERR(bio)) { 2350 if (IS_ERR(bio))
2354 return PTR_ERR(bio); 2351 return PTR_ERR(bio);
2355 }
2356 2352
2357 orig_bio = bio; 2353 orig_bio = bio;
2358 blk_queue_bounce(q, &bio); 2354 blk_queue_bounce(q, &bio);
2355
2359 /* 2356 /*
2360 * We link the bounce buffer in and could have to traverse it 2357 * We link the bounce buffer in and could have to traverse it
2361 * later so we have to get a ref to prevent it from being freed 2358 * later so we have to get a ref to prevent it from being freed
2362 */ 2359 */
2363 bio_get(bio); 2360 bio_get(bio);
2364 2361