25-akpm/drivers/block/as-iosched.c | 94 ++++++++++++++++++------------------- 1 files changed, 46 insertions(+), 48 deletions(-) diff -puN drivers/block/as-iosched.c~as-iosched-dyn drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~as-iosched-dyn Wed Apr 30 15:22:55 2003 +++ 25-akpm/drivers/block/as-iosched.c Wed Apr 30 15:22:55 2003 @@ -117,6 +117,7 @@ struct as_data { unsigned long current_batch_expires; unsigned long last_check_fifo[2]; int batch_data_dir; /* current/last batch READ or WRITE */ + mempool_t *arq_pool; int antic_status; unsigned long antic_start; /* jiffies: when it started */ @@ -1442,12 +1443,42 @@ static void as_work_handler(void *data) spin_unlock_irqrestore(q->queue_lock, flags); } +static void as_put_request(request_queue_t *q, struct request *rq) +{ + struct as_data *ad = q->elevator.elevator_data; + struct as_rq *arq = RQ_DATA(rq); + + if (arq) { + mempool_free(arq, ad->arq_pool); + rq->elevator_private = NULL; + } +} + +static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask) +{ + struct as_data *ad = q->elevator.elevator_data; + struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask); + + if (arq) { + RB_CLEAR(&arq->rb_node); + arq->request = rq; + + arq->as_io_context = NULL; + INIT_LIST_HEAD(&arq->hash); + arq->hash_valid_count = 0; + + INIT_LIST_HEAD(&arq->fifo); + + rq->elevator_private = arq; + return 0; + } + + return 1; +} + static void as_exit(request_queue_t *q, elevator_t *e) { struct as_data *ad = e->elevator_data; - struct as_rq *arq; - struct request *rq; - int i; del_timer_sync(&ad->antic_timer); kblockd_flush(); @@ -1455,21 +1486,7 @@ static void as_exit(request_queue_t *q, BUG_ON(!list_empty(&ad->fifo_list[READ])); BUG_ON(!list_empty(&ad->fifo_list[WRITE])); - for (i = READ; i <= WRITE; i++) { - struct request_list *rl = &q->rq[i]; - struct list_head *entry; - - list_for_each(entry, &rl->free) { - rq = list_entry_rq(entry); - - if ((arq = RQ_DATA(rq)) == NULL) - continue; - - rq->elevator_private = NULL; - kmem_cache_free(arq_pool, arq); - } - } - + mempool_destroy(ad->arq_pool); put_as_io_context(&ad->as_io_context); kfree(ad->hash); kfree(ad); @@ -1482,9 +1499,7 @@ static void as_exit(request_queue_t *q, static int as_init(request_queue_t *q, elevator_t *e) { struct as_data *ad; - struct as_rq *arq; - struct request *rq; - int i, ret = 0; + int i; if (!arq_pool) return -ENOMEM; @@ -1502,6 +1517,13 @@ static int as_init(request_queue_t *q, e return -ENOMEM; } + ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool); + if (!ad->arq_pool) { + kfree(ad->hash); + kfree(ad); + return -ENOMEM; + } + /* anticipatory scheduling helpers */ ad->antic_timer.function = as_antic_timeout; ad->antic_timer.data = (unsigned long)q; @@ -1525,33 +1547,7 @@ static int as_init(request_queue_t *q, e e->elevator_data = ad; ad->current_batch_expires = jiffies + ad->batch_expire[READ]; - - for (i = READ; i <= WRITE; i++) { - struct request_list *rl = &q->rq[i]; - struct list_head *entry; - - list_for_each(entry, &rl->free) { - rq = list_entry_rq(entry); - - arq = kmem_cache_alloc(arq_pool, GFP_KERNEL); - if (!arq) { - ret = -ENOMEM; - break; - } - - memset(arq, 0, sizeof(*arq)); - INIT_LIST_HEAD(&arq->fifo); - INIT_LIST_HEAD(&arq->hash); - RB_CLEAR(&arq->rb_node); - arq->request = rq; - rq->elevator_private = arq; - } - } - - if (ret) - as_exit(q, e); - - return ret; + return 0; } /* @@ -1705,6 +1701,8 @@ elevator_t iosched_as = { .elevator_completed_req_fn = as_completed_request, .elevator_former_req_fn = as_former_request, .elevator_latter_req_fn = as_latter_request, + .elevator_set_req_fn = as_set_request, + .elevator_put_req_fn = as_put_request, .elevator_init_fn = as_init, .elevator_exit_fn = as_exit, _