Revision d8550860d910c6b7b70f830f59003b33daaa52c9 authored by Paul Burton on 03 March 2017, 23:26:05 UTC, committed by Ralf Baechle on 30 June 2017, 02:40:18 UTC
When the scheduler sets TIF_NEED_RESCHED & we call into the scheduler
from arch/mips/kernel/entry.S we disable interrupts. This is true
regardless of whether we reach work_resched from syscall_exit_work,
resume_userspace or by looping after calling schedule(). Although we
disable interrupts in these paths we don't call trace_hardirqs_off()
before calling into C code which may acquire locks, and we therefore
leave lockdep with an inconsistent view of whether interrupts are
disabled or not when CONFIG_PROVE_LOCKING & CONFIG_DEBUG_LOCKDEP are
both enabled.

Without tracing this interrupt state lockdep will print warnings such
as the following once a task returns from a syscall via
syscall_exit_partial with TIF_NEED_RESCHED set:

[   49.927678] ------------[ cut here ]------------
[   49.934445] WARNING: CPU: 0 PID: 1 at kernel/locking/lockdep.c:3687 check_flags.part.41+0x1dc/0x1e8
[   49.946031] DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled)
[   49.946355] CPU: 0 PID: 1 Comm: init Not tainted 4.10.0-00439-gc9fd5d362289-dirty #197
[   49.963505] Stack : 0000000000000000 ffffffff81bb5d6a 0000000000000006 ffffffff801ce9c4
[   49.974431]         0000000000000000 0000000000000000 0000000000000000 000000000000004a
[   49.985300]         ffffffff80b7e487 ffffffff80a24498 a8000000ff160000 ffffffff80ede8b8
[   49.996194]         0000000000000001 0000000000000000 0000000000000000 0000000077c8030c
[   50.007063]         000000007fd8a510 ffffffff801cd45c 0000000000000000 a8000000ff127c88
[   50.017945]         0000000000000000 ffffffff801cf928 0000000000000001 ffffffff80a24498
[   50.028827]         0000000000000000 0000000000000001 0000000000000000 0000000000000000
[   50.039688]         0000000000000000 a8000000ff127bd0 0000000000000000 ffffffff805509bc
[   50.050575]         00000000140084e0 0000000000000000 0000000000000000 0000000000040a00
[   50.061448]         0000000000000000 ffffffff8010e1b0 0000000000000000 ffffffff805509bc
[   50.072327]         ...
[   50.076087] Call Trace:
[   50.079869] [<ffffffff8010e1b0>] show_stack+0x80/0xa8
[   50.086577] [<ffffffff805509bc>] dump_stack+0x10c/0x190
[   50.093498] [<ffffffff8015dde0>] __warn+0xf0/0x108
[   50.099889] [<ffffffff8015de34>] warn_slowpath_fmt+0x3c/0x48
[   50.107241] [<ffffffff801c15b4>] check_flags.part.41+0x1dc/0x1e8
[   50.114961] [<ffffffff801c239c>] lock_is_held_type+0x8c/0xb0
[   50.122291] [<ffffffff809461b8>] __schedule+0x8c0/0x10f8
[   50.129221] [<ffffffff80946a60>] schedule+0x30/0x98
[   50.135659] [<ffffffff80106278>] work_resched+0x8/0x34
[   50.142397] ---[ end trace 0cb4f6ef5b99fe21 ]---
[   50.148405] possible reason: unannotated irqs-off.
[   50.154600] irq event stamp: 400463
[   50.159566] hardirqs last  enabled at (400463): [<ffffffff8094edc8>] _raw_spin_unlock_irqrestore+0x40/0xa8
[   50.171981] hardirqs last disabled at (400462): [<ffffffff8094eb98>] _raw_spin_lock_irqsave+0x30/0xb0
[   50.183897] softirqs last  enabled at (400450): [<ffffffff8016580c>] __do_softirq+0x4ac/0x6a8
[   50.195015] softirqs last disabled at (400425): [<ffffffff80165e78>] irq_exit+0x110/0x128

Fix this by using the TRACE_IRQS_OFF macro to call trace_hardirqs_off()
when CONFIG_TRACE_IRQFLAGS is enabled. This is done before invoking
schedule() following the work_resched label because:

 1) Interrupts are disabled regardless of the path we take to reach
    work_resched() & schedule().

 2) Performing the tracing here avoids the need to do it in paths which
    disable interrupts but don't call out to C code before hitting a
    path which uses the RESTORE_SOME macro that will call
    trace_hardirqs_on() or trace_hardirqs_off() as appropriate.

