All of lore.kernel.org
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: "Peter Zijlstra" <peterz@infradead.org>,
	"Ingo Molnar" <mingo@redhat.com>,
	"Arnaldo Carvalho de Melo" <acme@kernel.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Alexander Shishkin" <alexander.shishkin@linux.intel.com>,
	"Jiri Olsa" <jolsa@kernel.org>,
	"Adrian Hunter" <adrian.hunter@intel.com>,
	"Kan Liang" <kan.liang@linux.intel.com>,
	"John Garry" <john.g.garry@oracle.com>,
	"Will Deacon" <will@kernel.org>,
	"James Clark" <james.clark@linaro.org>,
	"Mike Leach" <mike.leach@linaro.org>,
	"Leo Yan" <leo.yan@linux.dev>,
	"Ravi Bangoria" <ravi.bangoria@amd.com>,
	"Weilin Wang" <weilin.wang@intel.com>,
	"Jing Zhang" <renyu.zj@linux.alibaba.com>,
	"Xu Yang" <xu.yang_2@nxp.com>,
	"Sandipan Das" <sandipan.das@amd.com>,
	"Benjamin Gray" <bgray@linux.ibm.com>,
	"Athira Jajeev" <atrajeev@linux.vnet.ibm.com>,
	"Howard Chu" <howardchu95@gmail.com>,
	"Dominique Martinet" <asmadeus@codewreck.org>,
	"Yang Jihong" <yangjihong@bytedance.com>,
	"Colin Ian King" <colin.i.king@gmail.com>,
	"Veronika Molnarova" <vmolnaro@redhat.com>,
	"Dr. David Alan Gilbert" <linux@treblig.org>,
	"Oliver Upton" <oliver.upton@linux.dev>,
	"Changbin Du" <changbin.du@huawei.com>,
	"Ze Gao" <zegao2021@gmail.com>, "Andi Kleen" <ak@linux.intel.com>,
	"Clément Le Goffic" <clement.legoffic@foss.st.com>,
	"Sun Haiyong" <sunhaiyong@loongson.cn>,
	"Junhao He" <hejunhao3@huawei.com>,
	"Tiezhu Yang" <yangtiezhu@loongson.cn>,
	"Yicong Yang" <yangyicong@hisilicon.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v1 12/15] perf tool_pmu: Switch to standard pmu functions and json descriptions
Date: Mon, 9 Sep 2024 22:47:17 -0700	[thread overview]
Message-ID: <Zt_dZdGCWwTtHRT1@google.com> (raw)
In-Reply-To: <20240907050830.6752-13-irogers@google.com>

