Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37529
b: refs/heads/master
c: 2e662b6
h: refs/heads/master
i:
  37527: 1f50e53
v: v3
  • Loading branch information
Jens Axboe authored and Jens Axboe committed Sep 30, 2006
1 parent dda4be5 commit 3b9cc78
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 20 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: 10fd48f2376db52f08bf0420d2c4f580e39269e1
refs/heads/master: 2e662b65f05d550b6799ed6bfa9963b82279e6b7
123 changes: 109 additions & 14 deletions trunk/block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ int elevator_init(request_queue_t *q, char *name)
return ret;
}

EXPORT_SYMBOL(elevator_init);

void elevator_exit(elevator_t *e)
{
mutex_lock(&e->sysfs_lock);
Expand All @@ -250,6 +252,8 @@ void elevator_exit(elevator_t *e)
kobject_put(&e->kobj);
}

EXPORT_SYMBOL(elevator_exit);

static inline void __elv_rqhash_del(struct request *rq)
{
hlist_del_init(&rq->hash);
Expand Down Expand Up @@ -297,10 +301,69 @@ static struct request *elv_rqhash_find(request_queue_t *q, sector_t offset)
return NULL;
}

/*
* RB-tree support functions for inserting/lookup/removal of requests
* in a sorted RB tree.
*/
struct request *elv_rb_add(struct rb_root *root, struct request *rq)
{
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
struct request *__rq;

while (*p) {
parent = *p;
__rq = rb_entry(parent, struct request, rb_node);

if (rq->sector < __rq->sector)
p = &(*p)->rb_left;
else if (rq->sector > __rq->sector)
p = &(*p)->rb_right;
else
return __rq;
}

rb_link_node(&rq->rb_node, parent, p);
rb_insert_color(&rq->rb_node, root);
return NULL;
}

EXPORT_SYMBOL(elv_rb_add);

void elv_rb_del(struct rb_root *root, struct request *rq)
{
BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
rb_erase(&rq->rb_node, root);
RB_CLEAR_NODE(&rq->rb_node);
}

EXPORT_SYMBOL(elv_rb_del);

struct request *elv_rb_find(struct rb_root *root, sector_t sector)
{
struct rb_node *n = root->rb_node;
struct request *rq;

while (n) {
rq = rb_entry(n, struct request, rb_node);

if (sector < rq->sector)
n = n->rb_left;
else if (sector > rq->sector)
n = n->rb_right;
else
return rq;
}

return NULL;
}

EXPORT_SYMBOL(elv_rb_find);

/*
* Insert rq into dispatch queue of q. Queue lock must be held on
* entry. If sort != 0, rq is sort-inserted; otherwise, rq will be
* appended to the dispatch queue. To be used by specific elevators.
* entry. rq is sort insted into the dispatch queue. To be used by
* specific elevators.
*/
void elv_dispatch_sort(request_queue_t *q, struct request *rq)
{
Expand Down Expand Up @@ -335,8 +398,12 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
list_add(&rq->queuelist, entry);
}

EXPORT_SYMBOL(elv_dispatch_sort);

/*
* This should be in elevator.h, but that requires pulling in rq and q
* Insert rq into dispatch queue of q. Queue lock must be held on
* entry. rq is added to the back of the dispatch queue. To be used by
* specific elevators.
*/
void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
{
Expand All @@ -352,6 +419,8 @@ void elv_dispatch_add_tail(struct request_queue *q, struct request *rq)
list_add_tail(&rq->queuelist, &q->queue_head);
}

EXPORT_SYMBOL(elv_dispatch_add_tail);

int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
{
elevator_t *e = q->elevator;
Expand Down Expand Up @@ -384,14 +453,15 @@ int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
return ELEVATOR_NO_MERGE;
}

void elv_merged_request(request_queue_t *q, struct request *rq)
void elv_merged_request(request_queue_t *q, struct request *rq, int type)
{
elevator_t *e = q->elevator;

if (e->ops->elevator_merged_fn)
e->ops->elevator_merged_fn(q, rq);
e->ops->elevator_merged_fn(q, rq, type);

elv_rqhash_reposition(q, rq);
if (type == ELEVATOR_BACK_MERGE)
elv_rqhash_reposition(q, rq);

q->last_merge = rq;
}
Expand Down Expand Up @@ -577,6 +647,8 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
elv_insert(q, rq, where);
}

EXPORT_SYMBOL(__elv_add_request);

void elv_add_request(request_queue_t *q, struct request *rq, int where,
int plug)
{
Expand All @@ -587,6 +659,8 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where,
spin_unlock_irqrestore(q->queue_lock, flags);
}

EXPORT_SYMBOL(elv_add_request);

static inline struct request *__elv_next_request(request_queue_t *q)
{
struct request *rq;
Expand Down Expand Up @@ -670,6 +744,8 @@ struct request *elv_next_request(request_queue_t *q)
return rq;
}

EXPORT_SYMBOL(elv_next_request);

