[PATCH 1/1] elevator: indirect function calls reducing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From Leonid Ananiev

      The patch eliminates 1 of 3 additional main memory readings
in 17 indirrect io-scheduler function calls.
The "elevator" structure (~100 bytes) is embedded in request queue
structure.

Signed-off-by: Leonid Ananiev [email protected]
---
This patch is applied and tested kernel 2.6.15-rc2.
Online switching between io schedulers was introduced in
Linux 2.6.10 but performance degradation is marked
on Itanium as a result. A cause of degradation is in more steps
for indirect IO scheduler function calls.

 Sysbench fileio benchmark throughput on IPF was increased by 8% for
noop elevator after patching.
sysbench --test=fileio --file-test-mode=rndrw --num-threads=16 \
 --file-total-size=1500M --max-requests=150000
Main memory size was decreased by kernel boot parameter mem=1G

One of functions object codes before and after patching are
<elv_merge_requests>:       <elv_merge_requests>:   
alloc r36=ar.pfs,9,6,0      adds r3=24,r32
adds r8=24,r32              mov r35=b0
mov r35=b0                  adds r8=740,r32
adds r9=644,r32             mov r37=r1
mov r37=r1                  mov r40=r34;;
mov r40=r34;;               nop.m 0x0
nop.m 0x0                   mov.i ar.pfs=r36
mov.i ar.pfs=r36            nop.b 0x0
nop.b 0x0                   ld8 r2=[r3]
ld8 r3=[r8]                 mov r38=r32
mov r38=r32                 mov r39=r33;;
mov r39=r33                 adds r14=16,r2
adds r16=16,r32             adds r11=16,r32
nop.f 0x0                   mov b0=r35;;
mov b0=r35;;                nop.m 0x0
ld8 r2=[r3];;               ld8 r14=[r14]
adds r14=16,r2              nop.b 0x0;;
nop.i 0x0;;                 nop.m 0x0
ld8 r14=[r14];;             cmp.eq p6,p7=0,r14
nop.m 0x0                   br.cond.dpnt.few
cmp.eq p6,p7=0,r14
nop.b 0x0
nop.b 0x0
br.cond.dpnt.few


diff -urpN -X a/Documentation/dontdiff \
  a/block/as-iosched.c b/block/as-iosched.c
