Skip to content

Commit 27152bc

Browse files
akaherrostedt
authored andcommitted
eventfs: Move tracing/events to eventfs
Up until now, /sys/kernel/tracing/events was no different than any other part of tracefs. The files and directories within the events directory was created when the tracefs was mounted, and also created for the instances in /sys/kernel/tracing/instances/<instance>/events. Most of these files and directories will never be referenced. Since there are thousands of these files and directories they spend their time wasting precious memory resources. Move the "events" directory to the new eventfs. The eventfs will take the meta data of the events that they represent and store that. When the files in the events directory are referenced, the dentry and inodes to represent them are then created. When the files are no longer referenced, they are freed. This saves the precious memory resources that were wasted on these seldom referenced dentries and inodes. Running the following: ~# cat /proc/meminfo /proc/slabinfo > before.out ~# mkdir /sys/kernel/tracing/instances/foo ~# cat /proc/meminfo /proc/slabinfo > after.out to test the changes produces the following deltas: Before this change: Before after deltas for meminfo: MemFree: -32260 MemAvailable: -21496 KReclaimable: 21528 Slab: 22440 SReclaimable: 21528 SUnreclaim: 912 VmallocUsed: 16 Before after deltas for slabinfo: <slab>: <objects> [ * <size> = <total>] tracefs_inode_cache: 14472 [* 1184 = 17134848] buffer_head: 24 [* 168 = 4032] hmem_inode_cache: 28 [* 1480 = 41440] dentry: 14450 [* 312 = 4508400] lsm_inode_cache: 14453 [* 32 = 462496] vma_lock: 11 [* 152 = 1672] vm_area_struct: 2 [* 184 = 368] trace_event_file: 1748 [* 88 = 153824] kmalloc-256: 1072 [* 256 = 274432] kmalloc-64: 2842 [* 64 = 181888] Total slab additions in size: 22,763,400 bytes With this change: Before after deltas for meminfo: MemFree: -12600 MemAvailable: -12580 Cached: 24 Active: 12 Inactive: 68 Inactive(anon): 48 Active(file): 12 Inactive(file): 20 Dirty: -4 AnonPages: 68 KReclaimable: 12 Slab: 1856 SReclaimable: 12 SUnreclaim: 1844 KernelStack: 16 PageTables: 36 VmallocUsed: 16 Before after deltas for slabinfo: <slab>: <objects> [ * <size> = <total>] tracefs_inode_cache: 108 [* 1184 = 127872] buffer_head: 24 [* 168 = 4032] hmem_inode_cache: 18 [* 1480 = 26640] dentry: 127 [* 312 = 39624] lsm_inode_cache: 152 [* 32 = 4864] vma_lock: 67 [* 152 = 10184] vm_area_struct: -12 [* 184 = -2208] trace_event_file: 1764 [* 96 = 169344] kmalloc-96: 14322 [* 96 = 1374912] kmalloc-64: 2814 [* 64 = 180096] kmalloc-32: 1103 [* 32 = 35296] kmalloc-16: 2308 [* 16 = 36928] kmalloc-8: 12800 [* 8 = 102400] Total slab additions in size: 2,109,984 bytes Which is a savings of 20,653,416 bytes (20 MB) per tracing instance. Link: https://lkml.kernel.org/r/1690568452-46553-10-git-send-email-akaher@vmware.com Signed-off-by: Ajay Kaher <akaher@vmware.com> Co-developed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Tested-by: Ching-lin Yu <chinglinyu@google.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 5bdcd5f commit 27152bc

4 files changed

Lines changed: 53 additions & 33 deletions

File tree

fs/tracefs/inode.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,23 @@ static const struct super_operations tracefs_super_operations = {
374374
.show_options = tracefs_show_options,
375375
};
376376

