Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp3541940ybz; Mon, 20 Apr 2020 05:00:48 -0700 (PDT) X-Google-Smtp-Source: APiQypLSEeSi1ieyFdCo1bzCQfC4klxQewQ/sKmoW2odoGaRJOvgwqs3Cdnaw9X7GHJA0MI1sutL X-Received: by 2002:a05:6402:1d23:: with SMTP id dh3mr12199825edb.349.1587384047909; Mon, 20 Apr 2020 05:00:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587384047; cv=none; d=google.com; s=arc-20160816; b=MMeaSN/Jc7OEU/+vdsvBIsfgpUue7+YZxpyOvZS+N7piovsIxK+4YsLFGxRhPWU9cX HxGV4rx6YZUzDWncOn3h1zPvvWL5EjFe7DspqvyrMLxnVr+ZpPD0VQKwDbXz2Rt1M8q/ 5lPjjYhse3jiiFy4W5+jN29IOEOshLsVu0jleqq5qm8SsAGn2ZHszuL7gnwIJfPtbeHZ mz4CJ7UFkhCCQzT2gKLEjNiHEGl3rM6tP0RrJiFt/AtxgpAmUvYoDN+U72giKcHkB2jS Rb4XDTGrX0p7IBs0M2K4nLY9G1oWoFQ09Rj3dfu8YFUIGwetXDwrJhBuIRP+uuIkjFz+ gVnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Bpg4Yan8oPY5reGMTLmUAOYPKaDuIRb/fDsFJMAcuIA=; b=yOaRYsjrEGa/EbL1ZGLA+GO7DvCFuVFjSZ7bREEl/VxA4MK51l93KNCIZElEvr+5X1 ZlRrmMuwbM17G3OMBmvjMZJF+pm6CxDUYPgX5D1a8FNCEt20iN0A2LKX+/NsR9FRI0YB ioEbR24KXWz4/Y7D/U2+dQzQ7jnplKLyI7DkUjem9ayAj3tpyWEJBFTj0YZ5mUPYR7fU e78brOkGbj0TSHTVcsScztSefXWfzxXhl0Kb9C/47azB/yk3heth4P5oLIVZEszCdYH4 rdTpXk47H6oOGqSaPFlmK4SciY5jrHWzGmBA8Mi0Zql8XpOpJWg26K09v+hddESIcWtO 7HVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=vwuHH9Fz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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. [23.128.96.18]) by mx.google.com with ESMTP id j23si362114ejt.284.2020.04.20.05.00.25; Mon, 20 Apr 2020 05:00:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=vwuHH9Fz; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1727095AbgDTL4j (ORCPT + 99 others); Mon, 20 Apr 2020 07:56:39 -0400 Received: from mail.kernel.org ([198.145.29.99]:41058 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726669AbgDTL4h (ORCPT ); Mon, 20 Apr 2020 07:56:37 -0400 Received: from quaco.ghostprotocols.net (unknown [179.97.37.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 88B4022244; Mon, 20 Apr 2020 11:56:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1587383797; bh=oeXufR3m5lGo/Bj0Liajd+NZNCf8JjESaNgUdj3xLmw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vwuHH9Fz1+Zpmd5LT4IooiHKLH2QZF8iuuT50cR6jh54dVaWxMGam74fnY9AQH69m FdYSm/wORN4UtyNSmAXp7Wh7Ozqjvjefg4rRk/JoQFrO1e+smH9sITmsAx6hn3qWyH 4Z/K6TNh2bth4G38zlwajJjHU9q9R7bMMRJEez68= From: Arnaldo Carvalho de Melo To: Ingo Molnar , Thomas Gleixner Cc: Jiri Olsa , Namhyung Kim , Clark Williams , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, Kan Liang , Andi Kleen , Jiri Olsa , Adrian Hunter , Alexey Budankov , Mathieu Poirier , Michael Ellerman , Pavel Gerasimov , Peter Zijlstra , Ravi Bangoria , Stephane Eranian , Vitaly Slobodskoy , Arnaldo Carvalho de Melo Subject: [PATCH 44/60] perf pmu: Add support for PMU capabilities Date: Mon, 20 Apr 2020 08:53:00 -0300 Message-Id: <20200420115316.18781-45-acme@kernel.org> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20200420115316.18781-1-acme@kernel.org> References: <20200420115316.18781-1-acme@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Kan Liang The PMU capabilities information, which is located at /sys/bus/event_source/devices//caps, is required by perf tool. For example, the max LBR information is required to stitch LBR call stack. Add perf_pmu__caps_parse() to parse the PMU capabilities information. The information is stored in a list. The following patch will store the capabilities information in perf header. Committer notes: Here's an example of such directories and its files in an i5 7th gen machine: [root@seventh ~]# ls -lad /sys/bus/event_source/devices/*/caps drwxr-xr-x. 2 root root 0 Apr 14 13:33 /sys/bus/event_source/devices/cpu/caps drwxr-xr-x. 2 root root 0 Apr 14 13:33 /sys/bus/event_source/devices/intel_pt/caps [root@seventh ~]# ls -la /sys/bus/event_source/devices/intel_pt/caps total 0 drwxr-xr-x. 2 root root 0 Apr 14 13:33 . drwxr-xr-x. 5 root root 0 Apr 14 13:12 .. -r--r--r--. 1 root root 4096 Apr 16 13:10 cr3_filtering -r--r--r--. 1 root root 4096 Apr 16 11:42 cycle_thresholds -r--r--r--. 1 root root 4096 Apr 16 13:10 ip_filtering -r--r--r--. 1 root root 4096 Apr 16 13:10 max_subleaf -r--r--r--. 1 root root 4096 Apr 14 13:33 mtc -r--r--r--. 1 root root 4096 Apr 14 13:33 mtc_periods -r--r--r--. 1 root root 4096 Apr 16 13:10 num_address_ranges -r--r--r--. 1 root root 4096 Apr 16 13:10 output_subsys -r--r--r--. 1 root root 4096 Apr 16 13:10 payloads_lip -r--r--r--. 1 root root 4096 Apr 16 13:10 power_event_trace -r--r--r--. 1 root root 4096 Apr 14 13:33 psb_cyc -r--r--r--. 1 root root 4096 Apr 14 13:33 psb_periods -r--r--r--. 1 root root 4096 Apr 16 13:10 ptwrite -r--r--r--. 1 root root 4096 Apr 16 13:10 single_range_output -r--r--r--. 1 root root 4096 Apr 16 12:03 topa_multiple_entries -r--r--r--. 1 root root 4096 Apr 16 13:10 topa_output [root@seventh ~]# cat /sys/bus/event_source/devices/intel_pt/caps/topa_output 1 [root@seventh ~]# cat /sys/bus/event_source/devices/intel_pt/caps/topa_multiple_entries 1 [root@seventh ~]# cat /sys/bus/event_source/devices/intel_pt/caps/mtc 1 [root@seventh ~]# cat /sys/bus/event_source/devices/intel_pt/caps/power_event_trace 0 [root@seventh ~]# [root@seventh ~]# ls -la /sys/bus/event_source/devices/cpu/caps/ total 0 drwxr-xr-x. 2 root root 0 Apr 14 13:33 . drwxr-xr-x. 6 root root 0 Apr 14 13:12 .. -r--r--r--. 1 root root 4096 Apr 16 13:10 branches -r--r--r--. 1 root root 4096 Apr 14 13:33 max_precise -r--r--r--. 1 root root 4096 Apr 16 13:10 pmu_name [root@seventh ~]# cat /sys/bus/event_source/devices/cpu/caps/max_precise 3 [root@seventh ~]# cat /sys/bus/event_source/devices/cpu/caps/branches 32 [root@seventh ~]# cat /sys/bus/event_source/devices/cpu/caps/pmu_name skylake [root@seventh ~]# Wow, first time I've heard about /sys/bus/event_source/devices/cpu/caps/max_precise, I think I'll use it! :-) Signed-off-by: Kan Liang Reviewed-by: Andi Kleen Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Alexey Budankov Cc: Mathieu Poirier Cc: Michael Ellerman Cc: Namhyung Kim Cc: Pavel Gerasimov Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Stephane Eranian Cc: Vitaly Slobodskoy Link: http://lore.kernel.org/lkml/20200319202517.23423-2-kan.liang@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 82 +++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/pmu.h | 9 +++++ 2 files changed, 91 insertions(+) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index bc912a84b5e9..d9f89ed18dea 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -850,6 +850,7 @@ static struct perf_pmu *pmu_lookup(const char *name) INIT_LIST_HEAD(&pmu->format); INIT_LIST_HEAD(&pmu->aliases); + INIT_LIST_HEAD(&pmu->caps); list_splice(&format, &pmu->format); list_splice(&aliases, &pmu->aliases); list_add_tail(&pmu->list, &pmus); @@ -1594,3 +1595,84 @@ int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, va_end(args); return ret; } + +static int perf_pmu__new_caps(struct list_head *list, char *name, char *value) +{ + struct perf_pmu_caps *caps = zalloc(sizeof(*caps)); + + if (!caps) + return -ENOMEM; + + caps->name = strdup(name); + if (!caps->name) + goto free_caps; + caps->value = strndup(value, strlen(value) - 1); + if (!caps->value) + goto free_name; + list_add_tail(&caps->list, list); + return 0; + +free_name: + zfree(caps->name); +free_caps: + free(caps); + + return -ENOMEM; +} + +/* + * Reading/parsing the given pmu capabilities, which should be located at: + * /sys/bus/event_source/devices//caps as sysfs group attributes. + * Return the number of capabilities + */ +int perf_pmu__caps_parse(struct perf_pmu *pmu) +{ + struct stat st; + char caps_path[PATH_MAX]; + const char *sysfs = sysfs__mountpoint(); + DIR *caps_dir; + struct dirent *evt_ent; + int nr_caps = 0; + + if (!sysfs) + return -1; + + snprintf(caps_path, PATH_MAX, + "%s" EVENT_SOURCE_DEVICE_PATH "%s/caps", sysfs, pmu->name); + + if (stat(caps_path, &st) < 0) + return 0; /* no error if caps does not exist */ + + caps_dir = opendir(caps_path); + if (!caps_dir) + return -EINVAL; + + while ((evt_ent = readdir(caps_dir)) != NULL) { + char path[PATH_MAX + NAME_MAX + 1]; + char *name = evt_ent->d_name; + char value[128]; + FILE *file; + + if (!strcmp(name, ".") || !strcmp(name, "..")) + continue; + + snprintf(path, sizeof(path), "%s/%s", caps_path, name); + + file = fopen(path, "r"); + if (!file) + continue; + + if (!fgets(value, sizeof(value), file) || + (perf_pmu__new_caps(&pmu->caps, name, value) < 0)) { + fclose(file); + continue; + } + + nr_caps++; + fclose(file); + } + + closedir(caps_dir); + + return nr_caps; +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 5fb3f16828df..1edd214b75a5 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -22,6 +22,12 @@ enum { struct perf_event_attr; +struct perf_pmu_caps { + char *name; + char *value; + struct list_head list; +}; + struct perf_pmu { char *name; __u32 type; @@ -33,6 +39,7 @@ struct perf_pmu { struct perf_cpu_map *cpus; struct list_head format; /* HEAD struct perf_pmu_format -> list */ struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ + struct list_head caps; /* HEAD struct perf_pmu_caps -> list */ struct list_head list; /* ELEM */ }; @@ -107,4 +114,6 @@ bool pmu_uncore_alias_match(const char *pmu_name, const char *name); int perf_pmu__convert_scale(const char *scale, char **end, double *sval); +int perf_pmu__caps_parse(struct perf_pmu *pmu); + #endif /* __PMU_H */ -- 2.21.1