Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp671993imu; Wed, 16 Jan 2019 05:49:16 -0800 (PST) X-Google-Smtp-Source: ALg8bN64P6HvOgDub11RzmSDRryknmOP9FntkLGfs5TibLg9HMU0p+2L4D1/I7ijdO2/jV+XOSZX X-Received: by 2002:a17:902:bb86:: with SMTP id m6mr10029697pls.315.1547646555996; Wed, 16 Jan 2019 05:49:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547646555; cv=none; d=google.com; s=arc-20160816; b=cEuIY8bLrQooZJvfvOKHzxvml4z4Kw22jgltykihZqpfZGsjn6pZCQ38eDm25pXO2r UiA8D/9/BB5PMxKhh5j7UHD6/vIoT1Rxn4JLSSbmpwI+iYLKuNOxxaxhiJWd8l0OWYgl +GK8tZjU4+fC+4hYLa8a9ClfVer4Hp319qVOyS/Uv902qjpNVpC/OnjVn4IKxbThVgsH V2FEfgXopC+22qKgkQ7rrUuc7vTCHIipumZrABc1L0dYTguTNKvKcLB4ClnjhsMjDs0Z 9GxPQICVSCWbLw5mEglVx1sEXiIUYztyzePBejASLhoivrTmyZUHO/7XRSN9rRj/CAc8 xq+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=n29mzDy0IwIrtuTwoc3RDLeZVmiTgskPR85YPq4Gvg4=; b=KXVqEb/V26xYMhJoQNTDwZ5Y6AIkGj2cZ8Dzy8fHVjYtyKWd4ozrx79+1ZjkejC17O t9oJBbOXxktKMarXQ4DVHTE2gBhnMX6IcodL3EMvd5oMXD0ATxnUqXeuW1RVcUIn6ILX V3iClD/0hUxtDNDw1ajKgUD0aA4hGzYLq58PVi0EiWEYvrg08IhdpesOHug/FswXbwFV gEL1h3Sowp++hmzVa53FuAJM0SX9gAzNjlJIx6QTucnLtZmfWHQq5K9qcdhaRecRgZln PBSN+Jf4/M79wOLSnJ4+HC1E7XIzEslkBPBahsFwcVVzVSa0xnxn6PgotXGbfZ/z65AS TMbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=a1eNCuSx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d4si6507945pfa.150.2019.01.16.05.49.00; Wed, 16 Jan 2019 05:49:15 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=a1eNCuSx; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390969AbfAOWG2 (ORCPT + 99 others); Tue, 15 Jan 2019 17:06:28 -0500 Received: from mail.kernel.org ([198.145.29.99]:49356 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390945AbfAOWGZ (ORCPT ); Tue, 15 Jan 2019 17:06:25 -0500 Received: from localhost.localdomain (c-98-220-238-81.hsd1.il.comcast.net [98.220.238.81]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 36B1820883; Tue, 15 Jan 2019 22:06:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1547589984; bh=KppqNc77V6wunJeAZwvtm5EINzmd5/iNQxABoCe0O68=; h=From:To:Cc:Subject:Date:In-Reply-To:References:In-Reply-To: References:From; b=a1eNCuSxLCALr3jnUuMaVGHNd677X4EeprzgVEKu8inBQXEYCYyqaFuBZ4bouVjHH RwT56osxB9zGlJglh8bgRer+LjKVswocsffdY5dqmYh7TVYu7PXMU5bS3FPSAObi6o dTbyF21YBxF/0iaRaCg0AXoRBkC8G9sVMJx9ocn8= From: Tom Zanussi To: rostedt@goodmis.org Cc: tglx@linutronix.de, mhiramat@kernel.org, namhyung@kernel.org, vedang.patel@intel.com, bigeasy@linutronix.de, joel@joelfernandes.org, mathieu.desnoyers@efficios.com, julia@ni.com, linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org Subject: [PATCH v12 09/16] tracing: Add hist trigger onchange() handler Date: Tue, 15 Jan 2019 16:05:53 -0600 Message-Id: <139e92988e631f57e4ad26f1e06db92f1811bf74.1547589128.git.tom.zanussi@linux.intel.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tom Zanussi Add support for a hist:onchange($var) handler, similar to the onmax() handler but triggering whenever there's any change in $var, not just a max. Signed-off-by: Tom Zanussi --- kernel/trace/trace.c | 3 ++- kernel/trace/trace_events_hist.c | 58 ++++++++++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index fcc0f1a963e3..917677a9bcaa 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4896,7 +4896,8 @@ static const char readme_msg[] = "\t .\n\n" "\t The available handlers are:\n\n" "\t onmatch(matching.event) - invoke on addition or update\n" - "\t onmax(var) - invoke if var exceeds current max\n\n" + "\t onmax(var) - invoke if var exceeds current max\n" + "\t onchange(var) - invoke action if var changes\n\n" "\t The available actions are:\n\n" "\t (param list) - generate synthetic event\n" "\t save(field,...) - save current event fields\n" diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 568729d7c599..c3358ad63052 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -398,6 +398,7 @@ typedef u64 (*get_track_val_fn_t) (struct hist_trigger_data *hist_data, enum handler_id { HANDLER_ONMATCH = 1, HANDLER_ONMAX, + HANDLER_ONCHANGE, }; enum action_id { @@ -1996,7 +1997,8 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs) return ret; if ((str_has_prefix(str, "onmatch(")) || - (str_has_prefix(str, "onmax("))) { + (str_has_prefix(str, "onmax(")) || + (str_has_prefix(str, "onchange("))) { attrs->action_str[attrs->n_actions] = kstrdup(str, GFP_KERNEL); if (!attrs->action_str[attrs->n_actions]) { ret = -ENOMEM; @@ -3488,6 +3490,14 @@ static bool check_track_val_max(u64 track_val, u64 var_val) return true; } +static bool check_track_val_changed(u64 track_val, u64 var_val) +{ + if (var_val == track_val) + return false; + + return true; +} + static u64 get_track_val_local(struct hist_trigger_data *hist_data, struct tracing_map_elt *elt, struct action_data *data) @@ -3664,6 +3674,8 @@ static void track_data_print(struct seq_file *m, if (data->handler == HANDLER_ONMAX) seq_printf(m, "\n\tmax: %10llu", track_val); + else if (data->handler == HANDLER_ONCHANGE) + seq_printf(m, "\n\tchanged: %10llu", track_val); if (data->action == ACTION_SNAPSHOT) return; @@ -3750,14 +3762,14 @@ static int track_data_create(struct hist_trigger_data *hist_data, track_data_var_str = data->track_data.var_str; if (track_data_var_str[0] != '$') { - hist_err("For onmax(x), x must be a variable: ", track_data_var_str); + hist_err("For onmax(x) or onchange(x), x must be a variable: ", track_data_var_str); return -EINVAL; } track_data_var_str++; var_field = find_target_event_var(hist_data, NULL, NULL, track_data_var_str); if (!var_field) { - hist_err("Couldn't find onmax variable: ", track_data_var_str); + hist_err("Couldn't find onmax or onchange variable: ", track_data_var_str); return -EINVAL; } @@ -3774,6 +3786,14 @@ static int track_data_create(struct hist_trigger_data *hist_data, ret = PTR_ERR(track_var); goto out; } + + if (data->handler == HANDLER_ONCHANGE) + track_var = create_var(hist_data, file, "__change", sizeof(u64), "u64"); + if (IS_ERR(track_var)) { + hist_err("Couldn't create onchange variable: ", "__change"); + ret = PTR_ERR(track_var); + goto out; + } data->track_data.track_var = track_var; ret = action_create(hist_data, data); @@ -3853,6 +3873,8 @@ static int action_parse(char *str, struct action_data *data, if (handler == HANDLER_ONMAX) data->track_data.check_val = check_track_val_max; + else if (handler == HANDLER_ONCHANGE) + data->track_data.check_val = check_track_val_changed; else { hist_err("action parsing: Handler doesn't support action: ", action_name); ret = -EINVAL; @@ -3877,6 +3899,8 @@ static int action_parse(char *str, struct action_data *data, if (handler == HANDLER_ONMAX) data->track_data.check_val = check_track_val_max; + else if (handler == HANDLER_ONCHANGE) + data->track_data.check_val = check_track_val_changed; else { hist_err("action parsing: Handler doesn't support action: ", action_name); ret = -EINVAL; @@ -3900,6 +3924,8 @@ static int action_parse(char *str, struct action_data *data, if (handler == HANDLER_ONMAX) data->track_data.check_val = check_track_val_max; + else if (handler == HANDLER_ONCHANGE) + data->track_data.check_val = check_track_val_changed; if (handler != HANDLER_ONMATCH) { data->track_data.save_val = save_track_val_local; @@ -4743,7 +4769,8 @@ static void destroy_actions(struct hist_trigger_data *hist_data) if (data->handler == HANDLER_ONMATCH) onmatch_destroy(data); - else if (data->handler == HANDLER_ONMAX) + else if (data->handler == HANDLER_ONMAX || + data->handler == HANDLER_ONCHANGE) track_data_destroy(hist_data, data); else kfree(data); @@ -4779,6 +4806,15 @@ static int parse_actions(struct hist_trigger_data *hist_data) ret = PTR_ERR(data); break; } + } else if ((len = str_has_prefix(str, "onchange("))) { + char *action_str = str + len; + + data = track_data_parse(hist_data, action_str, + HANDLER_ONCHANGE); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + break; + } } else { ret = -EINVAL; break; @@ -4803,7 +4839,8 @@ static int create_actions(struct hist_trigger_data *hist_data) ret = onmatch_create(hist_data, data); if (ret) break; - } else if (data->handler == HANDLER_ONMAX) { + } else if (data->handler == HANDLER_ONMAX || + data->handler == HANDLER_ONCHANGE) { ret = track_data_create(hist_data, data); if (ret) break; @@ -4831,7 +4868,8 @@ static void print_actions(struct seq_file *m, continue; } - if (data->handler == HANDLER_ONMAX) + if (data->handler == HANDLER_ONMAX || + data->handler == HANDLER_ONCHANGE) track_data_print(m, hist_data, elt, data); } } @@ -4863,6 +4901,8 @@ static void print_track_data_spec(struct seq_file *m, { if (data->handler == HANDLER_ONMAX) seq_puts(m, ":onmax("); + else if (data->handler == HANDLER_ONCHANGE) + seq_puts(m, ":onchange("); seq_printf(m, "%s", data->track_data.var_str); seq_printf(m, ").%s(", data->action_name); @@ -4920,7 +4960,8 @@ static bool actions_match(struct hist_trigger_data *hist_data, if (strcmp(data->match_data.event, data_test->match_data.event) != 0) return false; - } else if (data->handler == HANDLER_ONMAX) { + } else if (data->handler == HANDLER_ONMAX || + data->handler == HANDLER_ONCHANGE) { if (strcmp(data->track_data.var_str, data_test->track_data.var_str) != 0) return false; @@ -4941,7 +4982,8 @@ static void print_actions_spec(struct seq_file *m, if (data->handler == HANDLER_ONMATCH) print_onmatch_spec(m, hist_data, data); - else if (data->handler == HANDLER_ONMAX) + else if (data->handler == HANDLER_ONMAX || + data->handler == HANDLER_ONCHANGE) print_track_data_spec(m, hist_data, data); } } -- 2.14.1