Commit 724142f8 authored by Wu Hao's avatar Wu Hao Committed by Greg Kroah-Hartman

fpga: dfl: fme: add performance reporting support

This patch adds support for performance reporting private feature
for FPGA Management Engine (FME). Now it supports several different
performance counters, including 'basic', 'cache', 'fabric', 'vtd'
and 'vtd_sip'. It allows user to use standard linux tools to access
these performance counters.

e.g. List all events by "perf list"

  perf list | grep fme

  dfl_fme0/cache_read_hit/                     [Kernel PMU event]
  dfl_fme0/cache_read_miss/                    [Kernel PMU event]
  ...

  dfl_fme0/fab_mmio_read/                      [Kernel PMU event]
  dfl_fme0/fab_mmio_write/                     [Kernel PMU event]
  ...

  dfl_fme0/fab_port_mmio_read,portid=?/        [Kernel PMU event]
  dfl_fme0/fab_port_mmio_write,portid=?/       [Kernel PMU event]
  ...

  dfl_fme0/vtd_port_devtlb_1g_fill,portid=?/   [Kernel PMU event]
  dfl_fme0/vtd_port_devtlb_2m_fill,portid=?/   [Kernel PMU event]
  ...

  dfl_fme0/vtd_sip_iotlb_1g_hit/               [Kernel PMU event]
  dfl_fme0/vtd_sip_iotlb_1g_miss/              [Kernel PMU event]
  ...

  dfl_fme0/clock                               [Kernel PMU event]
  ...

e.g. check increased counter value after run one application using
"perf stat" command.

 perf stat -e dfl_fme0/fab_mmio_read/,dfl_fme0/fab_mmio_write/ ./test

 Performance counter stats for './test':

                 1      dfl_fme0/fab_mmio_read/
                 2      dfl_fme0/fab_mmio_write/

       1.009496520 seconds time elapsed

Please note that fabric counters support both fab_* and fab_port_*, but
actually they are sharing one set of performance counters in hardware.
If user wants to monitor overall data events on fab_* then fab_port_*
can't be supported at the same time, see example below:

perf stat -e dfl_fme0/fab_mmio_read/,dfl_fme0/fab_port_mmio_write,portid=0/

 Performance counter stats for 'system wide':

                 0      dfl_fme0/fab_mmio_read/
   <not supported>      dfl_fme0/fab_port_mmio_write,portid=0/

       2.141064085 seconds time elapsed
