[PATCH 7/8] dyndbg: enable 'cache' of active pr_debug callsites

Jim Cromie jim.cromie at gmail.com
Wed Aug 5 14:30:22 EDT 2020


in ddebug_zpool_put() dont zs_unmap the callsite, if it is enabled for
printing.  This will eliminate possibly repeated un-maps then re-maps
of enabled and invoked pr-debug callsites, and will promptly retire
all other uses.

Unfortunately this causes mysterious problems:
(needs more editing down)

[jimc at frodo build-v2]$ gdb -x cmds vmlinux
GNU gdb (GDB) Fedora 9.1-5.fc32
...
Reading symbols from vmlinux...
0x000000000000fff0 in exception_stacks ()
Hardware assisted breakpoint 1 at 0xffffffff82c2de50: file ../lib/dynamic_debug.c, line 1164.

Breakpoint 1, ddebug_zpool_init () at ../lib/dynamic_debug.c:1164
1164		dd_callsite_zpool = zs_create_pool("dyndbg_callsites");
    at ../include/linux/compiler.h:352
--Type <RET> for more, q to quit, c to continue without paging--
Num     Type           Disp Enb Address            What
1       hw breakpoint  keep y   0xffffffff82c2de50 in ddebug_zpool_init at ../lib/dynamic_debug.c:1164
	breakpoint already hit 1 time
(gdb) l
1159	static void __init ddebug_zpool_init(void)
1160	{
1161		struct _ddebug *iter;
1162
1163		/* tbd- no corresponding destroy */
1164		dd_callsite_zpool = zs_create_pool("dyndbg_callsites");
1165		if (!dd_callsite_zpool) {
1166			pr_err("create pool failed\n");
1167			return;
1168		}
(gdb) l
1169
1170		/* add-module normally does this, but not in time for builtins */
1171		for (iter = __start___dyndbg; iter < __stop___dyndbg; iter++)
1172			ddebug_zpool_add(iter);
1173
1174		v2pr_info("total pages: %lu compaction: %lu\n",
1175			  zs_get_total_pages(dd_callsite_zpool),
1176			  zs_compact(dd_callsite_zpool));
1177	}
1178	late_initcall(ddebug_zpool_init);
(gdb) b 1174
Breakpoint 2 at 0xffffffff82c2de9b: file ../lib/dynamic_debug.c, line 1174.
(gdb) c
Continuing.