377+
static void tracefs_dentry_iput(struct dentry *dentry, struct inode *inode)
378+
{
379+
struct tracefs_inode *ti;
380+
381+
if (!dentry || !inode)
382+
return;
383+
384+
ti = get_tracefs(inode);
385+
if (ti && ti->flags & TRACEFS_EVENT_INODE)
386+
eventfs_set_ef_status_free(dentry);
387+
iput(inode);
388+
}
389+
390+
static const struct dentry_operations tracefs_dentry_operations = {
391+
.d_iput = tracefs_dentry_iput,
392+
};
393+
377394
static int trace_fill_super(struct super_block *sb, void *data, int silent)
378395
{
379396
static const struct tree_descr trace_files[] = {{""}};
@@ -396,6 +413,7 @@ static int trace_fill_super(struct super_block *sb, void *data, int silent)
396413
goto fail;
397414

398415
sb->s_op = &tracefs_super_operations;
416+
sb->s_d_op = &tracefs_dentry_operations;
399417

400418
tracefs_apply_options(sb, false);
401419

include/linux/trace_events.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ struct trace_event_file {
638638
struct list_head list;
639639
struct trace_event_call *event_call;
640640
struct event_filter __rcu *filter;
641+
struct eventfs_file *ef;
641642
struct dentry *dir;
642643
struct trace_array *tr;
643644
struct trace_subsystem_dir *system;

kernel/trace/trace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1334,7 +1334,7 @@ struct trace_subsystem_dir {
13341334
struct list_head list;
13351335
struct event_subsystem *subsystem;
13361336
struct trace_array *tr;
1337-
struct dentry *entry;
1337+
struct eventfs_file *ef;
13381338
int ref_count;
13391339
int nr_events;
13401340
};

kernel/trace/trace_events.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ static void remove_subsystem(struct trace_subsystem_dir *dir)
984984
return;
985985

986986
if (!--dir->nr_events) {
987-
tracefs_remove(dir->entry);
987+
eventfs_remove(dir->ef);
988988
list_del(&dir->list);
989989
__put_system_dir(dir);
990990
}
@@ -1005,7 +1005,7 @@ static void remove_event_file_dir(struct trace_event_file *file)
10051005

10061006
tracefs_remove(dir);
10071007
}
1008-
1008+
eventfs_remove(file->ef);
10091009
list_del(&file->list);
10101010
remove_subsystem(file->system);
10111011
free_event_filter(file->filter);
@@ -2291,21 +2291,21 @@ create_new_subsystem(const char *name)
22912291
return NULL;
22922292
}
22932293

2294-
static struct dentry *
2294+
static struct eventfs_file *
22952295
event_subsystem_dir(struct trace_array *tr, const char *name,
22962296
struct trace_event_file *file, struct dentry *parent)
22972297
{
22982298
struct event_subsystem *system, *iter;
22992299
struct trace_subsystem_dir *dir;
2300-
struct dentry *entry;
2300+
int res;
23012301

23022302
/* First see if we did not already create this dir */
23032303
list_for_each_entry(dir, &tr->systems, list) {
23042304
system = dir->subsystem;
23052305
if (strcmp(system->name, name) == 0) {
23062306
dir->nr_events++;
23072307
file->system = dir;
2308-
return dir->entry;
2308+
return dir->ef;
23092309
}
23102310
}
23112311

@@ -2329,8 +2329,8 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
23292329
} else
23302330
__get_system(system);
23312331

