• Michal Hocko's avatar
    lockdep: allow to disable reclaim lockup detection · 7e784422
    Michal Hocko authored
    The current implementation of the reclaim lockup detection can lead to
    false positives and those even happen and usually lead to tweak the code
    to silence the lockdep by using GFP_NOFS even though the context can use
    __GFP_FS just fine.
    
    See
    
      http://lkml.kernel.org/r/20160512080321.GA18496@dastard
    
    as an example.
    
      =================================
      [ INFO: inconsistent lock state ]
      4.5.0-rc2+ #4 Tainted: G           O
      ---------------------------------
      inconsistent {RECLAIM_FS-ON-R} -> {IN-RECLAIM_FS-W} usage.
      kswapd0/543 [HC0[0]:SC0[0]:HE1:SE1] takes:
    
      (&xfs_nondir_ilock_class){++++-+}, at: xfs_ilock+0x177/0x200 [xfs]
    
      {RECLAIM_FS-ON-R} state was registered at:
        mark_held_locks+0x79/0xa0
        lockdep_trace_alloc+0xb3/0x100
        kmem_cache_alloc+0x33/0x230
        kmem_zone_alloc+0x81/0x120 [xfs]
        xfs_refcountbt_init_cursor+0x3e/0xa0 [xfs]
        __xfs_refcount_find_shared+0x75/0x580 [xfs]
        xfs_refcount_find_shared+0x84/0xb0 [xfs]
        xfs_getbmap+0x608/0x8c0 [xfs]
        xfs_vn_fiemap+0xab/0xc0 [xfs]
        do_vfs_ioctl+0x498/0x670
        SyS_ioctl+0x79/0x90
        entry_SYSCALL_64_fastpath+0x12/0x6f
    
             CPU0
             ----
        lock(&xfs_nondir_ilock_class);
        <Interrupt>
          lock(&xfs_nondir_ilock_class);
    
       *** DEADLOCK ***
    
      3 locks held by kswapd0/543:
    
      stack backtrace:
      CPU: 0 PID: 543 Comm: kswapd0 Tainted: G           O    4.5.0-rc2+ #4
      Call Trace:
       lock_acquire+0xd8/0x1e0
       down_write_nested+0x5e/0xc0
       xfs_ilock+0x177/0x200 [xfs]
       xfs_reflink_cancel_cow_range+0x150/0x300 [xfs]
       xfs_fs_evict_inode+0xdc/0x1e0 [xfs]
       evict+0xc5/0x190
       dispose_list+0x39/0x60
       prune_icache_sb+0x4b/0x60
       super_cache_scan+0x14f/0x1a0
       shrink_slab.part.63.constprop.79+0x1e9/0x4e0
       shrink_zone+0x15e/0x170
       kswapd+0x4f1/0xa80
       kthread+0xf2/0x110
       ret_from_fork+0x3f/0x70
    
    To quote Dave:
     "Ignoring whether reflink should be doing anything or not, that's a
      "xfs_refcountbt_init_cursor() gets called both outside and inside
      transactions" lockdep false positive case. The problem here is lockdep
      has seen this allocation from within a transaction, hence a GFP_NOFS
      allocation, and now it's seeing it in a GFP_KERNEL context. Also note
      that we have an active reference to this inode.
    
      So, because the reclaim annotations overload the interrupt level
      detections and it's seen the inode ilock been taken in reclaim
      ("interrupt") context, this triggers a reclaim context warning where
      it thinks it is unsafe to do this allocation in GFP_KERNEL context
      holding the inode ilock..."
    
    This sounds like a fundamental problem of the reclaim lock detection.
    It is really impossible to annotate such a special usecase IMHO unless
    the reclaim lockup detection is reworked completely.  Until then it is
    much better to provide a way to add "I know what I am doing flag" and
    mark problematic places.  This would prevent from abusing GFP_NOFS flag
    which has a runtime effect even on configurations which have lockdep
    disabled.
    
    Introduce __GFP_NOLOCKDEP flag which tells the lockdep gfp tracking to
    skip the current allocation request.
    
    While we are at it also make sure that the radix tree doesn't
    accidentaly override tags stored in the upper part of the gfp_mask.
    
    Link: http://lkml.kernel.org/r/20170306131408.9828-3-mhocko@kernel.orgSigned-off-by: default avatarMichal Hocko <mhocko@suse.com>
    Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
    Cc: Dave Chinner <david@fromorbit.com>
    Cc: Theodore Ts'o <tytso@mit.edu>
    Cc: Chris Mason <clm@fb.com>
    Cc: David Sterba <dsterba@suse.cz>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Brian Foster <bfoster@redhat.com>
    Cc: Darrick J. Wong <darrick.wong@oracle.com>
    Cc: Nikolay Borisov <nborisov@suse.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    7e784422
