Whamcloud - gitweb
b=3668
authorphil <phil>
Wed, 30 Jun 2004 03:49:03 +0000 (03:49 +0000)
committerphil <phil>
Wed, 30 Jun 2004 03:49:03 +0000 (03:49 +0000)
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 <file>", 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
lustre/portals/libcfs/proc.c

index c850f69..5990ad8 100644 (file)
 
 #include <linux/kp30.h>
 #include <asm/div64.h>
+#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);
index c850f69..5990ad8 100644 (file)
 
 #include <linux/kp30.h>
 #include <asm/div64.h>
+#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);