Skip to content

Commit 12ab74e

Browse files
Steven Rostedtrostedt
authored andcommitted
tracing: Make syscall events suitable for multiple buffers
Currently the syscall events record into the global buffer. But if multiple buffers are in place, then we need to have syscall events record in the proper buffers. By adding descriptors to pass to the syscall event functions, the syscall events can now record into the buffers that have been assigned to them (one event may be applied to mulitple buffers). This will allow tracing high volume syscalls along with seldom occurring syscalls without losing the seldom syscall events. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
1 parent a7603ff commit 12ab74e

File tree

2 files changed

+57
-34
lines changed

2 files changed

+57
-34
lines changed

kernel/trace/trace.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
#include <linux/trace_seq.h>
1414
#include <linux/ftrace_event.h>
1515

16+
#ifdef CONFIG_FTRACE_SYSCALLS
17+
#include <asm/unistd.h> /* For NR_SYSCALLS */
18+
#include <asm/syscall.h> /* some archs define it here */
19+
#endif
20+
1621
enum trace_type {
1722
__TRACE_FIRST_TYPE = 0,
1823

@@ -173,6 +178,12 @@ struct trace_array {
173178
int cpu;
174179
int buffer_disabled;
175180
struct trace_cpu trace_cpu; /* place holder */
181+
#ifdef CONFIG_FTRACE_SYSCALLS
182+
int sys_refcount_enter;
183+
int sys_refcount_exit;
184+
DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls);
185+
DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls);
186+
#endif
176187
int stop_count;
177188
int clock_id;
178189
struct tracer *current_trace;

kernel/trace/trace_syscalls.c

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
#include "trace.h"
1313

1414
static DEFINE_MUTEX(syscall_trace_lock);
15-
static int sys_refcount_enter;
16-
static int sys_refcount_exit;
17-
static DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls);
18-
static DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls);
1915

2016
static int syscall_enter_register(struct ftrace_event_call *event,
2117
enum trace_reg type, void *data);
@@ -303,8 +299,9 @@ static int syscall_exit_define_fields(struct ftrace_event_call *call)
303299
return ret;
304300
}
305301

306-
static void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id)
302+
static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
307303
{
304+
struct trace_array *tr = data;
308305
struct syscall_trace_enter *entry;
309306
struct syscall_metadata *sys_data;
310307
struct ring_buffer_event *event;
@@ -315,7 +312,7 @@ static void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id)
315312
syscall_nr = trace_get_syscall_nr(current, regs);
316313
if (syscall_nr < 0)
317314
return;
318-
if (!test_bit(syscall_nr, enabled_enter_syscalls))
315+
if (!test_bit(syscall_nr, tr->enabled_enter_syscalls))
319316
return;
320317

321318
sys_data = syscall_nr_to_meta(syscall_nr);
@@ -324,7 +321,8 @@ static void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id)
324321

325322
size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args;
326323

327-
event = trace_current_buffer_lock_reserve(&buffer,
324+
buffer = tr->buffer;
325+
event = trace_buffer_lock_reserve(buffer,
328326
sys_data->enter_event->event.type, size, 0, 0);
329327
if (!event)
330328
return;
@@ -338,8 +336,9 @@ static void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id)
338336
trace_current_buffer_unlock_commit(buffer, event, 0, 0);
339337
}
340338

