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:
parent
d5d885fd51
commit
474beb575c
2 changed files with 23 additions and 0 deletions
|
@ -815,6 +815,17 @@ static void flush_pending_writes(struct r1conf *conf)
|
|||
bio = bio_list_get(&conf->pending_bio_list);
|
||||
conf->pending_count = 0;
|
||||
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);
|
||||
flush_bio_list(conf, bio);
|
||||
blk_finish_plug(&plug);
|
||||
|
|
|
@ -900,6 +900,18 @@ static void flush_pending_writes(struct r10conf *conf)
|
|||
bio = bio_list_get(&conf->pending_bio_list);
|
||||
conf->pending_count = 0;
|
||||
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);
|
||||
/* flush any pending bitmap writes to disk
|
||||
* before proceeding w/ I/O */
|
||||
|
|
Loading…
Reference in a new issue