Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 44845
b: refs/heads/master
c: da77526
h: refs/heads/master
i:
  44843: 3c0a682
v: v3
  • Loading branch information
Jens Axboe committed Dec 20, 2006
1 parent 36b16b1 commit 137bc95
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8e5cfc45e7527eb5c8a9a22d56a7b9227e7c0913
refs/heads/master: da775265021b61d5eb81df155e36cb0810f6df53
33 changes: 33 additions & 0 deletions trunk/block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,38 @@ cfq_merged_requests(request_queue_t *q, struct request *rq,
cfq_remove_request(next);
}

static int cfq_allow_merge(request_queue_t *q, struct request *rq,
struct bio *bio)
{
struct cfq_data *cfqd = q->elevator->elevator_data;
const int rw = bio_data_dir(bio);
struct cfq_queue *cfqq;
pid_t key;

/*
* If bio is async or a write, always allow merge
*/
if (!bio_sync(bio) || rw == WRITE)
return 1;

/*
* bio is sync. if request is not, disallow.
*/
if (!rq_is_sync(rq))
return 0;

/*
* Ok, both bio and request are sync. Allow merge if they are
* from the same queue.
*/
key = cfq_queue_pid(current, rw, 1);
cfqq = cfq_find_cfq_hash(cfqd, key, current->ioprio);
if (cfqq != RQ_CFQQ(rq))
return 0;

return 1;
}

static inline void
__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
{
Expand Down Expand Up @@ -2125,6 +2157,7 @@ static struct elevator_type iosched_cfq = {
.elevator_merge_fn = cfq_merge,
.elevator_merged_fn = cfq_merged_request,
.elevator_merge_req_fn = cfq_merged_requests,
.elevator_allow_merge_fn = cfq_allow_merge,
.elevator_dispatch_fn = cfq_dispatch_requests,
.elevator_add_req_fn = cfq_insert_request,
.elevator_activate_req_fn = cfq_activate_request,
Expand Down
26 changes: 22 additions & 4 deletions trunk/block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ static const int elv_hash_shift = 6;
#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))

/*
* Query io scheduler to see if the current process issuing bio may be
* merged with rq.
*/
static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
{
request_queue_t *q = rq->q;
elevator_t *e = q->elevator;

if (e->ops->elevator_allow_merge_fn)
return e->ops->elevator_allow_merge_fn(q, rq, bio);

return 1;
}

/*
* can we safely merge with this request?
*/
Expand All @@ -65,12 +80,15 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
return 0;

/*
* same device and no special stuff set, merge is ok
* must be same device and not a special request
*/
if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
return 1;
if (rq->rq_disk != bio->bi_bdev->bd_disk || !rq->special)
return 0;

return 0;
if (!elv_iosched_allow_merge(rq, bio))
return 0;

return 1;
}
EXPORT_SYMBOL(elv_rq_merge_ok);

Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struc

typedef void (elevator_merged_fn) (request_queue_t *, struct request *, int);

typedef int (elevator_allow_merge_fn) (request_queue_t *, struct request *, struct bio *);

typedef int (elevator_dispatch_fn) (request_queue_t *, int);

typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
Expand All @@ -33,6 +35,7 @@ struct elevator_ops
elevator_merge_fn *elevator_merge_fn;
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
elevator_allow_merge_fn *elevator_allow_merge_fn;

elevator_dispatch_fn *elevator_dispatch_fn;
elevator_add_req_fn *elevator_add_req_fn;
Expand Down

0 comments on commit 137bc95

Please sign in to comment.