On Fri, Sep 06, 2024 at 10:08:27PM -0700, Ian Rogers wrote:
> Use the regular PMU approaches with tool json events to reduce the
> amount of special tool_pmu code - tool_pmu__config_terms and
> tool_pmu__for_each_event_cb are removed. Some functions remain, like
> tool_pmu__str_to_event, as conveniences to metricgroups. Add
> tool_pmu__skip_event/tool_pmu__num_skip_events to handle the case that
> tool json events shouldn't appear on certain architectures. This isn't
> done in jevents.py due to complexity in the empty-pmu-events.c and
> when all vendor json is built into the tool.
> 
> Signed-off-by: Ian Rogers <irogers@google.com>
> ---
>  tools/perf/util/pmu.c      |  26 ++++-----
>  tools/perf/util/pmus.c     |   4 +-
>  tools/perf/util/tool_pmu.c | 111 ++++++++++++-------------------------
>  tools/perf/util/tool_pmu.h |  12 +---
>  4 files changed, 48 insertions(+), 105 deletions(-)
> 
> diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
> index a412c9c62f9c..5ff6556292fd 100644
> --- a/tools/perf/util/pmu.c
> +++ b/tools/perf/util/pmu.c
> @@ -1549,9 +1549,6 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
>  {
>  	bool zero = !!pmu->perf_event_attr_init_default;
>  
> -	if (perf_pmu__is_tool(pmu))
> -		return tool_pmu__config_terms(attr, head_terms, err);
> -
>  	/* Fake PMU doesn't have proper terms so nothing to configure in attr. */
>  	if (perf_pmu__is_fake(pmu))
>  		return 0;
> @@ -1664,8 +1661,8 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_
>  	info->scale    = 0.0;
>  	info->snapshot = false;
>  
> -	/* Tool/fake PMU doesn't rewrite terms. */
> -	if (perf_pmu__is_tool(pmu) || perf_pmu__is_fake(pmu))
> +	/* Fake PMU doesn't rewrite terms. */
> +	if (perf_pmu__is_fake(pmu))
>  		goto out;
>  
>  	list_for_each_entry_safe(term, h, &head_terms->terms, list) {
> @@ -1831,8 +1828,8 @@ bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name)
>  {
>  	if (!name)
>  		return false;
> -	if (perf_pmu__is_tool(pmu))
> -		return tool_pmu__str_to_event(name) != TOOL_PMU__EVENT_NONE;
> +	if (perf_pmu__is_tool(pmu) && tool_pmu__skip_event(name))
> +		return false;
>  	if (perf_pmu__find_alias(pmu, name, /*load=*/ true) != NULL)
>  		return true;
>  	if (pmu->cpu_aliases_added || !pmu->events_table)
> @@ -1844,9 +1841,6 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
>  {
>  	size_t nr;
>  
> -	if (perf_pmu__is_tool(pmu))
> -		return tool_pmu__num_events();
> -
>  	pmu_aliases_parse(pmu);
>  	nr = pmu->sysfs_aliases + pmu->sys_json_aliases;
>  
> @@ -1857,6 +1851,9 @@ size_t perf_pmu__num_events(struct perf_pmu *pmu)
>  	else
>  		assert(pmu->cpu_json_aliases == 0);
>  
> +	if (perf_pmu__is_tool(pmu))
> +		nr -= tool_pmu__num_skip_events();
> +
>  	return pmu->selectable ? nr + 1 : nr;
>  }
>  
> @@ -1907,15 +1904,15 @@ int perf_pmu__for_each_event(struct perf_pmu *pmu, bool skip_duplicate_pmus,
>  	int ret = 0;
>  	struct strbuf sb;
>  
> -	if (perf_pmu__is_tool(pmu))
> -		return tool_pmu__for_each_event_cb(pmu, state, cb);
> -
>  	strbuf_init(&sb, /*hint=*/ 0);
>  	pmu_aliases_parse(pmu);
>  	pmu_add_cpu_aliases(pmu);
>  	list_for_each_entry(event, &pmu->aliases, list) {
>  		size_t buf_used, pmu_name_len;
>  
> +		if (perf_pmu__is_tool(pmu) && tool_pmu__skip_event(event->name))
> +			continue;
> +
>  		info.pmu_name = event->pmu_name ?: pmu->name;
>  		pmu_name_len = pmu_deduped_name_len(pmu, info.pmu_name,
>  						    skip_duplicate_pmus);
> @@ -2321,9 +2318,6 @@ const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config)
>  	if (!pmu)
>  		return NULL;
>  
> -	if (perf_pmu__is_tool(pmu))
> -		return tool_pmu__event_to_str(config);
> -
>  	pmu_aliases_parse(pmu);
>  	pmu_add_cpu_aliases(pmu);
>  	list_for_each_entry(event, &pmu->aliases, list) {
> diff --git a/tools/perf/util/pmus.c b/tools/perf/util/pmus.c
> index 36329bc77316..19673b9991c6 100644
> --- a/tools/perf/util/pmus.c
> +++ b/tools/perf/util/pmus.c
> @@ -440,6 +440,7 @@ static int perf_pmus__print_pmu_events__callback(void *vstate,
>  		pr_err("Unexpected event %s/%s/\n", info->pmu->name, info->name);
>  		return 1;
>  	}
> +	assert(info->pmu != NULL || info->name != NULL);
>  	s = &state->aliases[state->index];
>  	s->pmu = info->pmu;
>  #define COPY_STR(str) s->str = info->str ? strdup(info->str) : NULL
> @@ -590,9 +591,6 @@ void perf_pmus__print_raw_pmu_events(const struct print_callbacks *print_cb, voi
>  		int len = pmu_name_len_no_suffix(pmu->name);
>  		const char *desc = "(see 'man perf-list' or 'man perf-record' on how to encode it)";
>  
> -		if (perf_pmu__is_tool(pmu))
> -			continue;
> -
>  		if (!pmu->is_core)
>  			desc = NULL;
>  
> diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
> index 3dc7cc7b8d32..f2d26e9e51f5 100644
> --- a/tools/perf/util/tool_pmu.c
> +++ b/tools/perf/util/tool_pmu.c
> @@ -33,101 +33,54 @@ static const char *const tool_pmu__event_names[TOOL_PMU__EVENT_MAX] = {
>  	"system_tsc_freq",
>  };
>  
> -
> -const char *tool_pmu__event_to_str(enum tool_pmu_event ev)
> -{
> -	if (ev > TOOL_PMU__EVENT_NONE && ev < TOOL_PMU__EVENT_MAX)
> -		return tool_pmu__event_names[ev];
> -
> -	return NULL;
> -}
> -
> -enum tool_pmu_event tool_pmu__str_to_event(const char *str)
> +bool tool_pmu__skip_event(const char *name)

I think you need __maybe_unused.


>  {
> -	int i;
> -
> -	tool_pmu__for_each_event(i) {
> -		if (!strcasecmp(str, tool_pmu__event_names[i])) {
>  #if !defined(__aarch64__)
> -			/* The slots event should only appear on arm64. */
> -			if (i == TOOL_PMU__EVENT_SLOTS)
> -				return TOOL_PMU__EVENT_NONE;
> +	/* The slots event should only appear on arm64. */
> +	if (strcasecmp(name, "slots") == 0)
> +		return true;
>  #endif
> -			return i;
> -		}
> -	}
> -	return TOOL_PMU__EVENT_NONE;
> +#if !defined(__i386__) && !defined(__x86_64__)
> +	/* The system_tsc_freq event should only appear on x86. */
> +	if (strcasecmp(name, "system_tsc_freq") == 0)
> +		return true;
> +#endif
> +	return false;
>  }
>  
> -static int tool_pmu__config_term(struct perf_event_attr *attr,
> -				 struct parse_events_term *term,
> -				 struct parse_events_error *err)
> +int tool_pmu__num_skip_events(void)
>  {
> -	if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) {
> -		enum tool_pmu_event ev = tool_pmu__str_to_event(term->config);
> +	int num = 0;
>  
> -		if (ev == TOOL_PMU__EVENT_NONE)
> -			goto err_out;
> -
> -		attr->config = ev;
> -		return 0;
> -	}
> -err_out:
> -	if (err) {
> -		char *err_str;
> -
> -		parse_events_error__handle(err, term->err_val,
> -					asprintf(&err_str,
> -						"unexpected tool event term (%s) %s",
> -						parse_events__term_type_str(term->type_term),
> -						term->config) < 0
> -					? strdup("unexpected tool event term")
> -					: err_str,
> -					NULL);
> -	}
> -	return -EINVAL;
> +#if !defined(__aarch64__)
> +	num++;
> +#endif
> +#if !defined(__i386__) && !defined(__x86_64__)
> +	num++;
> +#endif
> +	return num;
>  }
>  
> -int tool_pmu__config_terms(struct perf_event_attr *attr,
> -			   struct parse_events_terms *terms,
> -			   struct parse_events_error *err)
> +const char *tool_pmu__event_to_str(enum tool_pmu_event ev)
>  {
> -	struct parse_events_term *term;
> -
> -	list_for_each_entry(term, &terms->terms, list) {
> -		if (tool_pmu__config_term(attr, term, err))
> -			return -EINVAL;
> -	}
> -
> -	return 0;
> +	if (ev > TOOL_PMU__EVENT_NONE && ev < TOOL_PMU__EVENT_MAX)
> +		return tool_pmu__event_names[ev];
>  
> +	return NULL;
>  }
>  
> -int tool_pmu__for_each_event_cb(struct perf_pmu *pmu, void *state, pmu_event_callback cb)
> +enum tool_pmu_event tool_pmu__str_to_event(const char *str)
>  {
> -	struct pmu_event_info info = {
> -		.pmu = pmu,
> -		.event_type_desc = "Tool event",
> -	};
>  	int i;
>  
> +	if (tool_pmu__skip_event(str))
> +		return TOOL_PMU__EVENT_NONE;
> +
>  	tool_pmu__for_each_event(i) {
> -		int ret;
> -
> -		info.name = tool_pmu__event_to_str(i);
> -		info.alias = NULL;
> -		info.scale_unit = NULL;
> -		info.desc = NULL;
> -		info.long_desc = NULL;
> -		info.encoding_desc = NULL;
> -		info.topic = NULL;
> -		info.pmu_name = pmu->name;
> -		info.deprecated = false;
> -		ret = cb(state, &info);
> -		if (ret)
> -			return ret;
> +		if (!strcasecmp(str, tool_pmu__event_names[i]))
> +			return i;
>  	}
> -	return 0;
> +	return TOOL_PMU__EVENT_NONE;
>  }
>  
>  bool perf_pmu__is_tool(const struct perf_pmu *pmu)
> @@ -544,8 +497,12 @@ struct perf_pmu *perf_pmus__tool_pmu(void)
>  	static struct perf_pmu tool = {
>  		.name = "tool",
>  		.type = PERF_PMU_TYPE_TOOL,
> +		.aliases = LIST_HEAD_INIT(tool.aliases),
> +		.caps = LIST_HEAD_INIT(tool.caps),

This can be moved to the previous patch.

Thanks,
Namhyung


>  		.format = LIST_HEAD_INIT(tool.format),
>  	};
> +	if (!tool.events_table)
> +		tool.events_table = find_core_events_table("common", "common");
>  
>  	return &tool;
>  }
> diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h
> index ecdf316525bb..a60184859080 100644
> --- a/tools/perf/util/tool_pmu.h
> +++ b/tools/perf/util/tool_pmu.h
> @@ -29,17 +29,11 @@ enum tool_pmu_event {
>  #define tool_pmu__for_each_event(ev)					\
>  	for ((ev) = TOOL_PMU__EVENT_DURATION_TIME; (ev) < TOOL_PMU__EVENT_MAX; ev++)
>  
> -static inline size_t tool_pmu__num_events(void)
> -{
> -	return TOOL_PMU__EVENT_MAX - 1;
> -}
> -
>  const char *tool_pmu__event_to_str(enum tool_pmu_event ev);
>  enum tool_pmu_event tool_pmu__str_to_event(const char *str);
> -int tool_pmu__config_terms(struct perf_event_attr *attr,
> -			   struct parse_events_terms *terms,
> -			   struct parse_events_error *err);
> -int tool_pmu__for_each_event_cb(struct perf_pmu *pmu, void *state, pmu_event_callback cb);
> +bool tool_pmu__skip_event(const char *name);
> +int tool_pmu__num_skip_events(void);
> +
>  bool tool_pmu__read_event(enum tool_pmu_event ev, u64 *result);
>  
>  u64 tool_pmu__cpu_slots_per_cycle(void);
> -- 
> 2.46.0.469.g59c65b2a67-goog
> 

  reply	other threads:[~2024-09-10  5:47 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-07  5:08 [PATCH v1 00/15] Tool and hwmon PMUs Ian Rogers
2024-09-07  5:08 ` [PATCH v1 01/15] perf list: Avoid potential out of bounds memory read Ian Rogers
2024-09-11 14:26   ` Arnaldo Carvalho de Melo
2024-09-07  5:08 ` [PATCH v1 02/15] perf pmus: Fake PMU clean up Ian Rogers
2024-09-11 14:28   ` Arnaldo Carvalho de Melo
2024-09-07  5:08 ` [PATCH v1 03/15] perf evsel: Add accessor for tool_event Ian Rogers
2024-09-11 14:28   ` Arnaldo Carvalho de Melo
2024-09-07  5:08 ` [PATCH v1 04/15] perf pmu: To info add event_type_desc Ian Rogers
2024-09-07  5:08 ` [PATCH v1 05/15] perf pmu: Allow hardcoded terms to be applied to attributes Ian Rogers
2024-09-11 14:31   ` Arnaldo Carvalho de Melo
2024-09-07  5:08 ` [PATCH v1 06/15] perf parse-events: Expose/rename config_term_name Ian Rogers
2024-09-07  5:08 ` [PATCH v1 07/15] perf tool_pmu: Factor tool events into their own PMU Ian Rogers
2024-09-07  5:08 ` [PATCH v1 08/15] perf tool_pmu: Rename enum perf_tool_event to tool_pmu_event Ian Rogers
2024-09-07  5:08 ` [PATCH v1 09/15] perf tool_pmu: Rename perf_tool_event__* to tool_pmu__* Ian Rogers
2024-09-07  5:08 ` [PATCH v1 10/15] perf tool_pmu: Move expr literals to tool_pmu Ian Rogers
2024-09-07  5:08 ` [PATCH v1 11/15] perf jevents: Add tool event json under a common architecture Ian Rogers
2024-09-07  5:08 ` [PATCH v1 12/15] perf tool_pmu: Switch to standard pmu functions and json descriptions Ian Rogers
2024-09-10  5:47   ` Namhyung Kim [this message]
2024-09-07  5:08 ` [PATCH v1 13/15] perf tests: Add tool PMU test Ian Rogers
2024-09-10  5:50   ` Namhyung Kim
2024-09-10 15:59     ` Ian Rogers
2024-09-07  5:08 ` [PATCH v1 14/15] perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs Ian Rogers
2024-09-10  6:56   ` Namhyung Kim
2024-09-10 17:32     ` Ian Rogers
2024-09-07  5:08 ` [PATCH v1 15/15] perf docs: Document tool and hwmon events Ian Rogers
2024-09-10  2:21 ` [PATCH v1 00/15] Tool and hwmon PMUs Ian Rogers
2024-09-10  3:36   ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zt_dZdGCWwTtHRT1@google.com \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=asmadeus@codewreck.org \
    --cc=atrajeev@linux.vnet.ibm.com \
    --cc=bgray@linux.ibm.com \
    --cc=changbin.du@huawei.com \
    --cc=clement.legoffic@foss.st.com \
    --cc=colin.i.king@gmail.com \
    --cc=hejunhao3@huawei.com \
    --cc=howardchu95@gmail.com \
    --cc=irogers@google.com \
    --cc=james.clark@linaro.org \
    --cc=john.g.garry@oracle.com \
    --cc=jolsa@kernel.org \
    --cc=kan.liang@linux.intel.com \
    --cc=leo.yan@linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux@treblig.org \
    --cc=mark.rutland@arm.com \
    --cc=mike.leach@linaro.org \
    --cc=mingo@redhat.com \
    --cc=oliver.upton@linux.dev \
    --cc=peterz@infradead.org \
    --cc=ravi.bangoria@amd.com \
    --cc=renyu.zj@linux.alibaba.com \
    --cc=sandipan.das@amd.com \
    --cc=sunhaiyong@loongson.cn \
    --cc=vmolnaro@redhat.com \
    --cc=weilin.wang@intel.com \
    --cc=will@kernel.org \
    --cc=xu.yang_2@nxp.com \
    --cc=yangjihong@bytedance.com \
    --cc=yangtiezhu@loongson.cn \
    --cc=yangyicong@hisilicon.com \
    --cc=zegao2021@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.