Commit 336a1f77 authored by Jens Axboe's avatar Jens Axboe Committed by Paul Mackerras

[PATCH] elevator core update

The noop io scheduler has a data corrupting bug, because q->last_merge
doesn't get cleared properly.  So do that in io scheduler core, and
remove the same code from deadline.

Also kill bio_rq_in_between(), it's not used by anyone anymore. rbtrees
are the hot thing these days.

And finally, remove a direct test for REQ_CMD in rq flags, use
blk_fs_request() instead.
parent 34e450f1
...@@ -313,11 +313,6 @@ static void deadline_remove_request(request_queue_t *q, struct request *rq) ...@@ -313,11 +313,6 @@ static void deadline_remove_request(request_queue_t *q, struct request *rq)
deadline_del_drq_hash(drq); deadline_del_drq_hash(drq);
deadline_del_drq_rb(dd, drq); deadline_del_drq_rb(dd, drq);
} }
if (q->last_merge == &rq->queuelist)
q->last_merge = NULL;
list_del_init(&rq->queuelist);
} }
static int static int
......
...@@ -38,63 +38,6 @@ ...@@ -38,63 +38,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
/*
* This is a bit tricky. It's given that bio and rq are for the same
* device, but the next request might of course not be. Run through
* the tests below to check if we want to insert here if we can't merge
* bio into an existing request
*/
inline int bio_rq_in_between(struct bio *bio, struct request *rq,
struct list_head *head)
{
struct list_head *next;
struct request *next_rq;
/*
* if .next is a valid request
*/
next = rq->queuelist.next;
if (unlikely(next == head))
return 0;
next_rq = list_entry(next, struct request, queuelist);
/*
* not a sector based request
*/
if (!(next_rq->flags & REQ_CMD))
return 0;
/*
* if the device is different (not a normal case) just check if
* bio is after rq
*/
if (next_rq->rq_disk != rq->rq_disk)
return bio->bi_sector > rq->sector;
/*
* ok, rq, next_rq and bio are on the same device. if bio is in between
* the two, this is the sweet spot
*/
if (bio->bi_sector < next_rq->sector && bio->bi_sector > rq->sector)
return 1;
/*
* next_rq is ordered wrt rq, but bio is not in between the two
*/
if (next_rq->sector > rq->sector)
return 0;
/*
* next_rq and rq not ordered, if we happen to be either before
* next_rq or after rq insert here anyway
*/
if (bio->bi_sector > rq->sector || bio->bi_sector < next_rq->sector)
return 1;
return 0;
}
/* /*
* can we safely merge with this request? * can we safely merge with this request?
*/ */
...@@ -138,22 +81,10 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio) ...@@ -138,22 +81,10 @@ inline int elv_try_merge(struct request *__rq, struct bio *bio)
inline int elv_try_last_merge(request_queue_t *q, struct bio *bio) inline int elv_try_last_merge(request_queue_t *q, struct bio *bio)
{ {
int ret = ELEVATOR_NO_MERGE; if (q->last_merge)
return elv_try_merge(list_entry_rq(q->last_merge), bio);
/*
* give a one-shot try to merging with the last touched
* request
*/
if (q->last_merge) {
struct request *__rq = list_entry_rq(q->last_merge);
if (!rq_mergeable(__rq)) return ELEVATOR_NO_MERGE;
q->last_merge = NULL;
else
ret = elv_try_merge(__rq, bio);
}
return ret;
} }
/* /*
...@@ -181,7 +112,7 @@ int elevator_noop_merge(request_queue_t *q, struct list_head **insert, ...@@ -181,7 +112,7 @@ int elevator_noop_merge(request_queue_t *q, struct list_head **insert,
else if (__rq->flags & REQ_STARTED) else if (__rq->flags & REQ_STARTED)
break; break;
if (!(__rq->flags & REQ_CMD)) if (!blk_fs_request(__rq))
continue; continue;
if ((ret = elv_try_merge(__rq, bio))) { if ((ret = elv_try_merge(__rq, bio))) {
...@@ -276,6 +207,9 @@ void elv_merge_requests(request_queue_t *q, struct request *rq, ...@@ -276,6 +207,9 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
{ {
elevator_t *e = &q->elevator; elevator_t *e = &q->elevator;
if (q->last_merge == &next->queuelist)
q->last_merge = NULL;
if (e->elevator_merge_req_fn) if (e->elevator_merge_req_fn)
e->elevator_merge_req_fn(q, rq, next); e->elevator_merge_req_fn(q, rq, next);
} }
......
...@@ -83,7 +83,6 @@ extern elevator_t iosched_deadline; ...@@ -83,7 +83,6 @@ extern elevator_t iosched_deadline;
extern int elevator_init(request_queue_t *, elevator_t *); extern int elevator_init(request_queue_t *, elevator_t *);
extern void elevator_exit(request_queue_t *); extern void elevator_exit(request_queue_t *);
extern inline int bio_rq_in_between(struct bio *, struct request *, struct list_head *);
extern inline int elv_rq_merge_ok(struct request *, struct bio *); extern inline int elv_rq_merge_ok(struct request *, struct bio *);
extern inline int elv_try_merge(struct request *, struct bio *); extern inline int elv_try_merge(struct request *, struct bio *);
extern inline int elv_try_last_merge(request_queue_t *, struct bio *); extern inline int elv_try_last_merge(request_queue_t *, struct bio *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment