md/raid1,raid10: silence warning about wait-within-wait
If you prepare_to_wait() after a previous prepare_to_wait(), but before calling schedule(), you get warning: do not call blocking ops when !TASK_RUNNING; state=2 This is appropriate as it is often a bug. The event that the first prepare_to_wait() expects might wake up the schedule following the second prepare_to_wait(), which could be confusing. However if both prepare_to_wait()s are part of simple wait_event() loops, and if the inner one is rarely called, then there is no problem. The inner loop is too simple to get confused by a stray wakeup, and the outer loop won't spin unduly because the inner doesnt affect it often. This pattern occurs in both raid1.c and raid10.c in the use of flush_pending_writes(). The warning can be silenced by setting current->state to TASK_RUNNING. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
Родитель
d5d885fd51
Коммит
474beb575c
|
@ -815,6 +815,17 @@ static void flush_pending_writes(struct r1conf *conf)
|
||||||
bio = bio_list_get(&conf->pending_bio_list);
|
bio = bio_list_get(&conf->pending_bio_list);
|
||||||
conf->pending_count = 0;
|
conf->pending_count = 0;
|
||||||
spin_unlock_irq(&conf->device_lock);
|
spin_unlock_irq(&conf->device_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As this is called in a wait_event() loop (see freeze_array),
|
||||||
|
* current->state might be TASK_UNINTERRUPTIBLE which will
|
||||||
|
* cause a warning when we prepare to wait again. As it is
|
||||||
|
* rare that this path is taken, it is perfectly safe to force
|
||||||
|
* us to go around the wait_event() loop again, so the warning
|
||||||
|
* is a false-positive. Silence the warning by resetting
|
||||||
|
* thread state
|
||||||
|
*/
|
||||||
|
__set_current_state(TASK_RUNNING);
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
flush_bio_list(conf, bio);
|
flush_bio_list(conf, bio);
|
||||||
blk_finish_plug(&plug);
|
blk_finish_plug(&plug);
|
||||||
|
|
|
@ -900,6 +900,18 @@ static void flush_pending_writes(struct r10conf *conf)
|
||||||
bio = bio_list_get(&conf->pending_bio_list);
|
bio = bio_list_get(&conf->pending_bio_list);
|
||||||
conf->pending_count = 0;
|
conf->pending_count = 0;
|
||||||
spin_unlock_irq(&conf->device_lock);
|
spin_unlock_irq(&conf->device_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As this is called in a wait_event() loop (see freeze_array),
|
||||||
|
* current->state might be TASK_UNINTERRUPTIBLE which will
|
||||||
|
* cause a warning when we prepare to wait again. As it is
|
||||||
|
* rare that this path is taken, it is perfectly safe to force
|
||||||
|
* us to go around the wait_event() loop again, so the warning
|
||||||
|
* is a false-positive. Silence the warning by resetting
|
||||||
|
* thread state
|
||||||
|
*/
|
||||||
|
__set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
/* flush any pending bitmap writes to disk
|
/* flush any pending bitmap writes to disk
|
||||||
* before proceeding w/ I/O */
|
* before proceeding w/ I/O */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче