• ZhaoLong Wang's avatar
    ubi: Fix deadlock caused by recursively holding work_sem · f773f0a3
    ZhaoLong Wang authored
    During the processing of the bgt, if the sync_erase() return -EBUSY
    or some other error code in __erase_worker(),schedule_erase() called
    again lead to the down_read(ubi->work_sem) hold twice and may get
    block by down_write(ubi->work_sem) in ubi_update_fastmap(),
    which cause deadlock.
    
              ubi bgt                        other task
     do_work
      down_read(&ubi->work_sem)          ubi_update_fastmap
      erase_worker                         # Blocked by down_read
       __erase_worker                      down_write(&ubi->work_sem)
        schedule_erase
         schedule_ubi_work
          down_read(&ubi->work_sem)
    
    Fix this by changing input parameter @nested of the schedule_erase() to
    'true' to avoid recursively acquiring the down_read(&ubi->work_sem).
    
    Also, fix the incorrect comment about @nested parameter of the
    schedule_erase() because when down_write(ubi->work_sem) is held, the
    @nested is also need be true.
    
    Link: https://bugzilla.kernel.org/show_bug.cgi?id=217093
    Fixes: 2e8f08de ("ubi: Fix races around ubi_refill_pools()")
    Signed-off-by: default avatarZhaoLong Wang <wangzhaolong1@huawei.com>
    Reviewed-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
    Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
    f773f0a3
wl.c 56.1 KB