Skip to content

Commit 34597c8

Browse files
committed
Merge tag 'trace-v5.5-rc6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: "Various tracing fixes: - Fix a function comparison warning for a xen trace event macro - Fix a double perf_event linking to a trace_uprobe_filter for multiple events - Fix suspicious RCU warnings in trace event code for using list_for_each_entry_rcu() when the "_rcu" portion wasn't needed. - Fix a bug in the histogram code when using the same variable - Fix a NULL pointer dereference when tracefs lockdown enabled and calling trace_set_default_clock() - A fix to a bug found with the double perf_event linking patch" * tag 'trace-v5.5-rc6-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing/uprobe: Fix to make trace_uprobe_filter alignment safe tracing: Do not set trace clock if tracefs lockdown is in effect tracing: Fix histogram code when expression has same var as value tracing: trigger: Replace unneeded RCU-list traversals tracing/uprobe: Fix double perf_event linking on multiprobe uprobe tracing: xen: Ordered comparison of function pointers
2 parents fa0a4e3 + b61387c commit 34597c8

8 files changed

Lines changed: 163 additions & 71 deletions

File tree

include/trace/events/xen.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ TRACE_EVENT(xen_mc_callback,
6666
TP_PROTO(xen_mc_callback_fn_t fn, void *data),
6767
TP_ARGS(fn, data),
6868
TP_STRUCT__entry(
69-
__field(xen_mc_callback_fn_t, fn)
69+
/*
70+
* Use field_struct to avoid is_signed_type()
71+
* comparison of a function pointer.
72+
*/
73+
__field_struct(xen_mc_callback_fn_t, fn)
7074
__field(void *, data)
7175
),
7276
TP_fast_assign(

kernel/trace/trace.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9420,6 +9420,11 @@ __init static int tracing_set_default_clock(void)
94209420
{
94219421
/* sched_clock_stable() is determined in late_initcall */
94229422
if (!trace_boot_clock && !sched_clock_stable()) {
9423+
if (security_locked_down(LOCKDOWN_TRACEFS)) {
9424+
pr_warn("Can not set tracing clock due to lockdown\n");
9425+
return -EPERM;
9426+
}
9427+
94239428
printk(KERN_WARNING
94249429
"Unstable clock detected, switching default tracing clock to \"global\"\n"
94259430
"If you want to keep using the local clock, then add:\n"

kernel/trace/trace_events_hist.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct hist_field {
116116
struct ftrace_event_field *field;
117117
unsigned long flags;
118118
hist_field_fn_t fn;
119+
unsigned int ref;
119120
unsigned int size;
120121
unsigned int offset;
121122
unsigned int is_signed;
@@ -1766,11 +1767,13 @@ static struct hist_field *find_var(struct hist_trigger_data *hist_data,
17661767
struct event_trigger_data *test;
17671768
struct hist_field *hist_field;
17681769

1770+
lockdep_assert_held(&event_mutex);
1771+
17691772
hist_field = find_var_field(hist_data, var_name);
17701773
if (hist_field)
17711774
return hist_field;
17721775

1773-
list_for_each_entry_rcu(test, &file->triggers, list) {
1776+
list_for_each_entry(test, &file->triggers, list) {
17741777
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
17751778
test_data = test->private_data;
17761779
hist_field = find_var_field(test_data, var_name);
@@ -1820,7 +1823,9 @@ static struct hist_field *find_file_var(struct trace_event_file *file,
18201823
struct event_trigger_data *test;
18211824
struct hist_field *hist_field;
18221825

1823-
list_for_each_entry_rcu(test, &file->triggers, list) {
1826+
lockdep_assert_held(&event_mutex);
1827+
1828+
list_for_each_entry(test, &file->triggers, list) {
18241829
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
18251830
test_data = test->private_data;
18261831
hist_field = find_var_field(test_data, var_name);
@@ -2423,8 +2428,16 @@ static int contains_operator(char *str)
24232428
return field_op;
24242429
}
24252430

2431+
static void get_hist_field(struct hist_field *hist_field)
2432+
{
2433+
hist_field->ref++;
2434+
}
2435+
24262436
static void __destroy_hist_field(struct hist_field *hist_field)
24272437
{
2438+
if (--hist_field->ref > 1)
2439+
return;
2440+
24282441
kfree(hist_field->var.name);
24292442
kfree(hist_field->name);
24302443
kfree(hist_field->type);
@@ -2466,6 +2479,8 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data,
24662479
if (!hist_field)
24672480
return NULL;
24682481

2482+
hist_field->ref = 1;
2483+
24692484
hist_field->hist_data = hist_data;
24702485

24712486
if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS)
@@ -2661,6 +2676,17 @@ static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
26612676
{
26622677
unsigned long flags = HIST_FIELD_FL_VAR_REF;
26632678
struct hist_field *ref_field;
2679+
int i;
2680+
2681+
/* Check if the variable already exists */
2682+
for (i = 0; i < hist_data->n_var_refs; i++) {
2683+
ref_field = hist_data->var_refs[i];
2684+
if (ref_field->var.idx == var_field->var.idx &&
2685+
ref_field->var.hist_data == var_field->hist_data) {
2686+
get_hist_field(ref_field);
2687+
return ref_field;
2688+
}
2689+
}
26642690

26652691
ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
26662692
if (ref_field) {
@@ -3115,7 +3141,9 @@ static char *find_trigger_filter(struct hist_trigger_data *hist_data,
31153141
{
31163142
struct event_trigger_data *test;
31173143

3118-
list_for_each_entry_rcu(test, &file->triggers, list) {
3144+
lockdep_assert_held(&event_mutex);
3145+
3146+
list_for_each_entry(test, &file->triggers, list) {
31193147
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
31203148
if (test->private_data == hist_data)
31213149
return test->filter_str;
@@ -3166,9 +3194,11 @@ find_compatible_hist(struct hist_trigger_data *target_hist_data,
31663194
struct event_trigger_data *test;
31673195
unsigned int n_keys;
31683196

3197+
lockdep_assert_held(&event_mutex);
3198+
31693199
n_keys = target_hist_data->n_fields - target_hist_data->n_vals;
31703200

3171-
list_for_each_entry_rcu(test, &file->triggers, list) {
3201+
list_for_each_entry(test, &file->triggers, list) {
31723202
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
31733203
hist_data = test->private_data;
31743204

@@ -5528,7 +5558,7 @@ static int hist_show(struct seq_file *m, void *v)
55285558
goto out_unlock;
55295559
}
55305560

5531-
list_for_each_entry_rcu(data, &event_file->triggers, list) {
5561+
list_for_each_entry(data, &event_file->triggers, list) {
55325562
if (data->cmd_ops->trigger_type == ETT_EVENT_HIST)
55335563
hist_trigger_show(m, data, n++);
55345564
}
@@ -5921,7 +5951,9 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
59215951
if (hist_data->attrs->name && !named_data)
59225952
goto new;
59235953

5924-
list_for_each_entry_rcu(test, &file->triggers, list) {
5954+
lockdep_assert_held(&event_mutex);
5955+
5956+
list_for_each_entry(test, &file->triggers, list) {
59255957
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
59265958
if (!hist_trigger_match(data, test, named_data, false))
59275959
continue;
@@ -6005,10 +6037,12 @@ static bool have_hist_trigger_match(struct event_trigger_data *data,
60056037
struct event_trigger_data *test, *named_data = NULL;
60066038
bool match = false;
60076039

6040+
lockdep_assert_held(&event_mutex);
6041+
60086042
if (hist_data->attrs->name)
60096043
named_data = find_named_trigger(hist_data->attrs->name);
60106044

6011-
list_for_each_entry_rcu(test, &file->triggers, list) {
6045+
list_for_each_entry(test, &file->triggers, list) {
60126046
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
60136047
if (hist_trigger_match(data, test, named_data, false)) {
60146048
match = true;
@@ -6026,10 +6060,12 @@ static bool hist_trigger_check_refs(struct event_trigger_data *data,
60266060
struct hist_trigger_data *hist_data = data->private_data;
60276061
struct event_trigger_data *test, *named_data = NULL;
60286062

6063+
lockdep_assert_held(&event_mutex);
6064+
60296065
if (hist_data->attrs->name)
60306066
named_data = find_named_trigger(hist_data->attrs->name);
60316067

6032-
list_for_each_entry_rcu(test, &file->triggers, list) {
6068+
list_for_each_entry(test, &file->triggers, list) {
60336069
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
60346070
if (!hist_trigger_match(data, test, named_data, false))
60356071
continue;
@@ -6051,10 +6087,12 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
60516087
struct event_trigger_data *test, *named_data = NULL;
60526088
bool unregistered = false;
60536089

6090+
lockdep_assert_held(&event_mutex);
6091+
60546092
if (hist_data->attrs->name)
60556093
named_data = find_named_trigger(hist_data->attrs->name);
60566094

6057-
list_for_each_entry_rcu(test, &file->triggers, list) {
6095+
list_for_each_entry(test, &file->triggers, list) {
60586096
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
60596097
if (!hist_trigger_match(data, test, named_data, false))
60606098
continue;
@@ -6080,7 +6118,9 @@ static bool hist_file_check_refs(struct trace_event_file *file)
60806118
struct hist_trigger_data *hist_data;
60816119
struct event_trigger_data *test;
60826120

6083-
list_for_each_entry_rcu(test, &file->triggers, list) {
6121+
lockdep_assert_held(&event_mutex);
6122+
6123+
list_for_each_entry(test, &file->triggers, list) {
60846124
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
60856125
hist_data = test->private_data;
60866126
if (check_var_refs(hist_data))
@@ -6323,7 +6363,8 @@ hist_enable_trigger(struct event_trigger_data *data, void *rec,
63236363
struct enable_trigger_data *enable_data = data->private_data;
63246364
struct event_trigger_data *test;
63256365

6326-
list_for_each_entry_rcu(test, &enable_data->file->triggers, list) {
6366+
list_for_each_entry_rcu(test, &enable_data->file->triggers, list,
6367+
lockdep_is_held(&event_mutex)) {
63276368
if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
63286369
if (enable_data->enable)
63296370
test->paused = false;

kernel/trace/trace_events_trigger.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,9 @@ void update_cond_flag(struct trace_event_file *file)
501501
struct event_trigger_data *data;
502502
bool set_cond = false;
503503

504-
list_for_each_entry_rcu(data, &file->triggers, list) {
504+
lockdep_assert_held(&event_mutex);
505+
506+
list_for_each_entry(data, &file->triggers, list) {
505507
if (data->filter || event_command_post_trigger(data->cmd_ops) ||
506508
event_command_needs_rec(data->cmd_ops)) {
507509
set_cond = true;
@@ -536,7 +538,9 @@ static int register_trigger(char *glob, struct event_trigger_ops *ops,
536538
struct event_trigger_data *test;
537539
int ret = 0;
538540

539-
list_for_each_entry_rcu(test, &file->triggers, list) {
541+
lockdep_assert_held(&event_mutex);
542+
543+
list_for_each_entry(test, &file->triggers, list) {
540544
if (test->cmd_ops->trigger_type == data->cmd_ops->trigger_type) {
541545
ret = -EEXIST;
542546
goto out;
@@ -581,7 +585,9 @@ static void unregister_trigger(char *glob, struct event_trigger_ops *ops,
581585
struct event_trigger_data *data;
582586
bool unregistered = false;
583587

584-
list_for_each_entry_rcu(data, &file->triggers, list) {
588+
lockdep_assert_held(&event_mutex);
589+
590+
list_for_each_entry(data, &file->triggers, list) {
585591
if (data->cmd_ops->trigger_type == test->cmd_ops->trigger_type) {
586592
unregistered = true;
587593
list_del_rcu(&data->list);
@@ -1497,7 +1503,9 @@ int event_enable_register_trigger(char *glob,
14971503
struct event_trigger_data *test;
14981504
int ret = 0;
14991505

1500-
list_for_each_entry_rcu(test, &file->triggers, list) {
1506+
lockdep_assert_held(&event_mutex);
1507+
1508+
list_for_each_entry(test, &file->triggers, list) {
15011509
test_enable_data = test->private_data;
15021510
if (test_enable_data &&
15031511
(test->cmd_ops->trigger_type ==
@@ -1537,7 +1545,9 @@ void event_enable_unregister_trigger(char *glob,
15371545
struct event_trigger_data *data;
15381546
bool unregistered = false;
15391547

1540-
list_for_each_entry_rcu(data, &file->triggers, list) {
1548+
lockdep_assert_held(&event_mutex);
1549+
1550+
list_for_each_entry(data, &file->triggers, list) {
15411551
enable_data = data->private_data;
15421552
if (enable_data &&
15431553
(data->cmd_ops->trigger_type ==

kernel/trace/trace_kprobe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group,
290290
INIT_HLIST_NODE(&tk->rp.kp.hlist);
291291
INIT_LIST_HEAD(&tk->rp.kp.list);
292292

293-
ret = trace_probe_init(&tk->tp, event, group);
293+
ret = trace_probe_init(&tk->tp, event, group, false);
294294
if (ret < 0)
295295
goto error;
296296

kernel/trace/trace_probe.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,15 +984,19 @@ void trace_probe_cleanup(struct trace_probe *tp)
984984
}
985985

986986
int trace_probe_init(struct trace_probe *tp, const char *event,
987-
const char *group)
987+
const char *group, bool alloc_filter)
988988
{
989989
struct trace_event_call *call;
990+
size_t size = sizeof(struct trace_probe_event);
990991
int ret = 0;
991992

992993
if (!event || !group)
993994
return -EINVAL;
994995

995-
tp->event = kzalloc(sizeof(struct trace_probe_event), GFP_KERNEL);
996+
if (alloc_filter)
997+
size += sizeof(struct trace_uprobe_filter);
998+
999+
tp->event = kzalloc(size, GFP_KERNEL);
9961000
if (!tp->event)
9971001
return -ENOMEM;
9981002

kernel/trace/trace_probe.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,20 @@ struct probe_arg {
223223
const struct fetch_type *type; /* Type of this argument */
224224
};
225225

226+
struct trace_uprobe_filter {
227+
rwlock_t rwlock;
228+
int nr_systemwide;
229+
struct list_head perf_events;
230+
};
231+
226232
/* Event call and class holder */
227233
struct trace_probe_event {
228234
unsigned int flags; /* For TP_FLAG_* */
229235
struct trace_event_class class;
230236
struct trace_event_call call;
231237
struct list_head files;
232238
struct list_head probes;
239+
struct trace_uprobe_filter filter[0];
233240
};
234241

235242
struct trace_probe {
@@ -322,7 +329,7 @@ static inline bool trace_probe_has_single_file(struct trace_probe *tp)
322329
}
323330

324331
int trace_probe_init(struct trace_probe *tp, const char *event,
325-
const char *group);
332+
const char *group, bool alloc_filter);
326333
void trace_probe_cleanup(struct trace_probe *tp);
327334
int trace_probe_append(struct trace_probe *tp, struct trace_probe *to);
328335
void trace_probe_unlink(struct trace_probe *tp);

0 commit comments

Comments
 (0)