From aa25e046a6e01d0384a3011cfe8486ead648b7ba Mon Sep 17 00:00:00 2001 From: phil Date: Wed, 30 Jun 2004 03:49:03 +0000 Subject: [PATCH] b=3668 r=adilger A new lighter-weight CDEBUG infrastructure based on Zach's tracefile patches: - Each CPU gets its own list of pages, so a line can be inserted without locking - we do less printf'ing in the kernel, and send a packed structure of integers down for the leading bits of each line - lctl unpacks them, sorts the results (each page is sorted, but not globally), and prints - we are no longer limited to 5MB, because we don't vmalloc a single huge buffer (/proc/sys/portals/debug_size, in pages) - result: on a single system with client, MDS, OST, running iozone with -1 debug is no longer CPU-bound There is also a new debug daemon, naturally, which works in basically the same way as the old one. There are a couple of points, though: - you need to use lctl on the results, to unpack the struct and sort. It does not sort the whole n gigabytes as one piece, but it does sort each "chunk" that was dumped at a time. Those chunks are guaranteed to be chronologically ordered. - lctl debug_daemon [start|stop] are implemented in terms of /proc - you can "debug_daemon start ", or echo to proc, multiple times. If it's already running, it will atomically change to a new file, so that you can build a set of rotating debug daemon logs, without filling up your disk, and without losing any messages during the transition from one file to another. --- lnet/libcfs/proc.c | 38 +++++++++++++++++++++++++++++++------- lustre/portals/libcfs/proc.c | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/lnet/libcfs/proc.c b/lnet/libcfs/proc.c index c850f69..5990ad8 100644 --- a/lnet/libcfs/proc.c +++ b/lnet/libcfs/proc.c @@ -55,10 +55,10 @@ #include #include +#include "tracefile.h" static struct ctl_table_header *portals_table_header = NULL; extern char debug_file_path[1024]; -extern char debug_daemon_file_path[1024]; extern char portals_upcall[1024]; #define PSDEV_PORTALS (0x100) @@ -84,9 +84,6 @@ static struct ctl_table portals_table[] = { &proc_dointvec}, {PSDEV_DEBUG_PATH, "debug_path", debug_file_path, sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string}, - {PSDEV_DEBUG_DUMP_PATH, "debug_daemon_path", debug_daemon_file_path, - sizeof(debug_daemon_file_path), 0644, NULL, &proc_dostring, - &sysctl_string}, {PSDEV_PORTALS_UPCALL, "upcall", portals_upcall, sizeof(portals_upcall), 0644, NULL, &proc_dostring, &sysctl_string}, @@ -238,9 +235,9 @@ static unsigned char basedir[]="net/portals"; int insert_proc(void) { + struct proc_dir_entry *ent; #if PORTALS_PROFILING unsigned char dir[128]; - struct proc_dir_entry *ent; if (ARRAY_SIZE(prof_ents) != MAX_PROFS) { CERROR("profiling enum and array are out of sync.\n"); @@ -270,6 +267,29 @@ int insert_proc(void) portals_table_header = register_sysctl_table(top_table, 0); #endif + ent = create_proc_entry("sys/portals/dump_kernel", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register dump_kernel\n"); + return -1; + } + ent->write_proc = trace_dk; + + ent = create_proc_entry("sys/portals/daemon_file", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register daemon_file\n"); + return -1; + } + ent->write_proc = trace_write_daemon_file; + ent->read_proc = trace_read_daemon_file; + + ent = create_proc_entry("sys/portals/debug_size", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register debug_size\n"); + return -1; + } + ent->write_proc = trace_write_debug_size; + ent->read_proc = trace_read_debug_size; + return 0; } @@ -285,12 +305,16 @@ void remove_proc(void) end = strlen(dir); strcat(dir, "/cycles"); - remove_proc_entry(dir,0); + remove_proc_entry(dir, 0); dir[end] = '\0'; - remove_proc_entry(dir,0); + remove_proc_entry(dir, 0); #endif /* PORTALS_PROFILING */ + remove_proc_entry("sys/portals/dump_kernel", NULL); + remove_proc_entry("sys/portals/daemon_file", NULL); + remove_proc_entry("sys/portals/debug_size", NULL); + #ifdef CONFIG_SYSCTL if (portals_table_header) unregister_sysctl_table(portals_table_header); diff --git a/lustre/portals/libcfs/proc.c b/lustre/portals/libcfs/proc.c index c850f69..5990ad8 100644 --- a/lustre/portals/libcfs/proc.c +++ b/lustre/portals/libcfs/proc.c @@ -55,10 +55,10 @@ #include #include +#include "tracefile.h" static struct ctl_table_header *portals_table_header = NULL; extern char debug_file_path[1024]; -extern char debug_daemon_file_path[1024]; extern char portals_upcall[1024]; #define PSDEV_PORTALS (0x100) @@ -84,9 +84,6 @@ static struct ctl_table portals_table[] = { &proc_dointvec}, {PSDEV_DEBUG_PATH, "debug_path", debug_file_path, sizeof(debug_file_path), 0644, NULL, &proc_dostring, &sysctl_string}, - {PSDEV_DEBUG_DUMP_PATH, "debug_daemon_path", debug_daemon_file_path, - sizeof(debug_daemon_file_path), 0644, NULL, &proc_dostring, - &sysctl_string}, {PSDEV_PORTALS_UPCALL, "upcall", portals_upcall, sizeof(portals_upcall), 0644, NULL, &proc_dostring, &sysctl_string}, @@ -238,9 +235,9 @@ static unsigned char basedir[]="net/portals"; int insert_proc(void) { + struct proc_dir_entry *ent; #if PORTALS_PROFILING unsigned char dir[128]; - struct proc_dir_entry *ent; if (ARRAY_SIZE(prof_ents) != MAX_PROFS) { CERROR("profiling enum and array are out of sync.\n"); @@ -270,6 +267,29 @@ int insert_proc(void) portals_table_header = register_sysctl_table(top_table, 0); #endif + ent = create_proc_entry("sys/portals/dump_kernel", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register dump_kernel\n"); + return -1; + } + ent->write_proc = trace_dk; + + ent = create_proc_entry("sys/portals/daemon_file", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register daemon_file\n"); + return -1; + } + ent->write_proc = trace_write_daemon_file; + ent->read_proc = trace_read_daemon_file; + + ent = create_proc_entry("sys/portals/debug_size", 0, NULL); + if (ent == NULL) { + CERROR("couldn't register debug_size\n"); + return -1; + } + ent->write_proc = trace_write_debug_size; + ent->read_proc = trace_read_debug_size; + return 0; } @@ -285,12 +305,16 @@ void remove_proc(void) end = strlen(dir); strcat(dir, "/cycles"); - remove_proc_entry(dir,0); + remove_proc_entry(dir, 0); dir[end] = '\0'; - remove_proc_entry(dir,0); + remove_proc_entry(dir, 0); #endif /* PORTALS_PROFILING */ + remove_proc_entry("sys/portals/dump_kernel", NULL); + remove_proc_entry("sys/portals/daemon_file", NULL); + remove_proc_entry("sys/portals/debug_size", NULL); + #ifdef CONFIG_SYSCTL if (portals_table_header) unregister_sysctl_table(portals_table_header); -- 1.8.3.1