Breakpoint 2, ddebug_zpool_init () at ../lib/dynamic_debug.c:1174
1174		v2pr_info("total pages: %lu compaction: %lu\n",
(gdb) n
do_one_initcall (fn=0xffffffff82c2de50 <ddebug_zpool_init>) at ../init/main.c:1200
1200		do_trace_initcall_finish(fn, ret);
(gdb)
1204		if (preempt_count() != count) {
(gdb)
26		return raw_cpu_read_4(__preempt_count) & ~PREEMPT_NEED_RESCHED;
(gdb)
1208		if (irqs_disabled()) {
(gdb)
164		return !(flags & X86_EFLAGS_IF);
(gdb)
1212		WARN(msgbuf[0], "initcall %pS returned with %s\n", fn, msgbuf);
(gdb)
do_initcall_level (command_line=<optimized out>, level=<optimized out>) at ../init/main.c:1271
(gdb) info break
Num     Type           Disp Enb Address            What
1       hw breakpoint  keep y   0xffffffff82c2de50 in ddebug_zpool_init at ../lib/dynamic_debug.c:1164
	breakpoint already hit 1 time
2       breakpoint     keep y   0xffffffff82c2de9b in ddebug_zpool_init at ../lib/dynamic_debug.c:1174
	breakpoint already hit 1 time
(gdb) bt
(gdb) up
1288			do_initcall_level(level, command_line);
(gdb) up
1308		do_initcalls();
(gdb) return
Can not force return from an inlined function.
(gdb) b
Breakpoint 3 at 0xffffffff82bfe1c6: file ../include/linux/compiler.h, line 352.
(gdb) c
Continuing.

Breakpoint 3, offset_to_ptr (off=<optimized out>) at ../include/linux/compiler.h:352
352		return (void *)((unsigned long)off + *off);
(gdb) n
do_initcall_level (command_line=<optimized out>, level=<optimized out>) at ../init/main.c:1271
1271		for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
(gdb)

Breakpoint 3, offset_to_ptr (off=<optimized out>) at ../include/linux/compiler.h:352
352		return (void *)((unsigned long)off + *off);
(gdb)
do_initcall_level (command_line=<optimized out>, level=<optimized out>) at ../init/main.c:1271
1271		for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
(gdb)

Breakpoint 3, offset_to_ptr (off=<optimized out>) at ../include/linux/compiler.h:352
352		return (void *)((unsigned long)off + *off);
(gdb)
do_initcall_level (command_line=<optimized out>, level=<optimized out>) at ../init/main.c:1271
1271		for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
(gdb)
do_initcalls () at ../init/main.c:1285
1285		for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) {
(gdb)
1291		kfree(command_line);
(gdb)
kernel_init_freeable () at ../init/main.c:1507
1507		console_on_rootfs();
(gdb)
1514		if (!ramdisk_execute_command)
(gdb)
1515			ramdisk_execute_command = "/init";
(gdb)
1517		if (ksys_access((const char __user *)
(gdb)
1519			ramdisk_execute_command = NULL;
(gdb)
1520			prepare_namespace();
(gdb)

1532		integrity_load_keys();
(gdb)

kernel_init (unused=<optimized out>) at ../init/main.c:1401
1401		async_synchronize_full();
(gdb)
1403		free_initmem();
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1404		mark_readonly();
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1410		pti_finalize();
(gdb) bt
(gdb) info break
Num     Type           Disp Enb Address            What
1       hw breakpoint  keep y   0xffffffff82c2de50 in ddebug_zpool_init at ../lib/dynamic_debug.c:1164
	breakpoint already hit 1 time
2       breakpoint     keep y   0xffffffff82c2de9b in ddebug_zpool_init at ../lib/dynamic_debug.c:1174
	breakpoint already hit 1 time
3       breakpoint     keep y   0xffffffff82bfe1c6 ../include/linux/compiler.h:352
	breakpoint already hit 7 times
(gdb) info break 3
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0xffffffff82bfe1c6 ../include/linux/compiler.h:352
	breakpoint already hit 7 times
(gdb) n
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1412		system_state = SYSTEM_RUNNING;
(gdb) n
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1413		numa_default_policy();
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1415		rcu_end_inkernel_boot();
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1417		do_sysctl_args();
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1419		if (ramdisk_execute_command) {
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1433		if (execute_command) {
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1434			ret = run_init_process(execute_command);
(gdb) l
1429		 *
1430		 * The Bourne shell can be used instead of init if we are
1431		 * trying to recover a really broken machine.
1432		 */
1433		if (execute_command) {
1434			ret = run_init_process(execute_command);
1435			if (!ret)
1436				return 0;
1437			panic("Requested init %s failed (error %d).",
1438			      execute_command, ret);
(gdb) s
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
run_init_process (init_filename=0xffff888007fd6525 "/bin/sh") at ../init/main.c:1324
1324		argv_init[0] = init_filename;
(gdb) n
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1325		pr_info("Run %s as init process\n", init_filename);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1326		pr_debug("  with arguments:\n");
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1327		for (p = argv_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1328			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1327		for (p = argv_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1328			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1327		for (p = argv_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1328			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1327		for (p = argv_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1329		pr_debug("  with environment:\n");
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1330		for (p = envp_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1331			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1330		for (p = envp_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1331			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1330		for (p = envp_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1331			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1330		for (p = envp_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1331			pr_debug("    %s\n", *p);
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1330		for (p = envp_init; *p; p++)
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1332		return do_execve(getname_kernel(init_filename),
(gdb)
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
kernel_init (unused=<optimized out>) at ../init/main.c:1435
1435			if (!ret)
(gdb) n
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
1437			panic("Requested init %s failed (error %d).",
(gdb)

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 lib/dynamic_debug.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 102f47b2a439..9c51f24a9c66 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -174,7 +174,9 @@ static void ddebug_callsite_put(struct _ddebug *dp)
 		/* no site to unmap, or no means to restore */
 		return;
 
-	/* always unmap for now. if !pr-debug was too hard */
+	if (dp->flags & _DPRINTK_FLAGS_PRINT)
+		return; /* keep maps of enabled pr_debugs */
+
 	zs_unmap_object(dd_callsite_zpool, dp->zhandle);
 	dp->site = NULL;
 }
-- 
2.26.2




More information about the Kernelnewbies mailing list