void elv_dequeue_request(request_queue_t *q, struct request *rq)
{
BUG_ON(list_empty(&rq->queuelist));
Expand All @@ -686,6 +762,8 @@ void elv_dequeue_request(request_queue_t *q, struct request *rq)
q->in_flight++;
}

EXPORT_SYMBOL(elv_dequeue_request);

int elv_queue_empty(request_queue_t *q)
{
elevator_t *e = q->elevator;
Expand All @@ -699,6 +777,8 @@ int elv_queue_empty(request_queue_t *q)
return 1;
}

EXPORT_SYMBOL(elv_queue_empty);

struct request *elv_latter_request(request_queue_t *q, struct request *rq)
{
elevator_t *e = q->elevator;
Expand Down Expand Up @@ -1025,11 +1105,26 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
return len;
}

EXPORT_SYMBOL(elv_dispatch_sort);
EXPORT_SYMBOL(elv_add_request);
EXPORT_SYMBOL(__elv_add_request);
EXPORT_SYMBOL(elv_next_request);
EXPORT_SYMBOL(elv_dequeue_request);
EXPORT_SYMBOL(elv_queue_empty);
EXPORT_SYMBOL(elevator_exit);
EXPORT_SYMBOL(elevator_init);
struct request *elv_rb_former_request(request_queue_t *q, struct request *rq)
{
struct rb_node *rbprev = rb_prev(&rq->rb_node);

if (rbprev)
return rb_entry_rq(rbprev);

return NULL;
}

EXPORT_SYMBOL(elv_rb_former_request);

struct request *elv_rb_latter_request(request_queue_t *q, struct request *rq)
{
struct rb_node *rbnext = rb_next(&rq->rb_node);

if (rbnext)
return rb_entry_rq(rbnext);

return NULL;
}

EXPORT_SYMBOL(elv_rb_latter_request);
7 changes: 4 additions & 3 deletions trunk/block/ll_rw_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,12 @@ static inline void rq_init(request_queue_t *q, struct request *rq)
{
INIT_LIST_HEAD(&rq->queuelist);
INIT_LIST_HEAD(&rq->donelist);
INIT_HLIST_NODE(&rq->hash);

rq->errors = 0;
rq->rq_status = RQ_ACTIVE;
rq->bio = rq->biotail = NULL;
INIT_HLIST_NODE(&rq->hash);
RB_CLEAR_NODE(&rq->rb_node);
rq->ioprio = 0;
rq->buffer = NULL;
rq->ref_count = 1;
Expand Down Expand Up @@ -2943,7 +2944,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req->ioprio = ioprio_best(req->ioprio, prio);
drive_stat_acct(req, nr_sectors, 0);
if (!attempt_back_merge(q, req))
elv_merged_request(q, req);
elv_merged_request(q, req, el_ret);
goto out;

case ELEVATOR_FRONT_MERGE:
Expand All @@ -2970,7 +2971,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
req->ioprio = ioprio_best(req->ioprio, prio);
drive_stat_acct(req, nr_sectors, 0);
if (!attempt_front_merge(q, req))
elv_merged_request(q, req);
elv_merged_request(q, req, el_ret);
goto out;

/* ELV_NO_MERGE: elevator says don't/can't merge. */
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ struct request {
struct bio *biotail;

struct hlist_node hash; /* merge hash */
struct rb_node rb_node; /* sort/lookup */

void *elevator_private;
void *completion_data;
Expand Down
18 changes: 16 additions & 2 deletions trunk/include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ typedef int (elevator_merge_fn) (request_queue_t *, struct request **,

typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);

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

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

Expand Down Expand Up @@ -96,7 +96,7 @@ extern void elv_insert(request_queue_t *, struct request *, int);
extern int elv_merge(request_queue_t *, struct request **, struct bio *);
extern void elv_merge_requests(request_queue_t *, struct request *,
struct request *);
extern void elv_merged_request(request_queue_t *, struct request *);
extern void elv_merged_request(request_queue_t *, struct request *, int);
extern void elv_dequeue_request(request_queue_t *, struct request *);
extern void elv_requeue_request(request_queue_t *, struct request *);
extern int elv_queue_empty(request_queue_t *);
Expand Down Expand Up @@ -126,6 +126,19 @@ extern int elevator_init(request_queue_t *, char *);
extern void elevator_exit(elevator_t *);
extern int elv_rq_merge_ok(struct request *, struct bio *);

/*
* Helper functions.
*/
extern struct request *elv_rb_former_request(request_queue_t *, struct request *);
extern struct request *elv_rb_latter_request(request_queue_t *, struct request *);

/*
* rb support functions.
*/
extern struct request *elv_rb_add(struct rb_root *, struct request *);
extern void elv_rb_del(struct rb_root *, struct request *);
extern struct request *elv_rb_find(struct rb_root *, sector_t);

/*
* Return values from elevator merger
*/
Expand All @@ -151,5 +164,6 @@ enum {
};

#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
#define rb_entry_rq(node) rb_entry((node), struct request, rb_node)

#endif

0 comments on commit 3b9cc78

Please sign in to comment.