[PATCH 2/6] perf tools: Helper functions to enumerate and probe PCI devices
From: roman . sudarikov
Date: Tue Nov 26 2019 - 11:36:46 EST
From: Roman Sudarikov <roman.sudarikov@xxxxxxxxxxxxxxx>
This makes aggregation of performance data per I/O device
available in the perf user tools.
Signed-off-by: Roman Sudarikov <roman.sudarikov@xxxxxxxxxxxxxxx>
Co-developed-by: Alexander Antonov <alexander.antonov@xxxxxxxxx>
Signed-off-by: Alexander Antonov <alexander.antonov@xxxxxxxxx>
---
tools/perf/util/Build | 1 +
tools/perf/util/pci.c | 53 +++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/pci.h | 23 +++++++++++++++++++
3 files changed, 77 insertions(+)
create mode 100644 tools/perf/util/pci.c
create mode 100644 tools/perf/util/pci.h
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 8dcfca1a882f..02b699f8a10a 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -23,6 +23,7 @@ perf-y += memswap.o
perf-y += parse-events.o
perf-y += perf_regs.o
perf-y += path.o
+perf-y += pci.o
perf-y += print_binary.o
perf-y += rlimit.o
perf-y += argv_split.o
diff --git a/tools/perf/util/pci.c b/tools/perf/util/pci.c
new file mode 100644
index 000000000000..ba1a48e9d0cc
--- /dev/null
+++ b/tools/perf/util/pci.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helper functions to access PCI CFG space.
+ *
+ * Copyright (C) 2019, Intel Corporation
+ *
+ * Authors: Roman Sudarikov <roman.sudarikov@xxxxxxxxx>
+ * Alexander Antonov <alexander.antonov@xxxxxxxxx>
+ */
+#include "pci.h"
+#include <api/fs/fs.h>
+#include <linux/kernel.h>
+#include <string.h>
+#include <unistd.h>
+
+#define PCI_DEVICE_PATH_TEMPLATE "bus/pci/devices/0000:%02x:%02x.0"
+#define PCI_DEVICE_FILE_TEMPLATE PCI_DEVICE_PATH_TEMPLATE"/%s"
+
+static bool directory_exists(const char * const path)
+{
+ return (access(path, F_OK) == 0);
+}
+
+bool pci_device_probe(struct bdf bdf)
+{
+ char path[PATH_MAX];
+
+ scnprintf(path, PATH_MAX, "%s/"PCI_DEVICE_PATH_TEMPLATE,
+ sysfs__mountpoint(), bdf.busno, bdf.devno);
+ return directory_exists(path);
+}
+
+bool is_pci_device_root_port(struct bdf bdf, u8 *secondary, u8 *subordinate)
+{
+ char path[PATH_MAX];
+ int secondary_interim;
+ int subordinate_interim;
+
+ scnprintf(path, PATH_MAX, PCI_DEVICE_FILE_TEMPLATE,
+ bdf.busno, bdf.devno, "secondary_bus_number");
+ if (!sysfs__read_int(path, &secondary_interim)) {
+ scnprintf(path, PATH_MAX, PCI_DEVICE_FILE_TEMPLATE,
+ bdf.busno, bdf.devno, "subordinate_bus_number");
+ if (!sysfs__read_int(path, &subordinate_interim)) {
+ if (secondary)
+ *secondary = (u8)secondary_interim;
+ if (subordinate)
+ *subordinate = (u8)subordinate_interim;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/tools/perf/util/pci.h b/tools/perf/util/pci.h
new file mode 100644
index 000000000000..e963b12e10e7
--- /dev/null
+++ b/tools/perf/util/pci.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0*/
+/*
+ *
+ * Copyright (C) 2019, Intel Corporation
+ *
+ * Authors: Roman Sudarikov <roman.sudarikov@xxxxxxxxx>
+ * Alexander Antonov <alexander.antonov@xxxxxxxxx>
+ */
+#ifndef _PCI_H
+#define _PCI_H
+
+#include <linux/types.h>
+
+struct bdf {
+ u8 busno;
+ u8 devno;
+ u8 funcno;
+};
+
+bool pci_device_probe(struct bdf bdf);
+bool is_pci_device_root_port(struct bdf bdf, u8 *secondary, u8 *subordinate);
+
+#endif /* _PCI_H */
--
2.19.1