Commit 6c7e8cee6a9128eeb7f83c3ad1cb243f77f5cb16

Authored by Jens Axboe
1 parent d508afb437

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>

Showing 2 changed files with 31 additions and 13 deletions Side-by-side Diff

... ... @@ -70,6 +70,10 @@
70 70  
71 71 int blk_dev_init(void);
72 72  
  73 +void elv_quisce_start(struct request_queue *q);
  74 +void elv_quisce_end(struct request_queue *q);
  75 +
  76 +
73 77 /*
74 78 * Return the threshold (number of used requests) at which the queue is
75 79 * considered to be congested. It include a little hysteresis to keep the
... ... @@ -587,6 +587,31 @@
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 615 void elv_insert(struct request_queue *q, struct request *rq, int where)
591 616 {
592 617 struct list_head *pos;
593 618  
... ... @@ -1101,19 +1126,8 @@
1101 1126 * Turn on BYPASS and drain all requests w/ elevator private data
1102 1127 */
1103 1128 spin_lock_irq(q->queue_lock);
  1129 + elv_quisce_start(q);
1104 1130  
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   -
1117 1131 /*
1118 1132 * Remember old elevator.
1119 1133 */
... ... @@ -1136,7 +1150,7 @@
1136 1150 */
1137 1151 elevator_exit(old_elevator);
1138 1152 spin_lock_irq(q->queue_lock);
1139   - queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
  1153 + elv_quisce_end(q);
1140 1154 spin_unlock_irq(q->queue_lock);
1141 1155  
1142 1156 blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);