On 2018/06/13 23:46, Jan Kara wrote: > On Wed 13-06-18 19:43:47, Tetsuo Handa wrote: >> Can't we utilize RCU grace period (like shown below) ? > > Honestly, the variant 1 looks too ugly to me. However variant 2 looks > mostly OK. We can also avoid the schedule_timeout_uninterruptible(HZ / 10) > from your patch by careful handling of the bit waitqueues. Also I'd avoid > the addition argument to wb_writeback() and split the function instead. The > patch resulting from your and mine ideas is attached. Thoughts? > > Honza > +static bool cgwb_start_shutdown(struct bdi_writeback *wb) + __releases(cgwb_lock) +{ + if (!wb_start_shutdown(wb)) { + DEFINE_WAIT(wait); + wait_queue_head_t *wqh = bit_waitqueue(&wb->state, + WB_shutting_down); + bool sleep; + + prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); + sleep = test_bit(WB_shutting_down, &wb->state); + spin_unlock_irq(&cgwb_lock); + if (sleep) + schedule(); + return false; + } + spin_unlock_irq(&cgwb_lock); + return true; +} Since multiple addresses share bit_wait_table[256], isn't it possible that cgwb_start_shutdown() prematurely returns false due to wake_up_bit() by hash-conflicting addresses (i.e. not limited to clear_and_wake_up_bit() from wb_shutdown())? I think that we cannot be sure without confirming that test_bit(WB_shutting_down, &wb->state) == false after returning from schedule().