Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ocfs2: fix deadlock between setattr and dio_end_io_write
commit 90bd070 upstream. The following deadlock is detected: truncate -> setattr path is waiting for pending direct IO to be done (inode->i_dio_count become zero) with inode->i_rwsem held (down_write). PID: 14827 TASK: ffff881686a9af80 CPU: 20 COMMAND: "ora_p005_hrltd9" #0 __schedule at ffffffff818667cc #1 schedule at ffffffff81866de6 multipath-tcp#2 inode_dio_wait at ffffffff812a2d04 multipath-tcp#3 ocfs2_setattr at ffffffffc05f322e [ocfs2] multipath-tcp#4 notify_change at ffffffff812a5a09 multipath-tcp#5 do_truncate at ffffffff812808f5 multipath-tcp#6 do_sys_ftruncate.constprop.18 at ffffffff81280cf2 multipath-tcp#7 sys_ftruncate at ffffffff81280d8e multipath-tcp#8 do_syscall_64 at ffffffff81003949 multipath-tcp#9 entry_SYSCALL_64_after_hwframe at ffffffff81a001ad dio completion path is going to complete one direct IO (decrement inode->i_dio_count), but before that it hung at locking inode->i_rwsem: #0 __schedule+700 at ffffffff818667cc #1 schedule+54 at ffffffff81866de6 multipath-tcp#2 rwsem_down_write_failed+536 at ffffffff8186aa28 multipath-tcp#3 call_rwsem_down_write_failed+23 at ffffffff8185a1b7 multipath-tcp#4 down_write+45 at ffffffff81869c9d multipath-tcp#5 ocfs2_dio_end_io_write+180 at ffffffffc05d5444 [ocfs2] multipath-tcp#6 ocfs2_dio_end_io+85 at ffffffffc05d5a85 [ocfs2] multipath-tcp#7 dio_complete+140 at ffffffff812c873c multipath-tcp#8 dio_aio_complete_work+25 at ffffffff812c89f9 multipath-tcp#9 process_one_work+361 at ffffffff810b1889 multipath-tcp#10 worker_thread+77 at ffffffff810b233d multipath-tcp#11 kthread+261 at ffffffff810b7fd5 multipath-tcp#12 ret_from_fork+62 at ffffffff81a0035e Thus above forms ABBA deadlock. The same deadlock was mentioned in upstream commit 28f5a8a ("ocfs2: should wait dio before inode lock in ocfs2_setattr()"). It seems that that commit only removed the cluster lock (the victim of above dead lock) from the ABBA deadlock party. End-user visible effects: Process hang in truncate -> ocfs2_setattr path and other processes hang at ocfs2_dio_end_io_write path. This is to fix the deadlock itself. It removes inode_lock() call from dio completion path to remove the deadlock and add ip_alloc_sem lock in setattr path to synchronize the inode modifications. [[email protected]: remove the "had_alloc_lock" as suggested] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Wengang Wang <[email protected]> Reviewed-by: Joseph Qi <[email protected]> Cc: Mark Fasheh <[email protected]> Cc: Joel Becker <[email protected]> Cc: Junxiao Bi <[email protected]> Cc: Changwei Ge <[email protected]> Cc: Gang He <[email protected]> Cc: Jun Piao <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
- Loading branch information