We call trace_hardirqs_on() using the TRACE_IRQS_ON macro before calling
syscall_trace_leave() for similar reasons, ensuring that lockdep has a
consistent view of state after we re-enable interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: linux-mips@linux-mips.org
Cc: stable <stable@vger.kernel.org>
Patchwork: https://patchwork.linux-mips.org/patch/15385/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
1 parent 161c51c
History
File Mode Size
kasan
Kconfig -rw-r--r-- 23.9 KB
Kconfig.debug -rw-r--r-- 3.8 KB
Makefile -rw-r--r-- 3.5 KB
backing-dev.c -rw-r--r-- 27.5 KB
balloon_compaction.c -rw-r--r-- 4.7 KB
bootmem.c -rw-r--r-- 20.8 KB
cleancache.c -rw-r--r-- 9.9 KB
cma.c -rw-r--r-- 13.5 KB
cma.h -rw-r--r-- 534 bytes
cma_debug.c -rw-r--r-- 4.5 KB
compaction.c -rw-r--r-- 57.9 KB
debug.c -rw-r--r-- 4.3 KB
debug_page_ref.c -rw-r--r-- 1.3 KB
dmapool.c -rw-r--r-- 13.7 KB
early_ioremap.c -rw-r--r-- 6.2 KB
fadvise.c -rw-r--r-- 4.3 KB
failslab.c -rw-r--r-- 1.4 KB
filemap.c -rw-r--r-- 79.8 KB
frame_vector.c -rw-r--r-- 6.0 KB
frontswap.c -rw-r--r-- 14.3 KB
gup.c -rw-r--r-- 45.6 KB
highmem.c -rw-r--r-- 11.7 KB
huge_memory.c -rw-r--r-- 74.0 KB
hugetlb.c -rw-r--r-- 127.8 KB
hugetlb_cgroup.c -rw-r--r-- 10.9 KB
hwpoison-inject.c -rw-r--r-- 3.2 KB
init-mm.c -rw-r--r-- 680 bytes
internal.h -rw-r--r-- 16.2 KB
interval_tree.c -rw-r--r-- 3.1 KB
khugepaged.c -rw-r--r-- 48.4 KB
kmemcheck.c -rw-r--r-- 2.9 KB
kmemleak-test.c -rw-r--r-- 3.2 KB
kmemleak.c -rw-r--r-- 56.2 KB
ksm.c -rw-r--r-- 65.5 KB
list_lru.c -rw-r--r-- 12.6 KB
maccess.c -rw-r--r-- 3.0 KB
madvise.c -rw-r--r-- 21.5 KB
memblock.c -rw-r--r-- 50.6 KB
memcontrol.c -rw-r--r-- 154.6 KB
memory-failure.c -rw-r--r-- 49.4 KB
memory.c -rw-r--r-- 117.6 KB
memory_hotplug.c -rw-r--r-- 55.5 KB
mempolicy.c -rw-r--r-- 71.3 KB
mempool.c -rw-r--r-- 13.9 KB
memtest.c -rw-r--r-- 2.7 KB
migrate.c -rw-r--r-- 52.2 KB
mincore.c -rw-r--r-- 6.7 KB
mlock.c -rw-r--r-- 22.6 KB
mm_init.c -rw-r--r-- 4.8 KB
mmap.c -rw-r--r-- 96.2 KB
mmu_context.c -rw-r--r-- 1.3 KB
mmu_notifier.c -rw-r--r-- 11.5 KB
mmzone.c -rw-r--r-- 2.4 KB
mprotect.c -rw-r--r-- 13.5 KB
mremap.c -rw-r--r-- 16.2 KB
msync.c -rw-r--r-- 2.6 KB
nobootmem.c -rw-r--r-- 11.1 KB
nommu.c -rw-r--r-- 48.6 KB
oom_kill.c -rw-r--r-- 28.5 KB
page-writeback.c -rw-r--r-- 84.5 KB
page_alloc.c -rw-r--r-- 209.4 KB
page_counter.c -rw-r--r-- 4.8 KB
page_ext.c -rw-r--r-- 11.1 KB
page_idle.c -rw-r--r-- 5.4 KB
page_io.c -rw-r--r-- 9.4 KB
page_isolation.c -rw-r--r-- 8.3 KB
page_owner.c -rw-r--r-- 14.7 KB
page_poison.c -rw-r--r-- 2.6 KB
page_vma_mapped.c -rw-r--r-- 5.8 KB
pagewalk.c -rw-r--r-- 8.4 KB
percpu-km.c -rw-r--r-- 2.8 KB
percpu-vm.c -rw-r--r-- 10.0 KB
percpu.c -rw-r--r-- 66.8 KB
pgtable-generic.c -rw-r--r-- 5.2 KB
process_vm_access.c -rw-r--r-- 10.1 KB
quicklist.c -rw-r--r-- 2.4 KB
readahead.c -rw-r--r-- 16.1 KB
rmap.c -rw-r--r-- 48.0 KB
rodata_test.c -rw-r--r-- 1.4 KB
shmem.c -rw-r--r-- 110.3 KB
slab.c -rw-r--r-- 110.4 KB
slab.h -rw-r--r-- 14.7 KB
slab_common.c -rw-r--r-- 34.4 KB
slob.c -rw-r--r-- 16.0 KB
slub.c -rw-r--r-- 140.5 KB
sparse-vmemmap.c -rw-r--r-- 8.1 KB
sparse.c -rw-r--r-- 20.7 KB
swap.c -rw-r--r-- 27.0 KB
swap_cgroup.c -rw-r--r-- 4.7 KB
swap_slots.c -rw-r--r-- 8.9 KB
swap_state.c -rw-r--r-- 14.3 KB
swapfile.c -rw-r--r-- 84.6 KB
truncate.c -rw-r--r-- 25.3 KB
usercopy.c -rw-r--r-- 7.5 KB
userfaultfd.c -rw-r--r-- 14.3 KB
util.c -rw-r--r-- 18.1 KB
vmacache.c -rw-r--r-- 3.2 KB
vmalloc.c -rw-r--r-- 70.2 KB
vmpressure.c -rw-r--r-- 12.8 KB
vmscan.c -rw-r--r-- 113.4 KB
vmstat.c -rw-r--r-- 47.4 KB
workingset.c -rw-r--r-- 18.4 KB
z3fold.c -rw-r--r-- 23.8 KB
zbud.c -rw-r--r-- 18.2 KB
zpool.c -rw-r--r-- 10.0 KB
zsmalloc.c -rw-r--r-- 59.3 KB
zswap.c -rw-r--r-- 32.8 KB

back to top