Skip to content

Commit ce58e96

Browse files
beaubelgraverostedt
authored andcommitted
tracing/user_events: Limit global user_event count
Operators want to be able to ensure enough tracepoints exist on the system for kernel components as well as for user components. Since there are only up to 64K events, by default allow up to half to be used by user events. Add a kernel sysctl parameter (kernel.user_events_max) to set a global limit that is honored among all groups on the system. This ensures hard limits can be setup to prevent user processes from consuming all event IDs on the system. Link: https://lkml.kernel.org/r/20230328235219.203-12-beaub@linux.microsoft.com Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent f9cce23 commit ce58e96

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

kernel/trace/trace_events_user.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <linux/types.h>
2121
#include <linux/uaccess.h>
2222
#include <linux/highmem.h>
23+
#include <linux/init.h>
2324
#include <linux/user_events.h>
2425
#include "trace.h"
2526
#include "trace_dynevent.h"
@@ -61,6 +62,12 @@ struct user_event_group {
6162
/* Group for init_user_ns mapping, top-most group */
6263
static struct user_event_group *init_group;
6364

65+
/* Max allowed events for the whole system */
66+
static unsigned int max_user_events = 32768;
67+
68+
/* Current number of events on the whole system */
69+
static unsigned int current_user_events;
70+
6471
/*
6572
* Stores per-event properties, as users register events
6673
* within a file a user_event might be created if it does not
@@ -1241,6 +1248,8 @@ static int destroy_user_event(struct user_event *user)
12411248
{
12421249
int ret = 0;
12431250

1251+
lockdep_assert_held(&event_mutex);
1252+
12441253
/* Must destroy fields before call removal */
12451254
user_event_destroy_fields(user);
12461255

@@ -1257,6 +1266,11 @@ static int destroy_user_event(struct user_event *user)
12571266
kfree(EVENT_NAME(user));
12581267
kfree(user);
12591268

1269+
if (current_user_events > 0)
1270+
current_user_events--;
1271+
else
1272+
pr_alert("BUG: Bad current_user_events\n");
1273+
12601274
return ret;
12611275
}
12621276

@@ -1744,6 +1758,11 @@ static int user_event_parse(struct user_event_group *group, char *name,
17441758

17451759
mutex_lock(&event_mutex);
17461760

1761+
if (current_user_events >= max_user_events) {
1762+
ret = -EMFILE;
1763+
goto put_user_lock;
1764+
}
1765+
17471766
ret = user_event_trace_register(user);
17481767

17491768
if (ret)
@@ -1755,6 +1774,7 @@ static int user_event_parse(struct user_event_group *group, char *name,
17551774
dyn_event_init(&user->devent, &user_event_dops);
17561775
dyn_event_add(&user->devent, &user->call);
17571776
hash_add(group->register_table, &user->node, key);
1777+
current_user_events++;
17581778

17591779
mutex_unlock(&event_mutex);
17601780

@@ -2390,6 +2410,31 @@ static int create_user_tracefs(void)
23902410
return -ENODEV;
23912411
}
23922412

2413+
static int set_max_user_events_sysctl(struct ctl_table *table, int write,
2414+
void *buffer, size_t *lenp, loff_t *ppos)
2415+
{
2416+
int ret;
2417+
2418+
mutex_lock(&event_mutex);
2419+
2420+
ret = proc_douintvec(table, write, buffer, lenp, ppos);
2421+
2422+
mutex_unlock(&event_mutex);
2423+
2424+
return ret;
2425+
}
2426+
2427+
static struct ctl_table user_event_sysctls[] = {
2428+
{
2429+
.procname = "user_events_max",
2430+
.data = &max_user_events,
2431+
.maxlen = sizeof(unsigned int),
2432+
.mode = 0644,
2433+
.proc_handler = set_max_user_events_sysctl,
2434+
},
2435+
{}
2436+
};
2437+
23932438
static int __init trace_events_user_init(void)
23942439
{
23952440
int ret;
@@ -2419,6 +2464,8 @@ static int __init trace_events_user_init(void)
24192464
if (dyn_event_register(&user_event_dops))
24202465
pr_warn("user_events could not register with dyn_events\n");
24212466

2467+
register_sysctl_init("kernel", user_event_sysctls);
2468+
24222469
return 0;
24232470
}
24242471

0 commit comments

Comments
 (0)