2332-
dir->entry = tracefs_create_dir(name, parent);
2333-
if (!dir->entry) {
2332+
dir->ef = eventfs_add_subsystem_dir(name, parent);
2333+
if (IS_ERR(dir->ef)) {
23342334
pr_warn("Failed to create system directory %s\n", name);
23352335
__put_system(system);
23362336
goto out_free;
@@ -2345,22 +2345,22 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
23452345
/* the ftrace system is special, do not create enable or filter files */
23462346
if (strcmp(name, "ftrace") != 0) {
23472347

2348-
entry = tracefs_create_file("filter", TRACE_MODE_WRITE,
2349-
dir->entry, dir,
2348+
res = eventfs_add_file("filter", TRACE_MODE_WRITE,
2349+
dir->ef, dir,
23502350
&ftrace_subsystem_filter_fops);
2351-
if (!entry) {
2351+
if (res) {
23522352
kfree(system->filter);
23532353
system->filter = NULL;
23542354
pr_warn("Could not create tracefs '%s/filter' entry\n", name);
23552355
}
23562356

2357-
trace_create_file("enable", TRACE_MODE_WRITE, dir->entry, dir,
2357+
eventfs_add_file("enable", TRACE_MODE_WRITE, dir->ef, dir,
23582358
&ftrace_system_enable_fops);
23592359
}
23602360

23612361
list_add(&dir->list, &tr->systems);
23622362

2363-
return dir->entry;
2363+
return dir->ef;
23642364

23652365
out_free:
23662366
kfree(dir);
@@ -2413,8 +2413,8 @@ static int
24132413
event_create_dir(struct dentry *parent, struct trace_event_file *file)
24142414
{
24152415
struct trace_event_call *call = file->event_call;
2416+
struct eventfs_file *ef_subsystem = NULL;
24162417
struct trace_array *tr = file->tr;
2417-
struct dentry *d_events;
24182418
const char *name;
24192419
int ret;
24202420

@@ -2426,24 +2426,24 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
24262426
if (WARN_ON_ONCE(strcmp(call->class->system, TRACE_SYSTEM) == 0))
24272427
return -ENODEV;
24282428

2429-
d_events = event_subsystem_dir(tr, call->class->system, file, parent);
2430-
if (!d_events)
2429+
ef_subsystem = event_subsystem_dir(tr, call->class->system, file, parent);
2430+
if (!ef_subsystem)
24312431
return -ENOMEM;
24322432

24332433
name = trace_event_name(call);
2434-
file->dir = tracefs_create_dir(name, d_events);
2435-
if (!file->dir) {
2434+
file->ef = eventfs_add_dir(name, ef_subsystem);
2435+
if (IS_ERR(file->ef)) {
24362436
pr_warn("Could not create tracefs '%s' directory\n", name);
24372437
return -1;
24382438
}
24392439

24402440
if (call->class->reg && !(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE))
2441-
trace_create_file("enable", TRACE_MODE_WRITE, file->dir, file,
2441+
eventfs_add_file("enable", TRACE_MODE_WRITE, file->ef, file,
24422442
&ftrace_enable_fops);
24432443

24442444
#ifdef CONFIG_PERF_EVENTS
24452445
if (call->event.type && call->class->reg)
2446-
trace_create_file("id", TRACE_MODE_READ, file->dir,
2446+
eventfs_add_file("id", TRACE_MODE_READ, file->ef,
24472447
(void *)(long)call->event.type,
24482448
&ftrace_event_id_fops);
24492449
#endif
@@ -2459,27 +2459,27 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
24592459
* triggers or filters.
24602460
*/
24612461
if (!(call->flags & TRACE_EVENT_FL_IGNORE_ENABLE)) {
2462-
trace_create_file("filter", TRACE_MODE_WRITE, file->dir,
2462+
eventfs_add_file("filter", TRACE_MODE_WRITE, file->ef,
24632463
file, &ftrace_event_filter_fops);
24642464

2465-
trace_create_file("trigger", TRACE_MODE_WRITE, file->dir,
2465+
eventfs_add_file("trigger", TRACE_MODE_WRITE, file->ef,
24662466
file, &event_trigger_fops);
24672467
}
24682468

24692469
#ifdef CONFIG_HIST_TRIGGERS
2470-
trace_create_file("hist", TRACE_MODE_READ, file->dir, file,
2470+
eventfs_add_file("hist", TRACE_MODE_READ, file->ef, file,
24712471
&event_hist_fops);
24722472
#endif
24732473
#ifdef CONFIG_HIST_TRIGGERS_DEBUG
2474-
trace_create_file("hist_debug", TRACE_MODE_READ, file->dir, file,
2474+
eventfs_add_file("hist_debug", TRACE_MODE_READ, file->ef, file,
24752475
&event_hist_debug_fops);
24762476
#endif
2477-
trace_create_file("format", TRACE_MODE_READ, file->dir, call,
2477+
eventfs_add_file("format", TRACE_MODE_READ, file->ef, call,
24782478
&ftrace_event_format_fops);
24792479

24802480
#ifdef CONFIG_TRACE_EVENT_INJECT
24812481
if (call->event.type && call->class->reg)
2482-
trace_create_file("inject", 0200, file->dir, file,
2482+
eventfs_add_file("inject", 0200, file->ef, file,
24832483
&event_inject_fops);
24842484
#endif
24852485

@@ -3632,21 +3632,22 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
36323632
{
36333633
struct dentry *d_events;
36343634
struct dentry *entry;
3635+
int error = 0;
36353636

36363637
entry = trace_create_file("set_event", TRACE_MODE_WRITE, parent,
36373638
tr, &ftrace_set_event_fops);
36383639
if (!entry)
36393640
return -ENOMEM;
36403641

3641-
d_events = tracefs_create_dir("events", parent);
3642-
if (!d_events) {
3642+
d_events = eventfs_create_events_dir("events", parent);
3643+
if (IS_ERR(d_events)) {
36433644
pr_warn("Could not create tracefs 'events' directory\n");
36443645
return -ENOMEM;
36453646
}
36463647

3647-
entry = trace_create_file("enable", TRACE_MODE_WRITE, d_events,
3648+
error = eventfs_add_events_file("enable", TRACE_MODE_WRITE, d_events,
36483649
tr, &ftrace_tr_enable_fops);
3649-
if (!entry)
3650+
if (error)
36503651
return -ENOMEM;
36513652

36523653
/* There are not as crucial, just warn if they are not created */
@@ -3659,11 +3660,11 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
36593660
&ftrace_set_event_notrace_pid_fops);
36603661

36613662
/* ring buffer internal formats */
3662-
trace_create_file("header_page", TRACE_MODE_READ, d_events,
3663+
eventfs_add_events_file("header_page", TRACE_MODE_READ, d_events,
36633664
ring_buffer_print_page_header,
36643665
&ftrace_show_header_fops);
36653666

3666-
trace_create_file("header_event", TRACE_MODE_READ, d_events,
3667+
eventfs_add_events_file("header_event", TRACE_MODE_READ, d_events,
36673668
ring_buffer_print_entry_header,
36683669
&ftrace_show_header_fops);
36693670

@@ -3751,7 +3752,7 @@ int event_trace_del_tracer(struct trace_array *tr)
37513752

37523753
down_write(&trace_event_sem);
37533754
__trace_remove_event_dirs(tr);
3754-
tracefs_remove(tr->event_dir);
3755+
eventfs_remove_events_dir(tr->event_dir);
37553756
up_write(&trace_event_sem);
37563757

37573758
tr->event_dir = NULL;

0 commit comments

Comments
 (0)