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>
This commit is contained in:
Родитель
d508afb437
Коммит
6c7e8cee6a
|
@ -70,6 +70,10 @@ void blk_queue_congestion_threshold(struct request_queue *q);
|
|||
|
||||
int blk_dev_init(void);
|
||||
|
||||
void elv_quisce_start(struct request_queue *q);
|
||||
void elv_quisce_end(struct request_queue *q);
|
||||
|
||||
|
||||
/*
|
||||
* Return the threshold (number of used requests) at which the queue is
|
||||
* considered to be congested. It include a little hysteresis to keep the
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче