ANDROID: f2fs: fix potential deadlock by android ftrace

sb_internal#2 --> &s->s_dquot.dqio_sem --> fs_reclaim

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock(fs_reclaim);
                                lock(&s->s_dquot.dqio_sem);
                                lock(fs_reclaim);
   lock(sb_internal#2);

 *** DEADLOCK ***

 3 locks held by kswapd0/133:
  #0: ffffffda597c93a8 (fs_reclaim){+.+.}-{0:0}, at: __fs_reclaim_acquire+0x4/0x50
  #1: ffffffda597bc890 (shrinker_rwsem){++++}-{3:3}, at: shrink_slab+0xa0/0x19c
  #2: ffffff80d5fb90e0 (&type->s_umount_key#50){.+.+}-{3:3}, at: super_cache_scan+0x40/0x1dc

stack backtrace:
 CPU: 7 PID: 133 Comm: kswapd0 Tainted: G        W  O      5.10.43-android12-9-g4665ec64f3df #1
 Hardware name: MT6879(ENG) (DT)
 Call trace:
  dump_backtrace.cfi_jt+0x0/0x8
  show_stack+0x1c/0x2c
  dump_stack_lvl+0xd8/0x16c
  print_circular_bug+0x2d4/0x2d8
  check_noncircular+0x190/0x1a4
  validate_chain+0xc54/0x2d34
  __lock_acquire+0x7e4/0xed4
  lock_acquire+0x114/0x394
  f2fs_evict_inode+0x1a0/0x8b8
  evict+0xd4/0x2f8
  iput+0x1c0/0x258
  dentry_unlink_inode+0x16c/0x1dc
  __dentry_kill+0x128/0x280
  shrink_dentry_list+0x6c/0x420
  prune_dcache_sb+0x5c/0x90
  super_cache_scan+0x13c/0x1dc
  do_shrink_slab+0x1e0/0x388
  shrink_slab+0xf4/0x19c
  shrink_node_memcgs+0x80/0x25c
  shrink_node+0x324/0x710
  balance_pgdat+0x3a8/0x6a8
  kswapd+0x484/0x594
  kthread+0x15c/0x1ac
  ret_from_fork+0x10/0x30

Bug: 201025620
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
Change-Id: Idaa303eb7c681a56ad5d4e1f6dddbda71f7fece4
This commit is contained in:
Jaegeuk Kim
2021-10-27 09:07:09 -07:00
parent 8d5dd0a5a4
commit 1c0e68339c

View File

@@ -3314,7 +3314,13 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
block_t blkaddr = NULL_ADDR; block_t blkaddr = NULL_ADDR;
int err = 0; int err = 0;
if (trace_android_fs_datawrite_start_enabled()) { /*
* Should avoid quota operations which can make deadlock:
* kswapd -> f2fs_evict_inode -> dquot_drop ->
* f2fs_dquot_commit -> f2fs_write_begin ->
* d_obtain_alias -> __d_alloc -> kmem_cache_alloc(GFP_KERNEL)
*/
if (trace_android_fs_datawrite_start_enabled() && !IS_NOQUOTA(inode)) {
char *path, pathbuf[MAX_TRACE_PATHBUF_LEN]; char *path, pathbuf[MAX_TRACE_PATHBUF_LEN];
path = android_fstrace_get_pathname(pathbuf, path = android_fstrace_get_pathname(pathbuf,