Skip to content

Commit a744a20

Browse files
vineetgarcbwhacks
authored andcommitted
ARC: show_regs: lockdep: avoid page allocator...
commit ab6c036 upstream. and use smaller/on-stack buffer instead The motivation for this change was lockdep splat like below. | potentially unexpected fatal signal 11. | BUG: sleeping function called from invalid context at ../mm/page_alloc.c:4317 | in_atomic(): 1, irqs_disabled(): 0, pid: 57, name: segv | no locks held by segv/57. | Preemption disabled at: | [<8182f17e>] get_signal+0x4a6/0x7c4 | CPU: 0 PID: 57 Comm: segv Not tainted 4.17.0+ #23 | | Stack Trace: | arc_unwind_core.constprop.1+0xd0/0xf4 | __might_sleep+0x1f6/0x234 | __get_free_pages+0x174/0xca0 | show_regs+0x22/0x330 | get_signal+0x4ac/0x7c4 # print_fatal_signals() -> preempt_disable() | do_signal+0x30/0x224 | resume_user_mode_begin+0x90/0xd8 So signal handling core calls show_regs() with preemption disabled but an ensuing GFP_KERNEL page allocator call is flagged by lockdep. We could have switched to GFP_NOWAIT, but turns out that is not enough anways and eliding page allocator call leads to less code and instruction traces to sift thru when debugging pesky crashes. FWIW, this patch doesn't cure the lockdep splat (which next patch does). Reviewed-by: William Kucharski <william.kucharski@oracle.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
1 parent 1652b06 commit a744a20

File tree

1 file changed

+12
-14
lines changed

1 file changed

+12
-14
lines changed

arch/arc/kernel/troubleshoot.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <linux/file.h>
1616
#include <asm/arcregs.h>
1717

18+
#define ARC_PATH_MAX 256
19+
1820
/*
1921
* Common routine to print scratch regs (r0-r12) or callee regs (r13-r25)
2022
* -Prints 3 regs per line and a CR.
@@ -52,12 +54,13 @@ static void show_callee_regs(struct callee_regs *cregs)
5254
print_reg_file(&(cregs->r13), 13);
5355
}
5456

55-
static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
57+
static void print_task_path_n_nm(struct task_struct *tsk)
5658
{
5759
struct path path;
5860
char *path_nm = NULL;
5961
struct mm_struct *mm;
6062
struct file *exe_file;
63+
char buf[ARC_PATH_MAX];
6164

6265
mm = get_task_mm(tsk);
6366
if (!mm)
@@ -70,21 +73,20 @@ static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
7073
path = exe_file->f_path;
7174
path_get(&exe_file->f_path);
7275
fput(exe_file);
73-
path_nm = d_path(&path, buf, 255);
76+
path_nm = d_path(&path, buf, ARC_PATH_MAX-1);
7477
path_put(&path);
7578
}
7679

7780
done:
7881
pr_info("Path: %s\n", path_nm);
7982
}
8083

81-
static void show_faulting_vma(unsigned long address, char *buf)
84+
static void show_faulting_vma(unsigned long address)
8285
{
8386
struct vm_area_struct *vma;
8487
struct inode *inode;
8588
unsigned long ino = 0;
8689
dev_t dev = 0;
87-
char *nm = buf;
8890
struct mm_struct *active_mm = current->active_mm;
8991

9092
/* can't use print_vma_addr() yet as it doesn't check for
@@ -98,9 +100,12 @@ static void show_faulting_vma(unsigned long address, char *buf)
98100
*/
99101
if (vma && (vma->vm_start <= address)) {
100102
struct file *file = vma->vm_file;
103+
char buf[ARC_PATH_MAX];
104+
char *nm = "?";
105+
101106
if (file) {
102107
struct path *path = &file->f_path;
103-
nm = d_path(path, buf, PAGE_SIZE - 1);
108+
nm = d_path(path, buf, ARC_PATH_MAX-1);
104109
inode = file_inode(vma->vm_file);
105110
dev = inode->i_sb->s_dev;
106111
ino = inode->i_ino;
@@ -165,13 +170,8 @@ void show_regs(struct pt_regs *regs)
165170
{
166171
struct task_struct *tsk = current;
167172
struct callee_regs *cregs;
168-
char *buf;
169173

170-
buf = (char *)__get_free_page(GFP_TEMPORARY);
171-
if (!buf)
172-
return;
173-
174-
print_task_path_n_nm(tsk, buf);
174+
print_task_path_n_nm(tsk);
175175
show_regs_print_info(KERN_INFO);
176176

177177
show_ecr_verbose(regs);
@@ -181,7 +181,7 @@ void show_regs(struct pt_regs *regs)
181181
(void *)regs->blink, (void *)regs->ret);
182182

183183
if (user_mode(regs))
184-
show_faulting_vma(regs->ret, buf); /* faulting code, not data */
184+
show_faulting_vma(regs->ret); /* faulting code, not data */
185185

186186
pr_info("[STAT32]: 0x%08lx", regs->status32);
187187

@@ -205,8 +205,6 @@ void show_regs(struct pt_regs *regs)
205205
cregs = (struct callee_regs *)current->thread.callee_reg;
206206
if (cregs)
207207
show_callee_regs(cregs);
208-
209-
free_page((unsigned long)buf);
210208
}
211209

212210
void show_kernel_fault_diag(const char *str, struct pt_regs *regs,

0 commit comments

Comments
 (0)