• NeilBrown's avatar
    md: always clear ->safemode when md_check_recovery gets the mddev lock. · 33182d15
    NeilBrown authored
    If ->safemode == 1, md_check_recovery() will try to get the mddev lock
    and perform various other checks.
    If mddev->in_sync is zero, it will call set_in_sync, and clear
    ->safemode.  However if mddev->in_sync is not zero, ->safemode will not
    be cleared.
    
    When md_check_recovery() drops the mddev lock, the thread is woken
    up again.  Normally it would just check if there was anything else to
    do, find nothing, and go to sleep.  However as ->safemode was not
    cleared, it will take the mddev lock again, then wake itself up
    when unlocking.
    
    This results in an infinite loop, repeatedly calling
    md_check_recovery(), which RCU or the soft-lockup detector
    will eventually complain about.
    
    Prior to commit 4ad23a97 ("MD: use per-cpu counter for
    writes_pending"), safemode would only be set to one when the
    writes_pending counter reached zero, and would be cleared again
    when writes_pending is incremented.  Since that patch, safemode
    is set more freely, but is not reliably cleared.
    
    So in md_check_recovery() clear ->safemode before checking ->in_sync.
    
    Fixes: 4ad23a97 ("MD: use per-cpu counter for writes_pending")
    Cc: stable@vger.kernel.org (4.12+)
    Reported-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
    Reported-by: default avatarDavid R <david@unsolicited.net>
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    33182d15
md.c 241 KB