• Joe Thornber's avatar
    dm cache: fix a lock-inversion · 0596661f
    Joe Thornber authored
    When suspending a cache the policy is walked and the individual policy
    hints written to the metadata via sync_metadata().  This led to this
    lock order:
    
          policy->lock
            cache_metadata->root_lock
    
    When loading the cache target the policy is populated while the metadata
    lock is held:
    
          cache_metadata->root_lock
             policy->lock
    
    Fix this potential lock-inversion (ABBA) deadlock in sync_metadata() by
    ensuring the cache_metadata root_lock is held whilst all the hints are
    written, rather than being repeatedly locked while policy->lock is held
    (as was the case with each callout that policy_walk_mappings() made to
    the old save_hint() method).
    
    Found by turning on the CONFIG_PROVE_LOCKING ("Lock debugging: prove
    locking correctness") build option.  However, it is not clear how the
    LOCKDEP reported paths can lead to a deadlock since the two paths,
    suspending a target and loading a target, never occur at the same time.
    But that doesn't mean the same lock-inversion couldn't have occurred
    elsewhere.
    Reported-by: default avatarMarian Csontos <mcsontos@redhat.com>
    Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    Cc: stable@vger.kernel.org
    0596661f
dm-cache-target.c 75 KB