Commit b4878f24 authored by Jens Axboe's avatar Jens Axboe Committed by Jens Axboe

[PATCH] 02/05: update ioscheds to use generic dispatch queue

This patch updates all four ioscheds to use generic dispatch
queue.  There's one behavior change in as-iosched.

* In as-iosched, when force dispatching
  (ELEVATOR_INSERT_BACK), batch_data_dir is reset to REQ_SYNC
  and changed_batch and new_batch are cleared to zero.  This
  prevernts AS from doing incorrect update_write_batch after
  the forced dispatched requests are finished.

* In cfq-iosched, cfqd->rq_in_driver currently counts the
  number of activated (removed) requests to determine
  whether queue-kicking is needed and cfq_max_depth has been
  reached.  With generic dispatch queue, I think counting
  the number of dispatched requests would be more appropriate.

* cfq_max_depth can be lowered to 1 again.

Original from Tejun Heo, modified version applied.
Signed-off-by: default avatarJens Axboe <axboe@suse.de>
parent d9ebb192
This diff is collapsed.
This diff is collapsed.
...@@ -50,7 +50,6 @@ struct deadline_data { ...@@ -50,7 +50,6 @@ struct deadline_data {
* next in sort order. read, write or both are NULL * next in sort order. read, write or both are NULL
*/ */
struct deadline_rq *next_drq[2]; struct deadline_rq *next_drq[2];
struct list_head *dispatch; /* driver dispatch queue */
struct list_head *hash; /* request hash */ struct list_head *hash; /* request hash */
unsigned int batching; /* number of sequential requests made */ unsigned int batching; /* number of sequential requests made */
sector_t last_sector; /* head position */ sector_t last_sector; /* head position */
...@@ -239,10 +238,9 @@ deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) ...@@ -239,10 +238,9 @@ deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
dd->next_drq[data_dir] = rb_entry_drq(rbnext); dd->next_drq[data_dir] = rb_entry_drq(rbnext);
} }
if (ON_RB(&drq->rb_node)) { BUG_ON(!ON_RB(&drq->rb_node));
rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
RB_CLEAR(&drq->rb_node); RB_CLEAR(&drq->rb_node);
}
} }
static struct request * static struct request *
...@@ -286,7 +284,7 @@ deadline_find_first_drq(struct deadline_data *dd, int data_dir) ...@@ -286,7 +284,7 @@ deadline_find_first_drq(struct deadline_data *dd, int data_dir)
/* /*
* add drq to rbtree and fifo * add drq to rbtree and fifo
*/ */
static inline void static void
deadline_add_request(struct request_queue *q, struct request *rq) deadline_add_request(struct request_queue *q, struct request *rq)
{ {
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;
...@@ -315,14 +313,11 @@ deadline_add_request(struct request_queue *q, struct request *rq) ...@@ -315,14 +313,11 @@ deadline_add_request(struct request_queue *q, struct request *rq)
static void deadline_remove_request(request_queue_t *q, struct request *rq) static void deadline_remove_request(request_queue_t *q, struct request *rq)
{ {
struct deadline_rq *drq = RQ_DATA(rq); struct deadline_rq *drq = RQ_DATA(rq);
struct deadline_data *dd = q->elevator->elevator_data;
if (drq) { list_del_init(&drq->fifo);
struct deadline_data *dd = q->elevator->elevator_data; deadline_remove_merge_hints(q, drq);
deadline_del_drq_rb(dd, drq);
list_del_init(&drq->fifo);
deadline_remove_merge_hints(q, drq);
deadline_del_drq_rb(dd, drq);
}
} }
static int static int
...@@ -452,7 +447,7 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq) ...@@ -452,7 +447,7 @@ deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
request_queue_t *q = drq->request->q; request_queue_t *q = drq->request->q;
deadline_remove_request(q, drq->request); deadline_remove_request(q, drq->request);
list_add_tail(&drq->request->queuelist, dd->dispatch); elv_dispatch_add_tail(q, drq->request);
} }
/* /*
...@@ -502,8 +497,9 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) ...@@ -502,8 +497,9 @@ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
* deadline_dispatch_requests selects the best request according to * deadline_dispatch_requests selects the best request according to
* read/write expire, fifo_batch, etc * read/write expire, fifo_batch, etc
*/ */
static int deadline_dispatch_requests(struct deadline_data *dd) static int deadline_dispatch_requests(request_queue_t *q, int force)
{ {
struct deadline_data *dd = q->elevator->elevator_data;
const int reads = !list_empty(&dd->fifo_list[READ]); const int reads = !list_empty(&dd->fifo_list[READ]);
const int writes = !list_empty(&dd->fifo_list[WRITE]); const int writes = !list_empty(&dd->fifo_list[WRITE]);
struct deadline_rq *drq; struct deadline_rq *drq;
...@@ -597,65 +593,12 @@ static int deadline_dispatch_requests(struct deadline_data *dd) ...@@ -597,65 +593,12 @@ static int deadline_dispatch_requests(struct deadline_data *dd)
return 1; return 1;
} }
static struct request *deadline_next_request(request_queue_t *q)
{
struct deadline_data *dd = q->elevator->elevator_data;
struct request *rq;
/*
* if there are still requests on the dispatch queue, grab the first one
*/
if (!list_empty(dd->dispatch)) {
dispatch:
rq = list_entry_rq(dd->dispatch->next);
return rq;
}
if (deadline_dispatch_requests(dd))
goto dispatch;
return NULL;
}
static void
deadline_insert_request(request_queue_t *q, struct request *rq, int where)
{
struct deadline_data *dd = q->elevator->elevator_data;
/* barriers must flush the reorder queue */
if (unlikely(rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)
&& where == ELEVATOR_INSERT_SORT))
where = ELEVATOR_INSERT_BACK;
switch (where) {
case ELEVATOR_INSERT_BACK:
while (deadline_dispatch_requests(dd))
;
list_add_tail(&rq->queuelist, dd->dispatch);
break;
case ELEVATOR_INSERT_FRONT:
list_add(&rq->queuelist, dd->dispatch);
break;
case ELEVATOR_INSERT_SORT:
BUG_ON(!blk_fs_request(rq));
deadline_add_request(q, rq);
break;
default:
printk("%s: bad insert point %d\n", __FUNCTION__,where);
return;
}
}
static int deadline_queue_empty(request_queue_t *q) static int deadline_queue_empty(request_queue_t *q)
{ {
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;
if (!list_empty(&dd->fifo_list[WRITE]) return list_empty(&dd->fifo_list[WRITE])
|| !list_empty(&dd->fifo_list[READ]) && list_empty(&dd->fifo_list[READ]);
|| !list_empty(dd->dispatch))
return 0;
return 1;
} }
static struct request * static struct request *
...@@ -733,7 +676,6 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e) ...@@ -733,7 +676,6 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
INIT_LIST_HEAD(&dd->fifo_list[WRITE]); INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
dd->sort_list[READ] = RB_ROOT; dd->sort_list[READ] = RB_ROOT;
dd->sort_list[WRITE] = RB_ROOT; dd->sort_list[WRITE] = RB_ROOT;
dd->dispatch = &q->queue_head;
dd->fifo_expire[READ] = read_expire; dd->fifo_expire[READ] = read_expire;
dd->fifo_expire[WRITE] = write_expire; dd->fifo_expire[WRITE] = write_expire;
dd->writes_starved = writes_starved; dd->writes_starved = writes_starved;
...@@ -748,10 +690,8 @@ static void deadline_put_request(request_queue_t *q, struct request *rq) ...@@ -748,10 +690,8 @@ static void deadline_put_request(request_queue_t *q, struct request *rq)
struct deadline_data *dd = q->elevator->elevator_data; struct deadline_data *dd = q->elevator->elevator_data;
struct deadline_rq *drq = RQ_DATA(rq); struct deadline_rq *drq = RQ_DATA(rq);
if (drq) { mempool_free(drq, dd->drq_pool);
mempool_free(drq, dd->drq_pool); rq->elevator_private = NULL;
rq->elevator_private = NULL;
}
} }
static int static int
...@@ -917,9 +857,8 @@ static struct elevator_type iosched_deadline = { ...@@ -917,9 +857,8 @@ static struct elevator_type iosched_deadline = {
.elevator_merge_fn = deadline_merge, .elevator_merge_fn = deadline_merge,
.elevator_merged_fn = deadline_merged_request, .elevator_merged_fn = deadline_merged_request,
.elevator_merge_req_fn = deadline_merged_requests, .elevator_merge_req_fn = deadline_merged_requests,
.elevator_next_req_fn = deadline_next_request, .elevator_dispatch_fn = deadline_dispatch_requests,
.elevator_add_req_fn = deadline_insert_request, .elevator_add_req_fn = deadline_add_request,
.elevator_remove_req_fn = deadline_remove_request,
.elevator_queue_empty_fn = deadline_queue_empty, .elevator_queue_empty_fn = deadline_queue_empty,
.elevator_former_req_fn = deadline_former_request, .elevator_former_req_fn = deadline_former_request,
.elevator_latter_req_fn = deadline_latter_request, .elevator_latter_req_fn = deadline_latter_request,
......
...@@ -28,13 +28,9 @@ static void elevator_noop_merge_requests(request_queue_t *q, struct request *req ...@@ -28,13 +28,9 @@ static void elevator_noop_merge_requests(request_queue_t *q, struct request *req
list_del_init(&next->queuelist); list_del_init(&next->queuelist);
} }
static void elevator_noop_add_request(request_queue_t *q, struct request *rq, static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
int where)
{ {
if (where == ELEVATOR_INSERT_FRONT) elv_dispatch_add_tail(q, rq);
list_add(&rq->queuelist, &q->queue_head);
else
list_add_tail(&rq->queuelist, &q->queue_head);
/* /*
* new merges must not precede this barrier * new merges must not precede this barrier
...@@ -45,19 +41,16 @@ static void elevator_noop_add_request(request_queue_t *q, struct request *rq, ...@@ -45,19 +41,16 @@ static void elevator_noop_add_request(request_queue_t *q, struct request *rq,
q->last_merge = rq; q->last_merge = rq;
} }
static struct request *elevator_noop_next_request(request_queue_t *q) static int elevator_noop_dispatch(request_queue_t *q, int force)
{ {
if (!list_empty(&q->queue_head)) return 0;
return list_entry_rq(q->queue_head.next);
return NULL;
} }
static struct elevator_type elevator_noop = { static struct elevator_type elevator_noop = {
.ops = { .ops = {
.elevator_merge_fn = elevator_noop_merge, .elevator_merge_fn = elevator_noop_merge,
.elevator_merge_req_fn = elevator_noop_merge_requests, .elevator_merge_req_fn = elevator_noop_merge_requests,
.elevator_next_req_fn = elevator_noop_next_request, .elevator_dispatch_fn = elevator_noop_dispatch,
.elevator_add_req_fn = elevator_noop_add_request, .elevator_add_req_fn = elevator_noop_add_request,
}, },
.elevator_name = "noop", .elevator_name = "noop",
......
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