217478ddca954a9d3fc4c4c99bd9f3c93e498bb1
2 * Copyright (C) 2008 Pekka Enberg, Eduard - Gabriel Munteanu
4 * This file is released under GPL version 2.
22 #include <sys/types.h>
23 #include <sys/syscall.h>
24 #include <sys/sendfile.h>
28 #include "kmemtrace.h"
30 static volatile int terminate
;
32 static void write_str(const char *filename
, const char *value
)
36 fd
= open(filename
, O_RDWR
);
38 panic("Could not open() file %s: %s\n", filename
, strerror(errno
));
40 if (write(fd
, value
, strlen(value
)) < 0)
41 panic("Could not write() to file %s: %s\n", filename
, strerror(errno
));
46 static int open_channel(int cpu
)
48 char filename
[PATH_MAX
];
51 sprintf(filename
, "/sys/kernel/debug/kmemtrace/cpu%d", cpu
);
52 fd
= open(filename
, O_RDONLY
| O_NONBLOCK
);
54 panic("Could not open() file %s: %s\n", filename
, strerror(errno
));
58 static int open_log(int cpu
)
60 char filename
[PATH_MAX
];
63 sprintf(filename
, "cpu%d.out", cpu
);
64 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
65 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
67 panic("Could not open() file %s: %s\n",
68 filename
, strerror(errno
));
73 static void reader_set_affinity(unsigned long cpu
)
79 CPU_SET(cpu
, &cpumask
);
80 err
= sched_setaffinity(syscall(SYS_gettid
),
81 sizeof(cpu_set_t
), &cpumask
);
84 panic("reader_set_affinity: %s\n", strerror(errno
));
87 static void *reader_thread(void *data
)
89 unsigned long cpu
= (unsigned long) data
;
94 reader_set_affinity(cpu
);
96 relay_fd
= open_channel(cpu
);
97 log_fd
= open_log(cpu
);
100 panic("pipe() failed: %s\n", strerror(errno
));
104 * We don't strip extra features (due to ABI changes) from
105 * events; do that when actually parsing the data.
107 retval
= splice(relay_fd
, NULL
, pipe_fd
[1], NULL
,
110 panic("splice() (from) failed: %s\n",
112 retval
= splice(pipe_fd
[0], NULL
, log_fd
, NULL
,
115 panic("splice() (to) failed: %s\n", strerror(errno
));
116 } while (!terminate
);
121 static void copy_kallsyms(void)
127 in_fd
= open("/proc/kallsyms", O_RDONLY
);
131 out_fd
= open("kallsyms", O_CREAT
| O_WRONLY
| O_TRUNC
,
132 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
138 while ((count
= read(in_fd
, buf
, 256)) > 0)
139 write(out_fd
, buf
, count
);
146 panic("copy_kallsyms: %s\n", strerror(errno
));
149 int main(int argc
, char *argv
[])
151 unsigned long nr_cpus
;
157 sigemptyset(&signals
);
158 sigaddset(&signals
, SIGINT
);
159 sigaddset(&signals
, SIGTERM
);
160 pthread_sigmask(SIG_BLOCK
, &signals
, NULL
);
162 nr_cpus
= sysconf(_SC_NPROCESSORS_ONLN
);
164 readers
= calloc(nr_cpus
, sizeof(pthread_t
));
166 panic("Out of memory!\n");
168 write_str("/sys/kernel/debug/kmemtrace/enabled", "0");
170 printf("Copying /proc/kallsyms...\n");
173 for (i
= 0; i
< nr_cpus
; i
++) {
176 err
= pthread_create(&readers
[i
], NULL
, reader_thread
,
179 panic("Could not pthread_create(): %s!\n",
183 printf("Logging... Press Control-C to stop.\n");
185 while (sigwait(&signals
, &signal
) == 0) {
186 if (signal
== SIGINT
|| signal
== SIGTERM
)
188 * No synchronization needed, we wait for
195 write_str("/sys/kernel/debug/kmemtrace/enabled", "0");
197 for (i
= 0; i
< nr_cpus
; i
++)
198 pthread_join(readers
[i
], NULL
);