• Mikulas Patocka's avatar
    dm integrity: fix a deadlock due to offloading to an incorrect workqueue · 53770f0e
    Mikulas Patocka authored
    If we need to perform synchronous I/O in dm_integrity_map_continue(),
    we must make sure that we are not in the map function - in order to
    avoid the deadlock due to bio queuing in generic_make_request. To
    avoid the deadlock, we offload the request to metadata_wq.
    
    However, metadata_wq also processes metadata updates for write requests.
    If there are too many requests that get offloaded to metadata_wq at the
    beginning of dm_integrity_map_continue, the workqueue metadata_wq
    becomes clogged and the system is incapable of processing any metadata
    updates.
    
    This causes a deadlock because all the requests that need to do metadata
    updates wait for metadata_wq to proceed and metadata_wq waits inside
    wait_and_add_new_range until some existing request releases its range
    lock (which doesn't happen because the range lock is released after
    metadata update).
    
    In order to fix the deadlock, we create a new workqueue offload_wq and
    offload requests to it - so that processing of offload_wq is independent
    from processing of metadata_wq.
    
    Fixes: 7eada909 ("dm: add integrity target")
    Cc: stable@vger.kernel.org # v4.12+
    Reported-by: default avatarHeinz Mauelshagen <heinzm@redhat.com>
    Tested-by: default avatarHeinz Mauelshagen <heinzm@redhat.com>
    Signed-off-by: default avatarHeinz Mauelshagen <heinzm@redhat.com>
    Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    53770f0e
dm-integrity.c 122 KB