diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-11-15 16:56:11 -0800 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-11-15 16:56:11 -0800 |
commit | 4247f24c23589bcc3bc3490515ef8c9497e9ae55 (patch) | |
tree | 89726a0e171c443a3e8def2992b56dbd8a21df21 /kernel/extable.c | |
parent | 79ab67ede21f536851a99ea68ee6fc1f5435e055 (diff) | |
parent | 9f586fff6574f6ecbf323f92d44ffaf0d96225fe (diff) |
Merge branch 'for-4.15/dax' into libnvdimm-for-nextlibnvdimm-for-4.15
Diffstat (limited to 'kernel/extable.c')
-rw-r--r-- | kernel/extable.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index 38c2412401a1..9aa1cc41ecf7 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -102,15 +102,7 @@ int core_kernel_data(unsigned long addr) int __kernel_text_address(unsigned long addr) { - if (core_kernel_text(addr)) - return 1; - if (is_module_text_address(addr)) - return 1; - if (is_ftrace_trampoline(addr)) - return 1; - if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; - if (is_bpf_text_address(addr)) + if (kernel_text_address(addr)) return 1; /* * There might be init symbols in saved stacktraces. @@ -127,17 +119,42 @@ int __kernel_text_address(unsigned long addr) int kernel_text_address(unsigned long addr) { + bool no_rcu; + int ret = 1; + if (core_kernel_text(addr)) return 1; + + /* + * If a stack dump happens while RCU is not watching, then + * RCU needs to be notified that it requires to start + * watching again. This can happen either by tracing that + * triggers a stack trace, or a WARN() that happens during + * coming back from idle, or cpu on or offlining. + * + * is_module_text_address() as well as the kprobe slots + * and is_bpf_text_address() require RCU to be watching. + */ + no_rcu = !rcu_is_watching(); + + /* Treat this like an NMI as it can happen anywhere */ + if (no_rcu) + rcu_nmi_enter(); + if (is_module_text_address(addr)) - return 1; + goto out; if (is_ftrace_trampoline(addr)) - return 1; + goto out; if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) - return 1; + goto out; if (is_bpf_text_address(addr)) - return 1; - return 0; + goto out; + ret = 0; +out: + if (no_rcu) + rcu_nmi_exit(); + + return ret; } /* |