|
@@ -587,6 +587,31 @@ static void elv_drain_elevator(struct request_queue *q)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Call with queue lock held, interrupts disabled
|
|
|
+ */
|
|
|
+void elv_quisce_start(struct request_queue *q)
|
|
|
+{
|
|
|
+ queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * make sure we don't have any requests in flight
|
|
|
+ */
|
|
|
+ elv_drain_elevator(q);
|
|
|
+ while (q->rq.elvpriv) {
|
|
|
+ blk_start_queueing(q);
|
|
|
+ spin_unlock_irq(q->queue_lock);
|
|
|
+ msleep(10);
|
|
|
+ spin_lock_irq(q->queue_lock);
|
|
|
+ elv_drain_elevator(q);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void elv_quisce_end(struct request_queue *q)
|
|
|
+{
|
|
|
+ queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
|
|
|
+}
|
|
|
+
|
|
|
void elv_insert(struct request_queue *q, struct request *rq, int where)
|
|
|
{
|
|
|
struct list_head *pos;
|
|
@@ -1101,18 +1126,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
|
|
* Turn on BYPASS and drain all requests w/ elevator private data
|
|
|
*/
|
|
|
spin_lock_irq(q->queue_lock);
|
|
|
-
|
|
|
- queue_flag_set(QUEUE_FLAG_ELVSWITCH, q);
|
|
|
-
|
|
|
- elv_drain_elevator(q);
|
|
|
-
|
|
|
- while (q->rq.elvpriv) {
|
|
|
- blk_start_queueing(q);
|
|
|
- spin_unlock_irq(q->queue_lock);
|
|
|
- msleep(10);
|
|
|
- spin_lock_irq(q->queue_lock);
|
|
|
- elv_drain_elevator(q);
|
|
|
- }
|
|
|
+ elv_quisce_start(q);
|
|
|
|
|
|
/*
|
|
|
* Remember old elevator.
|
|
@@ -1136,7 +1150,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
|
|
|
*/
|
|
|
elevator_exit(old_elevator);
|
|
|
spin_lock_irq(q->queue_lock);
|
|
|
- queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q);
|
|
|
+ elv_quisce_end(q);
|
|
|
spin_unlock_irq(q->queue_lock);
|
|
|
|
|
|
blk_add_trace_msg(q, "elv switch: %s", e->elevator_type->elevator_name);
|