Name
Last commit
Last update
..
842 Loading commit data...
fonts Loading commit data...
lz4 Loading commit data...
lzo Loading commit data...
mpi Loading commit data...
raid6 Loading commit data...
reed_solomon Loading commit data...
xz Loading commit data...
zlib_deflate Loading commit data...
zlib_inflate Loading commit data...
.gitignore Loading commit data...
Kconfig Loading commit data...
Kconfig.debug Loading commit data...
Kconfig.kasan Loading commit data...
Kconfig.kgdb Loading commit data...
Kconfig.kmemcheck Loading commit data...
Kconfig.ubsan Loading commit data...
Makefile Loading commit data...
argv_split.c Loading commit data...
asn1_decoder.c Loading commit data...
assoc_array.c Loading commit data...
atomic64.c Loading commit data...
atomic64_test.c Loading commit data...
audit.c Loading commit data...
bcd.c Loading commit data...
bch.c Loading commit data...
bitmap.c Loading commit data...
bitrev.c Loading commit data...
bsearch.c Loading commit data...
btree.c Loading commit data...
bug.c Loading commit data...
build_OID_registry Loading commit data...
bust_spinlocks.c Loading commit data...
chacha20.c Loading commit data...
check_signature.c Loading commit data...
checksum.c Loading commit data...
clz_ctz.c Loading commit data...
clz_tab.c Loading commit data...
cmdline.c Loading commit data...
compat_audit.c Loading commit data...
cordic.c Loading commit data...
cpu_rmap.c Loading commit data...
cpumask.c Loading commit data...
crc-ccitt.c Loading commit data...
crc-itu-t.c Loading commit data...
crc-t10dif.c Loading commit data...
crc16.c Loading commit data...
crc32.c Loading commit data...
crc32defs.h Loading commit data...
crc32test.c Loading commit data...
crc7.c Loading commit data...
crc8.c Loading commit data...
ctype.c Loading commit data...
debug_info.c Loading commit data...
debug_locks.c Loading commit data...
debugobjects.c Loading commit data...
dec_and_lock.c Loading commit data...
decompress.c Loading commit data...
decompress_bunzip2.c Loading commit data...
decompress_inflate.c Loading commit data...
decompress_unlz4.c Loading commit data...
decompress_unlzma.c Loading commit data...
decompress_unlzo.c Loading commit data...
decompress_unxz.c Loading commit data...
devres.c Loading commit data...
digsig.c Loading commit data...
div64.c Loading commit data...
dma-debug.c Loading commit data...
dma-noop.c Loading commit data...
dma-virt.c Loading commit data...
dump_stack.c Loading commit data...
dynamic_debug.c Loading commit data...
dynamic_queue_limits.c Loading commit data...
earlycpio.c Loading commit data...
extable.c Loading commit data...
fault-inject.c Loading commit data...
fdt.c Loading commit data...
fdt_empty_tree.c Loading commit data...
fdt_ro.c Loading commit data...
fdt_rw.c Loading commit data...
fdt_strerror.c Loading commit data...
fdt_sw.c Loading commit data...
fdt_wip.c Loading commit data...
find_bit.c Loading commit data...
flex_array.c Loading commit data...
flex_proportions.c Loading commit data...
gcd.c Loading commit data...
gen_crc32table.c Loading commit data...
genalloc.c Loading commit data...
glob.c Loading commit data...
globtest.c Loading commit data...
hexdump.c Loading commit data...
hweight.c Loading commit data...
idr.c Loading commit data...
inflate.c Loading commit data...
int_sqrt.c Loading commit data...
interval_tree.c Loading commit data...
interval_tree_test.c Loading commit data...
iomap.c Loading commit data...
iomap_copy.c Loading commit data...
iommu-common.c Loading commit data...
iommu-helper.c Loading commit data...
ioremap.c Loading commit data...
iov_iter.c Loading commit data...
irq_poll.c Loading commit data...
irq_regs.c Loading commit data...
is_single_threaded.c Loading commit data...
jedec_ddr_data.c Loading commit data...
kasprintf.c Loading commit data...
kfifo.c Loading commit data...
klist.c Loading commit data...
kobject.c Loading commit data...
kobject_uevent.c Loading commit data...
kstrtox.c Loading commit data...
kstrtox.h Loading commit data...
lcm.c Loading commit data...
libcrc32c.c Loading commit data...
list_debug.c Loading commit data...
list_sort.c Loading commit data...
llist.c Loading commit data...
locking-selftest-hardirq.h Loading commit data...
locking-selftest-mutex.h Loading commit data...
locking-selftest-rlock-hardirq.h Loading commit data...
locking-selftest-rlock-softirq.h Loading commit data...
locking-selftest-rlock.h Loading commit data...
locking-selftest-rsem.h Loading commit data...
locking-selftest-softirq.h Loading commit data...
locking-selftest-spin-hardirq.h Loading commit data...
locking-selftest-spin-softirq.h Loading commit data...
locking-selftest-spin.h Loading commit data...
locking-selftest-wlock-hardirq.h Loading commit data...
locking-selftest-wlock-softirq.h Loading commit data...
locking-selftest-wlock.h Loading commit data...
locking-selftest-wsem.h Loading commit data...
locking-selftest.c Loading commit data...
lockref.c Loading commit data...
lru_cache.c Loading commit data...
memory-notifier-error-inject.c Loading commit data...
memweight.c Loading commit data...
net_utils.c Loading commit data...
netdev-notifier-error-inject.c Loading commit data...
nlattr.c Loading commit data...
nmi_backtrace.c Loading commit data...
nodemask.c Loading commit data...
notifier-error-inject.c Loading commit data...
notifier-error-inject.h Loading commit data...
of-reconfig-notifier-error-inject.c Loading commit data...
oid_registry.c Loading commit data...
once.c Loading commit data...
parman.c Loading commit data...
parser.c Loading commit data...
pci_iomap.c Loading commit data...
percpu-refcount.c Loading commit data...
percpu_counter.c Loading commit data...
percpu_ida.c Loading commit data...
percpu_test.c Loading commit data...
plist.c Loading commit data...
pm-notifier-error-inject.c Loading commit data...
prime_numbers.c Loading commit data...
radix-tree.c Loading commit data...
random32.c Loading commit data...
ratelimit.c Loading commit data...
rational.c Loading commit data...
rbtree.c Loading commit data...
rbtree_test.c Loading commit data...
reciprocal_div.c Loading commit data...
refcount.c Loading commit data...
rhashtable.c Loading commit data...
sbitmap.c Loading commit data...
scatterlist.c Loading commit data...
seq_buf.c Loading commit data...
sg_pool.c Loading commit data...
sg_split.c Loading commit data...
sha1.c Loading commit data...
show_mem.c Loading commit data...
siphash.c Loading commit data...
smp_processor_id.c Loading commit data...
sort.c Loading commit data...
stackdepot.c Loading commit data...
stmp_device.c Loading commit data...
string.c Loading commit data...
string_helpers.c Loading commit data...
strncpy_from_user.c Loading commit data...
strnlen_user.c Loading commit data...
swiotlb.c Loading commit data...
syscall.c Loading commit data...
test-kstrtox.c Loading commit data...
test-string_helpers.c Loading commit data...
test_bitmap.c Loading commit data...
test_bpf.c Loading commit data...
test_firmware.c Loading commit data...
test_hash.c Loading commit data...
test_hexdump.c Loading commit data...
test_kasan.c Loading commit data...
test_module.c Loading commit data...
test_parman.c Loading commit data...
test_printf.c Loading commit data...
test_rhashtable.c Loading commit data...
test_siphash.c Loading commit data...
test_sort.c Loading commit data...
test_static_key_base.c Loading commit data...
test_static_keys.c Loading commit data...
test_user_copy.c Loading commit data...
test_uuid.c Loading commit data...
textsearch.c Loading commit data...
timerqueue.c Loading commit data...
ts_bm.c Loading commit data...
ts_fsm.c Loading commit data...
ts_kmp.c Loading commit data...
ubsan.c Loading commit data...
ubsan.h Loading commit data...
ucs2_string.c Loading commit data...
usercopy.c Loading commit data...
uuid.c Loading commit data...
vsprintf.c Loading commit data...
win_minmax.c Loading commit data...