aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/trace/trace_events_hist.c93
1 files changed, 75 insertions, 18 deletions
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index f3caf6e484f4..6309f4dbfb9c 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1292,6 +1292,17 @@ static u64 hist_field_cpu(struct hist_field *hist_field,
1292 return cpu; 1292 return cpu;
1293} 1293}
1294 1294
1295/**
1296 * check_field_for_var_ref - Check if a VAR_REF field references a variable
1297 * @hist_field: The VAR_REF field to check
1298 * @var_data: The hist trigger that owns the variable
1299 * @var_idx: The trigger variable identifier
1300 *
1301 * Check the given VAR_REF field to see whether or not it references
1302 * the given variable associated with the given trigger.
1303 *
1304 * Return: The VAR_REF field if it does reference the variable, NULL if not
1305 */
1295static struct hist_field * 1306static struct hist_field *
1296check_field_for_var_ref(struct hist_field *hist_field, 1307check_field_for_var_ref(struct hist_field *hist_field,
1297 struct hist_trigger_data *var_data, 1308 struct hist_trigger_data *var_data,
@@ -1306,6 +1317,18 @@ check_field_for_var_ref(struct hist_field *hist_field,
1306 return NULL; 1317 return NULL;
1307} 1318}
1308 1319
1320/**
1321 * find_var_ref - Check if a trigger has a reference to a trigger variable
1322 * @hist_data: The hist trigger that might have a reference to the variable
1323 * @var_data: The hist trigger that owns the variable
1324 * @var_idx: The trigger variable identifier
1325 *
1326 * Check the list of var_refs[] on the first hist trigger to see
1327 * whether any of them are references to the variable on the second
1328 * trigger.
1329 *
1330 * Return: The VAR_REF field referencing the variable if so, NULL if not
1331 */
1309static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data, 1332static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data,
1310 struct hist_trigger_data *var_data, 1333 struct hist_trigger_data *var_data,
1311 unsigned int var_idx) 1334 unsigned int var_idx)
@@ -1322,6 +1345,20 @@ static struct hist_field *find_var_ref(struct hist_trigger_data *hist_data,
1322 return NULL; 1345 return NULL;
1323} 1346}
1324 1347
1348/**
1349 * find_any_var_ref - Check if there is a reference to a given trigger variable
1350 * @hist_data: The hist trigger
1351 * @var_idx: The trigger variable identifier
1352 *
1353 * Check to see whether the given variable is currently referenced by
1354 * any other trigger.
1355 *
1356 * The trigger the variable is defined on is explicitly excluded - the
1357 * assumption being that a self-reference doesn't prevent a trigger
1358 * from being removed.
1359 *
1360 * Return: The VAR_REF field referencing the variable if so, NULL if not
1361 */
1325static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data, 1362static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data,
1326 unsigned int var_idx) 1363 unsigned int var_idx)
1327{ 1364{
@@ -1340,6 +1377,19 @@ static struct hist_field *find_any_var_ref(struct hist_trigger_data *hist_data,
1340 return found; 1377 return found;
1341} 1378}
1342 1379
1380/**
1381 * check_var_refs - Check if there is a reference to any of trigger's variables
1382 * @hist_data: The hist trigger
1383 *
1384 * A trigger can define one or more variables. If any one of them is
1385 * currently referenced by any other trigger, this function will
1386 * determine that.
1387
1388 * Typically used to determine whether or not a trigger can be removed
1389 * - if there are any references to a trigger's variables, it cannot.
1390 *
1391 * Return: True if there is a reference to any of trigger's variables
1392 */
1343static bool check_var_refs(struct hist_trigger_data *hist_data) 1393static bool check_var_refs(struct hist_trigger_data *hist_data)
1344{ 1394{
1345 struct hist_field *field; 1395 struct hist_field *field;
@@ -2343,7 +2393,23 @@ static int init_var_ref(struct hist_field *ref_field,
2343 goto out; 2393 goto out;
2344} 2394}
2345 2395
2346static struct hist_field *create_var_ref(struct hist_field *var_field, 2396/**
2397 * create_var_ref - Create a variable reference and attach it to trigger
2398 * @hist_data: The trigger that will be referencing the variable
2399 * @var_field: The VAR field to create a reference to
2400 * @system: The optional system string
2401 * @event_name: The optional event_name string
2402 *
2403 * Given a variable hist_field, create a VAR_REF hist_field that
2404 * represents a reference to it.
2405 *
2406 * This function also adds the reference to the trigger that
2407 * now references the variable.
2408 *
2409 * Return: The VAR_REF field if successful, NULL if not
2410 */
2411static struct hist_field *create_var_ref(struct hist_trigger_data *hist_data,
2412 struct hist_field *var_field,
2347 char *system, char *event_name) 2413 char *system, char *event_name)
2348{ 2414{
2349 unsigned long flags = HIST_FIELD_FL_VAR_REF; 2415 unsigned long flags = HIST_FIELD_FL_VAR_REF;
@@ -2355,6 +2421,9 @@ static struct hist_field *create_var_ref(struct hist_field *var_field,
2355 destroy_hist_field(ref_field, 0); 2421 destroy_hist_field(ref_field, 0);
2356 return NULL; 2422 return NULL;
2357 } 2423 }
2424
2425 hist_data->var_refs[hist_data->n_var_refs] = ref_field;
2426 ref_field->var_ref_idx = hist_data->n_var_refs++;
2358 } 2427 }
2359 2428
2360 return ref_field; 2429 return ref_field;
@@ -2428,7 +2497,8 @@ static struct hist_field *parse_var_ref(struct hist_trigger_data *hist_data,
2428 2497
2429 var_field = find_event_var(hist_data, system, event_name, var_name); 2498 var_field = find_event_var(hist_data, system, event_name, var_name);
2430 if (var_field) 2499 if (var_field)
2431 ref_field = create_var_ref(var_field, system, event_name); 2500 ref_field = create_var_ref(hist_data, var_field,
2501 system, event_name);
2432 2502
2433 if (!ref_field) 2503 if (!ref_field)
2434 hist_err_event("Couldn't find variable: $", 2504 hist_err_event("Couldn't find variable: $",
@@ -2546,8 +2616,6 @@ static struct hist_field *parse_atom(struct hist_trigger_data *hist_data,
2546 if (!s) { 2616 if (!s) {
2547 hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var); 2617 hist_field = parse_var_ref(hist_data, ref_system, ref_event, ref_var);
2548 if (hist_field) { 2618 if (hist_field) {
2549 hist_data->var_refs[hist_data->n_var_refs] = hist_field;
2550 hist_field->var_ref_idx = hist_data->n_var_refs++;
2551 if (var_name) { 2619 if (var_name) {
2552 hist_field = create_alias(hist_data, hist_field, var_name); 2620 hist_field = create_alias(hist_data, hist_field, var_name);
2553 if (!hist_field) { 2621 if (!hist_field) {
@@ -3321,7 +3389,6 @@ static int onmax_create(struct hist_trigger_data *hist_data,
3321 unsigned int var_ref_idx = hist_data->n_var_refs; 3389 unsigned int var_ref_idx = hist_data->n_var_refs;
3322 struct field_var *field_var; 3390 struct field_var *field_var;
3323 char *onmax_var_str, *param; 3391 char *onmax_var_str, *param;
3324 unsigned long flags;
3325 unsigned int i; 3392 unsigned int i;
3326 int ret = 0; 3393 int ret = 0;
3327 3394
@@ -3338,18 +3405,10 @@ static int onmax_create(struct hist_trigger_data *hist_data,
3338 return -EINVAL; 3405 return -EINVAL;
3339 } 3406 }
3340 3407
3341 flags = HIST_FIELD_FL_VAR_REF; 3408 ref_field = create_var_ref(hist_data, var_field, NULL, NULL);
3342 ref_field = create_hist_field(hist_data, NULL, flags, NULL);
3343 if (!ref_field) 3409 if (!ref_field)
3344 return -ENOMEM; 3410 return -ENOMEM;
3345 3411
3346 if (init_var_ref(ref_field, var_field, NULL, NULL)) {
3347 destroy_hist_field(ref_field, 0);
3348 ret = -ENOMEM;
3349 goto out;
3350 }
3351 hist_data->var_refs[hist_data->n_var_refs] = ref_field;
3352 ref_field->var_ref_idx = hist_data->n_var_refs++;
3353 data->onmax.var = ref_field; 3412 data->onmax.var = ref_field;
3354 3413
3355 data->fn = onmax_save; 3414 data->fn = onmax_save;
@@ -3538,9 +3597,6 @@ static void save_synth_var_ref(struct hist_trigger_data *hist_data,
3538 struct hist_field *var_ref) 3597 struct hist_field *var_ref)
3539{ 3598{
3540 hist_data->synth_var_refs[hist_data->n_synth_var_refs++] = var_ref; 3599 hist_data->synth_var_refs[hist_data->n_synth_var_refs++] = var_ref;
3541
3542 hist_data->var_refs[hist_data->n_var_refs] = var_ref;
3543 var_ref->var_ref_idx = hist_data->n_var_refs++;
3544} 3600}
3545 3601
3546static int check_synth_field(struct synth_event *event, 3602static int check_synth_field(struct synth_event *event,
@@ -3694,7 +3750,8 @@ static int onmatch_create(struct hist_trigger_data *hist_data,
3694 } 3750 }
3695 3751
3696 if (check_synth_field(event, hist_field, field_pos) == 0) { 3752 if (check_synth_field(event, hist_field, field_pos) == 0) {
3697 var_ref = create_var_ref(hist_field, system, event_name); 3753 var_ref = create_var_ref(hist_data, hist_field,
3754 system, event_name);
3698 if (!var_ref) { 3755 if (!var_ref) {
3699 kfree(p); 3756 kfree(p);
3700 ret = -ENOMEM; 3757 ret = -ENOMEM;