341-
static void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
339+
static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
342340
{
341+
struct trace_array *tr = data;
343342
struct syscall_trace_exit *entry;
344343
struct syscall_metadata *sys_data;
345344
struct ring_buffer_event *event;
@@ -349,14 +348,15 @@ static void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
349348
syscall_nr = trace_get_syscall_nr(current, regs);
350349
if (syscall_nr < 0)
351350
return;
352-
if (!test_bit(syscall_nr, enabled_exit_syscalls))
351+
if (!test_bit(syscall_nr, tr->enabled_exit_syscalls))
353352
return;
354353

355354
sys_data = syscall_nr_to_meta(syscall_nr);
356355
if (!sys_data)
357356
return;
358357

359-
event = trace_current_buffer_lock_reserve(&buffer,
358+
buffer = tr->buffer;
359+
event = trace_buffer_lock_reserve(buffer,
360360
sys_data->exit_event->event.type, sizeof(*entry), 0, 0);
361361
if (!event)
362362
return;
@@ -370,71 +370,79 @@ static void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
370370
trace_current_buffer_unlock_commit(buffer, event, 0, 0);
371371
}
372372

373-
static int reg_event_syscall_enter(struct ftrace_event_call *call)
373+
static int reg_event_syscall_enter(struct ftrace_event_file *file,
374+
struct ftrace_event_call *call)
374375
{
376+
struct trace_array *tr = file->tr;
375377
int ret = 0;
376378
int num;
377379

378380
num = ((struct syscall_metadata *)call->data)->syscall_nr;
379381
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
380382
return -ENOSYS;
381383
mutex_lock(&syscall_trace_lock);
382-
if (!sys_refcount_enter)
383-
ret = register_trace_sys_enter(ftrace_syscall_enter, NULL);
384+
if (!tr->sys_refcount_enter)
385+
ret = register_trace_sys_enter(ftrace_syscall_enter, tr);
384386
if (!ret) {
385-
set_bit(num, enabled_enter_syscalls);
386-
sys_refcount_enter++;
387+
set_bit(num, tr->enabled_enter_syscalls);
388+
tr->sys_refcount_enter++;
387389
}
388390
mutex_unlock(&syscall_trace_lock);
389391
return ret;
390392
}
391393

392-
static void unreg_event_syscall_enter(struct ftrace_event_call *call)
394+
static void unreg_event_syscall_enter(struct ftrace_event_file *file,
395+
struct ftrace_event_call *call)
393396
{
397+
struct trace_array *tr = file->tr;
394398
int num;
395399

396400
num = ((struct syscall_metadata *)call->data)->syscall_nr;
397401
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
398402
return;
399403
mutex_lock(&syscall_trace_lock);
400-
sys_refcount_enter--;
401-
clear_bit(num, enabled_enter_syscalls);
402-
if (!sys_refcount_enter)
403-
unregister_trace_sys_enter(ftrace_syscall_enter, NULL);
404+
tr->sys_refcount_enter--;
405+
clear_bit(num, tr->enabled_enter_syscalls);
406+
if (!tr->sys_refcount_enter)
407+
unregister_trace_sys_enter(ftrace_syscall_enter, tr);
404408
mutex_unlock(&syscall_trace_lock);
405409
}
406410

407-
static int reg_event_syscall_exit(struct ftrace_event_call *call)
411+
static int reg_event_syscall_exit(struct ftrace_event_file *file,
412+
struct ftrace_event_call *call)
408413
{
414+
struct trace_array *tr = file->tr;
409415
int ret = 0;
410416
int num;
411417

412418
num = ((struct syscall_metadata *)call->data)->syscall_nr;
413419
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
414420
return -ENOSYS;
415421
mutex_lock(&syscall_trace_lock);
416-
if (!sys_refcount_exit)
417-
ret = register_trace_sys_exit(ftrace_syscall_exit, NULL);
422+
if (!tr->sys_refcount_exit)
423+
ret = register_trace_sys_exit(ftrace_syscall_exit, tr);
418424
if (!ret) {
419-
set_bit(num, enabled_exit_syscalls);
420-
sys_refcount_exit++;
425+
set_bit(num, tr->enabled_exit_syscalls);
426+
tr->sys_refcount_exit++;
421427
}
422428
mutex_unlock(&syscall_trace_lock);
423429
return ret;
424430
}
425431

426-
static void unreg_event_syscall_exit(struct ftrace_event_call *call)
432+
static void unreg_event_syscall_exit(struct ftrace_event_file *file,
433+
struct ftrace_event_call *call)
427434
{
435+
struct trace_array *tr = file->tr;
428436
int num;
429437

430438
num = ((struct syscall_metadata *)call->data)->syscall_nr;
431439
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
432440
return;
433441
mutex_lock(&syscall_trace_lock);
434-
sys_refcount_exit--;
435-
clear_bit(num, enabled_exit_syscalls);
436-
if (!sys_refcount_exit)
437-
unregister_trace_sys_exit(ftrace_syscall_exit, NULL);
442+
tr->sys_refcount_exit--;
443+
clear_bit(num, tr->enabled_exit_syscalls);
444+
if (!tr->sys_refcount_exit)
445+
unregister_trace_sys_exit(ftrace_syscall_exit, tr);
438446
mutex_unlock(&syscall_trace_lock);
439447
}
440448

@@ -685,11 +693,13 @@ static void perf_sysexit_disable(struct ftrace_event_call *call)
685693
static int syscall_enter_register(struct ftrace_event_call *event,
686694
enum trace_reg type, void *data)
687695
{
696+
struct ftrace_event_file *file = data;
697+
688698
switch (type) {
689699
case TRACE_REG_REGISTER:
690-
return reg_event_syscall_enter(event);
700+
return reg_event_syscall_enter(file, event);
691701
case TRACE_REG_UNREGISTER:
692-
unreg_event_syscall_enter(event);
702+
unreg_event_syscall_enter(file, event);
693703
return 0;
694704

695705
#ifdef CONFIG_PERF_EVENTS
@@ -711,11 +721,13 @@ static int syscall_enter_register(struct ftrace_event_call *event,
711721
static int syscall_exit_register(struct ftrace_event_call *event,
712722
enum trace_reg type, void *data)
713723
{
724+
struct ftrace_event_file *file = data;
725+
714726
switch (type) {
715727
case TRACE_REG_REGISTER:
716-
return reg_event_syscall_exit(event);
728+
return reg_event_syscall_exit(file, event);
717729
case TRACE_REG_UNREGISTER:
718-
unreg_event_syscall_exit(event);
730+
unreg_event_syscall_exit(file, event);
719731
return 0;
720732

721733
#ifdef CONFIG_PERF_EVENTS

0 commit comments

Comments
 (0)