linux_dsm_epyc7002/fs/ocfs2
Wengang Wang b1a5122554 ocfs2: fix deadlock between setattr and dio_end_io_write
commit 90bd070aae6c4fb5d302f9c4b9c88be60c8197ec 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
   #2  inode_dio_wait at ffffffff812a2d04
   #3  ocfs2_setattr at ffffffffc05f322e [ocfs2]
   #4  notify_change at ffffffff812a5a09
   #5  do_truncate at ffffffff812808f5
   #6  do_sys_ftruncate.constprop.18 at ffffffff81280cf2
   #7  sys_ftruncate at ffffffff81280d8e
   #8  do_syscall_64 at ffffffff81003949
   #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
   #2  rwsem_down_write_failed+536 at ffffffff8186aa28
   #3  call_rwsem_down_write_failed+23 at ffffffff8185a1b7
   #4  down_write+45 at ffffffff81869c9d
   #5  ocfs2_dio_end_io_write+180 at ffffffffc05d5444 [ocfs2]
   #6  ocfs2_dio_end_io+85 at ffffffffc05d5a85 [ocfs2]
   #7  dio_complete+140 at ffffffff812c873c
   #8  dio_aio_complete_work+25 at ffffffff812c89f9
   #9  process_one_work+361 at ffffffff810b1889
  #10  worker_thread+77 at ffffffff810b233d
  #11  kthread+261 at ffffffff810b7fd5
  #12  ret_from_fork+62 at ffffffff81a0035e

Thus above forms ABBA deadlock.  The same deadlock was mentioned in
upstream commit 28f5a8a7c0 ("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.

[wen.gang.wang@oracle.com: remove the "had_alloc_lock" as suggested]
  Link: https://lkml.kernel.org/r/20210402171344.1605-1-wen.gang.wang@oracle.com

Link: https://lkml.kernel.org/r/20210331203654.3911-1-wen.gang.wang@oracle.com
Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Gang He <ghe@suse.com>
Cc: Jun Piao <piaojun@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-04-14 08:41:58 +02:00
..
cluster ocfs2: fix a use after free on error 2021-03-04 11:38:18 +01:00
dlm ocfs2: add missing annotation for dlm_empty_lockres() 2020-06-02 10:59:05 -07:00
dlmfs dlmfs: clean up dlmfs_file_{read,write}() a bit 2020-06-14 19:04:42 -04:00
acl.c ocfs2: fix remounting needed after setfacl command 2020-08-07 11:33:21 -07:00
acl.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
alloc.c ocfs2: fix potential soft lockup during fstrim 2020-10-13 18:38:27 -07:00
alloc.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
aops.c ocfs2: fix deadlock between setattr and dio_end_io_write 2021-04-14 08:41:58 +02:00
aops.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
blockcheck.c ocfs2: replace HTTP links with HTTPS ones 2020-08-07 11:33:22 -07:00
blockcheck.h ocfs: no need to check return value of debugfs_create functions 2019-07-12 11:05:41 -07:00
buffer_head_io.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
buffer_head_io.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
dcache.c fs/ocfs2: fix race in ocfs2_dentry_attach_lock() 2019-06-13 17:34:56 -10:00
dcache.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
dir.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
dir.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
dlmglue.c ocfs2: fix unbalanced locking 2020-08-07 11:33:22 -07:00
dlmglue.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
export.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
export.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
extent_map.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
extent_map.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 405 2019-06-05 17:37:13 +02:00
file.c ocfs2: fix deadlock between setattr and dio_end_io_write 2021-04-14 08:41:58 +02:00
file.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
filecheck.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 286 2019-06-05 17:36:37 +02:00
filecheck.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 286 2019-06-05 17:36:37 +02:00
heartbeat.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
heartbeat.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
inode.c ocfs2: fix spelling mistake "ambigous" -> "ambiguous" 2019-09-24 15:54:07 -07:00
inode.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
ioctl.c compat_ioctl: remove most of fs/compat_ioctl.c 2019-12-01 13:46:15 -08:00
ioctl.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
journal.c jbd2: rename j_maxlen to j_total_len and add jbd2_journal_max_txn_bufs 2020-11-06 23:01:02 -05:00
journal.h ocfs2: fix a NULL pointer dereference when call ocfs2_update_inode_fsync_trans() 2020-01-31 10:30:36 -08:00
Kconfig ocfs2: replace HTTP links with HTTPS ones 2020-08-07 11:33:22 -07:00
localalloc.c ocfs2: delete repeated words in comments 2020-10-13 18:38:27 -07:00
localalloc.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
locks.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
locks.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
Makefile ocfs2: improve ocfs2 Makefile 2018-12-28 12:11:45 -08:00
mmap.c ocfs2: fix spelling mistake and grammar 2020-06-10 19:14:18 -07:00
mmap.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
move_extents.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
move_extents.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
namei.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
namei.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
ocfs1_fs_compat.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 405 2019-06-05 17:37:13 +02:00
ocfs2_fs.h ocfs2: fix value of OCFS2_INVALID_SLOT 2020-06-26 00:27:37 -07:00
ocfs2_ioctl.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
ocfs2_lockid.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
ocfs2_lockingver.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
ocfs2_trace.h ocfs2: fix the application IO timeout when fstrim is running 2019-03-05 21:07:13 -08:00
ocfs2.h ocfs2: change slot number type s16 to u16 2020-08-07 11:33:21 -07:00
quota_global.c quota: Check that quota is not dirty before release 2019-10-31 19:07:42 +01:00
quota_local.c ocfs2: return -EROFS when filesystem becomes read-only 2018-08-17 16:20:27 -07:00
quota.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
refcounttree.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
refcounttree.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
reservations.c ocfs2: remove unused macros 2020-04-02 09:35:25 -07:00
reservations.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00
resize.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
resize.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
slot_map.c ocfs2: mount shared volume without ha stack 2020-06-02 10:59:05 -07:00
slot_map.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
stack_o2cb.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 286 2019-06-05 17:36:37 +02:00
stack_user.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 286 2019-06-05 17:36:37 +02:00
stackglue.c ocfs2: remove FS_OCFS2_NM 2020-04-02 09:35:25 -07:00
stackglue.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 286 2019-06-05 17:36:37 +02:00
suballoc.c ocfs2: change slot number type s16 to u16 2020-08-07 11:33:21 -07:00
suballoc.h ocfs2: suballoc.h: delete a duplicated word 2020-08-07 11:33:21 -07:00
super.c ocfs2: initialize ip_next_orphan 2020-11-14 11:26:04 -08:00
super.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
symlink.c vfs: remove ".readlink = generic_readlink" assignments 2016-12-09 16:45:04 +01:00
symlink.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
sysfile.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
sysfile.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
uptodate.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
uptodate.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 145 2019-05-30 11:25:18 -07:00
xattr.c treewide: Remove uninitialized_var() usage 2020-07-16 12:35:15 -07:00
xattr.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 174 2019-05-30 11:26:41 -07:00