diff options
author | Jens Axboe <jens.axboe@oracle.com> | 2009-03-27 05:30:47 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2009-04-07 02:12:37 -0400 |
commit | 6c7e8cee6a9128eeb7f83c3ad1cb243f77f5cb16 (patch) | |
tree | f57ac6ab9e57a4e3317a54d04c39151d3bb942cf /block/elevator.c | |
parent | d508afb437daee7cf07da085b635c44a4ebf9b38 (diff) |
block: elevator quiescing helpers
Simple helper functions to quiesce the request queue. These are
currently only used for switching IO schedulers on-the-fly, but
we can use them to properly switch IO accounting on and off as well.
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'block/elevator.c')
-rw-r--r-- | block/elevator.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/block/elevator.c b/block/elevator.c index ca6788a0195a..c6744913ff4a 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -587,6 +587,31 @@ static void elv_drain_elevator(struct request_queue *q) | |||
587 | } | 587 | } |
588 | } | 588 | } |
589 | 589 | ||
590 | /* | ||
591 | * Call with queue lock held, interrupts disabled | ||
592 | */ | ||
593 | void elv_quisce_start(struct request_queue *q) | ||
594 | { | ||
595 | queue_flag_set(QUEUE_FLAG_ELVSWITCH, q); | ||
596 | |||
597 | /* | ||
598 | * make sure we don't have any requests in flight | ||
599 | */ | ||
600 | elv_drain_elevator(q); | ||
601 | while (q->rq.elvpriv) { | ||
602 | blk_start_queueing(q); | ||
603 | spin_unlock_irq(q->queue_lock); | ||
604 | msleep(10); | ||
605 | spin_lock_irq(q->queue_lock); | ||
606 | elv_drain_elevator(q); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | void elv_quisce_end(struct request_queue *q) | ||
611 | { | ||
612 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); | ||
613 | } | ||
614 | |||
590 | void elv_insert(struct request_queue *q, struct request *rq, int where) | 615 | void elv_insert(struct request_queue *q, struct request *rq, int where) |
591 | { | 616 | { |
592 | struct list_head *pos; | 617 | struct list_head *pos; |
@@ -1101,18 +1126,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
1101 | * Turn on BYPASS and drain all requests w/ elevator private data | 1126 | * Turn on BYPASS and drain all requests w/ elevator private data |
1102 | */ | 1127 | */ |
1103 | spin_lock_irq(q->queue_lock); | 1128 | spin_lock_irq(q->queue_lock); |
1104 | 1129 | elv_quisce_start(q); | |
1105 | queue_flag_set(QUEUE_FLAG_ELVSWITCH, q); | ||
1106 | |||
1107 | elv_drain_elevator(q); | ||
1108 | |||
1109 | while (q->rq.elvpriv) { | ||
1110 | blk_start_queueing(q); | ||
1111 | spin_unlock_irq(q->queue_lock); | ||
1112 | msleep(10); | ||
1113 | spin_lock_irq(q->queue_lock); | ||
1114 | elv_drain_elevator(q); | ||
1115 | } | ||
1116 | 1130 | ||
1117 | /* | 1131 | /* |
1118 | * Remember old elevator. | 1132 | * Remember old elevator. |
@@ -1136,7 +1150,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e) | |||
1136 | */ | 1150 | */ |
1137 | elevator_exit(old_elevator); | 1151 | elevator_exit(old_elevator); |
1138 | spin_lock_irq(q->queue_lock); | 1152 | spin_lock_irq(q->queue_lock); |
1139 | queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); | 1153 | elv_quisce_end(q); |
1140 | spin_unlock_irq(q->queue_lock); | 1154 | spin_unlock_irq(q->queue_lock); |
1141 | 1155 | ||
1142 | blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); | 1156 | blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name); |