Signed-off-by: default avatarLuwei Kang <luwei.kang@intel.com>
Signed-off-by: default avatarXu Yilun <yilun.xu@intel.com>
Signed-off-by: default avatarWu Hao <hao.wu@intel.com>
Link: https://lore.kernel.org/r/1587949583-12058-3-git-send-email-hao.wu@intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1f03ac94
What: /sys/bus/event_source/devices/dfl_fmeX/format
Date: April 2020
KernelVersion: 5.8
Contact: Wu Hao <hao.wu@intel.com>
Description: Read-only. Attribute group to describe the magic bits
that go into perf_event_attr.config for a particular pmu.
(See ABI/testing/sysfs-bus-event_source-devices-format).
Each attribute under this group defines a bit range of the
perf_event_attr.config. All supported attributes are listed
below.
event = "config:0-11" - event ID
evtype = "config:12-15" - event type
portid = "config:16-23" - event source
For example,
fab_mmio_read = "event=0x06,evtype=0x02,portid=0xff"
It shows this fab_mmio_read is a fabric type (0x02) event with
0x06 local event id for overall monitoring (portid=0xff).
What: /sys/bus/event_source/devices/dfl_fmeX/cpumask
Date: April 2020
KernelVersion: 5.8
Contact: Wu Hao <hao.wu@intel.com>
Description: Read-only. This file always returns cpu which the PMU is bound
for access to all fme pmu performance monitoring events.
What: /sys/bus/event_source/devices/dfl_fmeX/events
Date: April 2020
KernelVersion: 5.8
Contact: Wu Hao <hao.wu@intel.com>
Description: Read-only. Attribute group to describe performance monitoring
events specific to fme. Each attribute in this group describes
a single performance monitoring event supported by this fme pmu.
The name of the file is the name of the event.
(See ABI/testing/sysfs-bus-event_source-devices-events).
All supported performance monitoring events are listed below.
Basic events (evtype=0x00)
clock = "event=0x00,evtype=0x00,portid=0xff"
Cache events (evtype=0x01)
cache_read_hit = "event=0x00,evtype=0x01,portid=0xff"
cache_read_miss = "event=0x01,evtype=0x01,portid=0xff"
cache_write_hit = "event=0x02,evtype=0x01,portid=0xff"
cache_write_miss = "event=0x03,evtype=0x01,portid=0xff"
cache_hold_request = "event=0x05,evtype=0x01,portid=0xff"
cache_data_write_port_contention =
"event=0x06,evtype=0x01,portid=0xff"
cache_tag_write_port_contention =
"event=0x07,evtype=0x01,portid=0xff"
cache_tx_req_stall = "event=0x08,evtype=0x01,portid=0xff"
cache_rx_req_stall = "event=0x09,evtype=0x01,portid=0xff"
cache_eviction = "event=0x0a,evtype=0x01,portid=0xff"
Fabric events (evtype=0x02)
fab_pcie0_read = "event=0x00,evtype=0x02,portid=0xff"
fab_pcie0_write = "event=0x01,evtype=0x02,portid=0xff"
fab_pcie1_read = "event=0x02,evtype=0x02,portid=0xff"
fab_pcie1_write = "event=0x03,evtype=0x02,portid=0xff"
fab_upi_read = "event=0x04,evtype=0x02,portid=0xff"
fab_upi_write = "event=0x05,evtype=0x02,portid=0xff"
fab_mmio_read = "event=0x06,evtype=0x02,portid=0xff"
fab_mmio_write = "event=0x07,evtype=0x02,portid=0xff"
fab_port_pcie0_read = "event=0x00,evtype=0x02,portid=?"
fab_port_pcie0_write = "event=0x01,evtype=0x02,portid=?"
fab_port_pcie1_read = "event=0x02,evtype=0x02,portid=?"
fab_port_pcie1_write = "event=0x03,evtype=0x02,portid=?"
fab_port_upi_read = "event=0x04,evtype=0x02,portid=?"
fab_port_upi_write = "event=0x05,evtype=0x02,portid=?"
fab_port_mmio_read = "event=0x06,evtype=0x02,portid=?"
fab_port_mmio_write = "event=0x07,evtype=0x02,portid=?"
VTD events (evtype=0x03)
vtd_port_read_transaction = "event=0x00,evtype=0x03,portid=?"
vtd_port_write_transaction = "event=0x01,evtype=0x03,portid=?"
vtd_port_devtlb_read_hit = "event=0x02,evtype=0x03,portid=?"
vtd_port_devtlb_write_hit = "event=0x03,evtype=0x03,portid=?"
vtd_port_devtlb_4k_fill = "event=0x04,evtype=0x03,portid=?"
vtd_port_devtlb_2m_fill = "event=0x05,evtype=0x03,portid=?"
vtd_port_devtlb_1g_fill = "event=0x06,evtype=0x03,portid=?"
VTD SIP events (evtype=0x04)
vtd_sip_iotlb_4k_hit = "event=0x00,evtype=0x04,portid=0xff"
vtd_sip_iotlb_2m_hit = "event=0x01,evtype=0x04,portid=0xff"
vtd_sip_iotlb_1g_hit = "event=0x02,evtype=0x04,portid=0xff"
vtd_sip_slpwc_l3_hit = "event=0x03,evtype=0x04,portid=0xff"
vtd_sip_slpwc_l4_hit = "event=0x04,evtype=0x04,portid=0xff"
vtd_sip_rcc_hit = "event=0x05,evtype=0x04,portid=0xff"
vtd_sip_iotlb_4k_miss = "event=0x06,evtype=0x04,portid=0xff"
vtd_sip_iotlb_2m_miss = "event=0x07,evtype=0x04,portid=0xff"
vtd_sip_iotlb_1g_miss = "event=0x08,evtype=0x04,portid=0xff"
vtd_sip_slpwc_l3_miss = "event=0x09,evtype=0x04,portid=0xff"
vtd_sip_slpwc_l4_miss = "event=0x0a,evtype=0x04,portid=0xff"
vtd_sip_rcc_miss = "event=0x0b,evtype=0x04,portid=0xff"
...@@ -156,7 +156,7 @@ config FPGA_DFL ...@@ -156,7 +156,7 @@ config FPGA_DFL
config FPGA_DFL_FME config FPGA_DFL_FME
tristate "FPGA DFL FME Driver" tristate "FPGA DFL FME Driver"
depends on FPGA_DFL && HWMON depends on FPGA_DFL && HWMON && PERF_EVENTS
help help
The FPGA Management Engine (FME) is a feature device implemented The FPGA Management Engine (FME) is a feature device implemented
under Device Feature List (DFL) framework. Select this option to under Device Feature List (DFL) framework. Select this option to
......
...@@ -40,6 +40,7 @@ obj-$(CONFIG_FPGA_DFL_FME_REGION) += dfl-fme-region.o ...@@ -40,6 +40,7 @@ obj-$(CONFIG_FPGA_DFL_FME_REGION) += dfl-fme-region.o
obj-$(CONFIG_FPGA_DFL_AFU) += dfl-afu.o obj-$(CONFIG_FPGA_DFL_AFU) += dfl-afu.o
dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o dfl-fme-error.o dfl-fme-objs := dfl-fme-main.o dfl-fme-pr.o dfl-fme-error.o
dfl-fme-objs += dfl-fme-perf.o
dfl-afu-objs := dfl-afu-main.o dfl-afu-region.o dfl-afu-dma-region.o dfl-afu-objs := dfl-afu-main.o dfl-afu-region.o dfl-afu-dma-region.o
dfl-afu-objs += dfl-afu-error.o dfl-afu-objs += dfl-afu-error.o
......
...@@ -579,6 +579,10 @@ static struct dfl_feature_driver fme_feature_drvs[] = { ...@@ -579,6 +579,10 @@ static struct dfl_feature_driver fme_feature_drvs[] = {
.id_table = fme_power_mgmt_id_table, .id_table = fme_power_mgmt_id_table,
.ops = &fme_power_mgmt_ops, .ops = &fme_power_mgmt_ops,
}, },
{
.id_table = fme_perf_id_table,
.ops = &fme_perf_ops,
},
{ {
.ops = NULL, .ops = NULL,
}, },
......
This diff is collapsed.
...@@ -38,5 +38,7 @@ extern const struct dfl_feature_id fme_pr_mgmt_id_table[]; ...@@ -38,5 +38,7 @@ extern const struct dfl_feature_id fme_pr_mgmt_id_table[];
extern const struct dfl_feature_ops fme_global_err_ops; extern const struct dfl_feature_ops fme_global_err_ops;
extern const struct dfl_feature_id fme_global_err_id_table[]; extern const struct dfl_feature_id fme_global_err_id_table[];
extern const struct attribute_group fme_global_err_group; extern const struct attribute_group fme_global_err_group;
extern const struct dfl_feature_ops fme_perf_ops;
extern const struct dfl_feature_id fme_perf_id_table[];
#endif /* __DFL_FME_H */ #endif /* __DFL_FME_H */
...@@ -197,12 +197,14 @@ struct dfl_feature_driver { ...@@ -197,12 +197,14 @@ struct dfl_feature_driver {
* feature dev (platform device)'s reources. * feature dev (platform device)'s reources.
* @ioaddr: mapped mmio resource address. * @ioaddr: mapped mmio resource address.
* @ops: ops of this sub feature. * @ops: ops of this sub feature.
* @priv: priv data of this feature.
*/ */
struct dfl_feature { struct dfl_feature {
u64 id; u64 id;
int resource_index; int resource_index;
void __iomem *ioaddr; void __iomem *ioaddr;
const struct dfl_feature_ops *ops; const struct dfl_feature_ops *ops;
void *priv;
}; };
#define DEV_STATUS_IN_USE 0 #define DEV_STATUS_IN_USE 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment