aboutsummaryrefslogtreecommitdiffstats
path: root/block/elevator.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/elevator.c')
-rw-r--r--block/elevator.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/block/elevator.c b/block/elevator.c
index d4a49a3df829..e4c58827bb46 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -155,9 +155,10 @@ static void elevator_setup_default(void)
155 /* 155 /*
156 * If the given scheduler is not available, fall back to no-op. 156 * If the given scheduler is not available, fall back to no-op.
157 */ 157 */
158 if (!(e = elevator_find(chosen_elevator))) 158 if ((e = elevator_find(chosen_elevator)))
159 elevator_put(e);
160 else
159 strcpy(chosen_elevator, "noop"); 161 strcpy(chosen_elevator, "noop");
160 elevator_put(e);
161} 162}
162 163
163static int __init elevator_setup(char *str) 164static int __init elevator_setup(char *str)
@@ -190,14 +191,14 @@ int elevator_init(request_queue_t *q, char *name)
190 191
191 eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL); 192 eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
192 if (!eq) { 193 if (!eq) {
193 elevator_put(e->elevator_type); 194 elevator_put(e);
194 return -ENOMEM; 195 return -ENOMEM;
195 } 196 }
196 197
197 ret = elevator_attach(q, e, eq); 198 ret = elevator_attach(q, e, eq);
198 if (ret) { 199 if (ret) {
199 kfree(eq); 200 kfree(eq);
200 elevator_put(e->elevator_type); 201 elevator_put(e);
201 } 202 }
202 203
203 return ret; 204 return ret;
@@ -225,6 +226,7 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq)
225 226
226 if (q->last_merge == rq) 227 if (q->last_merge == rq)
227 q->last_merge = NULL; 228 q->last_merge = NULL;
229 q->nr_sorted--;
228 230
229 boundary = q->end_sector; 231 boundary = q->end_sector;
230 232
@@ -283,6 +285,7 @@ void elv_merge_requests(request_queue_t *q, struct request *rq,
283 285
284 if (e->ops->elevator_merge_req_fn) 286 if (e->ops->elevator_merge_req_fn)
285 e->ops->elevator_merge_req_fn(q, rq, next); 287 e->ops->elevator_merge_req_fn(q, rq, next);
288 q->nr_sorted--;
286 289
287 q->last_merge = rq; 290 q->last_merge = rq;
288} 291}
@@ -314,6 +317,20 @@ void elv_requeue_request(request_queue_t *q, struct request *rq)
314 __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); 317 __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
315} 318}
316 319
320static void elv_drain_elevator(request_queue_t *q)
321{
322 static int printed;
323 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
324 ;
325 if (q->nr_sorted == 0)
326 return;
327 if (printed++ < 10) {
328 printk(KERN_ERR "%s: forced dispatching is broken "
329 "(nr_sorted=%u), please report this\n",
330 q->elevator->elevator_type->elevator_name, q->nr_sorted);
331 }
332}
333
317void __elv_add_request(request_queue_t *q, struct request *rq, int where, 334void __elv_add_request(request_queue_t *q, struct request *rq, int where,
318 int plug) 335 int plug)
319{ 336{
@@ -348,9 +365,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
348 365
349 case ELEVATOR_INSERT_BACK: 366 case ELEVATOR_INSERT_BACK:
350 rq->flags |= REQ_SOFTBARRIER; 367 rq->flags |= REQ_SOFTBARRIER;
351 368 elv_drain_elevator(q);
352 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
353 ;
354 list_add_tail(&rq->queuelist, &q->queue_head); 369 list_add_tail(&rq->queuelist, &q->queue_head);
355 /* 370 /*
356 * We kick the queue here for the following reasons. 371 * We kick the queue here for the following reasons.
@@ -369,6 +384,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where,
369 case ELEVATOR_INSERT_SORT: 384 case ELEVATOR_INSERT_SORT:
370 BUG_ON(!blk_fs_request(rq)); 385 BUG_ON(!blk_fs_request(rq));
371 rq->flags |= REQ_SORTED; 386 rq->flags |= REQ_SORTED;
387 q->nr_sorted++;
372 if (q->last_merge == NULL && rq_mergeable(rq)) 388 if (q->last_merge == NULL && rq_mergeable(rq))
373 q->last_merge = rq; 389 q->last_merge = rq;
374 /* 390 /*
@@ -525,33 +541,19 @@ int elv_queue_empty(request_queue_t *q)
525 541
526struct request *elv_latter_request(request_queue_t *q, struct request *rq) 542struct request *elv_latter_request(request_queue_t *q, struct request *rq)
527{ 543{
528 struct list_head *next;
529
530 elevator_t *e = q->elevator; 544 elevator_t *e = q->elevator;
531 545
532 if (e->ops->elevator_latter_req_fn) 546 if (e->ops->elevator_latter_req_fn)
533 return e->ops->elevator_latter_req_fn(q, rq); 547 return e->ops->elevator_latter_req_fn(q, rq);
534
535 next = rq->queuelist.next;
536 if (next != &q->queue_head && next != &rq->queuelist)
537 return list_entry_rq(next);
538
539 return NULL; 548 return NULL;
540} 549}
541 550
542struct request *elv_former_request(request_queue_t *q, struct request *rq) 551struct request *elv_former_request(request_queue_t *q, struct request *rq)
543{ 552{
544 struct list_head *prev;
545
546 elevator_t *e = q->elevator; 553 elevator_t *e = q->elevator;
547 554
548 if (e->ops->elevator_former_req_fn) 555 if (e->ops->elevator_former_req_fn)
549 return e->ops->elevator_former_req_fn(q, rq); 556 return e->ops->elevator_former_req_fn(q, rq);
550
551 prev = rq->queuelist.prev;
552 if (prev != &q->queue_head && prev != &rq->queuelist)
553 return list_entry_rq(prev);
554
555 return NULL; 557 return NULL;
556} 558}
557 559
@@ -691,13 +693,15 @@ static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
691 693
692 set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); 694 set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
693 695
694 while (q->elevator->ops->elevator_dispatch_fn(q, 1)) 696 elv_drain_elevator(q);
695 ;
696 697
697 while (q->rq.elvpriv) { 698 while (q->rq.elvpriv) {
699 blk_remove_plug(q);
700 q->request_fn(q);
698 spin_unlock_irq(q->queue_lock); 701 spin_unlock_irq(q->queue_lock);
699 msleep(10); 702 msleep(10);
700 spin_lock_irq(q->queue_lock); 703 spin_lock_irq(q->queue_lock);
704 elv_drain_elevator(q);
701 } 705 }
702 706
703 spin_unlock_irq(q->queue_lock); 707 spin_unlock_irq(q->queue_lock);
@@ -744,13 +748,15 @@ error:
744ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count) 748ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
745{ 749{
746 char elevator_name[ELV_NAME_MAX]; 750 char elevator_name[ELV_NAME_MAX];
751 size_t len;
747 struct elevator_type *e; 752 struct elevator_type *e;
748 753
749 memset(elevator_name, 0, sizeof(elevator_name)); 754 elevator_name[sizeof(elevator_name) - 1] = '\0';
750 strncpy(elevator_name, name, sizeof(elevator_name)); 755 strncpy(elevator_name, name, sizeof(elevator_name) - 1);
756 len = strlen(elevator_name);
751 757
752 if (elevator_name[strlen(elevator_name) - 1] == '\n') 758 if (len && elevator_name[len - 1] == '\n')
753 elevator_name[strlen(elevator_name) - 1] = '\0'; 759 elevator_name[len - 1] = '\0';
754 760
755 e = elevator_get(elevator_name); 761 e = elevator_get(elevator_name);
756 if (!e) { 762 if (!e) {