--- a/block/as-iosched.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/as-iosched.c	2005-11-24 14:45:51.000000000 -0800
@@ -625,7 +625,7 @@ static void as_antic_stop(struct as_data
 static void as_antic_timeout(unsigned long data)
 {
 	struct request_queue *q = (struct request_queue *)data;
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(q->queue_lock, flags);
@@ -968,7 +968,7 @@ static void update_write_batch(struct as
  */
 static void as_completed_request(request_queue_t *q, struct request *rq)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(rq);
 
 	WARN_ON(!list_empty(&rq->queuelist));
@@ -1028,7 +1028,7 @@ static void as_remove_queued_request(req
 {
 	struct as_rq *arq = RQ_DATA(rq);
 	const int data_dir = arq->is_sync;
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 
 	WARN_ON(arq->state != AS_RQ_QUEUED);
 
@@ -1168,7 +1168,7 @@ static void as_move_to_dispatch(struct a
  */
 static int as_dispatch_request(request_queue_t *q, int force)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq;
 	const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
 	const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
@@ -1366,7 +1366,7 @@ as_add_aliased_request(struct as_data *a
  */
 static void as_add_request(request_queue_t *q, struct request *rq)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(rq);
 	struct as_rq *alias;
 	int data_dir;
@@ -1449,7 +1449,7 @@ static void as_deactivate_request(reques
  */
 static int as_queue_empty(request_queue_t *q)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 
 	return list_empty(&ad->fifo_list[REQ_ASYNC])
 		&& list_empty(&ad->fifo_list[REQ_SYNC]);
@@ -1484,7 +1484,7 @@ static struct request *as_latter_request
 static int
 as_merge(request_queue_t *q, struct request **req, struct bio *bio)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	sector_t rb_key = bio->bi_sector + bio_sectors(bio);
 	struct request *__rq;
 	int ret;
@@ -1527,7 +1527,7 @@ out:
 
 static void as_merged_request(request_queue_t *q, struct request *req)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(req);
 
 	/*
@@ -1568,7 +1568,7 @@ static void as_merged_request(request_qu
 static void as_merged_requests(request_queue_t *q, struct request *req,
 			 	struct request *next)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(req);
 	struct as_rq *anext = RQ_DATA(next);
 
@@ -1656,7 +1656,7 @@ static void as_work_handler(void *data)
 
 static void as_put_request(request_queue_t *q, struct request *rq)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = RQ_DATA(rq);
 
 	if (!arq) {
@@ -1678,7 +1678,7 @@ static void as_put_request(request_queue
 static int as_set_request(request_queue_t *q, struct request *rq,
 			  struct bio *bio, gfp_t gfp_mask)
 {
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
 
 	if (arq) {
@@ -1700,7 +1700,7 @@ static int as_set_request(request_queue_
 static int as_may_queue(request_queue_t *q, int rw, struct bio *bio)
 {
 	int ret = ELV_MQUEUE_MAY;
-	struct as_data *ad = q->elevator->elevator_data;
+	struct as_data *ad = q->elevator.elevator_data;
 	struct io_context *ioc;
 	if (ad->antic_status == ANTIC_WAIT_REQ ||
 			ad->antic_status == ANTIC_WAIT_NEXT) {
diff -urpN -X a/Documentation/dontdiff \
 a/block/cfq-iosched.c b/block/cfq-iosched.c
--- a/block/cfq-iosched.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/cfq-iosched.c	2005-11-24 14:45:51.000000000 -0800
@@ -342,7 +342,7 @@ static inline void cfq_schedule_dispatch
 
 static int cfq_queue_empty(request_queue_t *q)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 
 	return !cfqd->busy_queues;
 }
@@ -643,14 +643,14 @@ out:
 
 static void cfq_activate_request(request_queue_t *q, struct request *rq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 
 	cfqd->rq_in_driver++;
 }
 
 static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 
 	WARN_ON(!cfqd->rq_in_driver);
 	cfqd->rq_in_driver--;
@@ -668,7 +668,7 @@ static void cfq_remove_request(struct re
 static int
 cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct request *__rq;
 	int ret;
 
@@ -692,7 +692,7 @@ out:
 
 static void cfq_merged_request(request_queue_t *q, struct request *req)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct cfq_rq *crq = RQ_DATA(req);
 
 	cfq_del_crq_hash(crq);
@@ -928,7 +928,7 @@ static int cfq_arm_slice_timer(struct cf
 
 static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct cfq_queue *cfqq = crq->cfq_queue;
 
 	cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
@@ -1128,7 +1128,7 @@ cfq_forced_dispatch(struct cfq_data *cfq
 static int
 cfq_dispatch_requests(request_queue_t *q, int force)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct cfq_queue *cfqq;
 
 	if (!cfqd->busy_queues)
@@ -1676,7 +1676,7 @@ cfq_crq_enqueued(struct cfq_data *cfqd, 
 
 static void cfq_insert_request(request_queue_t *q, struct request *rq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct cfq_rq *crq = RQ_DATA(rq);
 	struct cfq_queue *cfqq = crq->cfq_queue;
 
@@ -1842,7 +1842,7 @@ __cfq_may_queue(struct cfq_data *cfqd, s
 
 static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct task_struct *tsk = current;
 	struct cfq_queue *cfqq;
 
@@ -1865,7 +1865,7 @@ static int cfq_may_queue(request_queue_t
 
 static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct request_list *rl = &q->rq;
 
 	if (cfqq->allocated[READ] <= cfqd->max_queued || cfqd->rq_starved) {
@@ -1886,7 +1886,7 @@ static void cfq_check_waiters(request_qu
  */
 static void cfq_put_request(request_queue_t *q, struct request *rq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct cfq_rq *crq = RQ_DATA(rq);
 
 	if (crq) {
@@ -1913,7 +1913,7 @@ static int
 cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
 		gfp_t gfp_mask)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	struct task_struct *tsk = current;
 	struct cfq_io_context *cic;
 	const int rw = rq_data_dir(rq);
@@ -1986,7 +1986,7 @@ queue_fail:
 static void cfq_kick_queue(void *data)
 {
 	request_queue_t *q = data;
-	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_data *cfqd = q->elevator.elevator_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(q->queue_lock, flags);
diff -urpN -X a/Documentation/dontdiff\
 a/block/deadline-iosched.c b/block/deadline-iosched.c
--- a/block/deadline-iosched.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/deadline-iosched.c	2005-11-24 14:45:51.000000000 -0800
@@ -276,7 +276,7 @@ deadline_find_first_drq(struct deadline_
 static void
 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;
 	struct deadline_rq *drq = RQ_DATA(rq);
 
 	const int data_dir = rq_data_dir(drq->request);
@@ -298,7 +298,7 @@ deadline_add_request(struct request_queu
 static void deadline_remove_request(request_queue_t *q, struct request *rq)
 {
 	struct deadline_rq *drq = RQ_DATA(rq);
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 
 	list_del_init(&drq->fifo);
 	deadline_del_drq_rb(dd, drq);
@@ -308,7 +308,7 @@ static void deadline_remove_request(requ
 static int
 deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
 {
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 	struct request *__rq;
 	int ret;
 
@@ -352,7 +352,7 @@ out:
 
 static void deadline_merged_request(request_queue_t *q, struct request *req)
 {
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq = RQ_DATA(req);
 
 	/*
@@ -374,7 +374,7 @@ static void
 deadline_merged_requests(request_queue_t *q, struct request *req,
 			 struct request *next)
 {
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq = RQ_DATA(req);
 	struct deadline_rq *dnext = RQ_DATA(next);
 
@@ -471,7 +471,7 @@ static inline int deadline_check_fifo(st
  */
 static int deadline_dispatch_requests(request_queue_t *q, int force)
 {
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 	const int reads = !list_empty(&dd->fifo_list[READ]);
 	const int writes = !list_empty(&dd->fifo_list[WRITE]);
 	struct deadline_rq *drq;
@@ -567,7 +567,7 @@ dispatch_request:
 
 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;
 
 	return list_empty(&dd->fifo_list[WRITE])
 		&& list_empty(&dd->fifo_list[READ]);
@@ -659,7 +659,7 @@ static int deadline_init_queue(request_q
 
 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);
 
 	mempool_free(drq, dd->drq_pool);
@@ -670,7 +670,7 @@ static int
 deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
 		     gfp_t gfp_mask)
 {
-	struct deadline_data *dd = q->elevator->elevator_data;
+	struct deadline_data *dd = q->elevator.elevator_data;
 	struct deadline_rq *drq;
 
 	drq = mempool_alloc(dd->drq_pool, gfp_mask);
diff -urpN -X a/Documentation/dontdiff\
 a/block/elevator.c b/block/elevator.c
--- a/block/elevator.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/elevator.c	2005-11-24 20:19:37.000000000 -0800
@@ -121,17 +121,15 @@ static struct elevator_type *elevator_ge
 	return e;
 }
 
-static int elevator_attach(request_queue_t *q, struct elevator_type *e,
-			   struct elevator_queue *eq)
+static int elevator_attach(request_queue_t *q, struct elevator_type *e)
 {
 	int ret = 0;
+	struct elevator_queue *eq;
 
-	memset(eq, 0, sizeof(*eq));
+	eq = &q->elevator;
 	eq->ops = &e->ops;
 	eq->elevator_type = e;
 
-	q->elevator = eq;
-
 	if (eq->ops->elevator_init_fn)
 		ret = eq->ops->elevator_init_fn(q, eq);
 
@@ -170,7 +168,6 @@ __setup("elevator=", elevator_setup);
 int elevator_init(request_queue_t *q, char *name)
 {
 	struct elevator_type *e = NULL;
-	struct elevator_queue *eq;
 	int ret = 0;
 
 	INIT_LIST_HEAD(&q->queue_head);
@@ -187,15 +184,8 @@ int elevator_init(request_queue_t *q, ch
 	if (!e)
 		return -EINVAL;
 
-	eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
-	if (!eq) {
-		elevator_put(e);
-		return -ENOMEM;
-	}
-
-	ret = elevator_attach(q, e, eq);
+	ret = elevator_attach(q, e);
 	if (ret) {
-		kfree(eq);
 		elevator_put(e);
 	}
 
@@ -209,7 +199,6 @@ void elevator_exit(elevator_t *e)
 
 	elevator_put(e->elevator_type);
 	e->elevator_type = NULL;
-	kfree(e);
 }
 
 /*
@@ -249,7 +238,7 @@ void elv_dispatch_sort(request_queue_t *
 
 int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 	int ret;
 
 	if (q->last_merge) {
@@ -268,7 +257,7 @@ int elv_merge(request_queue_t *q, struct
 
 void elv_merged_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_merged_fn)
 		e->ops->elevator_merged_fn(q, rq);
@@ -279,7 +268,7 @@ void elv_merged_request(request_queue_t 
 void elv_merge_requests(request_queue_t *q, struct request *rq,
 			     struct request *next)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_merge_req_fn)
 		e->ops->elevator_merge_req_fn(q, rq, next);
@@ -290,7 +279,7 @@ void elv_merge_requests(request_queue_t 
 
 void elv_requeue_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	/*
 	 * it already went through dequeue, we need to decrement the
@@ -318,14 +307,14 @@ void elv_requeue_request(request_queue_t
 static void elv_drain_elevator(request_queue_t *q)
 {
 	static int printed;
-	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+	while (q->elevator.ops->elevator_dispatch_fn(q, 1))
 		;
 	if (q->nr_sorted == 0)
 		return;
 	if (printed++ < 10) {
 		printk(KERN_ERR "%s: forced dispatching is broken "
 		       "(nr_sorted=%u), please report this\n",
-		       q->elevator->elevator_type->elevator_name, q->nr_sorted);
+		       q->elevator.elevator_type->elevator_name, q->nr_sorted);
 	}
 }
 
@@ -390,7 +379,7 @@ void __elv_add_request(request_queue_t *
 		 * rq cannot be accessed after calling
 		 * elevator_add_req_fn.
 		 */
-		q->elevator->ops->elevator_add_req_fn(q, rq);
+		q->elevator.ops->elevator_add_req_fn(q, rq);
 		break;
 
 	default:
@@ -423,7 +412,7 @@ static inline struct request *__elv_next
 	struct request *rq;
 
 	if (unlikely(list_empty(&q->queue_head) &&
-		     !q->elevator->ops->elevator_dispatch_fn(q, 0)))
+		     !q->elevator.ops->elevator_dispatch_fn(q, 0)))
 		return NULL;
 
 	rq = list_entry_rq(q->queue_head.next);
@@ -450,7 +439,7 @@ struct request *elv_next_request(request
 
 	while ((rq = __elv_next_request(q)) != NULL) {
 		if (!(rq->flags & REQ_STARTED)) {
-			elevator_t *e = q->elevator;
+			elevator_t *e = &q->elevator;
 
 			/*
 			 * This is the first time the device driver
@@ -526,7 +515,7 @@ void elv_dequeue_request(request_queue_t
 
 int elv_queue_empty(request_queue_t *q)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (!list_empty(&q->queue_head))
 		return 0;
@@ -539,7 +528,7 @@ int elv_queue_empty(request_queue_t *q)
 
 struct request *elv_latter_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_latter_req_fn)
 		return e->ops->elevator_latter_req_fn(q, rq);
@@ -548,7 +537,7 @@ struct request *elv_latter_request(reque
 
 struct request *elv_former_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_former_req_fn)
 		return e->ops->elevator_former_req_fn(q, rq);
@@ -558,7 +547,7 @@ struct request *elv_former_request(reque
 int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
 		    gfp_t gfp_mask)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_set_req_fn)
 		return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask);
@@ -569,7 +558,7 @@ int elv_set_request(request_queue_t *q, 
 
 void elv_put_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_put_req_fn)
 		e->ops->elevator_put_req_fn(q, rq);
@@ -577,7 +566,7 @@ void elv_put_request(request_queue_t *q,
 
 int elv_may_queue(request_queue_t *q, int rw, struct bio *bio)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	if (e->ops->elevator_may_queue_fn)
 		return e->ops->elevator_may_queue_fn(q, rw, bio);
@@ -587,7 +576,7 @@ int elv_may_queue(request_queue_t *q, in
 
 void elv_completed_request(request_queue_t *q, struct request *rq)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	/*
 	 * request is released from the driver, io must be done
@@ -601,7 +590,7 @@ void elv_completed_request(request_queue
 
 int elv_register_queue(struct request_queue *q)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 
 	e->kobj.parent = kobject_get(&q->kobj);
 	if (!e->kobj.parent)
@@ -616,7 +605,7 @@ int elv_register_queue(struct request_qu
 void elv_unregister_queue(struct request_queue *q)
 {
 	if (q) {
-		elevator_t *e = q->elevator;
+		elevator_t *e = &q->elevator;
 		kobject_unregister(&e->kobj);
 		kobject_put(&q->kobj);
 	}
@@ -675,14 +664,7 @@ EXPORT_SYMBOL_GPL(elv_unregister);
  */
 static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
 {
-	elevator_t *old_elevator, *e;
-
-	/*
-	 * Allocate new elevator
-	 */
-	e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
-	if (!e)
-		goto error;
+	elevator_t old_elevator;
 
 	/*
 	 * Turn on BYPASS and drain all requests w/ elevator private data
@@ -713,7 +695,7 @@ static void elevator_switch(request_queu
 	/*
 	 * attach and start new elevator
 	 */
-	if (elevator_attach(q, new_e, e))
+	if (elevator_attach(q, new_e))
 		goto fail;
 
 	if (elv_register_queue(q))
@@ -722,7 +704,7 @@ static void elevator_switch(request_queu
 	/*
 	 * finally exit old elevator and turn off BYPASS.
 	 */
-	elevator_exit(old_elevator);
+	elevator_exit(&old_elevator);
 	clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
 	return;
 
@@ -731,14 +713,11 @@ fail_register:
 	 * switch failed, exit the new io scheduler and reattach the old
 	 * one again (along with re-adding the sysfs dir)
 	 */
-	elevator_exit(e);
-	e = NULL;
+	elevator_exit(&q->elevator);
 fail:
 	q->elevator = old_elevator;
 	elv_register_queue(q);
 	clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
-	kfree(e);
-error:
 	elevator_put(new_e);
 	printk(KERN_ERR "elevator: switch to %s failed\n",new_e->elevator_name);
 }
@@ -762,7 +741,7 @@ ssize_t elv_iosched_store(request_queue_
 		return -EINVAL;
 	}
 
-	if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
+	if (!strcmp(elevator_name, q->elevator.elevator_type->elevator_name)) {
 		elevator_put(e);
 		return count;
 	}
@@ -773,7 +752,7 @@ ssize_t elv_iosched_store(request_queue_
 
 ssize_t elv_iosched_show(request_queue_t *q, char *name)
 {
-	elevator_t *e = q->elevator;
+	elevator_t *e = &q->elevator;
 	struct elevator_type *elv = e->elevator_type;
 	struct list_head *entry;
 	int len = 0;
diff -urpN -X a/Documentation/dontdiff\
 a/block/ll_rw_blk.c b/block/ll_rw_blk.c
--- a/block/ll_rw_blk.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/ll_rw_blk.c	2005-11-24 14:45:51.000000000 -0800
@@ -1612,8 +1612,7 @@ void blk_cleanup_queue(request_queue_t *
 	if (!atomic_dec_and_test(&q->refcnt))
 		return;
 
-	if (q->elevator)
-		elevator_exit(q->elevator);
+	elevator_exit(&q->elevator);
 
 	blk_sync_queue(q);
 
diff -urpN -X a/Documentation/dontdiff\
 a/block/noop-iosched.c b/block/noop-iosched.c
--- a/block/noop-iosched.c	2005-11-27 14:46:09.000000000 -0800
+++ b/block/noop-iosched.c	2005-11-24 20:21:15.000000000 -0800
@@ -19,7 +19,7 @@ static void noop_merged_requests(request
 
 static int noop_dispatch(request_queue_t *q, int force)
 {
-	struct noop_data *nd = q->elevator->elevator_data;
+	struct noop_data *nd = q->elevator.elevator_data;
 
 	if (!list_empty(&nd->queue)) {
 		struct request *rq;
@@ -33,14 +33,14 @@ static int noop_dispatch(request_queue_t
 
 static void noop_add_request(request_queue_t *q, struct request *rq)
 {
-	struct noop_data *nd = q->elevator->elevator_data;
+	struct noop_data *nd = q->elevator.elevator_data;
 
 	list_add_tail(&rq->queuelist, &nd->queue);
 }
 
 static int noop_queue_empty(request_queue_t *q)
 {
-	struct noop_data *nd = q->elevator->elevator_data;
+	struct noop_data *nd = q->elevator.elevator_data;
 
 	return list_empty(&nd->queue);
 }
@@ -48,7 +48,7 @@ static int noop_queue_empty(request_queu
 static struct request *
 noop_former_request(request_queue_t *q, struct request *rq)
 {
-	struct noop_data *nd = q->elevator->elevator_data;
+	struct noop_data *nd = q->elevator.elevator_data;
 
 	if (rq->queuelist.prev == &nd->queue)
 		return NULL;
@@ -58,7 +58,7 @@ noop_former_request(request_queue_t *q, 
 static struct request *
 noop_latter_request(request_queue_t *q, struct request *rq)
 {
-	struct noop_data *nd = q->elevator->elevator_data;
+	struct noop_data *nd = q->elevator.elevator_data;
 
 	if (rq->queuelist.next == &nd->queue)
 		return NULL;
diff -urpN -X a/Documentation/dontdiff\
 a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	2005-11-27 14:46:38.000000000 -0800
+++ b/include/linux/blkdev.h	2005-11-24 14:45:51.000000000 -0800
@@ -316,7 +316,7 @@ struct request_queue
 	 */
 	struct list_head	queue_head;
 	struct request		*last_merge;
-	elevator_t		*elevator;
+	elevator_t		elevator;
 
 	/*
 	 * the queue request freelist, one for reads and one for writes
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux