!1262 Add support for hisilicon uncore pmu drivers
From: @barbo Reviewed-by: @youngersun, @SuperSix173, @Lostwayzxc Signed-off-by: @zhang-changzhong
This commit is contained in:
commit
dfcc1aecd7
59
kernel.spec
59
kernel.spec
@ -32,7 +32,7 @@
|
||||
|
||||
Name: kernel
|
||||
Version: 4.19.90
|
||||
Release: %{hulkrelease}.0230
|
||||
Release: %{hulkrelease}.0231
|
||||
Summary: Linux Kernel
|
||||
License: GPLv2
|
||||
URL: http://www.kernel.org/
|
||||
@ -832,6 +832,63 @@ fi
|
||||
|
||||
%changelog
|
||||
|
||||
* Wed Nov 1 2023 hongrongxuan <hongrongxuan@huawei.com> - 4.19.90-2311.1.0.0231
|
||||
- perf/smmuv3: Add MODULE_ALIAS for module auto loading
|
||||
- perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09
|
||||
- perf/smmuv3: Enable HiSilicon Erratum 162001800 quirk
|
||||
- Revert "perf/smmuv3_pmu: Enable HiSilicon Erratum 162001800 quirk"
|
||||
- drivers/perf: hisi: add NULL check for name
|
||||
- drivers/perf: hisi: Remove redundant initialized of pmu->name
|
||||
- drivers/perf: hisi: Extract initialization of "cpa_pmu->pmu"
|
||||
- drivers/perf: hisi: Simplify the parameters of hisi_pmu_init()
|
||||
- drivers/perf: hisi: Advertise the PERF_PMU_CAP_NO_EXCLUDE capability
|
||||
- perf: hisi: Extract hisi_pmu_init
|
||||
- perf: hisi: Add configs for PMU isolation
|
||||
- perf: hisi: Fix read sccl_id and ccl_id error in TSV200
|
||||
- drivers/perf: fixed kabi broken for SLLC and PA PMU
|
||||
- drivers/perf: fixed the issue that the kabi value changed
|
||||
- drivers/perf: hisi: Don't migrate perf to the CPU going to teardown
|
||||
- drivers/perf: hisi: Add TLP filter support
|
||||
- docs: perf: Fix PMU instance name of hisi-pcie-pmu
|
||||
- docs: fix 'make htmldocs' warning in perf
|
||||
- docs: perf: Address some html build warnings
|
||||
- docs: perf: Add description for HiSilicon PCIe PMU driver
|
||||
- docs: perf: Add new description on HiSilicon uncore PMU v2
|
||||
- docs: perf: move to the admin-guide
|
||||
- drivers/perf: hisi: Fix some event id for hisi-pcie-pmu
|
||||
- drivers/perf: hisi: Add Support for CPA PMU
|
||||
- driver/perf: hisi: fix kabi broken for struct hisi_pmu
|
||||
- drivers/perf: hisi: Associate PMUs in SICL with CPUs online
|
||||
- drivers/perf: hisi: Add driver for HiSilicon PCIe PMU
|
||||
- PCI: Add pci_dev_id() helper
|
||||
- perf: hisi: Fix unexpected modifications in hisi_uncore_l3c_pmu.c
|
||||
- perf: hisi: Add support for HiSilicon SoC LPDDRC PMU
|
||||
- perf: hisi: Add support for HiSilicon SoC L3T PMU
|
||||
- perf: hisi: Fix read sccl_id and ccl_id error in some platform
|
||||
- perf: hisi: Make irq shared
|
||||
- drivers/perf: hisi: Fix data source control
|
||||
- perf/hisi: Use irq_set_affinity()
|
||||
- drivers/perf: hisi: Add support for HiSilicon PA PMU driver
|
||||
- drivers/perf: hisi: Add support for HiSilicon SLLC PMU driver
|
||||
- drivers/perf: hisi: Update DDRC PMU for programmable counter
|
||||
- drivers/perf: hisi: Add new functions for HHA PMU
|
||||
- drivers/perf: hisi: Add new functions for L3C PMU
|
||||
- drivers/perf: hisi: Add PMU version for uncore PMU drivers.
|
||||
- drivers/perf: hisi: Refactor code for more uncore PMUs
|
||||
- drivers/perf: hisi: Remove unnecessary check of counter index
|
||||
- drivers/perf: hisi: Add identifier sysfs file
|
||||
- perf: hisi: use devm_platform_ioremap_resource() to simplify code
|
||||
- drivers: provide devm_platform_ioremap_resource()
|
||||
- For drivers that do not support context exclusion let's advertise the PERF_PMU_CAP_NO_EXCLUDE capability. This ensures that perf will prevent us from handling events where any exclusion flags are set. Let's also remove the now unnecessary check for exclusion flags.
|
||||
- drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling
|
||||
- docs: perf: convert to ReST
|
||||
- Revert "perf: hisi: remove duplicated code"
|
||||
- Revert "drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling"
|
||||
- Revert "perf: hisi: Add support for HiSilicon SoC PMU driver dt probe"
|
||||
- Revert "perf: hisi: Add support for HiSilicon SoC LPDDRC PMU driver"
|
||||
- Revert "perf: hisi: Add support for HiSilicon SoC L3T PMU driver"
|
||||
- Revert "perf: hisi: Fix compile error if defined MODULE"
|
||||
|
||||
* Wed Nov 1 2023 Luo Shengwei <luoshengwei@huawei.com> - 4.19.90-2311.1.0.0230
|
||||
- !2609 Fix CVE-2023-5717
|
||||
- !2588 [openEuler-1.0-LTS] Add Phytium Display Engine support.
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
From 6f28c899df9750b13fdc86b9b3bb80d46aa89c8d Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 14:58:04 +0800
|
||||
Subject: [PATCH 01/55] Revert "perf: hisi: Fix compile error if defined
|
||||
MODULE"
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
This reverts commit f00917fa81207962a5455e1084c90aff36b3a6ae.
|
||||
|
||||
This bugfix fixed in higher verison in L3t pmu driver, inclusion it later.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
index ca395252ccc3..8f8b211788e0 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
@@ -241,7 +241,7 @@ static int hisi_lpddrc_pmu_init_irq(struct hisi_pmu *lpddrc_pmu,
|
||||
static const struct of_device_id lpddrc_of_match[] = {
|
||||
{ .compatible = "hisilicon,lpddrc-pmu", },
|
||||
{},
|
||||
-};
|
||||
+}
|
||||
MODULE_DEVICE_TABLE(of, lpddrc_of_match);
|
||||
|
||||
static int hisi_lpddrc_pmu_init_data(struct platform_device *pdev,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,480 @@
|
||||
From 7cd21a232cb93ea0598386c028c88e1931946887 Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 15:03:16 +0800
|
||||
Subject: [PATCH 02/55] Revert "perf: hisi: Add support for HiSilicon SoC L3T
|
||||
PMU driver"
|
||||
|
||||
driver inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
------------------------------------------------------------
|
||||
|
||||
This reverts commit 72ed85332d7704ab91afe3f14ab95b39fca17e97.
|
||||
|
||||
Now, revert it, then we will inclusion the newer version of L3T PMU
|
||||
driver.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/hisilicon/Makefile
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 7 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c | 432 -------------------
|
||||
2 files changed, 1 insertion(+), 438 deletions(-)
|
||||
delete mode 100644 drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 63942ae6b167..3651f18260e5 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1,6 +1 @@
|
||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o \
|
||||
- hisi_uncore_l3c_pmu.o \
|
||||
- hisi_uncore_hha_pmu.o \
|
||||
- hisi_uncore_ddrc_pmu.o \
|
||||
- hisi_uncore_lpddrc_pmu.o \
|
||||
- hisi_uncore_l3t_pmu.o
|
||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_lpddrc_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
deleted file mode 100644
|
||||
index bd4e600e0c32..000000000000
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
+++ /dev/null
|
||||
@@ -1,432 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0
|
||||
-/*
|
||||
- * HiSilicon SoC L3T uncore Hardware event counters support
|
||||
- *
|
||||
- * Copyright (C) 2021 Hisilicon Limited
|
||||
- * Author: Fang Lijun <fanglijun3@huawei.com>
|
||||
- * Anurup M <anurup.m@huawei.com>
|
||||
- * Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
- *
|
||||
- * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
- *
|
||||
- * This program is free software; you can redistribute it and/or modify
|
||||
- * it under the terms of the GNU General Public License version 2 as
|
||||
- * published by the Free Software Foundation.
|
||||
- */
|
||||
-#include <linux/acpi.h>
|
||||
-#include <linux/bug.h>
|
||||
-#include <linux/cpuhotplug.h>
|
||||
-#include <linux/interrupt.h>
|
||||
-#include <linux/irq.h>
|
||||
-#include <linux/list.h>
|
||||
-#include <linux/of.h>
|
||||
-#include <linux/platform_device.h>
|
||||
-#include <linux/smp.h>
|
||||
-
|
||||
-#include "hisi_uncore_pmu.h"
|
||||
-
|
||||
-/* L3T register definition */
|
||||
-#define L3T_PERF_CTRL 0x0408
|
||||
-#define L3T_INT_MASK 0x0800
|
||||
-#define L3T_INT_STATUS 0x0808
|
||||
-#define L3T_INT_CLEAR 0x080c
|
||||
-#define L3T_EVENT_CTRL 0x1c00
|
||||
-#define L3T_EVENT_TYPE0 0x1d00
|
||||
-/*
|
||||
- * Each counter is 48-bits and [48:63] are reserved
|
||||
- * which are Read-As-Zero and Writes-Ignored.
|
||||
- */
|
||||
-#define L3T_CNTR0_LOWER 0x1e00
|
||||
-
|
||||
-/* L3T has 8-counters */
|
||||
-#define L3T_NR_COUNTERS 0x8
|
||||
-
|
||||
-#define L3T_PERF_CTRL_EN 0x20000
|
||||
-#define L3T_EVTYPE_NONE 0xff
|
||||
-
|
||||
-/*
|
||||
- * Select the counter register offset using the counter index
|
||||
- */
|
||||
-static u32 hisi_l3t_pmu_get_counter_offset(u32 cntr_idx)
|
||||
-{
|
||||
- return (L3T_CNTR0_LOWER + (cntr_idx * 8));
|
||||
-}
|
||||
-
|
||||
-static u64 hisi_l3t_pmu_read_counter(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(l3t_pmu, idx)) {
|
||||
- dev_err(l3t_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- /* Read 64-bits and the upper 16 bits are RAZ */
|
||||
- return readq(l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(idx));
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_write_counter(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc, u64 val)
|
||||
-{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(l3t_pmu, idx)) {
|
||||
- dev_err(l3t_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* Write 64-bits and the upper 16 bits are WI */
|
||||
- writeq(val, l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(idx));
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_write_evtype(struct hisi_pmu *l3t_pmu, int idx,
|
||||
- u32 type)
|
||||
-{
|
||||
- u32 reg, reg_idx, shift, val;
|
||||
-
|
||||
- /*
|
||||
- * Select the appropriate event select register(L3T_EVENT_TYPE0/1).
|
||||
- * There are 2 event select registers for the 8 hardware counters.
|
||||
- * Event code is 8-bits and for the former 4 hardware counters,
|
||||
- * L3T_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
- * L3T_EVENT_TYPE1 is chosen.
|
||||
- */
|
||||
- reg = L3T_EVENT_TYPE0 + (idx / 4) * 4;
|
||||
- reg_idx = idx % 4;
|
||||
- shift = 8 * reg_idx;
|
||||
-
|
||||
- /* Write event code to L3T_EVENT_TYPEx Register */
|
||||
- val = readl(l3t_pmu->base + reg);
|
||||
- val &= ~(L3T_EVTYPE_NONE << shift);
|
||||
- val |= (type << shift);
|
||||
- writel(val, l3t_pmu->base + reg);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_start_counters(struct hisi_pmu *l3t_pmu)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /*
|
||||
- * Set perf_enable bit in L3T_PERF_CTRL register to start counting
|
||||
- * for all enabled counters.
|
||||
- */
|
||||
- val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
||||
- val |= L3T_PERF_CTRL_EN;
|
||||
- writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_stop_counters(struct hisi_pmu *l3t_pmu)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /*
|
||||
- * Clear perf_enable bit in L3T_PERF_CTRL register to stop counting
|
||||
- * for all enabled counters.
|
||||
- */
|
||||
- val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
||||
- val &= ~(L3T_PERF_CTRL_EN);
|
||||
- writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_enable_counter(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Enable counter index in L3T_EVENT_CTRL register */
|
||||
- val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
- val |= (1 << hwc->idx);
|
||||
- writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_disable_counter(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Clear counter index in L3T_EVENT_CTRL register */
|
||||
- val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
- val &= ~(1 << hwc->idx);
|
||||
- writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_enable_counter_int(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- val = readl(l3t_pmu->base + L3T_INT_MASK);
|
||||
- /* Write 0 to enable interrupt */
|
||||
- val &= ~(1 << hwc->idx);
|
||||
- writel(val, l3t_pmu->base + L3T_INT_MASK);
|
||||
-}
|
||||
-
|
||||
-static void hisi_l3t_pmu_disable_counter_int(struct hisi_pmu *l3t_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- val = readl(l3t_pmu->base + L3T_INT_MASK);
|
||||
- /* Write 1 to mask interrupt */
|
||||
- val |= (1 << hwc->idx);
|
||||
- writel(val, l3t_pmu->base + L3T_INT_MASK);
|
||||
-}
|
||||
-
|
||||
-static irqreturn_t hisi_l3t_pmu_isr(int irq, void *dev_id)
|
||||
-{
|
||||
- struct hisi_pmu *l3t_pmu = dev_id;
|
||||
- struct perf_event *event;
|
||||
- unsigned long overflown;
|
||||
- int idx;
|
||||
-
|
||||
- /* Read L3T_INT_STATUS register */
|
||||
- overflown = readl(l3t_pmu->base + L3T_INT_STATUS);
|
||||
- if (!overflown)
|
||||
- return IRQ_NONE;
|
||||
-
|
||||
- /*
|
||||
- * Find the counter index which overflowed if the bit was set
|
||||
- * and handle it.
|
||||
- */
|
||||
- for_each_set_bit(idx, &overflown, L3T_NR_COUNTERS) {
|
||||
- /* Write 1 to clear the IRQ status flag */
|
||||
- writel((1 << idx), l3t_pmu->base + L3T_INT_CLEAR);
|
||||
-
|
||||
- /* Get the corresponding event struct */
|
||||
- event = l3t_pmu->pmu_events.hw_events[idx];
|
||||
- if (!event)
|
||||
- continue;
|
||||
-
|
||||
- hisi_uncore_pmu_event_update(event);
|
||||
- hisi_uncore_pmu_set_event_period(event);
|
||||
- }
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
-}
|
||||
-
|
||||
-static int hisi_l3t_pmu_init_irq(struct hisi_pmu *l3t_pmu,
|
||||
- struct platform_device *pdev)
|
||||
-{
|
||||
- int irq, ret;
|
||||
-
|
||||
- /* Read and init IRQ */
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "L3T PMU get irq fail; irq:%d\n", irq);
|
||||
- return irq;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_l3t_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
|
||||
- dev_name(&pdev->dev), l3t_pmu);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- l3t_pmu->irq = irq;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static const struct of_device_id l3t_of_match[] = {
|
||||
- { .compatible = "hisilicon,l3t-pmu", },
|
||||
- {},
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, l3t_of_match);
|
||||
-
|
||||
-static int hisi_l3t_pmu_init_data(struct platform_device *pdev,
|
||||
- struct hisi_pmu *l3t_pmu)
|
||||
-{
|
||||
- struct resource *res;
|
||||
-
|
||||
- /*
|
||||
- * Use the SCCL_ID and CCL_ID to identify the L3T PMU, while
|
||||
- * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
||||
- */
|
||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
- &l3t_pmu->sccl_id)) {
|
||||
- dev_err(&pdev->dev, "Can not read l3t sccl-id!\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
|
||||
- &l3t_pmu->ccl_id)) {
|
||||
- dev_err(&pdev->dev, "Can not read l3t ccl-id!\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,index-id",
|
||||
- &l3t_pmu->index_id)) {
|
||||
- dev_err(&pdev->dev, "Can not read l3t index-id!\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- l3t_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
- if (IS_ERR(l3t_pmu->base)) {
|
||||
- dev_err(&pdev->dev, "ioremap failed for l3t_pmu resource\n");
|
||||
- return PTR_ERR(l3t_pmu->base);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct attribute *hisi_l3t_pmu_format_attr[] = {
|
||||
- HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_l3t_pmu_format_group = {
|
||||
- .name = "format",
|
||||
- .attrs = hisi_l3t_pmu_format_attr,
|
||||
-};
|
||||
-
|
||||
-static struct attribute *hisi_l3t_pmu_events_attr[] = {
|
||||
- HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
||||
- HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
||||
- HISI_PMU_EVENT_ATTR(rd_hit_cpipe, 0x02),
|
||||
- HISI_PMU_EVENT_ATTR(wr_hit_cpipe, 0x03),
|
||||
- HISI_PMU_EVENT_ATTR(victim_num, 0x04),
|
||||
- HISI_PMU_EVENT_ATTR(rd_spipe, 0x20),
|
||||
- HISI_PMU_EVENT_ATTR(wr_spipe, 0x21),
|
||||
- HISI_PMU_EVENT_ATTR(rd_hit_spipe, 0x22),
|
||||
- HISI_PMU_EVENT_ATTR(wr_hit_spipe, 0x23),
|
||||
- HISI_PMU_EVENT_ATTR(back_invalid, 0x29),
|
||||
- HISI_PMU_EVENT_ATTR(retry_cpu, 0x40),
|
||||
- HISI_PMU_EVENT_ATTR(retry_ring, 0x41),
|
||||
- HISI_PMU_EVENT_ATTR(prefetch_drop, 0x42),
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_l3t_pmu_events_group = {
|
||||
- .name = "events",
|
||||
- .attrs = hisi_l3t_pmu_events_attr,
|
||||
-};
|
||||
-
|
||||
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
-
|
||||
-static struct attribute *hisi_l3t_pmu_cpumask_attrs[] = {
|
||||
- &dev_attr_cpumask.attr,
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_l3t_pmu_cpumask_attr_group = {
|
||||
- .attrs = hisi_l3t_pmu_cpumask_attrs,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group *hisi_l3t_pmu_attr_groups[] = {
|
||||
- &hisi_l3t_pmu_format_group,
|
||||
- &hisi_l3t_pmu_events_group,
|
||||
- &hisi_l3t_pmu_cpumask_attr_group,
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct hisi_uncore_ops hisi_uncore_l3t_ops = {
|
||||
- .write_evtype = hisi_l3t_pmu_write_evtype,
|
||||
- .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
- .start_counters = hisi_l3t_pmu_start_counters,
|
||||
- .stop_counters = hisi_l3t_pmu_stop_counters,
|
||||
- .enable_counter = hisi_l3t_pmu_enable_counter,
|
||||
- .disable_counter = hisi_l3t_pmu_disable_counter,
|
||||
- .enable_counter_int = hisi_l3t_pmu_enable_counter_int,
|
||||
- .disable_counter_int = hisi_l3t_pmu_disable_counter_int,
|
||||
- .write_counter = hisi_l3t_pmu_write_counter,
|
||||
- .read_counter = hisi_l3t_pmu_read_counter,
|
||||
-};
|
||||
-
|
||||
-static int hisi_l3t_pmu_dev_probe(struct platform_device *pdev,
|
||||
- struct hisi_pmu *l3t_pmu)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hisi_l3t_pmu_init_data(pdev, l3t_pmu);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = hisi_l3t_pmu_init_irq(l3t_pmu, pdev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- l3t_pmu->num_counters = L3T_NR_COUNTERS;
|
||||
- l3t_pmu->counter_bits = 48;
|
||||
- l3t_pmu->ops = &hisi_uncore_l3t_ops;
|
||||
- l3t_pmu->dev = &pdev->dev;
|
||||
- l3t_pmu->on_cpu = -1;
|
||||
- l3t_pmu->check_event = 0x59;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int hisi_l3t_pmu_probe(struct platform_device *pdev)
|
||||
-{
|
||||
- struct hisi_pmu *l3t_pmu;
|
||||
- char *name;
|
||||
- int ret;
|
||||
-
|
||||
- l3t_pmu = devm_kzalloc(&pdev->dev, sizeof(*l3t_pmu), GFP_KERNEL);
|
||||
- if (!l3t_pmu)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- platform_set_drvdata(pdev, l3t_pmu);
|
||||
-
|
||||
- ret = hisi_l3t_pmu_dev_probe(pdev, l3t_pmu);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3t%u",
|
||||
- l3t_pmu->sccl_id, l3t_pmu->index_id);
|
||||
- HISI_INIT_PMU(&l3t_pmu->pmu, name, hisi_l3t_pmu_attr_groups);
|
||||
-
|
||||
- ret = perf_pmu_register(&l3t_pmu->pmu, name, -1);
|
||||
- if (ret) {
|
||||
- dev_err(l3t_pmu->dev, "L3T PMU register failed!\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- /* Pick one core to use for cpumask attributes */
|
||||
- cpumask_set_cpu(smp_processor_id(), &l3t_pmu->associated_cpus);
|
||||
-
|
||||
- l3t_pmu->on_cpu = cpumask_first(&l3t_pmu->associated_cpus);
|
||||
- if (l3t_pmu->on_cpu >= nr_cpu_ids)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int hisi_l3t_pmu_remove(struct platform_device *pdev)
|
||||
-{
|
||||
- struct hisi_pmu *l3t_pmu = platform_get_drvdata(pdev);
|
||||
-
|
||||
- perf_pmu_unregister(&l3t_pmu->pmu);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct platform_driver hisi_l3t_pmu_driver = {
|
||||
- .driver = {
|
||||
- .name = "hisi_l3t_pmu",
|
||||
- .of_match_table = of_match_ptr(l3t_of_match),
|
||||
- },
|
||||
- .probe = hisi_l3t_pmu_probe,
|
||||
- .remove = hisi_l3t_pmu_remove,
|
||||
-};
|
||||
-
|
||||
-static int __init hisi_l3t_pmu_module_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&hisi_l3t_pmu_driver);
|
||||
-}
|
||||
-module_init(hisi_l3t_pmu_module_init);
|
||||
-
|
||||
-static void __exit hisi_l3t_pmu_module_exit(void)
|
||||
-{
|
||||
- platform_driver_unregister(&hisi_l3t_pmu_driver);
|
||||
-}
|
||||
-module_exit(hisi_l3t_pmu_module_exit);
|
||||
-
|
||||
-MODULE_DESCRIPTION("HiSilicon SoC L3T uncore PMU driver");
|
||||
-MODULE_LICENSE("GPL v2");
|
||||
-MODULE_AUTHOR("HUAWEI TECHNOLOGIES CO., LTD.");
|
||||
-MODULE_AUTHOR("Fang Lijun <fanglijun3@huawei.com>");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,469 @@
|
||||
From a42c8f603e8d0aa7d67023014604d919227581dd Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 15:04:16 +0800
|
||||
Subject: [PATCH 03/55] Revert "perf: hisi: Add support for HiSilicon SoC
|
||||
LPDDRC PMU driver"
|
||||
|
||||
driver inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
-------------------------------------------------------------
|
||||
|
||||
This reverts commit be4e2dae37269ece33d54f906323b00208a569b0.
|
||||
|
||||
Now, revert it, then we will inclusion the newer version of LPDRRC PMU
|
||||
driver.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 2 +-
|
||||
.../perf/hisilicon/hisi_uncore_lpddrc_pmu.c | 429 ------------------
|
||||
2 files changed, 1 insertion(+), 430 deletions(-)
|
||||
delete mode 100644 drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 3651f18260e5..2621d51ae87a 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1 +1 @@
|
||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_lpddrc_pmu.o
|
||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
deleted file mode 100644
|
||||
index 8f8b211788e0..000000000000
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
+++ /dev/null
|
||||
@@ -1,429 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0
|
||||
-/*
|
||||
- * HiSilicon SoC LPDDRC uncore Hardware event counters support
|
||||
- *
|
||||
- * Copyright (C) 2021 Hisilicon Limited
|
||||
- * Author: Fang Lijun <fanglijun3@huawei.com>
|
||||
- * Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
- * Anurup M <anurup.m@huawei.com>
|
||||
- *
|
||||
- * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
- *
|
||||
- * This program is free software; you can redistribute it and/or modify
|
||||
- * it under the terms of the GNU General Public License version 2 as
|
||||
- * published by the Free Software Foundation.
|
||||
- */
|
||||
-#include <linux/acpi.h>
|
||||
-#include <linux/bug.h>
|
||||
-#include <linux/cpuhotplug.h>
|
||||
-#include <linux/interrupt.h>
|
||||
-#include <linux/irq.h>
|
||||
-#include <linux/list.h>
|
||||
-#include <linux/of.h>
|
||||
-#include <linux/platform_device.h>
|
||||
-#include <linux/smp.h>
|
||||
-
|
||||
-#include "hisi_uncore_pmu.h"
|
||||
-
|
||||
-/* LPDDRC register definition */
|
||||
-#define LPDDRC_PERF_CTRL 0x4930
|
||||
-#define LPDDRC_FLUX_WR 0x4948
|
||||
-#define LPDDRC_FLUX_RD 0x494c
|
||||
-#define LPDDRC_FLUX_WCMD 0x4950
|
||||
-#define LPDDRC_FLUX_RCMD 0x4954
|
||||
-#define LPDDRC_PRE_CMD 0x4984
|
||||
-#define LPDDRC_ACT_CMD 0x4988
|
||||
-#define LPDDRC_RNK_CHG 0x4990
|
||||
-#define LPDDRC_RW_CHG 0x4994
|
||||
-#define LPDDRC_EVENT_CTRL 0x4d60
|
||||
-#define LPDDRC_INT_MASK 0x6c8
|
||||
-#define LPDDRC_INT_STATUS 0x6cc
|
||||
-#define LPDDRC_INT_CLEAR 0x6d0
|
||||
-
|
||||
-/* LPDDRC has 8-counters */
|
||||
-#define LPDDRC_NR_COUNTERS 0x8
|
||||
-#define LPDDRC_PERF_CTRL_EN 0x1
|
||||
-
|
||||
-/*
|
||||
- * For LPDDRC PMU, there are eight-events and every event has been mapped
|
||||
- * to fixed-purpose counters which register offset is not consistent.
|
||||
- * Therefore there is no write event type and we assume that event
|
||||
- * code (0 to 7) is equal to counter index in PMU driver.
|
||||
- */
|
||||
-#define GET_LPDDRC_EVENTID(hwc) (hwc->config_base & 0x7)
|
||||
-
|
||||
-static const u32 lpddrc_reg_off[] = {
|
||||
- LPDDRC_FLUX_WR, LPDDRC_FLUX_RD, LPDDRC_FLUX_WCMD, LPDDRC_FLUX_RCMD,
|
||||
- LPDDRC_PRE_CMD, LPDDRC_ACT_CMD, LPDDRC_RNK_CHG, LPDDRC_RW_CHG
|
||||
-};
|
||||
-
|
||||
-/*
|
||||
- * Select the counter register offset using the counter index.
|
||||
- * In LPDDRC there are no programmable counter, the count
|
||||
- * is readed form the statistics counter register itself.
|
||||
- */
|
||||
-static u32 hisi_lpddrc_pmu_get_counter_offset(int cntr_idx)
|
||||
-{
|
||||
- return lpddrc_reg_off[cntr_idx];
|
||||
-}
|
||||
-
|
||||
-static u64 hisi_lpddrc_pmu_read_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- /* Use event code as counter index */
|
||||
- u32 idx = GET_LPDDRC_EVENTID(hwc);
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(lpddrc_pmu, idx)) {
|
||||
- dev_err(lpddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return readl(lpddrc_pmu->base + hisi_lpddrc_pmu_get_counter_offset(idx));
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * For LPDDRC PMU, event counter should be reset when start counters,
|
||||
- * reset the prev_count by software, because the counter register was RO.
|
||||
- */
|
||||
-static void hisi_lpddrc_pmu_write_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc, u64 val)
|
||||
-{
|
||||
- local64_set(&hwc->prev_count, 0);
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * For LPDDRC PMU, event has been mapped to fixed-purpose counter by hardware,
|
||||
- * so there is no need to write event type.
|
||||
- */
|
||||
-static void hisi_lpddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
||||
- u32 type)
|
||||
-{
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_start_counters(struct hisi_pmu *lpddrc_pmu)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Set perf_enable in LPDDRC_PERF_CTRL to start event counting */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
- val |= LPDDRC_PERF_CTRL_EN;
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_stop_counters(struct hisi_pmu *lpddrc_pmu)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Clear perf_enable in LPDDRC_PERF_CTRL to stop event counting */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
- val &= ~LPDDRC_PERF_CTRL_EN;
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_enable_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Set counter index(event code) in LPDDRC_EVENT_CTRL register */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
- val |= (1 << GET_LPDDRC_EVENTID(hwc));
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_disable_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Clear counter index(event code) in LPDDRC_EVENT_CTRL register */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
- val &= ~(1 << GET_LPDDRC_EVENTID(hwc));
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
-}
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_get_event_idx(struct perf_event *event)
|
||||
-{
|
||||
- struct hisi_pmu *lpddrc_pmu = to_hisi_pmu(event->pmu);
|
||||
- unsigned long *used_mask = lpddrc_pmu->pmu_events.used_mask;
|
||||
- struct hw_perf_event *hwc = &event->hw;
|
||||
- /* For LPDDRC PMU, we use event code as counter index */
|
||||
- int idx = GET_LPDDRC_EVENTID(hwc);
|
||||
-
|
||||
- if (test_bit(idx, used_mask))
|
||||
- return -EAGAIN;
|
||||
-
|
||||
- set_bit(idx, used_mask);
|
||||
-
|
||||
- return idx;
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_enable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Write 0 to enable interrupt */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
- val &= ~(1 << GET_LPDDRC_EVENTID(hwc));
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
-}
|
||||
-
|
||||
-static void hisi_lpddrc_pmu_disable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
-{
|
||||
- u32 val;
|
||||
-
|
||||
- /* Write 1 to mask interrupt */
|
||||
- val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
- val |= (1 << GET_LPDDRC_EVENTID(hwc));
|
||||
- writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
-}
|
||||
-
|
||||
-static irqreturn_t hisi_lpddrc_pmu_isr(int irq, void *dev_id)
|
||||
-{
|
||||
- struct hisi_pmu *lpddrc_pmu = dev_id;
|
||||
- struct perf_event *event;
|
||||
- unsigned long overflown;
|
||||
- int idx;
|
||||
-
|
||||
- /* Read the LPDDRC_INT_STATUS register */
|
||||
- overflown = readl(lpddrc_pmu->base + LPDDRC_INT_STATUS);
|
||||
- if (!overflown)
|
||||
- return IRQ_NONE;
|
||||
-
|
||||
- /*
|
||||
- * Find the counter index which overflowed if the bit was set
|
||||
- * and handle it
|
||||
- */
|
||||
- for_each_set_bit(idx, &overflown, LPDDRC_NR_COUNTERS) {
|
||||
- /* Write 1 to clear the IRQ status flag */
|
||||
- writel((1 << idx), lpddrc_pmu->base + LPDDRC_INT_CLEAR);
|
||||
-
|
||||
- /* Get the corresponding event struct */
|
||||
- event = lpddrc_pmu->pmu_events.hw_events[idx];
|
||||
- if (!event)
|
||||
- continue;
|
||||
-
|
||||
- hisi_uncore_pmu_event_update(event);
|
||||
- hisi_uncore_pmu_set_event_period(event);
|
||||
- }
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
-}
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_init_irq(struct hisi_pmu *lpddrc_pmu,
|
||||
- struct platform_device *pdev)
|
||||
-{
|
||||
- int irq, ret;
|
||||
-
|
||||
- /* Read and init IRQ */
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "LPDDRC PMU get irq fail; irq:%d\n", irq);
|
||||
- return irq;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_lpddrc_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
|
||||
- dev_name(&pdev->dev), lpddrc_pmu);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- lpddrc_pmu->irq = irq;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static const struct of_device_id lpddrc_of_match[] = {
|
||||
- { .compatible = "hisilicon,lpddrc-pmu", },
|
||||
- {},
|
||||
-}
|
||||
-MODULE_DEVICE_TABLE(of, lpddrc_of_match);
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_init_data(struct platform_device *pdev,
|
||||
- struct hisi_pmu *lpddrc_pmu)
|
||||
-{
|
||||
- struct resource *res;
|
||||
-
|
||||
- /*
|
||||
- * Use the SCCL_ID and LPDDRC channel ID to identify the
|
||||
- * LPDDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
||||
- */
|
||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,ch-id",
|
||||
- &lpddrc_pmu->index_id)) {
|
||||
- dev_err(&pdev->dev, "Can not read lpddrc channel-id!\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
- &lpddrc_pmu->sccl_id)) {
|
||||
- dev_err(&pdev->dev, "Can not read lpddrc sccl-id!\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- /* LPDDRC PMUs only share the same SCCL */
|
||||
- lpddrc_pmu->ccl_id = -1;
|
||||
-
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- lpddrc_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
- if (IS_ERR(lpddrc_pmu->base)) {
|
||||
- dev_err(&pdev->dev, "ioremap failed for lpddrc_pmu resource\n");
|
||||
- return PTR_ERR(lpddrc_pmu->base);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct attribute *hisi_lpddrc_pmu_format_attr[] = {
|
||||
- HISI_PMU_FORMAT_ATTR(event, "config:0-4"),
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_lpddrc_pmu_format_group = {
|
||||
- .name = "format",
|
||||
- .attrs = hisi_lpddrc_pmu_format_attr,
|
||||
-};
|
||||
-
|
||||
-static struct attribute *hisi_lpddrc_pmu_events_attr[] = {
|
||||
- HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
||||
- HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
||||
- HISI_PMU_EVENT_ATTR(flux_wcmd, 0x02),
|
||||
- HISI_PMU_EVENT_ATTR(flux_rcmd, 0x03),
|
||||
- HISI_PMU_EVENT_ATTR(pre_cmd, 0x04),
|
||||
- HISI_PMU_EVENT_ATTR(act_cmd, 0x05),
|
||||
- HISI_PMU_EVENT_ATTR(rnk_chg, 0x06),
|
||||
- HISI_PMU_EVENT_ATTR(rw_chg, 0x07),
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_lpddrc_pmu_events_group = {
|
||||
- .name = "events",
|
||||
- .attrs = hisi_lpddrc_pmu_events_attr,
|
||||
-};
|
||||
-
|
||||
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
-
|
||||
-static struct attribute *hisi_lpddrc_pmu_cpumask_attrs[] = {
|
||||
- &dev_attr_cpumask.attr,
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group hisi_lpddrc_pmu_cpumask_attr_group = {
|
||||
- .attrs = hisi_lpddrc_pmu_cpumask_attrs,
|
||||
-};
|
||||
-
|
||||
-static const struct attribute_group *hisi_lpddrc_pmu_attr_groups[] = {
|
||||
- &hisi_lpddrc_pmu_format_group,
|
||||
- &hisi_lpddrc_pmu_events_group,
|
||||
- &hisi_lpddrc_pmu_cpumask_attr_group,
|
||||
- NULL,
|
||||
-};
|
||||
-
|
||||
-static const struct hisi_uncore_ops hisi_uncore_lpddrc_ops = {
|
||||
- .write_evtype = hisi_lpddrc_pmu_write_evtype,
|
||||
- .get_event_idx = hisi_lpddrc_pmu_get_event_idx,
|
||||
- .start_counters = hisi_lpddrc_pmu_start_counters,
|
||||
- .stop_counters = hisi_lpddrc_pmu_stop_counters,
|
||||
- .enable_counter = hisi_lpddrc_pmu_enable_counter,
|
||||
- .disable_counter = hisi_lpddrc_pmu_disable_counter,
|
||||
- .enable_counter_int = hisi_lpddrc_pmu_enable_counter_int,
|
||||
- .disable_counter_int = hisi_lpddrc_pmu_disable_counter_int,
|
||||
- .write_counter = hisi_lpddrc_pmu_write_counter,
|
||||
- .read_counter = hisi_lpddrc_pmu_read_counter,
|
||||
-};
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
- struct hisi_pmu *lpddrc_pmu)
|
||||
-{
|
||||
- int ret;
|
||||
-
|
||||
- ret = hisi_lpddrc_pmu_init_data(pdev, lpddrc_pmu);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = hisi_lpddrc_pmu_init_irq(lpddrc_pmu, pdev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- lpddrc_pmu->num_counters = LPDDRC_NR_COUNTERS;
|
||||
- lpddrc_pmu->counter_bits = 32;
|
||||
- lpddrc_pmu->ops = &hisi_uncore_lpddrc_ops;
|
||||
- lpddrc_pmu->dev = &pdev->dev;
|
||||
- lpddrc_pmu->on_cpu = -1;
|
||||
- lpddrc_pmu->check_event = 7;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_probe(struct platform_device *pdev)
|
||||
-{
|
||||
- struct hisi_pmu *lpddrc_pmu;
|
||||
- char *name;
|
||||
- int ret;
|
||||
-
|
||||
- lpddrc_pmu = devm_kzalloc(&pdev->dev, sizeof(*lpddrc_pmu), GFP_KERNEL);
|
||||
- if (!lpddrc_pmu)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- platform_set_drvdata(pdev, lpddrc_pmu);
|
||||
-
|
||||
- ret = hisi_lpddrc_pmu_dev_probe(pdev, lpddrc_pmu);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_lpddrc%u",
|
||||
- lpddrc_pmu->sccl_id, lpddrc_pmu->index_id);
|
||||
- HISI_INIT_PMU(&lpddrc_pmu->pmu, name, hisi_lpddrc_pmu_attr_groups);
|
||||
- ret = perf_pmu_register(&lpddrc_pmu->pmu, name, -1);
|
||||
- if (ret) {
|
||||
- dev_err(lpddrc_pmu->dev, "LPDDRC PMU register failed!\n");
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- /* Pick one core to use for cpumask attributes */
|
||||
- cpumask_set_cpu(smp_processor_id(), &lpddrc_pmu->associated_cpus);
|
||||
-
|
||||
- lpddrc_pmu->on_cpu = cpumask_first(&lpddrc_pmu->associated_cpus);
|
||||
- if (lpddrc_pmu->on_cpu >= nr_cpu_ids)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int hisi_lpddrc_pmu_remove(struct platform_device *pdev)
|
||||
-{
|
||||
- struct hisi_pmu *lpddrc_pmu = platform_get_drvdata(pdev);
|
||||
-
|
||||
- perf_pmu_unregister(&lpddrc_pmu->pmu);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static struct platform_driver hisi_lpddrc_pmu_driver = {
|
||||
- .driver = {
|
||||
- .name = "hisi_lpddrc_pmu",
|
||||
- .of_match_table = lpddrc_of_match,
|
||||
- },
|
||||
- .probe = hisi_lpddrc_pmu_probe,
|
||||
- .remove = hisi_lpddrc_pmu_remove,
|
||||
-};
|
||||
-
|
||||
-static int __init hisi_lpddrc_pmu_module_init(void)
|
||||
-{
|
||||
- return platform_driver_register(&hisi_lpddrc_pmu_driver);
|
||||
-}
|
||||
-module_init(hisi_lpddrc_pmu_module_init);
|
||||
-
|
||||
-static void __exit hisi_lpddrc_pmu_module_exit(void)
|
||||
-{
|
||||
- platform_driver_unregister(&hisi_lpddrc_pmu_driver);
|
||||
-}
|
||||
-module_exit(hisi_lpddrc_pmu_module_exit);
|
||||
-
|
||||
-MODULE_DESCRIPTION("HiSilicon SoC LPDDRC uncore PMU driver");
|
||||
-MODULE_LICENSE("GPL v2");
|
||||
-MODULE_AUTHOR("Fang Lijun <fanglijun3@huawei.com>");
|
||||
-MODULE_AUTHOR("HUAWEI TECHNOLOGIES CO., LTD.");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,142 @@
|
||||
From 368cbff964ef136c493a3f06b88ff7e35454073d Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 15:21:52 +0800
|
||||
Subject: [PATCH 04/55] Revert "perf: hisi: Add support for HiSilicon SoC PMU
|
||||
driver dt probe"
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
-----------------------------------------------------------------
|
||||
|
||||
This reverts commit 31067ca7ca856eee32857bdc618e89d3b9a3261a.
|
||||
|
||||
In newer version of PMU drivers that we will inclusion them later,
|
||||
the acpi_evaluate_integer was removed, so this problem is gone.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/Kconfig
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 -
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 23 ++++---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 20 +++-------------
|
||||
3 files changed, 7 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 8d1c48bc9812..f2a144ba3724 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 52286739c8b9..540f664463a8 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
@@ -236,34 +235,20 @@ static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hisi_hha_pmu_acpi_match);
|
||||
|
||||
-#ifdef CONFIG_ACPI
|
||||
-static int hisi_hha_pmu_init_index(struct platform_device *pdev,
|
||||
+static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *hha_pmu)
|
||||
{
|
||||
- acpi_status status;
|
||||
unsigned long long id;
|
||||
+ struct resource *res;
|
||||
+ acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
- "_UID", NULL, &id);
|
||||
+ "_UID", NULL, &id);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
hha_pmu->index_id = id;
|
||||
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
- struct hisi_pmu *hha_pmu)
|
||||
-{
|
||||
- struct resource *res;
|
||||
-
|
||||
-#ifdef CONFIG_ACPI
|
||||
- if (hisi_hha_pmu_init_index(pdev, hha_pmu))
|
||||
- dev_info(&pdev->dev, "Can not init index id by acpi!\n");
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* Use SCCL_ID and UID to identify the HHA PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2].
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 0e766cea4a11..117edd114445 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
@@ -235,33 +234,20 @@ static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
|
||||
|
||||
-#ifdef CONFIG_ACPI
|
||||
-static int hisi_l3c_pmu_init_index(struct platform_device *pdev,
|
||||
+static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *l3c_pmu)
|
||||
{
|
||||
unsigned long long id;
|
||||
+ struct resource *res;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
- "_UID", NULL, &id);
|
||||
+ "_UID", NULL, &id);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
l3c_pmu->index_id = id;
|
||||
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
- struct hisi_pmu *l3c_pmu)
|
||||
-{
|
||||
- struct resource *res;
|
||||
-
|
||||
-#ifdef CONFIG_ACPI
|
||||
- if (hisi_l3c_pmu_init_index(pdev, l3c_pmu))
|
||||
- dev_info(&pdev->dev, "Can not init index id by acpi!");
|
||||
-#endif
|
||||
/*
|
||||
* Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 05df62b6b7f9e92e9f25b8a0bcd5c99c4ae02165 Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 15:26:10 +0800
|
||||
Subject: [PATCH 05/55] Revert "drivers/perf: Fix kernel panic when rmmod PMU
|
||||
modules during perf sampling"
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
This reverts commit 525a3927062f89be41f1b23ae33ad0638c13bf8e.
|
||||
|
||||
revert it, and inclusion the upstream version later.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 129896662cf2..8445ee581e46 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -105,7 +105,6 @@ static inline void HISI_INIT_PMU(struct pmu *pmu, const char *name,
|
||||
const struct attribute_group **attr_groups)
|
||||
{
|
||||
pmu->name = name;
|
||||
- pmu->module = THIS_MODULE;
|
||||
pmu->task_ctx_nr = perf_invalid_context;
|
||||
pmu->event_init = hisi_uncore_pmu_event_init;
|
||||
pmu->pmu_enable = hisi_uncore_pmu_enable;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
129
patches/0047-Revert-perf-hisi-remove-duplicated-code.patch
Normal file
129
patches/0047-Revert-perf-hisi-remove-duplicated-code.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From 41ea05f9ac69e7cbae775862e5c3e0dad2e1e4ca Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 15:26:31 +0800
|
||||
Subject: [PATCH 06/55] Revert "perf: hisi: remove duplicated code"
|
||||
|
||||
driver inclusion
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
This reverts commit de1ea4e7f5209c7f84965c38bf37287c11db02dc.
|
||||
|
||||
revert it, and inclusion the newer version of commit c38992d67c15(perf: hisi: Extract hisi_pmu_init) later.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 15 ++++++++++++++-
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 15 ++++++++++++++-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 14 +++++++++++++-
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 17 -----------------
|
||||
4 files changed, 41 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index f2a144ba3724..b3488ae1f2b8 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -384,7 +384,20 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_ddrc%u",
|
||||
ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
||||
- HISI_INIT_PMU(&ddrc_pmu->pmu, name, hisi_ddrc_pmu_attr_groups);
|
||||
+ ddrc_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = hisi_ddrc_pmu_attr_groups,
|
||||
+ };
|
||||
+
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 540f664463a8..f0215d50d84d 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -395,7 +395,20 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
- HISI_INIT_PMU(&hha_pmu->pmu, name, hisi_hha_pmu_attr_groups);
|
||||
+ hha_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = hisi_hha_pmu_attr_groups,
|
||||
+ };
|
||||
+
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 117edd114445..11563e29d983 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -385,7 +385,19 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
l3c_pmu->sccl_id, l3c_pmu->index_id);
|
||||
- HISI_INIT_PMU(&l3c_pmu->pmu, name, hisi_l3c_pmu_attr_groups);
|
||||
+ l3c_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = hisi_l3c_pmu_attr_groups,
|
||||
+ };
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 8445ee581e46..8f2f2fc5dde4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -100,21 +100,4 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
|
||||
int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
||||
-
|
||||
-static inline void HISI_INIT_PMU(struct pmu *pmu, const char *name,
|
||||
- const struct attribute_group **attr_groups)
|
||||
-{
|
||||
- pmu->name = name;
|
||||
- pmu->task_ctx_nr = perf_invalid_context;
|
||||
- pmu->event_init = hisi_uncore_pmu_event_init;
|
||||
- pmu->pmu_enable = hisi_uncore_pmu_enable;
|
||||
- pmu->pmu_disable = hisi_uncore_pmu_disable;
|
||||
- pmu->add = hisi_uncore_pmu_add;
|
||||
- pmu->del = hisi_uncore_pmu_del;
|
||||
- pmu->start = hisi_uncore_pmu_start;
|
||||
- pmu->stop = hisi_uncore_pmu_stop;
|
||||
- pmu->read = hisi_uncore_pmu_read;
|
||||
- pmu->attr_groups = attr_groups;
|
||||
-}
|
||||
-
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
315
patches/0048-docs-perf-convert-to-ReST.patch
Normal file
315
patches/0048-docs-perf-convert-to-ReST.patch
Normal file
@ -0,0 +1,315 @@
|
||||
From 926642e8644c860c77141b8251767e1485c6427c Mon Sep 17 00:00:00 2001
|
||||
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
Date: Thu, 18 Apr 2019 17:35:40 -0300
|
||||
Subject: [PATCH 07/55] docs: perf: convert to ReST
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 6baec31591cee0f2f6d446abb81c828499a6ed23
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6baec31591cee0f2f6d446abb81c828499a6ed23
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Rename the perf documentation files to ReST, add an
|
||||
index for them and adjust in order to produce a nice html
|
||||
output via the Sphinx build system.
|
||||
|
||||
At its new index.rst, let's add a :orphan: while this is not linked to
|
||||
the main index.rst file, in order to avoid build warnings.
|
||||
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../perf/{arm-ccn.txt => arm-ccn.rst} | 18 +++++----
|
||||
.../perf/{arm_dsu_pmu.txt => arm_dsu_pmu.rst} | 5 ++-
|
||||
.../perf/{hisi-pmu.txt => hisi-pmu.rst} | 37 +++++++++++--------
|
||||
Documentation/perf/index.rst | 16 ++++++++
|
||||
.../perf/{qcom_l2_pmu.txt => qcom_l2_pmu.rst} | 3 +-
|
||||
.../perf/{qcom_l3_pmu.txt => qcom_l3_pmu.rst} | 3 +-
|
||||
.../perf/{xgene-pmu.txt => xgene-pmu.rst} | 3 +-
|
||||
MAINTAINERS | 4 +-
|
||||
drivers/perf/qcom_l3_pmu.c | 2 +-
|
||||
9 files changed, 60 insertions(+), 31 deletions(-)
|
||||
rename Documentation/perf/{arm-ccn.txt => arm-ccn.rst} (86%)
|
||||
rename Documentation/perf/{arm_dsu_pmu.txt => arm_dsu_pmu.rst} (92%)
|
||||
rename Documentation/perf/{hisi-pmu.txt => hisi-pmu.rst} (73%)
|
||||
create mode 100644 Documentation/perf/index.rst
|
||||
rename Documentation/perf/{qcom_l2_pmu.txt => qcom_l2_pmu.rst} (94%)
|
||||
rename Documentation/perf/{qcom_l3_pmu.txt => qcom_l3_pmu.rst} (93%)
|
||||
rename Documentation/perf/{xgene-pmu.txt => xgene-pmu.rst} (96%)
|
||||
|
||||
diff --git a/Documentation/perf/arm-ccn.txt b/Documentation/perf/arm-ccn.rst
|
||||
similarity index 86%
|
||||
rename from Documentation/perf/arm-ccn.txt
|
||||
rename to Documentation/perf/arm-ccn.rst
|
||||
index 15cdb7bc57c3..832b0c64023a 100644
|
||||
--- a/Documentation/perf/arm-ccn.txt
|
||||
+++ b/Documentation/perf/arm-ccn.rst
|
||||
@@ -1,3 +1,4 @@
|
||||
+==========================
|
||||
ARM Cache Coherent Network
|
||||
==========================
|
||||
|
||||
@@ -29,6 +30,7 @@ Crosspoint watchpoint-based events (special "event" value 0xfe)
|
||||
require "xp" and "vc" as as above plus "port" (device port index),
|
||||
"dir" (transmit/receive direction), comparator values ("cmp_l"
|
||||
and "cmp_h") and "mask", being index of the comparator mask.
|
||||
+
|
||||
Masks are defined separately from the event description
|
||||
(due to limited number of the config values) in the "cmp_mask"
|
||||
directory, with first 8 configurable by user and additional
|
||||
@@ -44,16 +46,16 @@ request the events on this processor (if not, the perf_event->cpu value
|
||||
will be overwritten anyway). In case of this processor being offlined,
|
||||
the events are migrated to another one and the attribute is updated.
|
||||
|
||||
-Example of perf tool use:
|
||||
+Example of perf tool use::
|
||||
|
||||
-/ # perf list | grep ccn
|
||||
- ccn/cycles/ [Kernel PMU event]
|
||||
-<...>
|
||||
- ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/ [Kernel PMU event]
|
||||
-<...>
|
||||
+ / # perf list | grep ccn
|
||||
+ ccn/cycles/ [Kernel PMU event]
|
||||
+ <...>
|
||||
+ ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/ [Kernel PMU event]
|
||||
+ <...>
|
||||
|
||||
-/ # perf stat -a -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
||||
- sleep 1
|
||||
+ / # perf stat -a -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
||||
+ sleep 1
|
||||
|
||||
The driver does not support sampling, therefore "perf record" will
|
||||
not work. Per-task (without "-a") perf sessions are not supported.
|
||||
diff --git a/Documentation/perf/arm_dsu_pmu.txt b/Documentation/perf/arm_dsu_pmu.rst
|
||||
similarity index 92%
|
||||
rename from Documentation/perf/arm_dsu_pmu.txt
|
||||
rename to Documentation/perf/arm_dsu_pmu.rst
|
||||
index d611e15f5add..7fd34db75d13 100644
|
||||
--- a/Documentation/perf/arm_dsu_pmu.txt
|
||||
+++ b/Documentation/perf/arm_dsu_pmu.rst
|
||||
@@ -1,3 +1,4 @@
|
||||
+==================================
|
||||
ARM DynamIQ Shared Unit (DSU) PMU
|
||||
==================================
|
||||
|
||||
@@ -13,7 +14,7 @@ PMU doesn't support process specific events and cannot be used in sampling mode.
|
||||
The DSU provides a bitmap for a subset of implemented events via hardware
|
||||
registers. There is no way for the driver to determine if the other events
|
||||
are available or not. Hence the driver exposes only those events advertised
|
||||
-by the DSU, in "events" directory under :
|
||||
+by the DSU, in "events" directory under::
|
||||
|
||||
/sys/bus/event_sources/devices/arm_dsu_<N>/
|
||||
|
||||
@@ -23,6 +24,6 @@ and use the raw event code for the unlisted events.
|
||||
The driver also exposes the CPUs connected to the DSU instance in "associated_cpus".
|
||||
|
||||
|
||||
-e.g usage :
|
||||
+e.g usage::
|
||||
|
||||
perf stat -a -e arm_dsu_0/cycles/
|
||||
diff --git a/Documentation/perf/hisi-pmu.txt b/Documentation/perf/hisi-pmu.rst
|
||||
similarity index 73%
|
||||
rename from Documentation/perf/hisi-pmu.txt
|
||||
rename to Documentation/perf/hisi-pmu.rst
|
||||
index 267a028b2741..404a5c3d9d00 100644
|
||||
--- a/Documentation/perf/hisi-pmu.txt
|
||||
+++ b/Documentation/perf/hisi-pmu.rst
|
||||
@@ -1,5 +1,7 @@
|
||||
+======================================================
|
||||
HiSilicon SoC uncore Performance Monitoring Unit (PMU)
|
||||
======================================================
|
||||
+
|
||||
The HiSilicon SoC chip includes various independent system device PMUs
|
||||
such as L3 cache (L3C), Hydra Home Agent (HHA) and DDRC. These PMUs are
|
||||
independent and have hardware logic to gather statistics and performance
|
||||
@@ -11,11 +13,13 @@ called Super CPU cluster (SCCL) and is made up of 6 CCLs. Each SCCL has
|
||||
two HHAs (0 - 1) and four DDRCs (0 - 3), respectively.
|
||||
|
||||
HiSilicon SoC uncore PMU driver
|
||||
----------------------------------------
|
||||
+-------------------------------
|
||||
+
|
||||
Each device PMU has separate registers for event counting, control and
|
||||
interrupt, and the PMU driver shall register perf PMU drivers like L3C,
|
||||
HHA and DDRC etc. The available events and configuration options shall
|
||||
-be described in the sysfs, see :
|
||||
+be described in the sysfs, see:
|
||||
+
|
||||
/sys/devices/hisi_sccl{X}_<l3c{Y}/hha{Y}/ddrc{Y}>/, or
|
||||
/sys/bus/event_source/devices/hisi_sccl{X}_<l3c{Y}/hha{Y}/ddrc{Y}>.
|
||||
The "perf list" command shall list the available events from sysfs.
|
||||
@@ -24,27 +28,30 @@ Each L3C, HHA and DDRC is registered as a separate PMU with perf. The PMU
|
||||
name will appear in event listing as hisi_sccl<sccl-id>_module<index-id>.
|
||||
where "sccl-id" is the identifier of the SCCL and "index-id" is the index of
|
||||
module.
|
||||
+
|
||||
e.g. hisi_sccl3_l3c0/rd_hit_cpipe is READ_HIT_CPIPE event of L3C index #0 in
|
||||
SCCL ID #3.
|
||||
+
|
||||
e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
|
||||
SCCL ID #1.
|
||||
|
||||
The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
|
||||
ID used to count the uncore PMU event.
|
||||
|
||||
-Example usage of perf:
|
||||
-$# perf list
|
||||
-hisi_sccl3_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
||||
-------------------------------------------
|
||||
-hisi_sccl3_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
||||
-------------------------------------------
|
||||
-hisi_sccl1_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
||||
-------------------------------------------
|
||||
-hisi_sccl1_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
||||
-------------------------------------------
|
||||
-
|
||||
-$# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5
|
||||
-$# perf stat -a -e hisi_sccl3_l3c0/config=0x02/ sleep 5
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf list
|
||||
+ hisi_sccl3_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
||||
+ ------------------------------------------
|
||||
+ hisi_sccl3_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
||||
+ ------------------------------------------
|
||||
+ hisi_sccl1_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
||||
+ ------------------------------------------
|
||||
+ hisi_sccl1_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
||||
+ ------------------------------------------
|
||||
+
|
||||
+ $# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5
|
||||
+ $# perf stat -a -e hisi_sccl3_l3c0/config=0x02/ sleep 5
|
||||
|
||||
The current driver does not support sampling. So "perf record" is unsupported.
|
||||
Also attach to a task is unsupported as the events are all uncore.
|
||||
diff --git a/Documentation/perf/index.rst b/Documentation/perf/index.rst
|
||||
new file mode 100644
|
||||
index 000000000000..4bf848e27f26
|
||||
--- /dev/null
|
||||
+++ b/Documentation/perf/index.rst
|
||||
@@ -0,0 +1,16 @@
|
||||
+:orphan:
|
||||
+
|
||||
+===========================
|
||||
+Performance monitor support
|
||||
+===========================
|
||||
+
|
||||
+.. toctree::
|
||||
+ :maxdepth: 1
|
||||
+
|
||||
+ hisi-pmu
|
||||
+ qcom_l2_pmu
|
||||
+ qcom_l3_pmu
|
||||
+ arm-ccn
|
||||
+ xgene-pmu
|
||||
+ arm_dsu_pmu
|
||||
+ thunderx2-pmu
|
||||
diff --git a/Documentation/perf/qcom_l2_pmu.txt b/Documentation/perf/qcom_l2_pmu.rst
|
||||
similarity index 94%
|
||||
rename from Documentation/perf/qcom_l2_pmu.txt
|
||||
rename to Documentation/perf/qcom_l2_pmu.rst
|
||||
index b25b97659ab9..c130178a4a55 100644
|
||||
--- a/Documentation/perf/qcom_l2_pmu.txt
|
||||
+++ b/Documentation/perf/qcom_l2_pmu.rst
|
||||
@@ -1,3 +1,4 @@
|
||||
+=====================================================================
|
||||
Qualcomm Technologies Level-2 Cache Performance Monitoring Unit (PMU)
|
||||
=====================================================================
|
||||
|
||||
@@ -28,7 +29,7 @@ The driver provides a "cpumask" sysfs attribute which contains a mask
|
||||
consisting of one CPU per cluster which will be used to handle all the PMU
|
||||
events on that cluster.
|
||||
|
||||
-Examples for use with perf:
|
||||
+Examples for use with perf::
|
||||
|
||||
perf stat -e l2cache_0/config=0x001/,l2cache_0/config=0x042/ -a sleep 1
|
||||
|
||||
diff --git a/Documentation/perf/qcom_l3_pmu.txt b/Documentation/perf/qcom_l3_pmu.rst
|
||||
similarity index 93%
|
||||
rename from Documentation/perf/qcom_l3_pmu.txt
|
||||
rename to Documentation/perf/qcom_l3_pmu.rst
|
||||
index 96b3a9444a0d..a3d014a46bfd 100644
|
||||
--- a/Documentation/perf/qcom_l3_pmu.txt
|
||||
+++ b/Documentation/perf/qcom_l3_pmu.rst
|
||||
@@ -1,3 +1,4 @@
|
||||
+===========================================================================
|
||||
Qualcomm Datacenter Technologies L3 Cache Performance Monitoring Unit (PMU)
|
||||
===========================================================================
|
||||
|
||||
@@ -17,7 +18,7 @@ The hardware implements 32bit event counters and has a flat 8bit event space
|
||||
exposed via the "event" format attribute. In addition to the 32bit physical
|
||||
counters the driver supports virtual 64bit hardware counters by using hardware
|
||||
counter chaining. This feature is exposed via the "lc" (long counter) format
|
||||
-flag. E.g.:
|
||||
+flag. E.g.::
|
||||
|
||||
perf stat -e l3cache_0_0/read-miss,lc/
|
||||
|
||||
diff --git a/Documentation/perf/xgene-pmu.txt b/Documentation/perf/xgene-pmu.rst
|
||||
similarity index 96%
|
||||
rename from Documentation/perf/xgene-pmu.txt
|
||||
rename to Documentation/perf/xgene-pmu.rst
|
||||
index d7cff4454e5b..644f8ed89152 100644
|
||||
--- a/Documentation/perf/xgene-pmu.txt
|
||||
+++ b/Documentation/perf/xgene-pmu.rst
|
||||
@@ -1,3 +1,4 @@
|
||||
+================================================
|
||||
APM X-Gene SoC Performance Monitoring Unit (PMU)
|
||||
================================================
|
||||
|
||||
@@ -33,7 +34,7 @@ each PMU, please refer to APM X-Gene User Manual.
|
||||
Each perf driver also provides a "cpumask" sysfs attribute, which contains a
|
||||
single CPU ID of the processor which will be used to handle all the PMU events.
|
||||
|
||||
-Example for perf tool use:
|
||||
+Example for perf tool use::
|
||||
|
||||
/ # perf list | grep -e l3c -e iob -e mcb -e mc
|
||||
l3c0/ackq-full/ [Kernel PMU event]
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 5d0b782c973c..0b2a68401b0e 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1040,7 +1040,7 @@ APPLIED MICRO (APM) X-GENE SOC PMU
|
||||
M: Tai Nguyen <ttnguyen@apm.com>
|
||||
S: Supported
|
||||
F: drivers/perf/xgene_pmu.c
|
||||
-F: Documentation/perf/xgene-pmu.txt
|
||||
+F: Documentation/perf/xgene-pmu.rst
|
||||
F: Documentation/devicetree/bindings/perf/apm-xgene-pmu.txt
|
||||
|
||||
APTINA CAMERA SENSOR PLL
|
||||
@@ -6663,7 +6663,7 @@ M: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
W: http://www.hisilicon.com
|
||||
S: Supported
|
||||
F: drivers/perf/hisilicon
|
||||
-F: Documentation/perf/hisi-pmu.txt
|
||||
+F: Documentation/perf/hisi-pmu.rst
|
||||
|
||||
HISILICON PTT DRIVER
|
||||
M: Yicong Yang <yangyicong@hisilicon.com>
|
||||
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
|
||||
index b349e7bf4dd9..cc88dc92577e 100644
|
||||
--- a/drivers/perf/qcom_l3_pmu.c
|
||||
+++ b/drivers/perf/qcom_l3_pmu.c
|
||||
@@ -7,7 +7,7 @@
|
||||
* the slices. User space needs to aggregate to individual counts to provide
|
||||
* a global picture.
|
||||
*
|
||||
- * See Documentation/perf/qcom_l3_pmu.txt for more details.
|
||||
+ * See Documentation/perf/qcom_l3_pmu.rst for more details.
|
||||
*
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,113 @@
|
||||
From 7901f6e0c3c188badd67a49ba546df8da2f0a123 Mon Sep 17 00:00:00 2001
|
||||
From: Qi Liu <liuqi115@huawei.com>
|
||||
Date: Thu, 16 Jul 2020 17:19:25 +0800
|
||||
Subject: [PATCH 08/55] drivers/perf: Fix kernel panic when rmmod PMU modules
|
||||
during perf sampling
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.8-rc1
|
||||
commit bdc5c744c7b6457d18a95c26769dad0e7f480a08
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bdc5c744c7b6457d18a95c26769dad0e7f480a08
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When users try to remove PMU modules during perf sampling, kernel panic
|
||||
will happen because the pmu->read() is a NULL pointer here.
|
||||
|
||||
INFO on HiSilicon hip08 platform as follow:
|
||||
pc : hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
|
||||
lr : hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
|
||||
sp : ffff800010103e90
|
||||
x29: ffff800010103e90 x28: ffff0027db0c0e40
|
||||
x27: ffffa29a76f129d8 x26: ffffa29a77ceb000
|
||||
x25: ffffa29a773a5000 x24: ffffa29a77392000
|
||||
x23: ffffddffe5943f08 x22: ffff002784285960
|
||||
x21: ffff002784285800 x20: ffff0027d2e76c80
|
||||
x19: ffff0027842859e0 x18: ffff80003498bcc8
|
||||
x17: ffffa29a76afe910 x16: ffffa29a7583f530
|
||||
x15: 16151a1512061a1e x14: 0000000000000000
|
||||
x13: ffffa29a76f1e238 x12: 0000000000000001
|
||||
x11: 0000000000000400 x10: 00000000000009f0
|
||||
x9 : ffff8000107b3e70 x8 : ffff0027db0c1890
|
||||
x7 : ffffa29a773a7000 x6 : 00000007f5131013
|
||||
x5 : 00000007f5131013 x4 : 09f257d417c00000
|
||||
x3 : 00000002187bd7ce x2 : ffffa29a38f0f0d8
|
||||
x1 : ffffa29a38eae268 x0 : ffff0027d2e76c80
|
||||
Call trace:
|
||||
hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
|
||||
hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
|
||||
__perf_event_read+0x1a0/0x1f8
|
||||
flush_smp_call_function_queue+0xa0/0x160
|
||||
generic_smp_call_function_single_interrupt+0x18/0x20
|
||||
handle_IPI+0x31c/0x4dc
|
||||
gic_handle_irq+0x2c8/0x310
|
||||
el1_irq+0xcc/0x180
|
||||
arch_cpu_idle+0x4c/0x20c
|
||||
default_idle_call+0x20/0x30
|
||||
do_idle+0x1b4/0x270
|
||||
cpu_startup_entry+0x28/0x30
|
||||
secondary_start_kernel+0x1a4/0x1fc
|
||||
|
||||
To solve the above issue, current module should be registered to kernel,
|
||||
so that try_module_get() can be invoked when perf sampling starts. This
|
||||
adds the reference counting of module and could prevent users from removing
|
||||
modules during sampling.
|
||||
|
||||
Reported-by: Haifeng Wang <wang.wanghaifeng@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Link: https://lore.kernel.org/r/1594891165-8228-1-git-send-email-liuqi115@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/fsl_imx8_ddr_perf.c
|
||||
drivers/perf/arm_smmuv3_pmu.c
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 1 +
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 1 +
|
||||
3 files changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index b3488ae1f2b8..620fa1345150 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -386,6 +386,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
||||
ddrc_pmu->pmu = (struct pmu) {
|
||||
.name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.event_init = hisi_uncore_pmu_event_init,
|
||||
.pmu_enable = hisi_uncore_pmu_enable,
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index f0215d50d84d..33a0da941be2 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -397,6 +397,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
hha_pmu->pmu = (struct pmu) {
|
||||
.name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.event_init = hisi_uncore_pmu_event_init,
|
||||
.pmu_enable = hisi_uncore_pmu_enable,
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 11563e29d983..92485f00dcc8 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -387,6 +387,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
l3c_pmu->sccl_id, l3c_pmu->index_id);
|
||||
l3c_pmu->pmu = (struct pmu) {
|
||||
.name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
.task_ctx_nr = perf_invalid_context,
|
||||
.event_init = hisi_uncore_pmu_event_init,
|
||||
.pmu_enable = hisi_uncore_pmu_enable,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,194 @@
|
||||
From 6d7245609c516aae8719e8d27b737337635ad8c3 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Murray <andrew.murray@arm.com>
|
||||
Date: Thu, 10 Jan 2019 13:53:29 +0000
|
||||
Subject: [PATCH 09/55] For drivers that do not support context exclusion let's
|
||||
advertise the PERF_PMU_CAP_NO_EXCLUDE capability. This ensures that perf will
|
||||
prevent us from handling events where any exclusion flags are set. Let's also
|
||||
remove the now unnecessary check for exclusion flags.
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.1-rc1
|
||||
commit 306563985819ed2af9df0a26ae368ed12cf28f41
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?=306563985819ed2af9df0a26ae368ed12cf28f41
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
|
||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
||||
Acked-by: Will Deacon <will.deacon@arm.com>
|
||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Cc: Borislav Petkov <bp@alien8.de>
|
||||
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Matt Turner <mattst88@gmail.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Paul Mackerras <paulus@samba.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Richard Henderson <rth@twiddle.net>
|
||||
Cc: Russell King <linux@armlinux.org.uk>
|
||||
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
||||
Cc: Shawn Guo <shawnguo@kernel.org>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Cc: linuxppc-dev@lists.ozlabs.org
|
||||
Cc: robin.murphy@arm.com
|
||||
Cc: suzuki.poulose@arm.com
|
||||
Link: https://lkml.kernel.org/r/1547128414-50693-8-git-send-email-andrew.murray@arm.com
|
||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/thunderx2_pmu.c
|
||||
---
|
||||
drivers/perf/arm-cci.c | 10 +---------
|
||||
drivers/perf/arm-ccn.c | 6 ++----
|
||||
drivers/perf/arm_dsu_pmu.c | 9 ++-------
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 1 +
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 1 +
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 9 ---------
|
||||
7 files changed, 8 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
|
||||
index 3bbc853dc12f..aca4570f78a8 100644
|
||||
--- a/drivers/perf/arm-cci.c
|
||||
+++ b/drivers/perf/arm-cci.c
|
||||
@@ -1327,15 +1327,6 @@ static int cci_pmu_event_init(struct perf_event *event)
|
||||
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- /* We have no filtering of any kind */
|
||||
- if (event->attr.exclude_user ||
|
||||
- event->attr.exclude_kernel ||
|
||||
- event->attr.exclude_hv ||
|
||||
- event->attr.exclude_idle ||
|
||||
- event->attr.exclude_host ||
|
||||
- event->attr.exclude_guest)
|
||||
- return -EINVAL;
|
||||
-
|
||||
/*
|
||||
* Following the example set by other "uncore" PMUs, we accept any CPU
|
||||
* and rewrite its affinity dynamically rather than having perf core
|
||||
@@ -1433,6 +1424,7 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
|
||||
.stop = cci_pmu_stop,
|
||||
.read = pmu_read,
|
||||
.attr_groups = pmu_attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
cci_pmu->plat_device = pdev;
|
||||
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
|
||||
index e4e06d2fbe29..e13ff765b362 100644
|
||||
--- a/drivers/perf/arm-ccn.c
|
||||
+++ b/drivers/perf/arm-ccn.c
|
||||
@@ -741,10 +741,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
- if (has_branch_stack(event) || event->attr.exclude_user ||
|
||||
- event->attr.exclude_kernel || event->attr.exclude_hv ||
|
||||
- event->attr.exclude_idle || event->attr.exclude_host ||
|
||||
- event->attr.exclude_guest) {
|
||||
+ if (has_branch_stack(event)) {
|
||||
dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1290,6 +1287,7 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
|
||||
.read = arm_ccn_pmu_event_read,
|
||||
.pmu_enable = arm_ccn_pmu_enable,
|
||||
.pmu_disable = arm_ccn_pmu_disable,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
/* No overflow interrupt? Have to use a timer instead. */
|
||||
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
|
||||
index f1cb7a910394..87573eaa7fdd 100644
|
||||
--- a/drivers/perf/arm_dsu_pmu.c
|
||||
+++ b/drivers/perf/arm_dsu_pmu.c
|
||||
@@ -562,13 +562,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (has_branch_stack(event) ||
|
||||
- event->attr.exclude_user ||
|
||||
- event->attr.exclude_kernel ||
|
||||
- event->attr.exclude_hv ||
|
||||
- event->attr.exclude_idle ||
|
||||
- event->attr.exclude_host ||
|
||||
- event->attr.exclude_guest) {
|
||||
+ if (has_branch_stack(event)) {
|
||||
dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -735,6 +729,7 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
|
||||
.read = dsu_pmu_read,
|
||||
|
||||
.attr_groups = dsu_pmu_attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
rc = perf_pmu_register(&dsu_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 620fa1345150..4bab34504425 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -397,6 +397,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
.attr_groups = hisi_ddrc_pmu_attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 33a0da941be2..53711b945551 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -408,6 +408,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
.attr_groups = hisi_hha_pmu_attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 92485f00dcc8..171cf74405b3 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -398,6 +398,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
.attr_groups = hisi_l3c_pmu_attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 53f623ac4cc6..50b654a13305 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -148,15 +148,6 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
|
||||
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
- /* counters do not have these bits */
|
||||
- if (event->attr.exclude_user ||
|
||||
- event->attr.exclude_kernel ||
|
||||
- event->attr.exclude_host ||
|
||||
- event->attr.exclude_guest ||
|
||||
- event->attr.exclude_hv ||
|
||||
- event->attr.exclude_idle)
|
||||
- return -EINVAL;
|
||||
-
|
||||
/*
|
||||
* The uncore counters not specific to any CPU, so cannot
|
||||
* support per-task
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
From 9adb641d4a64e0ed52ba63ea401a9858efe8976d Mon Sep 17 00:00:00 2001
|
||||
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
||||
Date: Wed, 20 Feb 2019 11:12:39 +0000
|
||||
Subject: [PATCH 10/55] drivers: provide devm_platform_ioremap_resource()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.1-rc1
|
||||
commit 306563985819ed2af9df0a26ae368ed12cf28f41
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=306563985819ed2af9df0a26ae368ed12cf28f41
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
There are currently 1200+ instances of using platform_get_resource()
|
||||
and devm_ioremap_resource() together in the kernel tree.
|
||||
|
||||
This patch wraps these two calls in a single helper. Thanks to that
|
||||
we don't have to declare a local variable for struct resource * and can
|
||||
omit the redundant argument for resource type. We also have one
|
||||
function call less.
|
||||
|
||||
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/base/platform.c | 18 ++++++++++++++++++
|
||||
include/linux/platform_device.h | 3 +++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
|
||||
index be8c82cc4445..23ec70ef6897 100644
|
||||
--- a/drivers/base/platform.c
|
||||
+++ b/drivers/base/platform.c
|
||||
@@ -80,6 +80,24 @@ struct resource *platform_get_resource(struct platform_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(platform_get_resource);
|
||||
|
||||
+/**
|
||||
+ * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
|
||||
+ * device
|
||||
+ *
|
||||
+ * @pdev: platform device to use both for memory resource lookup as well as
|
||||
+ * resource managemend
|
||||
+ * @index: resource index
|
||||
+ */
|
||||
+void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
|
||||
+ unsigned int index)
|
||||
+{
|
||||
+ struct resource *res;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, index);
|
||||
+ return devm_ioremap_resource(&pdev->dev, res);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource);
|
||||
+
|
||||
/**
|
||||
* platform_get_irq - get an IRQ for a device
|
||||
* @dev: platform device
|
||||
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
|
||||
index 1a9f38f27f65..9e5c98fcea8c 100644
|
||||
--- a/include/linux/platform_device.h
|
||||
+++ b/include/linux/platform_device.h
|
||||
@@ -51,6 +51,9 @@ extern struct device platform_bus;
|
||||
extern void arch_setup_pdev_archdata(struct platform_device *);
|
||||
extern struct resource *platform_get_resource(struct platform_device *,
|
||||
unsigned int, unsigned int);
|
||||
+extern void __iomem *
|
||||
+devm_platform_ioremap_resource(struct platform_device *pdev,
|
||||
+ unsigned int index);
|
||||
extern int platform_get_irq(struct platform_device *, unsigned int);
|
||||
extern int platform_irq_count(struct platform_device *);
|
||||
extern struct resource *platform_get_resource_byname(struct platform_device *,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
From ce76ffbdbb8cf7dcdc4bbd2988971202f4ab7e0f Mon Sep 17 00:00:00 2001
|
||||
From: YueHaibing <yuehaibing@huawei.com>
|
||||
Date: Fri, 6 Sep 2019 22:36:44 +0800
|
||||
Subject: [PATCH 11/55] perf: hisi: use devm_platform_ioremap_resource() to
|
||||
simplify code
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.5-rc1
|
||||
commit 42c184ade43a79d36f50a0b3394b3326633f53f5
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42c184ade43a79d36f50a0b3394b3326633f53f5
|
||||
|
||||
---------------------------------------------------------------
|
||||
|
||||
Use devm_platform_ioremap_resource() to simplify the code a bit.
|
||||
This is detected by coccinelle.
|
||||
|
||||
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 5 +----
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 4 +---
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 4 +---
|
||||
3 files changed, 3 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 4bab34504425..5d9dd4078994 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -248,8 +248,6 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
|
||||
static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
- struct resource *res;
|
||||
-
|
||||
/*
|
||||
* Use the SCCL_ID and DDRC channel ID to identify the
|
||||
* DDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
||||
@@ -268,8 +266,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
/* DDRC PMUs only share the same SCCL */
|
||||
ddrc_pmu->ccl_id = -1;
|
||||
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- ddrc_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ddrc_pmu->base)) {
|
||||
dev_err(&pdev->dev, "ioremap failed for ddrc_pmu resource\n");
|
||||
return PTR_ERR(ddrc_pmu->base);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 53711b945551..d3c517325a3f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -239,7 +239,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *hha_pmu)
|
||||
{
|
||||
unsigned long long id;
|
||||
- struct resource *res;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
@@ -261,8 +260,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
/* HHA PMUs only share the same SCCL */
|
||||
hha_pmu->ccl_id = -1;
|
||||
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- hha_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(hha_pmu->base)) {
|
||||
dev_err(&pdev->dev, "ioremap failed for hha_pmu resource\n");
|
||||
return PTR_ERR(hha_pmu->base);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 171cf74405b3..cbbf73ea66e6 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -238,7 +238,6 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *l3c_pmu)
|
||||
{
|
||||
unsigned long long id;
|
||||
- struct resource *res;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
@@ -264,8 +263,7 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
- l3c_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ l3c_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(l3c_pmu->base)) {
|
||||
dev_err(&pdev->dev, "ioremap failed for l3c_pmu resource\n");
|
||||
return PTR_ERR(l3c_pmu->base);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
218
patches/0053-drivers-perf-hisi-Add-identifier-sysfs-file.patch
Normal file
218
patches/0053-drivers-perf-hisi-Add-identifier-sysfs-file.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From 7da4fb60563da82f9b482af152909d29818b5d9e Mon Sep 17 00:00:00 2001
|
||||
From: John Garry <john.garry@huawei.com>
|
||||
Date: Fri, 30 Jul 2021 15:43:58 +0800
|
||||
Subject: [PATCH 12/55] drivers/perf: hisi: Add identifier sysfs file
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.10-rc3
|
||||
commit ac4511c9364c9a6390e8585cdd4596103bca16eb
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ac4511c9364c9a6390e8585cdd4596103bca16eb
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
To allow userspace to identify the specific implementation of the device,
|
||||
add an "identifier" sysfs file.
|
||||
|
||||
Encoding is as follows (same for all uncore drivers):
|
||||
hi1620: 0x0
|
||||
hi1630: 0x30
|
||||
|
||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
||||
Link: https://lore.kernel.org/r/1602149181-237415-2-git-send-email-john.garry@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 16 ++++++++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 16 ++++++++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 16 ++++++++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 10 ++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 7 +++++++
|
||||
5 files changed, 65 insertions(+)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 5d9dd4078994..a88c7d840d38 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#define DDRC_INT_MASK 0x6c8
|
||||
#define DDRC_INT_STATUS 0x6cc
|
||||
#define DDRC_INT_CLEAR 0x6d0
|
||||
+#define DDRC_VERSION 0x710
|
||||
|
||||
/* DDRC has 8-counters */
|
||||
#define DDRC_NR_COUNTERS 0x8
|
||||
@@ -272,6 +273,8 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
return PTR_ERR(ddrc_pmu->base);
|
||||
}
|
||||
|
||||
+ ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -313,10 +316,23 @@ static const struct attribute_group hisi_ddrc_pmu_cpumask_attr_group = {
|
||||
.attrs = hisi_ddrc_pmu_cpumask_attrs,
|
||||
};
|
||||
|
||||
+static struct device_attribute hisi_ddrc_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_ddrc_pmu_identifier_attrs[] = {
|
||||
+ &hisi_ddrc_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_ddrc_pmu_identifier_group = {
|
||||
+ .attrs = hisi_ddrc_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
static const struct attribute_group *hisi_ddrc_pmu_attr_groups[] = {
|
||||
&hisi_ddrc_pmu_format_group,
|
||||
&hisi_ddrc_pmu_events_group,
|
||||
&hisi_ddrc_pmu_cpumask_attr_group,
|
||||
+ &hisi_ddrc_pmu_identifier_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index d3c517325a3f..1e0138bbe6e7 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#define HHA_INT_MASK 0x0804
|
||||
#define HHA_INT_STATUS 0x0808
|
||||
#define HHA_INT_CLEAR 0x080C
|
||||
+#define HHA_VERSION 0x1cf0
|
||||
#define HHA_PERF_CTRL 0x1E00
|
||||
#define HHA_EVENT_CTRL 0x1E04
|
||||
#define HHA_EVENT_TYPE0 0x1E80
|
||||
@@ -266,6 +267,8 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
return PTR_ERR(hha_pmu->base);
|
||||
}
|
||||
|
||||
+ hha_pmu->identifier = readl(hha_pmu->base + HHA_VERSION);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -325,10 +328,23 @@ static const struct attribute_group hisi_hha_pmu_cpumask_attr_group = {
|
||||
.attrs = hisi_hha_pmu_cpumask_attrs,
|
||||
};
|
||||
|
||||
+static struct device_attribute hisi_hha_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_hha_pmu_identifier_attrs[] = {
|
||||
+ &hisi_hha_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_hha_pmu_identifier_group = {
|
||||
+ .attrs = hisi_hha_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
static const struct attribute_group *hisi_hha_pmu_attr_groups[] = {
|
||||
&hisi_hha_pmu_format_group,
|
||||
&hisi_hha_pmu_events_group,
|
||||
&hisi_hha_pmu_cpumask_attr_group,
|
||||
+ &hisi_hha_pmu_identifier_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index cbbf73ea66e6..1707ae551ece 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#define L3C_INT_STATUS 0x0808
|
||||
#define L3C_INT_CLEAR 0x080c
|
||||
#define L3C_EVENT_CTRL 0x1c00
|
||||
+#define L3C_VERSION 0x1cf0
|
||||
#define L3C_EVENT_TYPE0 0x1d00
|
||||
/*
|
||||
* Each counter is 48-bits and [48:63] are reserved
|
||||
@@ -269,6 +270,8 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
return PTR_ERR(l3c_pmu->base);
|
||||
}
|
||||
|
||||
+ l3c_pmu->identifier = readl(l3c_pmu->base + L3C_VERSION);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -315,10 +318,23 @@ static const struct attribute_group hisi_l3c_pmu_cpumask_attr_group = {
|
||||
.attrs = hisi_l3c_pmu_cpumask_attrs,
|
||||
};
|
||||
|
||||
+static struct device_attribute hisi_l3c_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_l3c_pmu_identifier_attrs[] = {
|
||||
+ &hisi_l3c_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_l3c_pmu_identifier_group = {
|
||||
+ .attrs = hisi_l3c_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
static const struct attribute_group *hisi_l3c_pmu_attr_groups[] = {
|
||||
&hisi_l3c_pmu_format_group,
|
||||
&hisi_l3c_pmu_events_group,
|
||||
&hisi_l3c_pmu_cpumask_attr_group,
|
||||
+ &hisi_l3c_pmu_identifier_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 50b654a13305..f6a992da24bf 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -122,6 +122,16 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx);
|
||||
|
||||
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *page)
|
||||
+{
|
||||
+ struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
|
||||
+
|
||||
+ return snprintf(page, PAGE_SIZE, "0x%08x\n", hisi_pmu->identifier);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
|
||||
+
|
||||
static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
||||
{
|
||||
if (!hisi_uncore_pmu_counter_valid(hisi_pmu, idx)) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 8f2f2fc5dde4..098a8f6dc7ee 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -78,6 +78,7 @@ struct hisi_pmu {
|
||||
int counter_bits;
|
||||
/* check event code range */
|
||||
int check_event;
|
||||
+ u32 identifier;
|
||||
};
|
||||
|
||||
int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx);
|
||||
@@ -100,4 +101,10 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
|
||||
int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
||||
+
|
||||
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ char *page);
|
||||
+
|
||||
+
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,193 @@
|
||||
From 34861133469cfd5c5851f7f4ab05e3d3af1dd13a Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:02 +0800
|
||||
Subject: [PATCH 13/55] drivers/perf: hisi: Remove unnecessary check of counter
|
||||
index
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit 4e4cb8ca48bd68c00df67c10ff867016abb7391f
|
||||
category: cleanup
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e4cb8ca48bd68c00df67c10ff867016abb7391f
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
The sanity check for counter index has been done in the function
|
||||
hisi_uncore_pmu_get_event_idx, so remove the redundant interface
|
||||
hisi_uncore_pmu_counter_valid() and sanity check.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-2-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 20 +++----------------
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 18 ++---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 18 ++---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 11 ----------
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 1 -
|
||||
5 files changed, 7 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index a88c7d840d38..bcb2c2d66b7f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -68,29 +68,15 @@ static u32 hisi_ddrc_pmu_get_counter_offset(int cntr_idx)
|
||||
static u64 hisi_ddrc_pmu_read_counter(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
- /* Use event code as counter index */
|
||||
- u32 idx = GET_DDRC_EVENTID(hwc);
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(ddrc_pmu, idx)) {
|
||||
- dev_err(ddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return readl(ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(idx));
|
||||
+ return readl(ddrc_pmu->base +
|
||||
+ hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_ddrc_pmu_write_counter(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc, u64 val)
|
||||
{
|
||||
- u32 idx = GET_DDRC_EVENTID(hwc);
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(ddrc_pmu, idx)) {
|
||||
- dev_err(ddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
writel((u32)val,
|
||||
- ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(idx));
|
||||
+ ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 1e0138bbe6e7..de1766342b4e 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -54,29 +54,15 @@ static u32 hisi_hha_pmu_get_counter_offset(u32 cntr_idx)
|
||||
static u64 hisi_hha_pmu_read_counter(struct hisi_pmu *hha_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(hha_pmu, idx)) {
|
||||
- dev_err(hha_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
/* Read 64 bits and like L3C, top 16 bits are RAZ */
|
||||
- return readq(hha_pmu->base + hisi_hha_pmu_get_counter_offset(idx));
|
||||
+ return readq(hha_pmu->base + hisi_hha_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_hha_pmu_write_counter(struct hisi_pmu *hha_pmu,
|
||||
struct hw_perf_event *hwc, u64 val)
|
||||
{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(hha_pmu, idx)) {
|
||||
- dev_err(hha_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
/* Write 64 bits and like L3C, top 16 bits are WI */
|
||||
- writeq(val, hha_pmu->base + hisi_hha_pmu_get_counter_offset(idx));
|
||||
+ writeq(val, hha_pmu->base + hisi_hha_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_hha_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 1707ae551ece..c4afeaaaa3a4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -53,29 +53,15 @@ static u32 hisi_l3c_pmu_get_counter_offset(u32 cntr_idx)
|
||||
static u64 hisi_l3c_pmu_read_counter(struct hisi_pmu *l3c_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(l3c_pmu, idx)) {
|
||||
- dev_err(l3c_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
/* Read 64-bits and the upper 16 bits are RAZ */
|
||||
- return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(idx));
|
||||
+ return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_l3c_pmu_write_counter(struct hisi_pmu *l3c_pmu,
|
||||
struct hw_perf_event *hwc, u64 val)
|
||||
{
|
||||
- u32 idx = hwc->idx;
|
||||
-
|
||||
- if (!hisi_uncore_pmu_counter_valid(l3c_pmu, idx)) {
|
||||
- dev_err(l3c_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
/* Write 64-bits and the upper 16 bits are WI */
|
||||
- writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(idx));
|
||||
+ writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_l3c_pmu_write_evtype(struct hisi_pmu *l3c_pmu, int idx,
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index f6a992da24bf..9ebdb76dd3a4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -99,12 +99,6 @@ static bool hisi_validate_event_group(struct perf_event *event)
|
||||
return counters <= hisi_pmu->num_counters;
|
||||
}
|
||||
|
||||
-int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx)
|
||||
-{
|
||||
- return idx >= 0 && idx < hisi_pmu->num_counters;
|
||||
-}
|
||||
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_counter_valid);
|
||||
-
|
||||
int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
|
||||
{
|
||||
struct hisi_pmu *hisi_pmu = to_hisi_pmu(event->pmu);
|
||||
@@ -134,11 +128,6 @@ EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
|
||||
|
||||
static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
||||
{
|
||||
- if (!hisi_uncore_pmu_counter_valid(hisi_pmu, idx)) {
|
||||
- dev_err(hisi_pmu->dev, "Unsupported event index:%d!\n", idx);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
clear_bit(idx, hisi_pmu->pmu_events.used_mask);
|
||||
}
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 098a8f6dc7ee..d71a6c86b282 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -81,7 +81,6 @@ struct hisi_pmu {
|
||||
u32 identifier;
|
||||
};
|
||||
|
||||
-int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx);
|
||||
int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
|
||||
void hisi_uncore_pmu_read(struct perf_event *event);
|
||||
int hisi_uncore_pmu_add(struct perf_event *event, int flags);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,448 @@
|
||||
From 990f0977794c7bc3a78dbea66e3b5e276eccaad4 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:03 +0800
|
||||
Subject: [PATCH 14/55] drivers/perf: hisi: Refactor code for more uncore PMUs
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit baff06c315a146a6943b4fcabb4fe4fa36167413
|
||||
category: cleanup
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=baff06c315a146a6943b4fcabb4fe4fa36167413
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
On HiSilicon uncore PMU drivers, interrupt handling function and interrupt
|
||||
registration function are very similar in differents PMU modules. Let's
|
||||
refactor the frame.
|
||||
|
||||
Two new callbacks are added for the HW accessors:
|
||||
|
||||
* hisi_uncore_ops::get_int_status returns a bitmap of events which
|
||||
have overflowed and raised an interrupt
|
||||
|
||||
* hisi_uncore_ops::clear_int_status clears the overflow status for a
|
||||
specific event
|
||||
|
||||
These callback functions are used by a common IRQ handler,
|
||||
hisi_uncore_pmu_isr().
|
||||
|
||||
One more function hisi_uncore_pmu_init_irq() is added to replace each
|
||||
PMU initialization IRQ interface and simplify the code.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-3-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 61 +++----------------
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 61 +++----------------
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 61 +++----------------
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 54 ++++++++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 6 +-
|
||||
5 files changed, 80 insertions(+), 163 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index bcb2c2d66b7f..a03e3f8058b3 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
@@ -168,62 +167,14 @@ static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
||||
}
|
||||
|
||||
-static irqreturn_t hisi_ddrc_pmu_isr(int irq, void *dev_id)
|
||||
+static u32 hisi_ddrc_pmu_get_int_status(struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
- struct hisi_pmu *ddrc_pmu = dev_id;
|
||||
- struct perf_event *event;
|
||||
- unsigned long overflown;
|
||||
- int idx;
|
||||
-
|
||||
- /* Read the DDRC_INT_STATUS register */
|
||||
- overflown = readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
||||
- if (!overflown)
|
||||
- return IRQ_NONE;
|
||||
-
|
||||
- /*
|
||||
- * Find the counter index which overflowed if the bit was set
|
||||
- * and handle it
|
||||
- */
|
||||
- for_each_set_bit(idx, &overflown, DDRC_NR_COUNTERS) {
|
||||
- /* Write 1 to clear the IRQ status flag */
|
||||
- writel((1 << idx), ddrc_pmu->base + DDRC_INT_CLEAR);
|
||||
-
|
||||
- /* Get the corresponding event struct */
|
||||
- event = ddrc_pmu->pmu_events.hw_events[idx];
|
||||
- if (!event)
|
||||
- continue;
|
||||
-
|
||||
- hisi_uncore_pmu_event_update(event);
|
||||
- hisi_uncore_pmu_set_event_period(event);
|
||||
- }
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
+ return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
||||
}
|
||||
|
||||
-static int hisi_ddrc_pmu_init_irq(struct hisi_pmu *ddrc_pmu,
|
||||
- struct platform_device *pdev)
|
||||
+static void hisi_ddrc_pmu_clear_int_status(struct hisi_pmu *ddrc_pmu, int idx)
|
||||
{
|
||||
- int irq, ret;
|
||||
-
|
||||
- /* Read and init IRQ */
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "DDRC PMU get irq fail; irq:%d\n", irq);
|
||||
- return irq;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_ddrc_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
||||
- dev_name(&pdev->dev), ddrc_pmu);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- ddrc_pmu->irq = irq;
|
||||
-
|
||||
- return 0;
|
||||
+ writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id hisi_ddrc_pmu_acpi_match[] = {
|
||||
@@ -333,6 +284,8 @@ static const struct hisi_uncore_ops hisi_uncore_ddrc_ops = {
|
||||
.disable_counter_int = hisi_ddrc_pmu_disable_counter_int,
|
||||
.write_counter = hisi_ddrc_pmu_write_counter,
|
||||
.read_counter = hisi_ddrc_pmu_read_counter,
|
||||
+ .get_int_status = hisi_ddrc_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_ddrc_pmu_clear_int_status,
|
||||
};
|
||||
|
||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -344,7 +297,7 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = hisi_ddrc_pmu_init_irq(ddrc_pmu, pdev);
|
||||
+ ret = hisi_uncore_pmu_init_irq(ddrc_pmu, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index de1766342b4e..536d1f637fa7 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
@@ -158,62 +157,14 @@ static void hisi_hha_pmu_disable_counter_int(struct hisi_pmu *hha_pmu,
|
||||
writel(val, hha_pmu->base + HHA_INT_MASK);
|
||||
}
|
||||
|
||||
-static irqreturn_t hisi_hha_pmu_isr(int irq, void *dev_id)
|
||||
+static u32 hisi_hha_pmu_get_int_status(struct hisi_pmu *hha_pmu)
|
||||
{
|
||||
- struct hisi_pmu *hha_pmu = dev_id;
|
||||
- struct perf_event *event;
|
||||
- unsigned long overflown;
|
||||
- int idx;
|
||||
-
|
||||
- /* Read HHA_INT_STATUS register */
|
||||
- overflown = readl(hha_pmu->base + HHA_INT_STATUS);
|
||||
- if (!overflown)
|
||||
- return IRQ_NONE;
|
||||
-
|
||||
- /*
|
||||
- * Find the counter index which overflowed if the bit was set
|
||||
- * and handle it
|
||||
- */
|
||||
- for_each_set_bit(idx, &overflown, HHA_NR_COUNTERS) {
|
||||
- /* Write 1 to clear the IRQ status flag */
|
||||
- writel((1 << idx), hha_pmu->base + HHA_INT_CLEAR);
|
||||
-
|
||||
- /* Get the corresponding event struct */
|
||||
- event = hha_pmu->pmu_events.hw_events[idx];
|
||||
- if (!event)
|
||||
- continue;
|
||||
-
|
||||
- hisi_uncore_pmu_event_update(event);
|
||||
- hisi_uncore_pmu_set_event_period(event);
|
||||
- }
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
+ return readl(hha_pmu->base + HHA_INT_STATUS);
|
||||
}
|
||||
|
||||
-static int hisi_hha_pmu_init_irq(struct hisi_pmu *hha_pmu,
|
||||
- struct platform_device *pdev)
|
||||
+static void hisi_hha_pmu_clear_int_status(struct hisi_pmu *hha_pmu, int idx)
|
||||
{
|
||||
- int irq, ret;
|
||||
-
|
||||
- /* Read and init IRQ */
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "HHA PMU get irq fail; irq:%d\n", irq);
|
||||
- return irq;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_hha_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
||||
- dev_name(&pdev->dev), hha_pmu);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- hha_pmu->irq = irq;
|
||||
-
|
||||
- return 0;
|
||||
+ writel(1 << idx, hha_pmu->base + HHA_INT_CLEAR);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
||||
@@ -345,6 +296,8 @@ static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
||||
.disable_counter_int = hisi_hha_pmu_disable_counter_int,
|
||||
.write_counter = hisi_hha_pmu_write_counter,
|
||||
.read_counter = hisi_hha_pmu_read_counter,
|
||||
+ .get_int_status = hisi_hha_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_hha_pmu_clear_int_status,
|
||||
};
|
||||
|
||||
static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -356,7 +309,7 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = hisi_hha_pmu_init_irq(hha_pmu, pdev);
|
||||
+ ret = hisi_uncore_pmu_init_irq(hha_pmu, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index c4afeaaaa3a4..5256e4ce3384 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/list.h>
|
||||
-#include <linux/platform_device.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
@@ -157,62 +156,14 @@ static void hisi_l3c_pmu_disable_counter_int(struct hisi_pmu *l3c_pmu,
|
||||
writel(val, l3c_pmu->base + L3C_INT_MASK);
|
||||
}
|
||||
|
||||
-static irqreturn_t hisi_l3c_pmu_isr(int irq, void *dev_id)
|
||||
+static u32 hisi_l3c_pmu_get_int_status(struct hisi_pmu *l3c_pmu)
|
||||
{
|
||||
- struct hisi_pmu *l3c_pmu = dev_id;
|
||||
- struct perf_event *event;
|
||||
- unsigned long overflown;
|
||||
- int idx;
|
||||
-
|
||||
- /* Read L3C_INT_STATUS register */
|
||||
- overflown = readl(l3c_pmu->base + L3C_INT_STATUS);
|
||||
- if (!overflown)
|
||||
- return IRQ_NONE;
|
||||
-
|
||||
- /*
|
||||
- * Find the counter index which overflowed if the bit was set
|
||||
- * and handle it.
|
||||
- */
|
||||
- for_each_set_bit(idx, &overflown, L3C_NR_COUNTERS) {
|
||||
- /* Write 1 to clear the IRQ status flag */
|
||||
- writel((1 << idx), l3c_pmu->base + L3C_INT_CLEAR);
|
||||
-
|
||||
- /* Get the corresponding event struct */
|
||||
- event = l3c_pmu->pmu_events.hw_events[idx];
|
||||
- if (!event)
|
||||
- continue;
|
||||
-
|
||||
- hisi_uncore_pmu_event_update(event);
|
||||
- hisi_uncore_pmu_set_event_period(event);
|
||||
- }
|
||||
-
|
||||
- return IRQ_HANDLED;
|
||||
+ return readl(l3c_pmu->base + L3C_INT_STATUS);
|
||||
}
|
||||
|
||||
-static int hisi_l3c_pmu_init_irq(struct hisi_pmu *l3c_pmu,
|
||||
- struct platform_device *pdev)
|
||||
+static void hisi_l3c_pmu_clear_int_status(struct hisi_pmu *l3c_pmu, int idx)
|
||||
{
|
||||
- int irq, ret;
|
||||
-
|
||||
- /* Read and init IRQ */
|
||||
- irq = platform_get_irq(pdev, 0);
|
||||
- if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "L3C PMU get irq fail; irq:%d\n", irq);
|
||||
- return irq;
|
||||
- }
|
||||
-
|
||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_l3c_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
||||
- dev_name(&pdev->dev), l3c_pmu);
|
||||
- if (ret < 0) {
|
||||
- dev_err(&pdev->dev,
|
||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- l3c_pmu->irq = irq;
|
||||
-
|
||||
- return 0;
|
||||
+ writel(1 << idx, l3c_pmu->base + L3C_INT_CLEAR);
|
||||
}
|
||||
|
||||
static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
||||
@@ -335,6 +286,8 @@ static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
||||
.disable_counter_int = hisi_l3c_pmu_disable_counter_int,
|
||||
.write_counter = hisi_l3c_pmu_write_counter,
|
||||
.read_counter = hisi_l3c_pmu_read_counter,
|
||||
+ .get_int_status = hisi_l3c_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_l3c_pmu_clear_int_status,
|
||||
};
|
||||
|
||||
static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -346,7 +299,7 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = hisi_l3c_pmu_init_irq(l3c_pmu, pdev);
|
||||
+ ret = hisi_uncore_pmu_init_irq(l3c_pmu, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 9ebdb76dd3a4..53ac9f062c0f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -131,6 +131,60 @@ static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
||||
clear_bit(idx, hisi_pmu->pmu_events.used_mask);
|
||||
}
|
||||
|
||||
+static irqreturn_t hisi_uncore_pmu_isr(int irq, void *data)
|
||||
+{
|
||||
+ struct hisi_pmu *hisi_pmu = data;
|
||||
+ struct perf_event *event;
|
||||
+ unsigned long overflown;
|
||||
+ int idx;
|
||||
+
|
||||
+ overflown = hisi_pmu->ops->get_int_status(hisi_pmu);
|
||||
+ if (!overflown)
|
||||
+ return IRQ_NONE;
|
||||
+
|
||||
+ /*
|
||||
+ * Find the counter index which overflowed if the bit was set
|
||||
+ * and handle it.
|
||||
+ */
|
||||
+ for_each_set_bit(idx, &overflown, hisi_pmu->num_counters) {
|
||||
+ /* Write 1 to clear the IRQ status flag */
|
||||
+ hisi_pmu->ops->clear_int_status(hisi_pmu, idx);
|
||||
+ /* Get the corresponding event struct */
|
||||
+ event = hisi_pmu->pmu_events.hw_events[idx];
|
||||
+ if (!event)
|
||||
+ continue;
|
||||
+
|
||||
+ hisi_uncore_pmu_event_update(event);
|
||||
+ hisi_uncore_pmu_set_event_period(event);
|
||||
+ }
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
+ struct platform_device *pdev)
|
||||
+{
|
||||
+ int irq, ret;
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0)
|
||||
+ return irq;
|
||||
+
|
||||
+ ret = devm_request_irq(&pdev->dev, irq, hisi_uncore_pmu_isr,
|
||||
+ IRQF_NOBALANCING | IRQF_NO_THREAD,
|
||||
+ dev_name(&pdev->dev), hisi_pmu);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(&pdev->dev,
|
||||
+ "Fail to request IRQ: %d ret: %d.\n", irq, ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ hisi_pmu->irq = irq;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(hisi_uncore_pmu_init_irq);
|
||||
+
|
||||
int hisi_uncore_pmu_event_init(struct perf_event *event)
|
||||
{
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index d71a6c86b282..3336723e8cf6 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/perf_event.h>
|
||||
+#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#undef pr_fmt
|
||||
@@ -50,6 +51,8 @@ struct hisi_uncore_ops {
|
||||
void (*disable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
|
||||
void (*start_counters)(struct hisi_pmu *);
|
||||
void (*stop_counters)(struct hisi_pmu *);
|
||||
+ u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
|
||||
+ void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
|
||||
};
|
||||
|
||||
struct hisi_pmu_hwevents {
|
||||
@@ -104,6 +107,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
||||
ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *page);
|
||||
-
|
||||
+int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
+ struct platform_device *pdev);
|
||||
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,448 @@
|
||||
From 3d5c7ff8c993e8f570d32755ba43ae17e02b007e Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:04 +0800
|
||||
Subject: [PATCH 15/55] drivers/perf: hisi: Add PMU version for uncore PMU
|
||||
drivers.
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit 3da582df575c3b2910e09e0445c27c3ebc8096e5
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3da582df575c3b2910e09e0445c27c3ebc8096e5
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
For HiSilicon uncore PMU, more versions are supported and some variables
|
||||
shall be added suffix to distinguish the version which are prepared for
|
||||
the new drivers.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-4-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 96 ++++++++++---------
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 27 +++---
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 23 ++---
|
||||
3 files changed, 75 insertions(+), 71 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index a03e3f8058b3..1d1c8e9f417e 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -39,7 +39,8 @@
|
||||
|
||||
/* DDRC has 8-counters */
|
||||
#define DDRC_NR_COUNTERS 0x8
|
||||
-#define DDRC_PERF_CTRL_EN 0x2
|
||||
+#define DDRC_V1_PERF_CTRL_EN 0x2
|
||||
+#define DDRC_V1_NR_EVENTS 0x7
|
||||
|
||||
/*
|
||||
* For DDRC PMU, there are eight-events and every event has been mapped
|
||||
@@ -56,26 +57,26 @@ static const u32 ddrc_reg_off[] = {
|
||||
|
||||
/*
|
||||
* Select the counter register offset using the counter index.
|
||||
- * In DDRC there are no programmable counter, the count
|
||||
- * is readed form the statistics counter register itself.
|
||||
+ * In PMU v1, there are no programmable counter, the count
|
||||
+ * is read form the statistics counter register itself.
|
||||
*/
|
||||
-static u32 hisi_ddrc_pmu_get_counter_offset(int cntr_idx)
|
||||
+static u32 hisi_ddrc_pmu_v1_get_counter_offset(int cntr_idx)
|
||||
{
|
||||
return ddrc_reg_off[cntr_idx];
|
||||
}
|
||||
|
||||
-static u64 hisi_ddrc_pmu_read_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+static u64 hisi_ddrc_pmu_v1_read_counter(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
return readl(ddrc_pmu->base +
|
||||
- hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
||||
+ hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_write_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+static void hisi_ddrc_pmu_v1_write_counter(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc, u64 val)
|
||||
{
|
||||
writel((u32)val,
|
||||
- ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
||||
+ ddrc_pmu->base + hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -87,28 +88,28 @@ static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
||||
{
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_start_counters(struct hisi_pmu *ddrc_pmu)
|
||||
+static void hisi_ddrc_pmu_v1_start_counters(struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Set perf_enable in DDRC_PERF_CTRL to start event counting */
|
||||
val = readl(ddrc_pmu->base + DDRC_PERF_CTRL);
|
||||
- val |= DDRC_PERF_CTRL_EN;
|
||||
+ val |= DDRC_V1_PERF_CTRL_EN;
|
||||
writel(val, ddrc_pmu->base + DDRC_PERF_CTRL);
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_stop_counters(struct hisi_pmu *ddrc_pmu)
|
||||
+static void hisi_ddrc_pmu_v1_stop_counters(struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
/* Clear perf_enable in DDRC_PERF_CTRL to stop event counting */
|
||||
val = readl(ddrc_pmu->base + DDRC_PERF_CTRL);
|
||||
- val &= ~DDRC_PERF_CTRL_EN;
|
||||
+ val &= ~DDRC_V1_PERF_CTRL_EN;
|
||||
writel(val, ddrc_pmu->base + DDRC_PERF_CTRL);
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_enable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
+static void hisi_ddrc_pmu_v1_enable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@@ -118,8 +119,8 @@ static void hisi_ddrc_pmu_enable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
writel(val, ddrc_pmu->base + DDRC_EVENT_CTRL);
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_disable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
+static void hisi_ddrc_pmu_v1_disable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@@ -129,7 +130,7 @@ static void hisi_ddrc_pmu_disable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
writel(val, ddrc_pmu->base + DDRC_EVENT_CTRL);
|
||||
}
|
||||
|
||||
-static int hisi_ddrc_pmu_get_event_idx(struct perf_event *event)
|
||||
+static int hisi_ddrc_pmu_v1_get_event_idx(struct perf_event *event)
|
||||
{
|
||||
struct hisi_pmu *ddrc_pmu = to_hisi_pmu(event->pmu);
|
||||
unsigned long *used_mask = ddrc_pmu->pmu_events.used_mask;
|
||||
@@ -145,8 +146,8 @@ static int hisi_ddrc_pmu_get_event_idx(struct perf_event *event)
|
||||
return idx;
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
+static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@@ -156,8 +157,8 @@ static void hisi_ddrc_pmu_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
- struct hw_perf_event *hwc)
|
||||
+static void hisi_ddrc_pmu_v1_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@@ -167,12 +168,13 @@ static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
||||
}
|
||||
|
||||
-static u32 hisi_ddrc_pmu_get_int_status(struct hisi_pmu *ddrc_pmu)
|
||||
+static u32 hisi_ddrc_pmu_v1_get_int_status(struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
||||
}
|
||||
|
||||
-static void hisi_ddrc_pmu_clear_int_status(struct hisi_pmu *ddrc_pmu, int idx)
|
||||
+static void hisi_ddrc_pmu_v1_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
||||
+ int idx)
|
||||
{
|
||||
writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
||||
}
|
||||
@@ -215,17 +217,17 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct attribute *hisi_ddrc_pmu_format_attr[] = {
|
||||
+static struct attribute *hisi_ddrc_pmu_v1_format_attr[] = {
|
||||
HISI_PMU_FORMAT_ATTR(event, "config:0-4"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_ddrc_pmu_format_group = {
|
||||
+static const struct attribute_group hisi_ddrc_pmu_v1_format_group = {
|
||||
.name = "format",
|
||||
- .attrs = hisi_ddrc_pmu_format_attr,
|
||||
+ .attrs = hisi_ddrc_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
-static struct attribute *hisi_ddrc_pmu_events_attr[] = {
|
||||
+static struct attribute *hisi_ddrc_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
||||
HISI_PMU_EVENT_ATTR(flux_wcmd, 0x02),
|
||||
@@ -237,9 +239,9 @@ static struct attribute *hisi_ddrc_pmu_events_attr[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_ddrc_pmu_events_group = {
|
||||
+static const struct attribute_group hisi_ddrc_pmu_v1_events_group = {
|
||||
.name = "events",
|
||||
- .attrs = hisi_ddrc_pmu_events_attr,
|
||||
+ .attrs = hisi_ddrc_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
@@ -265,27 +267,27 @@ static struct attribute_group hisi_ddrc_pmu_identifier_group = {
|
||||
.attrs = hisi_ddrc_pmu_identifier_attrs,
|
||||
};
|
||||
|
||||
-static const struct attribute_group *hisi_ddrc_pmu_attr_groups[] = {
|
||||
- &hisi_ddrc_pmu_format_group,
|
||||
- &hisi_ddrc_pmu_events_group,
|
||||
+static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
|
||||
+ &hisi_ddrc_pmu_v1_format_group,
|
||||
+ &hisi_ddrc_pmu_v1_events_group,
|
||||
&hisi_ddrc_pmu_cpumask_attr_group,
|
||||
&hisi_ddrc_pmu_identifier_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct hisi_uncore_ops hisi_uncore_ddrc_ops = {
|
||||
+static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
||||
.write_evtype = hisi_ddrc_pmu_write_evtype,
|
||||
- .get_event_idx = hisi_ddrc_pmu_get_event_idx,
|
||||
- .start_counters = hisi_ddrc_pmu_start_counters,
|
||||
- .stop_counters = hisi_ddrc_pmu_stop_counters,
|
||||
- .enable_counter = hisi_ddrc_pmu_enable_counter,
|
||||
- .disable_counter = hisi_ddrc_pmu_disable_counter,
|
||||
- .enable_counter_int = hisi_ddrc_pmu_enable_counter_int,
|
||||
- .disable_counter_int = hisi_ddrc_pmu_disable_counter_int,
|
||||
- .write_counter = hisi_ddrc_pmu_write_counter,
|
||||
- .read_counter = hisi_ddrc_pmu_read_counter,
|
||||
- .get_int_status = hisi_ddrc_pmu_get_int_status,
|
||||
- .clear_int_status = hisi_ddrc_pmu_clear_int_status,
|
||||
+ .get_event_idx = hisi_ddrc_pmu_v1_get_event_idx,
|
||||
+ .start_counters = hisi_ddrc_pmu_v1_start_counters,
|
||||
+ .stop_counters = hisi_ddrc_pmu_v1_stop_counters,
|
||||
+ .enable_counter = hisi_ddrc_pmu_v1_enable_counter,
|
||||
+ .disable_counter = hisi_ddrc_pmu_v1_disable_counter,
|
||||
+ .enable_counter_int = hisi_ddrc_pmu_v1_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_ddrc_pmu_v1_disable_counter_int,
|
||||
+ .write_counter = hisi_ddrc_pmu_v1_write_counter,
|
||||
+ .read_counter = hisi_ddrc_pmu_v1_read_counter,
|
||||
+ .get_int_status = hisi_ddrc_pmu_v1_get_int_status,
|
||||
+ .clear_int_status = hisi_ddrc_pmu_v1_clear_int_status,
|
||||
};
|
||||
|
||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -303,10 +305,10 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
|
||||
ddrc_pmu->num_counters = DDRC_NR_COUNTERS;
|
||||
ddrc_pmu->counter_bits = 32;
|
||||
- ddrc_pmu->ops = &hisi_uncore_ddrc_ops;
|
||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
||||
ddrc_pmu->dev = &pdev->dev;
|
||||
ddrc_pmu->on_cpu = -1;
|
||||
- ddrc_pmu->check_event = 7;
|
||||
+ ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -348,7 +350,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_ddrc_pmu_attr_groups,
|
||||
+ .attr_groups = hisi_ddrc_pmu_v1_attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 536d1f637fa7..7941900ea667 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -36,10 +36,11 @@
|
||||
#define HHA_CNT0_LOWER 0x1F00
|
||||
|
||||
/* HHA has 16-counters */
|
||||
-#define HHA_NR_COUNTERS 0x10
|
||||
+#define HHA_V1_NR_COUNTERS 0x10
|
||||
|
||||
#define HHA_PERF_CTRL_EN 0x1
|
||||
#define HHA_EVTYPE_NONE 0xff
|
||||
+#define HHA_V1_NR_EVENT 0x65
|
||||
|
||||
/*
|
||||
* Select the counter register offset using the counter index
|
||||
@@ -209,17 +210,17 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct attribute *hisi_hha_pmu_format_attr[] = {
|
||||
+static struct attribute *hisi_hha_pmu_v1_format_attr[] = {
|
||||
HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_hha_pmu_format_group = {
|
||||
+static const struct attribute_group hisi_hha_pmu_v1_format_group = {
|
||||
.name = "format",
|
||||
- .attrs = hisi_hha_pmu_format_attr,
|
||||
+ .attrs = hisi_hha_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
-static struct attribute *hisi_hha_pmu_events_attr[] = {
|
||||
+static struct attribute *hisi_hha_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
||||
HISI_PMU_EVENT_ATTR(rx_sccl, 0x02),
|
||||
@@ -249,9 +250,9 @@ static struct attribute *hisi_hha_pmu_events_attr[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_hha_pmu_events_group = {
|
||||
+static const struct attribute_group hisi_hha_pmu_v1_events_group = {
|
||||
.name = "events",
|
||||
- .attrs = hisi_hha_pmu_events_attr,
|
||||
+ .attrs = hisi_hha_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
@@ -277,9 +278,9 @@ static struct attribute_group hisi_hha_pmu_identifier_group = {
|
||||
.attrs = hisi_hha_pmu_identifier_attrs,
|
||||
};
|
||||
|
||||
-static const struct attribute_group *hisi_hha_pmu_attr_groups[] = {
|
||||
- &hisi_hha_pmu_format_group,
|
||||
- &hisi_hha_pmu_events_group,
|
||||
+static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
|
||||
+ &hisi_hha_pmu_v1_format_group,
|
||||
+ &hisi_hha_pmu_v1_events_group,
|
||||
&hisi_hha_pmu_cpumask_attr_group,
|
||||
&hisi_hha_pmu_identifier_group,
|
||||
NULL,
|
||||
@@ -313,12 +314,12 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- hha_pmu->num_counters = HHA_NR_COUNTERS;
|
||||
+ hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
||||
hha_pmu->counter_bits = 48;
|
||||
hha_pmu->ops = &hisi_uncore_hha_ops;
|
||||
hha_pmu->dev = &pdev->dev;
|
||||
hha_pmu->on_cpu = -1;
|
||||
- hha_pmu->check_event = 0x65;
|
||||
+ hha_pmu->check_event = HHA_V1_NR_EVENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -360,7 +361,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_hha_pmu_attr_groups,
|
||||
+ .attr_groups = hisi_hha_pmu_v1_attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 5256e4ce3384..5a4975e64368 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
#define L3C_PERF_CTRL_EN 0x10000
|
||||
#define L3C_EVTYPE_NONE 0xff
|
||||
+#define L3C_V1_NR_EVENTS 0x59
|
||||
|
||||
/*
|
||||
* Select the counter register offset using the counter index
|
||||
@@ -212,17 +213,17 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct attribute *hisi_l3c_pmu_format_attr[] = {
|
||||
+static struct attribute *hisi_l3c_pmu_v1_format_attr[] = {
|
||||
HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_l3c_pmu_format_group = {
|
||||
+static const struct attribute_group hisi_l3c_pmu_v1_format_group = {
|
||||
.name = "format",
|
||||
- .attrs = hisi_l3c_pmu_format_attr,
|
||||
+ .attrs = hisi_l3c_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
-static struct attribute *hisi_l3c_pmu_events_attr[] = {
|
||||
+static struct attribute *hisi_l3c_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
||||
HISI_PMU_EVENT_ATTR(rd_hit_cpipe, 0x02),
|
||||
@@ -239,9 +240,9 @@ static struct attribute *hisi_l3c_pmu_events_attr[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
-static const struct attribute_group hisi_l3c_pmu_events_group = {
|
||||
+static const struct attribute_group hisi_l3c_pmu_v1_events_group = {
|
||||
.name = "events",
|
||||
- .attrs = hisi_l3c_pmu_events_attr,
|
||||
+ .attrs = hisi_l3c_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
@@ -267,9 +268,9 @@ static struct attribute_group hisi_l3c_pmu_identifier_group = {
|
||||
.attrs = hisi_l3c_pmu_identifier_attrs,
|
||||
};
|
||||
|
||||
-static const struct attribute_group *hisi_l3c_pmu_attr_groups[] = {
|
||||
- &hisi_l3c_pmu_format_group,
|
||||
- &hisi_l3c_pmu_events_group,
|
||||
+static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
|
||||
+ &hisi_l3c_pmu_v1_format_group,
|
||||
+ &hisi_l3c_pmu_v1_events_group,
|
||||
&hisi_l3c_pmu_cpumask_attr_group,
|
||||
&hisi_l3c_pmu_identifier_group,
|
||||
NULL,
|
||||
@@ -308,7 +309,7 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
||||
l3c_pmu->ops = &hisi_uncore_l3c_ops;
|
||||
l3c_pmu->dev = &pdev->dev;
|
||||
l3c_pmu->on_cpu = -1;
|
||||
- l3c_pmu->check_event = 0x59;
|
||||
+ l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -350,7 +351,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_l3c_pmu_attr_groups,
|
||||
+ .attr_groups = hisi_l3c_pmu_v1_attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,505 @@
|
||||
From d4d47e781c088759005a0a6dc4e843a8bfeb5bdd Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:05 +0800
|
||||
Subject: [PATCH 16/55] drivers/perf: hisi: Add new functions for L3C PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit 486a7f46b966a825484808d4edf53bbe02698fb3
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=486a7f46b966a825484808d4edf53bbe02698fb3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
On HiSilicon Hip09 platform, some new functions are enhanced on L3C PMU:
|
||||
|
||||
* tt_req: it is the abbreviation of tracetag request and allows user to
|
||||
count only read/write/atomic operations. tt_req is 3-bit and details are
|
||||
listed in the hisi-pmu document.
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_req=0x4/ sleep 5
|
||||
|
||||
* tt_core: it is the abbreviation of tracetag core and allows user to
|
||||
filter by core/thread within the cluster, it is a 8-bit bitmap that each
|
||||
bit represents the corresponding core/thread in this L3C.
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_core=0xf/ sleep 5
|
||||
|
||||
* datasrc_cfg: it is the abbreviation of data source configuration and
|
||||
allows user to check where the data comes from, such as: from local DDR,
|
||||
cross-die DDR or cross-socket DDR. Its is 5-bit and represents different
|
||||
data source in the SoC.
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/dat_access,datasrc_cfg=0xe/ sleep 5
|
||||
|
||||
* datasrc_skt: it is the abbreviation of data source from another socket
|
||||
and is used in the multi-chips, if user wants to check the cross-socket
|
||||
datat source, it shall be added in perf command. Only one bit is used to
|
||||
control this.
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/dat_access,datasrc_cfg=0x10,datasrc_skt=1/ sleep 5
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-5-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 259 +++++++++++++++++--
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 8 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 11 +
|
||||
3 files changed, 258 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 5a4975e64368..87ca2a9ca8c5 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -26,12 +26,17 @@
|
||||
#define L3C_INT_MASK 0x0800
|
||||
#define L3C_INT_STATUS 0x0808
|
||||
#define L3C_INT_CLEAR 0x080c
|
||||
+#define L3C_CORE_CTRL 0x1b04
|
||||
+#define L3C_TRACETAG_CTRL 0x1b20
|
||||
+#define L3C_DATSRC_TYPE 0x1b48
|
||||
+#define L3C_DATSRC_CTRL 0x1bf0
|
||||
#define L3C_EVENT_CTRL 0x1c00
|
||||
#define L3C_VERSION 0x1cf0
|
||||
#define L3C_EVENT_TYPE0 0x1d00
|
||||
/*
|
||||
- * Each counter is 48-bits and [48:63] are reserved
|
||||
- * which are Read-As-Zero and Writes-Ignored.
|
||||
+ * If the HW version only supports a 48-bit counter, then
|
||||
+ * bits [63:48] are reserved, which are Read-As-Zero and
|
||||
+ * Writes-Ignored.
|
||||
*/
|
||||
#define L3C_CNTR0_LOWER 0x1e00
|
||||
|
||||
@@ -39,8 +44,186 @@
|
||||
#define L3C_NR_COUNTERS 0x8
|
||||
|
||||
#define L3C_PERF_CTRL_EN 0x10000
|
||||
+#define L3C_TRACETAG_EN BIT(31)
|
||||
+#define L3C_TRACETAG_REQ_SHIFT 7
|
||||
+#define L3C_TRACETAG_MARK_EN BIT(0)
|
||||
+#define L3C_TRACETAG_REQ_EN (L3C_TRACETAG_MARK_EN | BIT(2))
|
||||
+#define L3C_TRACETAG_CORE_EN (L3C_TRACETAG_MARK_EN | BIT(3))
|
||||
+#define L3C_CORE_EN BIT(20)
|
||||
+#define L3C_COER_NONE 0x0
|
||||
+#define L3C_DATSRC_MASK 0xFF
|
||||
+#define L3C_DATSRC_SKT_EN BIT(23)
|
||||
+#define L3C_DATSRC_NONE 0x0
|
||||
#define L3C_EVTYPE_NONE 0xff
|
||||
#define L3C_V1_NR_EVENTS 0x59
|
||||
+#define L3C_V2_NR_EVENTS 0xFF
|
||||
+
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_core, config1, 7, 0);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_req, config1, 10, 8);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_cfg, config1, 15, 11);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_skt, config1, 16, 16);
|
||||
+
|
||||
+static void hisi_l3c_pmu_config_req_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_req = hisi_get_tt_req(event);
|
||||
+
|
||||
+ if (tt_req) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Set request-type for tracetag */
|
||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ val |= tt_req << L3C_TRACETAG_REQ_SHIFT;
|
||||
+ val |= L3C_TRACETAG_REQ_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+
|
||||
+ /* Enable request-tracetag statistics */
|
||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ val |= L3C_TRACETAG_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_clear_req_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_req = hisi_get_tt_req(event);
|
||||
+
|
||||
+ if (tt_req) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear request-type */
|
||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ val &= ~(tt_req << L3C_TRACETAG_REQ_SHIFT);
|
||||
+ val &= ~L3C_TRACETAG_REQ_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+
|
||||
+ /* Disable request-tracetag statistics */
|
||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ val &= ~L3C_TRACETAG_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_write_ds(struct perf_event *event, u32 ds_cfg)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ struct hw_perf_event *hwc = &event->hw;
|
||||
+ u32 reg, reg_idx, shift, val;
|
||||
+ int idx = hwc->idx;
|
||||
+
|
||||
+ /*
|
||||
+ * Select the appropriate datasource register(L3C_DATSRC_TYPE0/1).
|
||||
+ * There are 2 datasource ctrl register for the 8 hardware counters.
|
||||
+ * Datasrc is 8-bits and for the former 4 hardware counters,
|
||||
+ * L3C_DATSRC_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
+ * L3C_DATSRC_TYPE1 is chosen.
|
||||
+ */
|
||||
+ reg = L3C_DATSRC_TYPE + (idx / 4) * 4;
|
||||
+ reg_idx = idx % 4;
|
||||
+ shift = 8 * reg_idx;
|
||||
+
|
||||
+ val = readl(l3c_pmu->base + reg);
|
||||
+ val &= ~(L3C_DATSRC_MASK << shift);
|
||||
+ val |= ds_cfg << shift;
|
||||
+ writel(val, l3c_pmu->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_config_ds(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 ds_cfg = hisi_get_datasrc_cfg(event);
|
||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
||||
+
|
||||
+ if (ds_cfg)
|
||||
+ hisi_l3c_pmu_write_ds(event, ds_cfg);
|
||||
+
|
||||
+ if (ds_skt) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(l3c_pmu->base + L3C_DATSRC_CTRL);
|
||||
+ val |= L3C_DATSRC_SKT_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_DATSRC_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_clear_ds(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 ds_cfg = hisi_get_datasrc_cfg(event);
|
||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
||||
+
|
||||
+ if (ds_cfg)
|
||||
+ hisi_l3c_pmu_write_ds(event, L3C_DATSRC_NONE);
|
||||
+
|
||||
+ if (ds_skt) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(l3c_pmu->base + L3C_DATSRC_CTRL);
|
||||
+ val &= ~L3C_DATSRC_SKT_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_DATSRC_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_config_core_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 core = hisi_get_tt_core(event);
|
||||
+
|
||||
+ if (core) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Config and enable core information */
|
||||
+ writel(core, l3c_pmu->base + L3C_CORE_CTRL);
|
||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ val |= L3C_CORE_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+
|
||||
+ /* Enable core-tracetag statistics */
|
||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ val |= L3C_TRACETAG_CORE_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_clear_core_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 core = hisi_get_tt_core(event);
|
||||
+
|
||||
+ if (core) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear core information */
|
||||
+ writel(L3C_COER_NONE, l3c_pmu->base + L3C_CORE_CTRL);
|
||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+ val &= ~L3C_CORE_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
||||
+
|
||||
+ /* Disable core-tracetag statistics */
|
||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ val &= ~L3C_TRACETAG_CORE_EN;
|
||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_enable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_l3c_pmu_config_req_tracetag(event);
|
||||
+ hisi_l3c_pmu_config_core_tracetag(event);
|
||||
+ hisi_l3c_pmu_config_ds(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3c_pmu_disable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_l3c_pmu_clear_ds(event);
|
||||
+ hisi_l3c_pmu_clear_core_tracetag(event);
|
||||
+ hisi_l3c_pmu_clear_req_tracetag(event);
|
||||
+ }
|
||||
+}
|
||||
|
||||
/*
|
||||
* Select the counter register offset using the counter index
|
||||
@@ -53,14 +236,12 @@ static u32 hisi_l3c_pmu_get_counter_offset(u32 cntr_idx)
|
||||
static u64 hisi_l3c_pmu_read_counter(struct hisi_pmu *l3c_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
- /* Read 64-bits and the upper 16 bits are RAZ */
|
||||
return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
static void hisi_l3c_pmu_write_counter(struct hisi_pmu *l3c_pmu,
|
||||
struct hw_perf_event *hwc, u64 val)
|
||||
{
|
||||
- /* Write 64-bits and the upper 16 bits are WI */
|
||||
writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
@@ -169,23 +350,14 @@ static void hisi_l3c_pmu_clear_int_status(struct hisi_pmu *l3c_pmu, int idx)
|
||||
|
||||
static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
||||
{ "HISI0213", },
|
||||
- {},
|
||||
+ { "HISI0214", },
|
||||
+ {}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
|
||||
|
||||
static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *l3c_pmu)
|
||||
{
|
||||
- unsigned long long id;
|
||||
- acpi_status status;
|
||||
-
|
||||
- status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
- "_UID", NULL, &id);
|
||||
- if (ACPI_FAILURE(status))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- l3c_pmu->index_id = id;
|
||||
-
|
||||
/*
|
||||
* Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
||||
@@ -223,6 +395,20 @@ static const struct attribute_group hisi_l3c_pmu_v1_format_group = {
|
||||
.attrs = hisi_l3c_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_l3c_pmu_v2_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tt_core, "config1:0-7"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tt_req, "config1:8-10"),
|
||||
+ HISI_PMU_FORMAT_ATTR(datasrc_cfg, "config1:11-15"),
|
||||
+ HISI_PMU_FORMAT_ATTR(datasrc_skt, "config1:16"),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_l3c_pmu_v2_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_l3c_pmu_v2_format_attr,
|
||||
+};
|
||||
+
|
||||
static struct attribute *hisi_l3c_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
||||
@@ -245,6 +431,19 @@ static const struct attribute_group hisi_l3c_pmu_v1_events_group = {
|
||||
.attrs = hisi_l3c_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_l3c_pmu_v2_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(l3c_hit, 0x48),
|
||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x7f),
|
||||
+ HISI_PMU_EVENT_ATTR(l3c_ref, 0xb8),
|
||||
+ HISI_PMU_EVENT_ATTR(dat_access, 0xb9),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_l3c_pmu_v2_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_l3c_pmu_v2_events_attr,
|
||||
+};
|
||||
+
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
|
||||
static struct attribute *hisi_l3c_pmu_cpumask_attrs[] = {
|
||||
@@ -276,6 +475,14 @@ static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
+static const struct attribute_group *hisi_l3c_pmu_v2_attr_groups[] = {
|
||||
+ &hisi_l3c_pmu_v2_format_group,
|
||||
+ &hisi_l3c_pmu_v2_events_group,
|
||||
+ &hisi_l3c_pmu_cpumask_attr_group,
|
||||
+ &hisi_l3c_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
||||
.write_evtype = hisi_l3c_pmu_write_evtype,
|
||||
.get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
@@ -289,6 +496,8 @@ static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
||||
.read_counter = hisi_l3c_pmu_read_counter,
|
||||
.get_int_status = hisi_l3c_pmu_get_int_status,
|
||||
.clear_int_status = hisi_l3c_pmu_clear_int_status,
|
||||
+ .enable_filter = hisi_l3c_pmu_enable_filter,
|
||||
+ .disable_filter = hisi_l3c_pmu_disable_filter,
|
||||
};
|
||||
|
||||
static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -304,12 +513,20 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (l3c_pmu->identifier >= HISI_PMU_V2) {
|
||||
+ l3c_pmu->counter_bits = 64;
|
||||
+ l3c_pmu->check_event = L3C_V2_NR_EVENTS;
|
||||
+ l3c_pmu->pmu_events.attr_groups = hisi_l3c_pmu_v2_attr_groups;
|
||||
+ } else {
|
||||
+ l3c_pmu->counter_bits = 48;
|
||||
+ l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
||||
+ l3c_pmu->pmu_events.attr_groups = hisi_l3c_pmu_v1_attr_groups;
|
||||
+ }
|
||||
+
|
||||
l3c_pmu->num_counters = L3C_NR_COUNTERS;
|
||||
- l3c_pmu->counter_bits = 48;
|
||||
l3c_pmu->ops = &hisi_uncore_l3c_ops;
|
||||
l3c_pmu->dev = &pdev->dev;
|
||||
l3c_pmu->on_cpu = -1;
|
||||
- l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -337,8 +554,12 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * CCL_ID is used to identify the L3C in the same SCCL which was
|
||||
+ * used _UID by mistake.
|
||||
+ */
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
- l3c_pmu->sccl_id, l3c_pmu->index_id);
|
||||
+ l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
l3c_pmu->pmu = (struct pmu) {
|
||||
.name = name,
|
||||
.module = THIS_MODULE,
|
||||
@@ -351,7 +572,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_l3c_pmu_v1_attr_groups,
|
||||
+ .attr_groups = l3c_pmu->pmu_events.attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 53ac9f062c0f..c0f221e39aff 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "hisi_uncore_pmu.h"
|
||||
|
||||
#define HISI_GET_EVENTID(ev) (ev->hw.config_base & 0xff)
|
||||
-#define HISI_MAX_PERIOD(nr) (BIT_ULL(nr) - 1)
|
||||
+#define HISI_MAX_PERIOD(nr) (GENMASK_ULL((nr) - 1, 0))
|
||||
|
||||
/*
|
||||
* PMU format attributes
|
||||
@@ -248,6 +248,9 @@ static void hisi_uncore_pmu_enable_event(struct perf_event *event)
|
||||
hisi_pmu->ops->write_evtype(hisi_pmu, hwc->idx,
|
||||
HISI_GET_EVENTID(event));
|
||||
|
||||
+ if (hisi_pmu->ops->enable_filter)
|
||||
+ hisi_pmu->ops->enable_filter(event);
|
||||
+
|
||||
hisi_pmu->ops->enable_counter_int(hisi_pmu, hwc);
|
||||
hisi_pmu->ops->enable_counter(hisi_pmu, hwc);
|
||||
}
|
||||
@@ -262,6 +265,9 @@ static void hisi_uncore_pmu_disable_event(struct perf_event *event)
|
||||
|
||||
hisi_pmu->ops->disable_counter(hisi_pmu, hwc);
|
||||
hisi_pmu->ops->disable_counter_int(hisi_pmu, hwc);
|
||||
+
|
||||
+ if (hisi_pmu->ops->disable_filter)
|
||||
+ hisi_pmu->ops->disable_filter(event);
|
||||
}
|
||||
|
||||
void hisi_uncore_pmu_set_event_period(struct perf_event *event)
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 3336723e8cf6..1147dbd25344 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef __HISI_UNCORE_PMU_H__
|
||||
#define __HISI_UNCORE_PMU_H__
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -25,6 +26,7 @@
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) "hisi_pmu: " fmt
|
||||
|
||||
+#define HISI_PMU_V2 0x30
|
||||
#define HISI_MAX_COUNTERS 0x10
|
||||
#define to_hisi_pmu(p) (container_of(p, struct hisi_pmu, pmu))
|
||||
|
||||
@@ -38,6 +40,12 @@
|
||||
#define HISI_PMU_EVENT_ATTR(_name, _config) \
|
||||
HISI_PMU_ATTR(_name, hisi_event_sysfs_show, (unsigned long)_config)
|
||||
|
||||
+#define HISI_PMU_EVENT_ATTR_EXTRACTOR(name, config, hi, lo) \
|
||||
+ static inline u32 hisi_get_##name(struct perf_event *event) \
|
||||
+ { \
|
||||
+ return FIELD_GET(GENMASK_ULL(hi, lo), event->attr.config); \
|
||||
+ }
|
||||
+
|
||||
struct hisi_pmu;
|
||||
|
||||
struct hisi_uncore_ops {
|
||||
@@ -53,11 +61,14 @@ struct hisi_uncore_ops {
|
||||
void (*stop_counters)(struct hisi_pmu *);
|
||||
u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
|
||||
void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
|
||||
+ void (*enable_filter)(struct perf_event *event);
|
||||
+ void (*disable_filter)(struct perf_event *event);
|
||||
};
|
||||
|
||||
struct hisi_pmu_hwevents {
|
||||
struct perf_event *hw_events[HISI_MAX_COUNTERS];
|
||||
DECLARE_BITMAP(used_mask, HISI_MAX_COUNTERS);
|
||||
+ const struct attribute_group **attr_groups;
|
||||
};
|
||||
|
||||
/* Generic pmu struct for different pmu types */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,340 @@
|
||||
From 77e91e65e043b7cec81e193b005ead3183316bb6 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:06 +0800
|
||||
Subject: [PATCH 17/55] drivers/perf: hisi: Add new functions for HHA PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit 932f6a99f9b0c6b7039a5e2ce961009a8dc8c07c
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=932f6a99f9b0c6b7039a5e2ce961009a8dc8c07c
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
On HiSilicon Hip09 platform, some new functions are also supported on
|
||||
HHA PMU.
|
||||
|
||||
* tracetag_en: it is the abbreviation of tracetag enable and allows user
|
||||
to count events according to tt_req or tt_core set in L3C PMU.
|
||||
|
||||
* datasrc_skt: it is the abbreviation of data source from another
|
||||
socket and it is used in the multi-chips. It's the same as L3C PMU.
|
||||
|
||||
* srcid_cmd & srcid_msk: pair of the fields are used to filter
|
||||
statistics that come from the specific CCL/ICL by the configuration.
|
||||
These are the abbreviation of source ID command and mask. The source
|
||||
ID is 11-bit and detailed descriptions are documented in
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-6-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 203 +++++++++++++++++--
|
||||
1 file changed, 188 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 7941900ea667..a7e1749fc3e4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -28,19 +28,136 @@
|
||||
#define HHA_VERSION 0x1cf0
|
||||
#define HHA_PERF_CTRL 0x1E00
|
||||
#define HHA_EVENT_CTRL 0x1E04
|
||||
+#define HHA_SRCID_CTRL 0x1E08
|
||||
+#define HHA_DATSRC_CTRL 0x1BF0
|
||||
#define HHA_EVENT_TYPE0 0x1E80
|
||||
/*
|
||||
- * Each counter is 48-bits and [48:63] are reserved
|
||||
- * which are Read-As-Zero and Writes-Ignored.
|
||||
+ * If the HW version only supports a 48-bit counter, then
|
||||
+ * bits [63:48] are reserved, which are Read-As-Zero and
|
||||
+ * Writes-Ignored.
|
||||
*/
|
||||
#define HHA_CNT0_LOWER 0x1F00
|
||||
|
||||
-/* HHA has 16-counters */
|
||||
+/* HHA PMU v1 has 16 counters and v2 only has 8 counters */
|
||||
#define HHA_V1_NR_COUNTERS 0x10
|
||||
+#define HHA_V2_NR_COUNTERS 0x8
|
||||
|
||||
#define HHA_PERF_CTRL_EN 0x1
|
||||
+#define HHA_TRACETAG_EN BIT(31)
|
||||
+#define HHA_SRCID_EN BIT(2)
|
||||
+#define HHA_SRCID_CMD_SHIFT 6
|
||||
+#define HHA_SRCID_MSK_SHIFT 20
|
||||
+#define HHA_SRCID_CMD GENMASK(16, 6)
|
||||
+#define HHA_SRCID_MSK GENMASK(30, 20)
|
||||
+#define HHA_DATSRC_SKT_EN BIT(23)
|
||||
#define HHA_EVTYPE_NONE 0xff
|
||||
#define HHA_V1_NR_EVENT 0x65
|
||||
+#define HHA_V2_NR_EVENT 0xCE
|
||||
+
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 10, 0);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 21, 11);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 22, 22);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_skt, config1, 23, 23);
|
||||
+
|
||||
+static void hisi_hha_pmu_enable_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
||||
+
|
||||
+ if (tt_en) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ val |= HHA_TRACETAG_EN;
|
||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_clear_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ val &= ~HHA_TRACETAG_EN;
|
||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_config_ds(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
||||
+
|
||||
+ if (ds_skt) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ val |= HHA_DATSRC_SKT_EN;
|
||||
+ writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_clear_ds(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
||||
+
|
||||
+ if (ds_skt) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ val &= ~HHA_DATSRC_SKT_EN;
|
||||
+ writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_config_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 val, msk;
|
||||
+
|
||||
+ msk = hisi_get_srcid_msk(event);
|
||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ val |= HHA_SRCID_EN | (cmd << HHA_SRCID_CMD_SHIFT) |
|
||||
+ (msk << HHA_SRCID_MSK_SHIFT);
|
||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_disable_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ val &= ~(HHA_SRCID_EN | HHA_SRCID_MSK | HHA_SRCID_CMD);
|
||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_enable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_hha_pmu_enable_tracetag(event);
|
||||
+ hisi_hha_pmu_config_ds(event);
|
||||
+ hisi_hha_pmu_config_srcid(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_hha_pmu_disable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_hha_pmu_disable_srcid(event);
|
||||
+ hisi_hha_pmu_clear_ds(event);
|
||||
+ hisi_hha_pmu_clear_tracetag(event);
|
||||
+ }
|
||||
+}
|
||||
|
||||
/*
|
||||
* Select the counter register offset using the counter index
|
||||
@@ -170,7 +287,8 @@ static void hisi_hha_pmu_clear_int_status(struct hisi_pmu *hha_pmu, int idx)
|
||||
|
||||
static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
||||
{ "HISI0243", },
|
||||
- {},
|
||||
+ { "HISI0244", },
|
||||
+ {}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hisi_hha_pmu_acpi_match);
|
||||
|
||||
@@ -180,13 +298,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
unsigned long long id;
|
||||
acpi_status status;
|
||||
|
||||
- status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
- "_UID", NULL, &id);
|
||||
- if (ACPI_FAILURE(status))
|
||||
- return -EINVAL;
|
||||
-
|
||||
- hha_pmu->index_id = id;
|
||||
-
|
||||
/*
|
||||
* Use SCCL_ID and UID to identify the HHA PMU, while
|
||||
* SCCL_ID is in MPIDR[aff2].
|
||||
@@ -196,6 +307,22 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
||||
dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Early versions of BIOS support _UID by mistake, so we support
|
||||
+ * both "hisilicon, idx-id" as preference, if available.
|
||||
+ */
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
+ &hha_pmu->index_id)) {
|
||||
+ status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
||||
+ "_UID", NULL, &id);
|
||||
+ if (ACPI_FAILURE(status)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ hha_pmu->index_id = id;
|
||||
+ }
|
||||
/* HHA PMUs only share the same SCCL */
|
||||
hha_pmu->ccl_id = -1;
|
||||
|
||||
@@ -220,6 +347,20 @@ static const struct attribute_group hisi_hha_pmu_v1_format_group = {
|
||||
.attrs = hisi_hha_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_hha_pmu_v2_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:0-10"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:11-21"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:22"),
|
||||
+ HISI_PMU_FORMAT_ATTR(datasrc_skt, "config1:23"),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_hha_pmu_v2_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_hha_pmu_v2_format_attr,
|
||||
+};
|
||||
+
|
||||
static struct attribute *hisi_hha_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
||||
@@ -255,6 +396,20 @@ static const struct attribute_group hisi_hha_pmu_v1_events_group = {
|
||||
.attrs = hisi_hha_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_hha_pmu_v2_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
||||
+ HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
||||
+ HISI_PMU_EVENT_ATTR(rx_sccl, 0x02),
|
||||
+ HISI_PMU_EVENT_ATTR(hha_retry, 0x2e),
|
||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x55),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_hha_pmu_v2_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_hha_pmu_v2_events_attr,
|
||||
+};
|
||||
+
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
|
||||
static struct attribute *hisi_hha_pmu_cpumask_attrs[] = {
|
||||
@@ -286,6 +441,14 @@ static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
+static const struct attribute_group *hisi_hha_pmu_v2_attr_groups[] = {
|
||||
+ &hisi_hha_pmu_v2_format_group,
|
||||
+ &hisi_hha_pmu_v2_events_group,
|
||||
+ &hisi_hha_pmu_cpumask_attr_group,
|
||||
+ &hisi_hha_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
||||
.write_evtype = hisi_hha_pmu_write_evtype,
|
||||
.get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
@@ -299,6 +462,8 @@ static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
||||
.read_counter = hisi_hha_pmu_read_counter,
|
||||
.get_int_status = hisi_hha_pmu_get_int_status,
|
||||
.clear_int_status = hisi_hha_pmu_clear_int_status,
|
||||
+ .enable_filter = hisi_hha_pmu_enable_filter,
|
||||
+ .disable_filter = hisi_hha_pmu_disable_filter,
|
||||
};
|
||||
|
||||
static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
||||
@@ -314,12 +479,20 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
||||
- hha_pmu->counter_bits = 48;
|
||||
+ if (hha_pmu->identifier >= HISI_PMU_V2) {
|
||||
+ hha_pmu->counter_bits = 64;
|
||||
+ hha_pmu->check_event = HHA_V2_NR_EVENT;
|
||||
+ hha_pmu->pmu_events.attr_groups = hisi_hha_pmu_v2_attr_groups;
|
||||
+ hha_pmu->num_counters = HHA_V2_NR_COUNTERS;
|
||||
+ } else {
|
||||
+ hha_pmu->counter_bits = 48;
|
||||
+ hha_pmu->check_event = HHA_V1_NR_EVENT;
|
||||
+ hha_pmu->pmu_events.attr_groups = hisi_hha_pmu_v1_attr_groups;
|
||||
+ hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
||||
+ }
|
||||
hha_pmu->ops = &hisi_uncore_hha_ops;
|
||||
hha_pmu->dev = &pdev->dev;
|
||||
hha_pmu->on_cpu = -1;
|
||||
- hha_pmu->check_event = HHA_V1_NR_EVENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -361,7 +534,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_hha_pmu_v1_attr_groups,
|
||||
+ .attr_groups = hha_pmu->pmu_events.attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,400 @@
|
||||
From c00401895e634812a41f81e20223244782e503a8 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:07 +0800
|
||||
Subject: [PATCH 18/55] drivers/perf: hisi: Update DDRC PMU for programmable
|
||||
counter
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit cce03e702c9f26a43b16c51bf03029911feab692
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cce03e702c9f26a43b16c51bf03029911feab692
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
DDRC PMU's events are useful for performance profiling, but the events
|
||||
are limited and counter is fixed. On HiSilicon Hip09 platform, PMU
|
||||
counters are the programmable and more events are supported. Let's
|
||||
add the DDRC PMU v2 driver.
|
||||
|
||||
Bandwidth events are exposed directly in driver and some more events
|
||||
will listed in JSON file later.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-7-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 207 ++++++++++++++++--
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 2 +
|
||||
2 files changed, 196 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 1d1c8e9f417e..af5f8c16eab1 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
|
||||
-/* DDRC register definition */
|
||||
+/* DDRC register definition in v1 */
|
||||
#define DDRC_PERF_CTRL 0x010
|
||||
#define DDRC_FLUX_WR 0x380
|
||||
#define DDRC_FLUX_RD 0x384
|
||||
@@ -37,13 +37,24 @@
|
||||
#define DDRC_INT_CLEAR 0x6d0
|
||||
#define DDRC_VERSION 0x710
|
||||
|
||||
+/* DDRC register definition in v2 */
|
||||
+#define DDRC_V2_INT_MASK 0x528
|
||||
+#define DDRC_V2_INT_STATUS 0x52c
|
||||
+#define DDRC_V2_INT_CLEAR 0x530
|
||||
+#define DDRC_V2_EVENT_CNT 0xe00
|
||||
+#define DDRC_V2_EVENT_CTRL 0xe70
|
||||
+#define DDRC_V2_EVENT_TYPE 0xe74
|
||||
+#define DDRC_V2_PERF_CTRL 0xeA0
|
||||
+
|
||||
/* DDRC has 8-counters */
|
||||
#define DDRC_NR_COUNTERS 0x8
|
||||
#define DDRC_V1_PERF_CTRL_EN 0x2
|
||||
+#define DDRC_V2_PERF_CTRL_EN 0x1
|
||||
#define DDRC_V1_NR_EVENTS 0x7
|
||||
+#define DDRC_V2_NR_EVENTS 0x90
|
||||
|
||||
/*
|
||||
- * For DDRC PMU, there are eight-events and every event has been mapped
|
||||
+ * For PMU v1, there are eight-events and every event has been mapped
|
||||
* to fixed-purpose counters which register offset is not consistent.
|
||||
* Therefore there is no write event type and we assume that event
|
||||
* code (0 to 7) is equal to counter index in PMU driver.
|
||||
@@ -65,6 +76,11 @@ static u32 hisi_ddrc_pmu_v1_get_counter_offset(int cntr_idx)
|
||||
return ddrc_reg_off[cntr_idx];
|
||||
}
|
||||
|
||||
+static u32 hisi_ddrc_pmu_v2_get_counter_offset(int cntr_idx)
|
||||
+{
|
||||
+ return DDRC_V2_EVENT_CNT + cntr_idx * 8;
|
||||
+}
|
||||
+
|
||||
static u64 hisi_ddrc_pmu_v1_read_counter(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
@@ -79,13 +95,34 @@ static void hisi_ddrc_pmu_v1_write_counter(struct hisi_pmu *ddrc_pmu,
|
||||
ddrc_pmu->base + hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
||||
}
|
||||
|
||||
+static u64 hisi_ddrc_pmu_v2_read_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readq(ddrc_pmu->base +
|
||||
+ hisi_ddrc_pmu_v2_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_write_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ writeq(val,
|
||||
+ ddrc_pmu->base + hisi_ddrc_pmu_v2_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
/*
|
||||
- * For DDRC PMU, event has been mapped to fixed-purpose counter by hardware,
|
||||
- * so there is no need to write event type.
|
||||
+ * For DDRC PMU v1, event has been mapped to fixed-purpose counter by hardware,
|
||||
+ * so there is no need to write event type, while it is programmable counter in
|
||||
+ * PMU v2.
|
||||
*/
|
||||
static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
||||
u32 type)
|
||||
{
|
||||
+ u32 offset;
|
||||
+
|
||||
+ if (hha_pmu->identifier >= HISI_PMU_V2) {
|
||||
+ offset = DDRC_V2_EVENT_TYPE + 4 * idx;
|
||||
+ writel(type, hha_pmu->base + offset);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void hisi_ddrc_pmu_v1_start_counters(struct hisi_pmu *ddrc_pmu)
|
||||
@@ -146,6 +183,49 @@ static int hisi_ddrc_pmu_v1_get_event_idx(struct perf_event *event)
|
||||
return idx;
|
||||
}
|
||||
|
||||
+static int hisi_ddrc_pmu_v2_get_event_idx(struct perf_event *event)
|
||||
+{
|
||||
+ return hisi_uncore_pmu_get_event_idx(event);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_start_counters(struct hisi_pmu *ddrc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
||||
+ val |= DDRC_V2_PERF_CTRL_EN;
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_stop_counters(struct hisi_pmu *ddrc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
||||
+ val &= ~DDRC_V2_PERF_CTRL_EN;
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_enable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_disable_counter(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
struct hw_perf_event *hwc)
|
||||
{
|
||||
@@ -153,7 +233,7 @@ static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
|
||||
/* Write 0 to enable interrupt */
|
||||
val = readl(ddrc_pmu->base + DDRC_INT_MASK);
|
||||
- val &= ~(1 << GET_DDRC_EVENTID(hwc));
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
||||
}
|
||||
|
||||
@@ -164,10 +244,30 @@ static void hisi_ddrc_pmu_v1_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
|
||||
/* Write 1 to mask interrupt */
|
||||
val = readl(ddrc_pmu->base + DDRC_INT_MASK);
|
||||
- val |= (1 << GET_DDRC_EVENTID(hwc));
|
||||
+ val |= 1 << hwc->idx;
|
||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
||||
}
|
||||
|
||||
+static void hisi_ddrc_pmu_v2_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_INT_MASK);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(ddrc_pmu->base + DDRC_V2_INT_MASK);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, ddrc_pmu->base + DDRC_V2_INT_MASK);
|
||||
+}
|
||||
+
|
||||
static u32 hisi_ddrc_pmu_v1_get_int_status(struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
||||
@@ -179,9 +279,21 @@ static void hisi_ddrc_pmu_v1_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
||||
writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
||||
}
|
||||
|
||||
+static u32 hisi_ddrc_pmu_v2_get_int_status(struct hisi_pmu *ddrc_pmu)
|
||||
+{
|
||||
+ return readl(ddrc_pmu->base + DDRC_V2_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_ddrc_pmu_v2_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
||||
+ int idx)
|
||||
+{
|
||||
+ writel(1 << idx, ddrc_pmu->base + DDRC_V2_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
static const struct acpi_device_id hisi_ddrc_pmu_acpi_match[] = {
|
||||
{ "HISI0233", },
|
||||
- {},
|
||||
+ { "HISI0234", },
|
||||
+ {}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
|
||||
|
||||
@@ -213,6 +325,13 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
||||
}
|
||||
|
||||
ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
|
||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2) {
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
|
||||
+ &ddrc_pmu->sub_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read sub-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -227,6 +346,16 @@ static const struct attribute_group hisi_ddrc_pmu_v1_format_group = {
|
||||
.attrs = hisi_ddrc_pmu_v1_format_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_ddrc_pmu_v2_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_ddrc_pmu_v2_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_ddrc_pmu_v2_format_attr,
|
||||
+};
|
||||
+
|
||||
static struct attribute *hisi_ddrc_pmu_v1_events_attr[] = {
|
||||
HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
||||
HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
||||
@@ -244,6 +373,18 @@ static const struct attribute_group hisi_ddrc_pmu_v1_events_group = {
|
||||
.attrs = hisi_ddrc_pmu_v1_events_attr,
|
||||
};
|
||||
|
||||
+static struct attribute *hisi_ddrc_pmu_v2_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x00),
|
||||
+ HISI_PMU_EVENT_ATTR(flux_wr, 0x83),
|
||||
+ HISI_PMU_EVENT_ATTR(flux_rd, 0x84),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_ddrc_pmu_v2_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_ddrc_pmu_v2_events_attr,
|
||||
+};
|
||||
+
|
||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
|
||||
static struct attribute *hisi_ddrc_pmu_cpumask_attrs[] = {
|
||||
@@ -275,6 +416,14 @@ static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
+static const struct attribute_group *hisi_ddrc_pmu_v2_attr_groups[] = {
|
||||
+ &hisi_ddrc_pmu_v2_format_group,
|
||||
+ &hisi_ddrc_pmu_v2_events_group,
|
||||
+ &hisi_ddrc_pmu_cpumask_attr_group,
|
||||
+ &hisi_ddrc_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
||||
.write_evtype = hisi_ddrc_pmu_write_evtype,
|
||||
.get_event_idx = hisi_ddrc_pmu_v1_get_event_idx,
|
||||
@@ -290,6 +439,21 @@ static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
||||
.clear_int_status = hisi_ddrc_pmu_v1_clear_int_status,
|
||||
};
|
||||
|
||||
+static const struct hisi_uncore_ops hisi_uncore_ddrc_v2_ops = {
|
||||
+ .write_evtype = hisi_ddrc_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_ddrc_pmu_v2_get_event_idx,
|
||||
+ .start_counters = hisi_ddrc_pmu_v2_start_counters,
|
||||
+ .stop_counters = hisi_ddrc_pmu_v2_stop_counters,
|
||||
+ .enable_counter = hisi_ddrc_pmu_v2_enable_counter,
|
||||
+ .disable_counter = hisi_ddrc_pmu_v2_disable_counter,
|
||||
+ .enable_counter_int = hisi_ddrc_pmu_v2_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_ddrc_pmu_v2_disable_counter_int,
|
||||
+ .write_counter = hisi_ddrc_pmu_v2_write_counter,
|
||||
+ .read_counter = hisi_ddrc_pmu_v2_read_counter,
|
||||
+ .get_int_status = hisi_ddrc_pmu_v2_get_int_status,
|
||||
+ .clear_int_status = hisi_ddrc_pmu_v2_clear_int_status,
|
||||
+};
|
||||
+
|
||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
struct hisi_pmu *ddrc_pmu)
|
||||
{
|
||||
@@ -303,12 +467,21 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2) {
|
||||
+ ddrc_pmu->counter_bits = 48;
|
||||
+ ddrc_pmu->check_event = DDRC_V2_NR_EVENTS;
|
||||
+ ddrc_pmu->pmu_events.attr_groups = hisi_ddrc_pmu_v2_attr_groups;
|
||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v2_ops;
|
||||
+ } else {
|
||||
+ ddrc_pmu->counter_bits = 32;
|
||||
+ ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
||||
+ ddrc_pmu->pmu_events.attr_groups = hisi_ddrc_pmu_v1_attr_groups;
|
||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
||||
+ }
|
||||
+
|
||||
ddrc_pmu->num_counters = DDRC_NR_COUNTERS;
|
||||
- ddrc_pmu->counter_bits = 32;
|
||||
- ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
||||
ddrc_pmu->dev = &pdev->dev;
|
||||
ddrc_pmu->on_cpu = -1;
|
||||
- ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -336,8 +509,16 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_ddrc%u",
|
||||
- ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2)
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
+ "hisi_sccl%u_ddrc%u_%u",
|
||||
+ ddrc_pmu->sccl_id, ddrc_pmu->index_id,
|
||||
+ ddrc_pmu->sub_id);
|
||||
+ else
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
+ "hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
||||
+ ddrc_pmu->index_id);
|
||||
+
|
||||
ddrc_pmu->pmu = (struct pmu) {
|
||||
.name = name,
|
||||
.module = THIS_MODULE,
|
||||
@@ -350,7 +531,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
.start = hisi_uncore_pmu_start,
|
||||
.stop = hisi_uncore_pmu_stop,
|
||||
.read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hisi_ddrc_pmu_v1_attr_groups,
|
||||
+ .attr_groups = ddrc_pmu->pmu_events.attr_groups,
|
||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 1147dbd25344..de6aa17a1355 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -88,6 +88,8 @@ struct hisi_pmu {
|
||||
void __iomem *base;
|
||||
/* the ID of the PMU modules */
|
||||
u32 index_id;
|
||||
+ /* For DDRC PMU v2: each DDRC has more than one DMC */
|
||||
+ u32 sub_id;
|
||||
int num_counters;
|
||||
int counter_bits;
|
||||
/* check event code range */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,618 @@
|
||||
From 16c054f4640b9f7c21bb784ac54e1ea32ac65df0 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:08 +0800
|
||||
Subject: [PATCH 19/55] drivers/perf: hisi: Add support for HiSilicon SLLC PMU
|
||||
driver
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit 3bf30882c3c7b6e376d9d6d04082c9aa2d2ac30a
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3bf30882c3c7b6e376d9d6d04082c9aa2d2ac30a
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
HiSilicon's Hip09 is comprised by multi-dies that can be connected by SLLC
|
||||
module (Skyros Link Layer Controller), its has separate PMU registers which
|
||||
the driver can program it freely and interrupt is supported to handle
|
||||
counter overflow. Let's support its driver under the framework of HiSilicon
|
||||
uncore PMU driver.
|
||||
|
||||
SLLC PMU supports the following filter functions:
|
||||
* tracetag_en: allows user to count data according to tt_req or
|
||||
tt_core set in L3C PMU.
|
||||
|
||||
* srcid_cmd & srcid_msk: allows user to filter statistics that come from
|
||||
specific CCL/ICL by configuration source ID.
|
||||
|
||||
* tgtid_hi & tgtid_lo: it also supports event statistics that these
|
||||
operations will go to the CCL/ICL by configuration target ID or
|
||||
target ID range. It's the same as source ID with 11-bit width in
|
||||
the SoC. More introduction is added in documentation:
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-8-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/hisilicon/Makefile
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 4 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 530 ++++++++++++++++++
|
||||
include/linux/cpuhotplug.h | 1 +
|
||||
3 files changed, 534 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 2621d51ae87a..6600a9d45dd8 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1 +1,3 @@
|
||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o
|
||||
+# SPDX-License-Identifier: GPL-2.0-only
|
||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
+ hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
new file mode 100644
|
||||
index 000000000000..46be312fa126
|
||||
--- /dev/null
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -0,0 +1,530 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * HiSilicon SLLC uncore Hardware event counters support
|
||||
+ *
|
||||
+ * Copyright (C) 2020 Hisilicon Limited
|
||||
+ * Author: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
+ *
|
||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
+ */
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/cpuhotplug.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "hisi_uncore_pmu.h"
|
||||
+
|
||||
+/* SLLC register definition */
|
||||
+#define SLLC_INT_MASK 0x0814
|
||||
+#define SLLC_INT_STATUS 0x0818
|
||||
+#define SLLC_INT_CLEAR 0x081c
|
||||
+#define SLLC_PERF_CTRL 0x1c00
|
||||
+#define SLLC_SRCID_CTRL 0x1c04
|
||||
+#define SLLC_TGTID_CTRL 0x1c08
|
||||
+#define SLLC_EVENT_CTRL 0x1c14
|
||||
+#define SLLC_EVENT_TYPE0 0x1c18
|
||||
+#define SLLC_VERSION 0x1cf0
|
||||
+#define SLLC_EVENT_CNT0_L 0x1d00
|
||||
+
|
||||
+#define SLLC_EVTYPE_MASK 0xff
|
||||
+#define SLLC_PERF_CTRL_EN BIT(0)
|
||||
+#define SLLC_FILT_EN BIT(1)
|
||||
+#define SLLC_TRACETAG_EN BIT(2)
|
||||
+#define SLLC_SRCID_EN BIT(4)
|
||||
+#define SLLC_SRCID_NONE 0x0
|
||||
+#define SLLC_TGTID_EN BIT(5)
|
||||
+#define SLLC_TGTID_NONE 0x0
|
||||
+#define SLLC_TGTID_MIN_SHIFT 1
|
||||
+#define SLLC_TGTID_MAX_SHIFT 12
|
||||
+#define SLLC_SRCID_CMD_SHIFT 1
|
||||
+#define SLLC_SRCID_MSK_SHIFT 12
|
||||
+#define SLLC_NR_EVENTS 0x80
|
||||
+
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_min, config1, 10, 0);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_max, config1, 21, 11);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
||||
+
|
||||
+static bool tgtid_is_valid(u32 max, u32 min)
|
||||
+{
|
||||
+ return max > 0 && max >= min;
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_enable_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
||||
+
|
||||
+ if (tt_en) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val |= SLLC_TRACETAG_EN | SLLC_FILT_EN;
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_disable_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
||||
+
|
||||
+ if (tt_en) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val &= ~(SLLC_TRACETAG_EN | SLLC_FILT_EN);
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_config_tgtid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 min = hisi_get_tgtid_min(event);
|
||||
+ u32 max = hisi_get_tgtid_max(event);
|
||||
+
|
||||
+ if (tgtid_is_valid(max, min)) {
|
||||
+ u32 val = (max << SLLC_TGTID_MAX_SHIFT) | (min << SLLC_TGTID_MIN_SHIFT);
|
||||
+
|
||||
+ writel(val, sllc_pmu->base + SLLC_TGTID_CTRL);
|
||||
+ /* Enable the tgtid */
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val |= SLLC_TGTID_EN | SLLC_FILT_EN;
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_clear_tgtid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 min = hisi_get_tgtid_min(event);
|
||||
+ u32 max = hisi_get_tgtid_max(event);
|
||||
+
|
||||
+ if (tgtid_is_valid(max, min)) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ writel(SLLC_TGTID_NONE, sllc_pmu->base + SLLC_TGTID_CTRL);
|
||||
+ /* Disable the tgtid */
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val &= ~(SLLC_TGTID_EN | SLLC_FILT_EN);
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_config_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 val, msk;
|
||||
+
|
||||
+ msk = hisi_get_srcid_msk(event);
|
||||
+ val = (cmd << SLLC_SRCID_CMD_SHIFT) | (msk << SLLC_SRCID_MSK_SHIFT);
|
||||
+ writel(val, sllc_pmu->base + SLLC_SRCID_CTRL);
|
||||
+ /* Enable the srcid */
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val |= SLLC_SRCID_EN | SLLC_FILT_EN;
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_clear_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ writel(SLLC_SRCID_NONE, sllc_pmu->base + SLLC_SRCID_CTRL);
|
||||
+ /* Disable the srcid */
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val &= ~(SLLC_SRCID_EN | SLLC_FILT_EN);
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_enable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_sllc_pmu_enable_tracetag(event);
|
||||
+ hisi_sllc_pmu_config_srcid(event);
|
||||
+ hisi_sllc_pmu_config_tgtid(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_clear_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_sllc_pmu_disable_tracetag(event);
|
||||
+ hisi_sllc_pmu_clear_srcid(event);
|
||||
+ hisi_sllc_pmu_clear_tgtid(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_sllc_pmu_get_counter_offset(int idx)
|
||||
+{
|
||||
+ return (SLLC_EVENT_CNT0_L + idx * 8);
|
||||
+}
|
||||
+
|
||||
+static u64 hisi_sllc_pmu_read_counter(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readq(sllc_pmu->base +
|
||||
+ hisi_sllc_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_write_counter(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ writeq(val, sllc_pmu->base +
|
||||
+ hisi_sllc_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_write_evtype(struct hisi_pmu *sllc_pmu, int idx,
|
||||
+ u32 type)
|
||||
+{
|
||||
+ u32 reg, reg_idx, shift, val;
|
||||
+
|
||||
+ /*
|
||||
+ * Select the appropriate event select register(SLLC_EVENT_TYPE0/1).
|
||||
+ * There are 2 event select registers for the 8 hardware counters.
|
||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
||||
+ * SLLC_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
+ * SLLC_EVENT_TYPE1 is chosen.
|
||||
+ */
|
||||
+ reg = SLLC_EVENT_TYPE0 + (idx / 4) * 4;
|
||||
+ reg_idx = idx % 4;
|
||||
+ shift = 8 * reg_idx;
|
||||
+
|
||||
+ /* Write event code to SLLC_EVENT_TYPEx Register */
|
||||
+ val = readl(sllc_pmu->base + reg);
|
||||
+ val &= ~(SLLC_EVTYPE_MASK << shift);
|
||||
+ val |= (type << shift);
|
||||
+ writel(val, sllc_pmu->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_start_counters(struct hisi_pmu *sllc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val |= SLLC_PERF_CTRL_EN;
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_stop_counters(struct hisi_pmu *sllc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+ val &= ~(SLLC_PERF_CTRL_EN);
|
||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_enable_counter(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_disable_counter(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_enable_counter_int(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_INT_MASK);
|
||||
+ /* Write 0 to enable interrupt */
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, sllc_pmu->base + SLLC_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_disable_counter_int(struct hisi_pmu *sllc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(sllc_pmu->base + SLLC_INT_MASK);
|
||||
+ /* Write 1 to mask interrupt */
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, sllc_pmu->base + SLLC_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_sllc_pmu_get_int_status(struct hisi_pmu *sllc_pmu)
|
||||
+{
|
||||
+ return readl(sllc_pmu->base + SLLC_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_sllc_pmu_clear_int_status(struct hisi_pmu *sllc_pmu, int idx)
|
||||
+{
|
||||
+ writel(1 << idx, sllc_pmu->base + SLLC_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id hisi_sllc_pmu_acpi_match[] = {
|
||||
+ { "HISI0263", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
|
||||
+
|
||||
+static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *sllc_pmu)
|
||||
+{
|
||||
+ /*
|
||||
+ * Use the SCCL_ID and the index ID to identify the SLLC PMU,
|
||||
+ * while SCCL_ID is from MPIDR_EL1 by CPU.
|
||||
+ */
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
+ &sllc_pmu->sccl_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
+ &sllc_pmu->index_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* SLLC PMUs only share the same SCCL */
|
||||
+ sllc_pmu->ccl_id = -1;
|
||||
+
|
||||
+ sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(sllc_pmu->base)) {
|
||||
+ dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
|
||||
+ return PTR_ERR(sllc_pmu->base);
|
||||
+ }
|
||||
+
|
||||
+ sllc_pmu->identifier = readl(sllc_pmu->base + SLLC_VERSION);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct attribute *hisi_sllc_pmu_v2_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tgtid_min, "config1:0-10"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tgtid_max, "config1:11-21"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:22-32"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:33-43"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:44"),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_sllc_pmu_v2_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_sllc_pmu_v2_format_attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute *hisi_sllc_pmu_v2_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(rx_req, 0x30),
|
||||
+ HISI_PMU_EVENT_ATTR(rx_data, 0x31),
|
||||
+ HISI_PMU_EVENT_ATTR(tx_req, 0x34),
|
||||
+ HISI_PMU_EVENT_ATTR(tx_data, 0x35),
|
||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x09),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_sllc_pmu_v2_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_sllc_pmu_v2_events_attr,
|
||||
+};
|
||||
+
|
||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_sllc_pmu_cpumask_attrs[] = {
|
||||
+ &dev_attr_cpumask.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_sllc_pmu_cpumask_attr_group = {
|
||||
+ .attrs = hisi_sllc_pmu_cpumask_attrs,
|
||||
+};
|
||||
+
|
||||
+static struct device_attribute hisi_sllc_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_sllc_pmu_identifier_attrs[] = {
|
||||
+ &hisi_sllc_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_sllc_pmu_identifier_group = {
|
||||
+ .attrs = hisi_sllc_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
|
||||
+ &hisi_sllc_pmu_v2_format_group,
|
||||
+ &hisi_sllc_pmu_v2_events_group,
|
||||
+ &hisi_sllc_pmu_cpumask_attr_group,
|
||||
+ &hisi_sllc_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct hisi_uncore_ops hisi_uncore_sllc_ops = {
|
||||
+ .write_evtype = hisi_sllc_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
+ .start_counters = hisi_sllc_pmu_start_counters,
|
||||
+ .stop_counters = hisi_sllc_pmu_stop_counters,
|
||||
+ .enable_counter = hisi_sllc_pmu_enable_counter,
|
||||
+ .disable_counter = hisi_sllc_pmu_disable_counter,
|
||||
+ .enable_counter_int = hisi_sllc_pmu_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_sllc_pmu_disable_counter_int,
|
||||
+ .write_counter = hisi_sllc_pmu_write_counter,
|
||||
+ .read_counter = hisi_sllc_pmu_read_counter,
|
||||
+ .get_int_status = hisi_sllc_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_sllc_pmu_clear_int_status,
|
||||
+ .enable_filter = hisi_sllc_pmu_enable_filter,
|
||||
+ .disable_filter = hisi_sllc_pmu_clear_filter,
|
||||
+};
|
||||
+
|
||||
+static int hisi_sllc_pmu_dev_probe(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *sllc_pmu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hisi_sllc_pmu_init_data(pdev, sllc_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = hisi_uncore_pmu_init_irq(sllc_pmu, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ sllc_pmu->pmu_events.attr_groups = hisi_sllc_pmu_v2_attr_groups;
|
||||
+ sllc_pmu->ops = &hisi_uncore_sllc_ops;
|
||||
+ sllc_pmu->check_event = SLLC_NR_EVENTS;
|
||||
+ sllc_pmu->counter_bits = 64;
|
||||
+ sllc_pmu->num_counters = 8;
|
||||
+ sllc_pmu->dev = &pdev->dev;
|
||||
+ sllc_pmu->on_cpu = -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu;
|
||||
+ char *name;
|
||||
+ int ret;
|
||||
+
|
||||
+ sllc_pmu = devm_kzalloc(&pdev->dev, sizeof(*sllc_pmu), GFP_KERNEL);
|
||||
+ if (!sllc_pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = hisi_sllc_pmu_dev_probe(pdev, sllc_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_sllc%u",
|
||||
+ sllc_pmu->sccl_id, sllc_pmu->index_id);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
+ &sllc_pmu->node);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ sllc_pmu->pmu = (struct pmu) {
|
||||
+ .module = THIS_MODULE,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = sllc_pmu->pmu_events.attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
+ };
|
||||
+
|
||||
+ ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
||||
+ if (ret) {
|
||||
+ dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
+ cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
+ &sllc_pmu->node);
|
||||
+ irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, sllc_pmu);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hisi_sllc_pmu_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *sllc_pmu = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ perf_pmu_unregister(&sllc_pmu->pmu);
|
||||
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
+ &sllc_pmu->node);
|
||||
+ irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver hisi_sllc_pmu_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "hisi_sllc_pmu",
|
||||
+ .acpi_match_table = hisi_sllc_pmu_acpi_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+ .probe = hisi_sllc_pmu_probe,
|
||||
+ .remove = hisi_sllc_pmu_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init hisi_sllc_pmu_module_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
+ "AP_PERF_ARM_HISI_SLLC_ONLINE",
|
||||
+ hisi_uncore_pmu_online_cpu,
|
||||
+ hisi_uncore_pmu_offline_cpu);
|
||||
+ if (ret) {
|
||||
+ pr_err("SLLC PMU: cpuhp state setup failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_driver_register(&hisi_sllc_pmu_driver);
|
||||
+ if (ret)
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+module_init(hisi_sllc_pmu_module_init);
|
||||
+
|
||||
+static void __exit hisi_sllc_pmu_module_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&hisi_sllc_pmu_driver);
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
||||
+}
|
||||
+module_exit(hisi_sllc_pmu_module_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("HiSilicon SLLC uncore PMU driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
||||
+MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");
|
||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
||||
index d67c0035165c..b5c55a408a30 100644
|
||||
--- a/include/linux/cpuhotplug.h
|
||||
+++ b/include/linux/cpuhotplug.h
|
||||
@@ -161,6 +161,7 @@ enum cpuhp_state {
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
+ CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,584 @@
|
||||
From 71cf98350d1423660b390740a190ce8a98502c37 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:09 +0800
|
||||
Subject: [PATCH 20/55] drivers/perf: hisi: Add support for HiSilicon PA PMU
|
||||
driver
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.12-rc3
|
||||
commit a0ab25cd82eeb68bfa19a4d93a097521af5011b8
|
||||
category: feature
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a0ab25cd82eeb68bfa19a4d93a097521af5011b8
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
On HiSilicon Hip09 platform, there is a PA (Protocol Adapter) module on
|
||||
each chip SICL (Super I/O Cluster) which incorporates three Hydra interface
|
||||
and facilitates the cache coherency between the dies on the chip. While PA
|
||||
uncore PMU model is the same as other Hip09 PMU modules and many PMU events
|
||||
are supported. Let's support the PMU driver using the HiSilicon uncore PMU
|
||||
framework.
|
||||
|
||||
PA PMU supports the following filter functions:
|
||||
* tracetag_en: allows user to count events according to tt_req or
|
||||
tt_core set in L3C PMU. It's the same as other PMUs.
|
||||
|
||||
* srcid_cmd & srcid_msk: allows user to filter statistics that come from
|
||||
specific CCL/ICL by configuration source ID.
|
||||
|
||||
* tgtid_cmd & tgtid_msk: it is the similar function to srcid_cmd &
|
||||
srcid_msk. Both are used to check where the data comes from or go to.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-9-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 3 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 500 ++++++++++++++++++++
|
||||
include/linux/cpuhotplug.h | 1 +
|
||||
3 files changed, 503 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 6600a9d45dd8..7643c9f93e36 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
- hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o
|
||||
+ hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
||||
+ hisi_uncore_pa_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
new file mode 100644
|
||||
index 000000000000..5517a90552ec
|
||||
--- /dev/null
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -0,0 +1,500 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * HiSilicon PA uncore Hardware event counters support
|
||||
+ *
|
||||
+ * Copyright (C) 2020 HiSilicon Limited
|
||||
+ * Author: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
+ *
|
||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
+ */
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/cpuhotplug.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "hisi_uncore_pmu.h"
|
||||
+
|
||||
+/* PA register definition */
|
||||
+#define PA_PERF_CTRL 0x1c00
|
||||
+#define PA_EVENT_CTRL 0x1c04
|
||||
+#define PA_TT_CTRL 0x1c08
|
||||
+#define PA_TGTID_CTRL 0x1c14
|
||||
+#define PA_SRCID_CTRL 0x1c18
|
||||
+#define PA_INT_MASK 0x1c70
|
||||
+#define PA_INT_STATUS 0x1c78
|
||||
+#define PA_INT_CLEAR 0x1c7c
|
||||
+#define PA_EVENT_TYPE0 0x1c80
|
||||
+#define PA_PMU_VERSION 0x1cf0
|
||||
+#define PA_EVENT_CNT0_L 0x1d00
|
||||
+
|
||||
+#define PA_EVTYPE_MASK 0xff
|
||||
+#define PA_NR_COUNTERS 0x8
|
||||
+#define PA_PERF_CTRL_EN BIT(0)
|
||||
+#define PA_TRACETAG_EN BIT(4)
|
||||
+#define PA_TGTID_EN BIT(11)
|
||||
+#define PA_SRCID_EN BIT(11)
|
||||
+#define PA_TGTID_NONE 0
|
||||
+#define PA_SRCID_NONE 0
|
||||
+#define PA_TGTID_MSK_SHIFT 12
|
||||
+#define PA_SRCID_MSK_SHIFT 12
|
||||
+
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_cmd, config1, 10, 0);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_msk, config1, 21, 11);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
||||
+
|
||||
+static void hisi_pa_pmu_enable_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
||||
+
|
||||
+ if (tt_en) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(pa_pmu->base + PA_TT_CTRL);
|
||||
+ val |= PA_TRACETAG_EN;
|
||||
+ writel(val, pa_pmu->base + PA_TT_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_clear_tracetag(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
||||
+
|
||||
+ if (tt_en) {
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(pa_pmu->base + PA_TT_CTRL);
|
||||
+ val &= ~PA_TRACETAG_EN;
|
||||
+ writel(val, pa_pmu->base + PA_TT_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_config_tgtid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_tgtid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 msk = hisi_get_tgtid_msk(event);
|
||||
+ u32 val = cmd | PA_TGTID_EN | (msk << PA_TGTID_MSK_SHIFT);
|
||||
+
|
||||
+ writel(val, pa_pmu->base + PA_TGTID_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_clear_tgtid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_tgtid_cmd(event);
|
||||
+
|
||||
+ if (cmd)
|
||||
+ writel(PA_TGTID_NONE, pa_pmu->base + PA_TGTID_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_config_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd) {
|
||||
+ u32 msk = hisi_get_srcid_msk(event);
|
||||
+ u32 val = cmd | PA_SRCID_EN | (msk << PA_SRCID_MSK_SHIFT);
|
||||
+
|
||||
+ writel(val, pa_pmu->base + PA_SRCID_CTRL);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_clear_srcid(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
||||
+
|
||||
+ if (cmd)
|
||||
+ writel(PA_SRCID_NONE, pa_pmu->base + PA_SRCID_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_enable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_pa_pmu_enable_tracetag(event);
|
||||
+ hisi_pa_pmu_config_srcid(event);
|
||||
+ hisi_pa_pmu_config_tgtid(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_disable_filter(struct perf_event *event)
|
||||
+{
|
||||
+ if (event->attr.config1 != 0x0) {
|
||||
+ hisi_pa_pmu_clear_tgtid(event);
|
||||
+ hisi_pa_pmu_clear_srcid(event);
|
||||
+ hisi_pa_pmu_clear_tracetag(event);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_pa_pmu_get_counter_offset(int idx)
|
||||
+{
|
||||
+ return (PA_EVENT_CNT0_L + idx * 8);
|
||||
+}
|
||||
+
|
||||
+static u64 hisi_pa_pmu_read_counter(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readq(pa_pmu->base + hisi_pa_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_write_counter(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ writeq(val, pa_pmu->base + hisi_pa_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_write_evtype(struct hisi_pmu *pa_pmu, int idx,
|
||||
+ u32 type)
|
||||
+{
|
||||
+ u32 reg, reg_idx, shift, val;
|
||||
+
|
||||
+ /*
|
||||
+ * Select the appropriate event select register(PA_EVENT_TYPE0/1).
|
||||
+ * There are 2 event select registers for the 8 hardware counters.
|
||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
||||
+ * PA_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
+ * PA_EVENT_TYPE1 is chosen.
|
||||
+ */
|
||||
+ reg = PA_EVENT_TYPE0 + (idx / 4) * 4;
|
||||
+ reg_idx = idx % 4;
|
||||
+ shift = 8 * reg_idx;
|
||||
+
|
||||
+ /* Write event code to pa_EVENT_TYPEx Register */
|
||||
+ val = readl(pa_pmu->base + reg);
|
||||
+ val &= ~(PA_EVTYPE_MASK << shift);
|
||||
+ val |= (type << shift);
|
||||
+ writel(val, pa_pmu->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_start_counters(struct hisi_pmu *pa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(pa_pmu->base + PA_PERF_CTRL);
|
||||
+ val |= PA_PERF_CTRL_EN;
|
||||
+ writel(val, pa_pmu->base + PA_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_stop_counters(struct hisi_pmu *pa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(pa_pmu->base + PA_PERF_CTRL);
|
||||
+ val &= ~(PA_PERF_CTRL_EN);
|
||||
+ writel(val, pa_pmu->base + PA_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_enable_counter(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Enable counter index in PA_EVENT_CTRL register */
|
||||
+ val = readl(pa_pmu->base + PA_EVENT_CTRL);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, pa_pmu->base + PA_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_disable_counter(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear counter index in PA_EVENT_CTRL register */
|
||||
+ val = readl(pa_pmu->base + PA_EVENT_CTRL);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, pa_pmu->base + PA_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_enable_counter_int(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 0 to enable interrupt */
|
||||
+ val = readl(pa_pmu->base + PA_INT_MASK);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, pa_pmu->base + PA_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_disable_counter_int(struct hisi_pmu *pa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 1 to mask interrupt */
|
||||
+ val = readl(pa_pmu->base + PA_INT_MASK);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, pa_pmu->base + PA_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_pa_pmu_get_int_status(struct hisi_pmu *pa_pmu)
|
||||
+{
|
||||
+ return readl(pa_pmu->base + PA_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
|
||||
+{
|
||||
+ writel(1 << idx, pa_pmu->base + PA_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id hisi_pa_pmu_acpi_match[] = {
|
||||
+ { "HISI0273", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, hisi_pa_pmu_acpi_match);
|
||||
+
|
||||
+static int hisi_pa_pmu_init_data(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *pa_pmu)
|
||||
+{
|
||||
+ /*
|
||||
+ * Use the SCCL_ID and the index ID to identify the PA PMU,
|
||||
+ * while SCCL_ID is the nearst SCCL_ID from this SICL and
|
||||
+ * CPU core is chosen from this SCCL to manage this PMU.
|
||||
+ */
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
+ &pa_pmu->sccl_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
+ &pa_pmu->index_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ pa_pmu->ccl_id = -1;
|
||||
+
|
||||
+ pa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(pa_pmu->base)) {
|
||||
+ dev_err(&pdev->dev, "ioremap failed for pa_pmu resource.\n");
|
||||
+ return PTR_ERR(pa_pmu->base);
|
||||
+ }
|
||||
+
|
||||
+ pa_pmu->identifier = readl(pa_pmu->base + PA_PMU_VERSION);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct attribute *hisi_pa_pmu_v2_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tgtid_cmd, "config1:0-10"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tgtid_msk, "config1:11-21"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:22-32"),
|
||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:33-43"),
|
||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:44"),
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_pa_pmu_v2_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_pa_pmu_v2_format_attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute *hisi_pa_pmu_v2_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(rx_req, 0x40),
|
||||
+ HISI_PMU_EVENT_ATTR(tx_req, 0x5c),
|
||||
+ HISI_PMU_EVENT_ATTR(cycle, 0x78),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_pa_pmu_v2_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_pa_pmu_v2_events_attr,
|
||||
+};
|
||||
+
|
||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_pa_pmu_cpumask_attrs[] = {
|
||||
+ &dev_attr_cpumask.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_pa_pmu_cpumask_attr_group = {
|
||||
+ .attrs = hisi_pa_pmu_cpumask_attrs,
|
||||
+};
|
||||
+
|
||||
+static struct device_attribute hisi_pa_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_pa_pmu_identifier_attrs[] = {
|
||||
+ &hisi_pa_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_pa_pmu_identifier_group = {
|
||||
+ .attrs = hisi_pa_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *hisi_pa_pmu_v2_attr_groups[] = {
|
||||
+ &hisi_pa_pmu_v2_format_group,
|
||||
+ &hisi_pa_pmu_v2_events_group,
|
||||
+ &hisi_pa_pmu_cpumask_attr_group,
|
||||
+ &hisi_pa_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct hisi_uncore_ops hisi_uncore_pa_ops = {
|
||||
+ .write_evtype = hisi_pa_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
+ .start_counters = hisi_pa_pmu_start_counters,
|
||||
+ .stop_counters = hisi_pa_pmu_stop_counters,
|
||||
+ .enable_counter = hisi_pa_pmu_enable_counter,
|
||||
+ .disable_counter = hisi_pa_pmu_disable_counter,
|
||||
+ .enable_counter_int = hisi_pa_pmu_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_pa_pmu_disable_counter_int,
|
||||
+ .write_counter = hisi_pa_pmu_write_counter,
|
||||
+ .read_counter = hisi_pa_pmu_read_counter,
|
||||
+ .get_int_status = hisi_pa_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_pa_pmu_clear_int_status,
|
||||
+ .enable_filter = hisi_pa_pmu_enable_filter,
|
||||
+ .disable_filter = hisi_pa_pmu_disable_filter,
|
||||
+};
|
||||
+
|
||||
+static int hisi_pa_pmu_dev_probe(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *pa_pmu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hisi_pa_pmu_init_data(pdev, pa_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = hisi_uncore_pmu_init_irq(pa_pmu, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ pa_pmu->pmu_events.attr_groups = hisi_pa_pmu_v2_attr_groups;
|
||||
+ pa_pmu->num_counters = PA_NR_COUNTERS;
|
||||
+ pa_pmu->ops = &hisi_uncore_pa_ops;
|
||||
+ pa_pmu->check_event = 0xB0;
|
||||
+ pa_pmu->counter_bits = 64;
|
||||
+ pa_pmu->dev = &pdev->dev;
|
||||
+ pa_pmu->on_cpu = -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu;
|
||||
+ char *name;
|
||||
+ int ret;
|
||||
+
|
||||
+ pa_pmu = devm_kzalloc(&pdev->dev, sizeof(*pa_pmu), GFP_KERNEL);
|
||||
+ if (!pa_pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = hisi_pa_pmu_dev_probe(pdev, pa_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ /*
|
||||
+ * PA is attached in SICL and the CPU core is chosen to manage this
|
||||
+ * PMU which is the nearest SCCL, while its SCCL_ID is greater than
|
||||
+ * one with the SICL_ID.
|
||||
+ */
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%u_pa%u",
|
||||
+ pa_pmu->sccl_id - 1, pa_pmu->index_id);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
+ &pa_pmu->node);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ pa_pmu->pmu = (struct pmu) {
|
||||
+ .module = THIS_MODULE,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = pa_pmu->pmu_events.attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
+ };
|
||||
+
|
||||
+ ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
||||
+ if (ret) {
|
||||
+ dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
+ cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
+ &pa_pmu->node);
|
||||
+ irq_set_affinity_hint(pa_pmu->irq, NULL);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, pa_pmu);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hisi_pa_pmu_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *pa_pmu = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ perf_pmu_unregister(&pa_pmu->pmu);
|
||||
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
+ &pa_pmu->node);
|
||||
+ irq_set_affinity_hint(pa_pmu->irq, NULL);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver hisi_pa_pmu_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "hisi_pa_pmu",
|
||||
+ .acpi_match_table = hisi_pa_pmu_acpi_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+ .probe = hisi_pa_pmu_probe,
|
||||
+ .remove = hisi_pa_pmu_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init hisi_pa_pmu_module_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
+ "AP_PERF_ARM_HISI_PA_ONLINE",
|
||||
+ hisi_uncore_pmu_online_cpu,
|
||||
+ hisi_uncore_pmu_offline_cpu);
|
||||
+ if (ret) {
|
||||
+ pr_err("PA PMU: cpuhp state setup failed, ret = %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_driver_register(&hisi_pa_pmu_driver);
|
||||
+ if (ret)
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+module_init(hisi_pa_pmu_module_init);
|
||||
+
|
||||
+static void __exit hisi_pa_pmu_module_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&hisi_pa_pmu_driver);
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
||||
+}
|
||||
+module_exit(hisi_pa_pmu_module_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("HiSilicon Protocol Adapter uncore PMU driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
||||
+MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");
|
||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
||||
index b5c55a408a30..225b095a96db 100644
|
||||
--- a/include/linux/cpuhotplug.h
|
||||
+++ b/include/linux/cpuhotplug.h
|
||||
@@ -161,6 +161,7 @@ enum cpuhp_state {
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
+ CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
181
patches/0062-perf-hisi-Use-irq_set_affinity.patch
Normal file
181
patches/0062-perf-hisi-Use-irq_set_affinity.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From e0b763c0b1c8c96a04fd56f7be82d13903123b19 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Gleixner <tglx@linutronix.de>
|
||||
Date: Fri, 30 Jul 2021 15:44:12 +0800
|
||||
Subject: [PATCH 21/55] perf/hisi: Use irq_set_affinity()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.13-rc3
|
||||
commit 77b06ddc04354293f746d0434f00700110d3392d
|
||||
category: bugfix
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77b06ddc04354293f746d0434f00700110d3392d
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
These drivers use irq_set_affinity_hint() to set the affinity for the PMU
|
||||
interrupts, which relies on the undocumented side effect that this function
|
||||
actually sets the affinity under the hood.
|
||||
|
||||
Setting an hint is clearly not a guarantee and for these PMU interrupts an
|
||||
affinity hint, which is supposed to guide userspace for setting affinity,
|
||||
is beyond pointless, because the affinity of these interrupts cannot be
|
||||
modified from user space.
|
||||
|
||||
Aside of that the error checks are bogus because the only error which is
|
||||
returned from irq_set_affinity_hint() is when there is no irq descriptor
|
||||
for the interrupt number, but not when the affinity set fails. That's on
|
||||
purpose because the hint can point to an offline CPU.
|
||||
|
||||
Replace the mindless abuse with irq_set_affinity().
|
||||
|
||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: linux-arm-kernel@lists.infradead.org
|
||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
||||
Link: https://lore.kernel.org/r/20210518093118.813375875@linutronix.de
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 3 ---
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 3 ---
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 3 ---
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 3 ---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 4 ++--
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 3 ---
|
||||
6 files changed, 2 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index af5f8c16eab1..457ac6a1ad64 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -540,7 +540,6 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node);
|
||||
- irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -553,8 +552,6 @@ static int hisi_ddrc_pmu_remove(struct platform_device *pdev)
|
||||
perf_pmu_unregister(&ddrc_pmu->pmu);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
&ddrc_pmu->node);
|
||||
- irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index a7e1749fc3e4..89996b4d939f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -543,7 +543,6 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node);
|
||||
- irq_set_affinity_hint(hha_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -556,8 +555,6 @@ static int hisi_hha_pmu_remove(struct platform_device *pdev)
|
||||
perf_pmu_unregister(&hha_pmu->pmu);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
&hha_pmu->node);
|
||||
- irq_set_affinity_hint(hha_pmu->irq, NULL);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 87ca2a9ca8c5..d70a01587d72 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -581,7 +581,6 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
dev_err(l3c_pmu->dev, "L3C PMU register failed!\n");
|
||||
cpuhp_state_remove_instance_nocalls(
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node);
|
||||
- irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -594,8 +593,6 @@ static int hisi_l3c_pmu_remove(struct platform_device *pdev)
|
||||
perf_pmu_unregister(&l3c_pmu->pmu);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
&l3c_pmu->node);
|
||||
- irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index 5517a90552ec..390e59f4ef60 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -436,7 +436,6 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
&pa_pmu->node);
|
||||
- irq_set_affinity_hint(pa_pmu->irq, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -451,8 +450,6 @@ static int hisi_pa_pmu_remove(struct platform_device *pdev)
|
||||
perf_pmu_unregister(&pa_pmu->pmu);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
&pa_pmu->node);
|
||||
- irq_set_affinity_hint(pa_pmu->irq, NULL);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index c0f221e39aff..2758cab39a58 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -491,7 +491,7 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
hisi_pmu->on_cpu = cpu;
|
||||
|
||||
/* Overflow interrupt also should use the same CPU */
|
||||
- WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(cpu)));
|
||||
+ WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -524,7 +524,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
perf_pmu_migrate_context(&hisi_pmu->pmu, cpu, target);
|
||||
/* Use this CPU for event counting */
|
||||
hisi_pmu->on_cpu = target;
|
||||
- WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(target)));
|
||||
+ WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(target)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
index 46be312fa126..835ec3e2178f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -465,7 +465,6 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
&sllc_pmu->node);
|
||||
- irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -481,8 +480,6 @@ static int hisi_sllc_pmu_remove(struct platform_device *pdev)
|
||||
perf_pmu_unregister(&sllc_pmu->pmu);
|
||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
&sllc_pmu->node);
|
||||
- irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
60
patches/0063-drivers-perf-hisi-Fix-data-source-control.patch
Normal file
60
patches/0063-drivers-perf-hisi-Fix-data-source-control.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 07451c781b0890dd194b0a53606250bed8f6ecbf Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Fri, 30 Jul 2021 15:44:13 +0800
|
||||
Subject: [PATCH 22/55] drivers/perf: hisi: Fix data source control
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.13-rc3
|
||||
commit 814be609baae62aaa6c02fa6f3ad66cff32a6d15
|
||||
category: bugfix
|
||||
bugzilla: 175148
|
||||
CVE: NA
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=814be609baae62aaa6c02fa6f3ad66cff32a6d15
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
'Data source' is a new function for HHA PMU and config / clear
|
||||
interface was wrong by mistake. 'HHA_DATSRC_CTRL' register is
|
||||
mainly used for data source configuration, if we enable bit0
|
||||
as driver, it will go on count the event and we didn't check
|
||||
it carefully. So fix the issue and do as the initial purpose.
|
||||
|
||||
Fixes: 932f6a99f9b0 ("drivers/perf: hisi: Add new functions for HHA PMU")
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1622709291-37996-1-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 89996b4d939f..3b120fc55e01 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -93,7 +93,7 @@ static void hisi_hha_pmu_config_ds(struct perf_event *event)
|
||||
|
||||
val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
val |= HHA_DATSRC_SKT_EN;
|
||||
- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ writel(val, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ static void hisi_hha_pmu_clear_ds(struct perf_event *event)
|
||||
|
||||
val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
val &= ~HHA_DATSRC_SKT_EN;
|
||||
- writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
+ writel(val, hha_pmu->base + HHA_DATSRC_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
44
patches/0064-perf-hisi-Make-irq-shared.patch
Normal file
44
patches/0064-perf-hisi-Make-irq-shared.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From d6ffa958e5f2fd9eff8cec5b41817e9bdec94f5e Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Thu, 19 May 2022 20:09:48 +0800
|
||||
Subject: [PATCH 23/55] perf: hisi: Make irq shared
|
||||
|
||||
hulk inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
On some platforms, there are some error:
|
||||
genirq: Flags mismatch irq 23. 00010804 (xxx) vs. 00010804 (xxx)
|
||||
|
||||
The reason is that there are more than one pmu nodes witch uses the same
|
||||
irq number.
|
||||
|
||||
Add IROF_SHARED when devm_request_irq
|
||||
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 2758cab39a58..eceff43c89f7 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -171,7 +171,7 @@ int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
return irq;
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, hisi_uncore_pmu_isr,
|
||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
||||
+ IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
|
||||
dev_name(&pdev->dev), hisi_pmu);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 52b22aa2df42650d15ff80d32c827a55e6907a49 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Thu, 19 May 2022 20:09:49 +0800
|
||||
Subject: [PATCH 24/55] perf: hisi: Fix read sccl_id and ccl_id error in some
|
||||
platform
|
||||
|
||||
hulk inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
Some platforms with TSV200 or CORTEX_A55, sccl and ccl are keep in
|
||||
aff2 if mt.
|
||||
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index eceff43c89f7..4a781c2e1992 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -437,12 +437,19 @@ static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
|
||||
bool mt = mpidr & MPIDR_MT_BITMASK;
|
||||
int sccl, ccl;
|
||||
|
||||
- if (mt && read_cpuid_part_number() == HISI_CPU_PART_TSV110) {
|
||||
- sccl = aff2 >> 3;
|
||||
- ccl = aff2 & 0x7;
|
||||
- } else if (mt) {
|
||||
- sccl = aff3;
|
||||
- ccl = aff2;
|
||||
+ if (mt) {
|
||||
+ switch (read_cpuid_part_number()) {
|
||||
+ case HISI_CPU_PART_TSV110:
|
||||
+ case HISI_CPU_PART_TSV200:
|
||||
+ case ARM_CPU_PART_CORTEX_A55:
|
||||
+ sccl = aff2 >> 3;
|
||||
+ ccl = aff2 & 0x7;
|
||||
+ break;
|
||||
+ default:
|
||||
+ sccl = aff3;
|
||||
+ ccl = aff2;
|
||||
+ break;
|
||||
+ }
|
||||
} else {
|
||||
sccl = aff2;
|
||||
ccl = aff1;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,461 @@
|
||||
From 88223b8764dabcbfde85e37927fbd12100957f22 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Thu, 19 May 2022 20:09:50 +0800
|
||||
Subject: [PATCH 25/55] perf: hisi: Add support for HiSilicon SoC L3T PMU
|
||||
|
||||
hulk inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
Add support for HiSilicon SoC L3T PMU
|
||||
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 3 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c | 403 +++++++++++++++++++
|
||||
3 files changed, 406 insertions(+), 2 deletions(-)
|
||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 7643c9f93e36..18abcb612216 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1,4 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
||||
- hisi_uncore_pa_pmu.o
|
||||
+ hisi_uncore_pa_pmu.o \
|
||||
+ hisi_uncore_l3t_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index d70a01587d72..bb39b44761a5 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -611,7 +611,7 @@ static int __init hisi_l3c_pmu_module_init(void)
|
||||
int ret;
|
||||
|
||||
ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_L3_ONLINE",
|
||||
+ "AP_PERF_ARM_HISI_L3T_ONLINE",
|
||||
hisi_uncore_pmu_online_cpu,
|
||||
hisi_uncore_pmu_offline_cpu);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
new file mode 100644
|
||||
index 000000000000..f414dc1736aa
|
||||
--- /dev/null
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
||||
@@ -0,0 +1,403 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * HiSilicon SoC L3T uncore Hardware event counters support
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Hisilicon Limited
|
||||
+ * Author: Anurup M <anurup.m@huawei.com>
|
||||
+ * Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
+ *
|
||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
+ */
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/bug.h>
|
||||
+#include <linux/cpuhotplug.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "hisi_uncore_pmu.h"
|
||||
+
|
||||
+/* L3T register definition */
|
||||
+#define L3T_PERF_CTRL 0x0408
|
||||
+#define L3T_INT_MASK 0x0800
|
||||
+#define L3T_INT_STATUS 0x0808
|
||||
+#define L3T_INT_CLEAR 0x080c
|
||||
+#define L3T_EVENT_CTRL 0x1c00
|
||||
+#define L3T_VERSION 0x1cf0
|
||||
+#define L3T_EVENT_TYPE0 0x1d00
|
||||
+/*
|
||||
+ * If the HW version only supports a 48-bit counter, then
|
||||
+ * bits [63:48] are reserved, which are Read-As-Zero and
|
||||
+ * Writes-Ignored.
|
||||
+ */
|
||||
+#define L3T_CNTR0_LOWER 0x1e00
|
||||
+
|
||||
+/* L3T has 8-counters */
|
||||
+#define L3T_NR_COUNTERS 0x8
|
||||
+
|
||||
+#define L3T_PERF_CTRL_EN 0x20000
|
||||
+#define L3T_EVTYPE_NONE 0xff
|
||||
+#define L3T_NR_EVENTS 0x59
|
||||
+
|
||||
+/*
|
||||
+ * Select the counter register offset using the counter index
|
||||
+ */
|
||||
+static u32 hisi_l3t_pmu_get_counter_offset(int cntr_idx)
|
||||
+{
|
||||
+ return (L3T_CNTR0_LOWER + (cntr_idx * 8));
|
||||
+}
|
||||
+
|
||||
+static u64 hisi_l3t_pmu_read_counter(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readq(l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_write_counter(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ writeq(val, l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_write_evtype(struct hisi_pmu *l3t_pmu, int idx,
|
||||
+ u32 type)
|
||||
+{
|
||||
+ u32 reg, reg_idx, shift, val;
|
||||
+
|
||||
+ /*
|
||||
+ * Select the appropriate event select register(L3T_EVENT_TYPE0/1).
|
||||
+ * There are 2 event select registers for the 8 hardware counters.
|
||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
||||
+ * L3T_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
+ * L3T_EVENT_TYPE1 is chosen.
|
||||
+ */
|
||||
+ reg = L3T_EVENT_TYPE0 + (idx / 4) * 4;
|
||||
+ reg_idx = idx % 4;
|
||||
+ shift = 8 * reg_idx;
|
||||
+
|
||||
+ /* Write event code to L3T_EVENT_TYPEx Register */
|
||||
+ val = readl(l3t_pmu->base + reg);
|
||||
+ val &= ~(L3T_EVTYPE_NONE << shift);
|
||||
+ val |= (type << shift);
|
||||
+ writel(val, l3t_pmu->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_start_counters(struct hisi_pmu *l3t_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * Set perf_enable bit in L3T_PERF_CTRL register to start counting
|
||||
+ * for all enabled counters.
|
||||
+ */
|
||||
+ val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
||||
+ val |= L3T_PERF_CTRL_EN;
|
||||
+ writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_stop_counters(struct hisi_pmu *l3t_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /*
|
||||
+ * Clear perf_enable bit in L3T_PERF_CTRL register to stop counting
|
||||
+ * for all enabled counters.
|
||||
+ */
|
||||
+ val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
||||
+ val &= ~(L3T_PERF_CTRL_EN);
|
||||
+ writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_enable_counter(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Enable counter index in L3T_EVENT_CTRL register */
|
||||
+ val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
+ val |= (1 << hwc->idx);
|
||||
+ writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_disable_counter(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear counter index in L3T_EVENT_CTRL register */
|
||||
+ val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_enable_counter_int(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(l3t_pmu->base + L3T_INT_MASK);
|
||||
+ /* Write 0 to enable interrupt */
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, l3t_pmu->base + L3T_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_disable_counter_int(struct hisi_pmu *l3t_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(l3t_pmu->base + L3T_INT_MASK);
|
||||
+ /* Write 1 to mask interrupt */
|
||||
+ val |= (1 << hwc->idx);
|
||||
+ writel(val, l3t_pmu->base + L3T_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_l3t_pmu_get_int_status(struct hisi_pmu *l3t_pmu)
|
||||
+{
|
||||
+ return readl(l3t_pmu->base + L3T_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_l3t_pmu_clear_int_status(struct hisi_pmu *l3t_pmu, int idx)
|
||||
+{
|
||||
+ writel(1 << idx, l3t_pmu->base + L3T_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id hisi_l3t_pmu_acpi_match[] = {
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, hisi_l3t_pmu_acpi_match);
|
||||
+
|
||||
+static const struct of_device_id l3t_of_match[] = {
|
||||
+ { .compatible = "hisilicon,l3t-pmu", },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static int hisi_l3t_pmu_init_data(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *l3t_pmu)
|
||||
+{
|
||||
+ /*
|
||||
+ * Use the SCCL_ID and CCL_ID to identify the L3T PMU, while
|
||||
+ * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
||||
+ */
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
+ &l3t_pmu->sccl_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read l3t sccl-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
|
||||
+ &l3t_pmu->ccl_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read l3t ccl-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ l3t_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(l3t_pmu->base)) {
|
||||
+ dev_err(&pdev->dev, "ioremap failed for l3t_pmu resource\n");
|
||||
+ return PTR_ERR(l3t_pmu->base);
|
||||
+ }
|
||||
+
|
||||
+ l3t_pmu->identifier = readl(l3t_pmu->base + L3T_VERSION);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct attribute *hisi_l3t_pmu_v1_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_l3t_pmu_v1_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_l3t_pmu_v1_format_attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute *hisi_l3t_pmu_v1_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
||||
+ HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
||||
+ HISI_PMU_EVENT_ATTR(rd_hit_cpipe, 0x02),
|
||||
+ HISI_PMU_EVENT_ATTR(wr_hit_cpipe, 0x03),
|
||||
+ HISI_PMU_EVENT_ATTR(victim_num, 0x04),
|
||||
+ HISI_PMU_EVENT_ATTR(rd_spipe, 0x20),
|
||||
+ HISI_PMU_EVENT_ATTR(wr_spipe, 0x21),
|
||||
+ HISI_PMU_EVENT_ATTR(rd_hit_spipe, 0x22),
|
||||
+ HISI_PMU_EVENT_ATTR(wr_hit_spipe, 0x23),
|
||||
+ HISI_PMU_EVENT_ATTR(back_invalid, 0x29),
|
||||
+ HISI_PMU_EVENT_ATTR(retry_cpu, 0x40),
|
||||
+ HISI_PMU_EVENT_ATTR(retry_ring, 0x41),
|
||||
+ HISI_PMU_EVENT_ATTR(prefetch_drop, 0x42),
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_l3t_pmu_v1_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_l3t_pmu_v1_events_attr,
|
||||
+};
|
||||
+
|
||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_l3t_pmu_cpumask_attrs[] = {
|
||||
+ &dev_attr_cpumask.attr,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_l3t_pmu_cpumask_attr_group = {
|
||||
+ .attrs = hisi_l3t_pmu_cpumask_attrs,
|
||||
+};
|
||||
+
|
||||
+static struct device_attribute hisi_l3t_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_l3t_pmu_identifier_attrs[] = {
|
||||
+ &hisi_l3t_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_l3t_pmu_identifier_group = {
|
||||
+ .attrs = hisi_l3t_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *hisi_l3t_pmu_v1_attr_groups[] = {
|
||||
+ &hisi_l3t_pmu_v1_format_group,
|
||||
+ &hisi_l3t_pmu_v1_events_group,
|
||||
+ &hisi_l3t_pmu_cpumask_attr_group,
|
||||
+ &hisi_l3t_pmu_identifier_group,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct hisi_uncore_ops hisi_uncore_l3t_ops = {
|
||||
+ .write_evtype = hisi_l3t_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
+ .start_counters = hisi_l3t_pmu_start_counters,
|
||||
+ .stop_counters = hisi_l3t_pmu_stop_counters,
|
||||
+ .enable_counter = hisi_l3t_pmu_enable_counter,
|
||||
+ .disable_counter = hisi_l3t_pmu_disable_counter,
|
||||
+ .enable_counter_int = hisi_l3t_pmu_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_l3t_pmu_disable_counter_int,
|
||||
+ .write_counter = hisi_l3t_pmu_write_counter,
|
||||
+ .read_counter = hisi_l3t_pmu_read_counter,
|
||||
+ .get_int_status = hisi_l3t_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_l3t_pmu_clear_int_status,
|
||||
+};
|
||||
+
|
||||
+static int hisi_l3t_pmu_dev_probe(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *l3t_pmu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hisi_l3t_pmu_init_data(pdev, l3t_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = hisi_uncore_pmu_init_irq(l3t_pmu, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ l3t_pmu->counter_bits = 48;
|
||||
+ l3t_pmu->check_event = L3T_NR_EVENTS;
|
||||
+ l3t_pmu->pmu_events.attr_groups = hisi_l3t_pmu_v1_attr_groups;
|
||||
+
|
||||
+ l3t_pmu->num_counters = L3T_NR_COUNTERS;
|
||||
+ l3t_pmu->ops = &hisi_uncore_l3t_ops;
|
||||
+ l3t_pmu->dev = &pdev->dev;
|
||||
+ l3t_pmu->on_cpu = -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hisi_l3t_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *l3t_pmu;
|
||||
+ char *name;
|
||||
+ int ret;
|
||||
+
|
||||
+ l3t_pmu = devm_kzalloc(&pdev->dev, sizeof(*l3t_pmu), GFP_KERNEL);
|
||||
+ if (!l3t_pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, l3t_pmu);
|
||||
+
|
||||
+ ret = hisi_l3t_pmu_dev_probe(pdev, l3t_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,index-id", &l3t_pmu->index_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read l3t index-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * CCL_ID is used to identify the L3T in the same SCCL which was
|
||||
+ * used _UID by mistake.
|
||||
+ */
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3t%u",
|
||||
+ l3t_pmu->sccl_id, l3t_pmu->index_id);
|
||||
+ l3t_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = l3t_pmu->pmu_events.attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
+ };
|
||||
+
|
||||
+ /* Pick one core to use for cpumask attributes */
|
||||
+ cpumask_set_cpu(smp_processor_id(), &l3t_pmu->associated_cpus);
|
||||
+
|
||||
+ l3t_pmu->on_cpu = cpumask_first(&l3t_pmu->associated_cpus);
|
||||
+ if (l3t_pmu->on_cpu >= nr_cpu_ids)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = perf_pmu_register(&l3t_pmu->pmu, name, -1);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hisi_l3t_pmu_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *l3t_pmu = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ perf_pmu_unregister(&l3t_pmu->pmu);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver hisi_l3t_pmu_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "hisi_l3t_pmu",
|
||||
+ .acpi_match_table = ACPI_PTR(hisi_l3t_pmu_acpi_match),
|
||||
+ .of_match_table = l3t_of_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+ .probe = hisi_l3t_pmu_probe,
|
||||
+ .remove = hisi_l3t_pmu_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init hisi_l3t_pmu_module_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = platform_driver_register(&hisi_l3t_pmu_driver);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+module_init(hisi_l3t_pmu_module_init);
|
||||
+
|
||||
+static void __exit hisi_l3t_pmu_module_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&hisi_l3t_pmu_driver);
|
||||
+}
|
||||
+module_exit(hisi_l3t_pmu_module_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("HiSilicon SoC L3T uncore PMU driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Anurup M <anurup.m@huawei.com>");
|
||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,452 @@
|
||||
From f61fd1d5a4ff1adaae0626f0a99fc38e82efde55 Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Thu, 19 May 2022 20:09:51 +0800
|
||||
Subject: [PATCH 26/55] perf: hisi: Add support for HiSilicon SoC LPDDRC PMU
|
||||
|
||||
hulk inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
Add support for HiSilicon SoC LPDDRC PMU
|
||||
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 3 +-
|
||||
.../perf/hisilicon/hisi_uncore_lpddrc_pmu.c | 408 ++++++++++++++++++
|
||||
2 files changed, 410 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index 18abcb612216..22e384cdfd53 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -2,4 +2,5 @@
|
||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
||||
hisi_uncore_pa_pmu.o \
|
||||
- hisi_uncore_l3t_pmu.o
|
||||
+ hisi_uncore_l3t_pmu.o \
|
||||
+ hisi_uncore_lpddrc_pmu.o
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
new file mode 100644
|
||||
index 000000000000..03a4bb1a9948
|
||||
--- /dev/null
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
||||
@@ -0,0 +1,408 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * HiSilicon SoC LPDDRC uncore Hardware event counters support
|
||||
+ *
|
||||
+ * Copyright (C) 2017 Hisilicon Limited
|
||||
+ * Author: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
+ * Anurup M <anurup.m@huawei.com>
|
||||
+ *
|
||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
+ */
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/bug.h>
|
||||
+#include <linux/cpuhotplug.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "hisi_uncore_pmu.h"
|
||||
+
|
||||
+/* LPDDRC register definition in v1 */
|
||||
+#define LPDDRC_PERF_CTRL 0x4930
|
||||
+#define LPDDRC_FLUX_WR 0x4948
|
||||
+#define LPDDRC_FLUX_RD 0x494c
|
||||
+#define LPDDRC_FLUX_WCMD 0x4950
|
||||
+#define LPDDRC_FLUX_RCMD 0x4954
|
||||
+#define LPDDRC_PRE_CMD 0x4984
|
||||
+#define LPDDRC_ACT_CMD 0x4988
|
||||
+#define LPDDRC_RNK_CHG 0x4990
|
||||
+#define LPDDRC_RW_CHG 0x4994
|
||||
+#define LPDDRC_EVENT_CTRL 0x4d60
|
||||
+#define LPDDRC_INT_MASK 0x6c8
|
||||
+#define LPDDRC_INT_STATUS 0x6cc
|
||||
+#define LPDDRC_INT_CLEAR 0x6d0
|
||||
+#define LPDDRC_VERSION 0x710
|
||||
+
|
||||
+#define LPDDRC_NR_COUNTERS 0x8
|
||||
+#define LPDDRC_V1_PERF_CTRL_EN 0x1
|
||||
+#define LPDDRC_V1_NR_EVENTS 0x7
|
||||
+
|
||||
+/*
|
||||
+ * For PMU v1, there are eight-events and every event has been mapped
|
||||
+ * to fixed-purpose counters which register offset is not consistent.
|
||||
+ * Therefore there is no write event type and we assume that event
|
||||
+ * code (0 to 7) is equal to counter index in PMU driver.
|
||||
+ */
|
||||
+#define GET_LPDDRC_EVENTID(hwc) (hwc->config_base & 0x7)
|
||||
+
|
||||
+static const u32 lpddrc_reg_off[] = {
|
||||
+ LPDDRC_FLUX_WR, LPDDRC_FLUX_RD, LPDDRC_FLUX_WCMD, LPDDRC_FLUX_RCMD,
|
||||
+ LPDDRC_PRE_CMD, LPDDRC_ACT_CMD, LPDDRC_RNK_CHG, LPDDRC_RW_CHG
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Select the counter register offset using the counter index.
|
||||
+ * In PMU v1, there are no programmable counter, the count
|
||||
+ * is read form the statistics counter register itself.
|
||||
+ */
|
||||
+static u32 hisi_lpddrc_pmu_v1_get_counter_offset(int cntr_idx)
|
||||
+{
|
||||
+ return lpddrc_reg_off[cntr_idx];
|
||||
+}
|
||||
+
|
||||
+static u64 hisi_lpddrc_pmu_v1_read_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readl(lpddrc_pmu->base +
|
||||
+ hisi_lpddrc_pmu_v1_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * For LPDDRC PMU, event counter should be reset when start counters,
|
||||
+ * reset the prev_count by software, because the counter register was RO.
|
||||
+ */
|
||||
+static void hisi_lpddrc_pmu_v1_write_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ local64_set(&hwc->prev_count, 0);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * For LPDDRC PMU v1, event has been mapped to fixed-purpose counter by hardware,
|
||||
+ * so there is no need to write event type, while it is programmable counter in
|
||||
+ * PMU v2.
|
||||
+ */
|
||||
+static void hisi_lpddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
||||
+ u32 type)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_start_counters(struct hisi_pmu *lpddrc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Set perf_enable in LPDDRC_PERF_CTRL to start event counting */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
+ val |= LPDDRC_V1_PERF_CTRL_EN;
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_stop_counters(struct hisi_pmu *lpddrc_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear perf_enable in LPDDRC_PERF_CTRL to stop event counting */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
+ val &= ~LPDDRC_V1_PERF_CTRL_EN;
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_enable_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Set counter index(event code) in LPDDRC_EVENT_CTRL register */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
+ val |= (1 << GET_LPDDRC_EVENTID(hwc));
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_disable_counter(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear counter index(event code) in LPDDRC_EVENT_CTRL register */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
+ val &= ~(1 << GET_LPDDRC_EVENTID(hwc));
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static int hisi_lpddrc_pmu_v1_get_event_idx(struct perf_event *event)
|
||||
+{
|
||||
+ struct hisi_pmu *lpddrc_pmu = to_hisi_pmu(event->pmu);
|
||||
+ unsigned long *used_mask = lpddrc_pmu->pmu_events.used_mask;
|
||||
+ struct hw_perf_event *hwc = &event->hw;
|
||||
+ /* For LPDDRC PMU, we use event code as counter index */
|
||||
+ int idx = GET_LPDDRC_EVENTID(hwc);
|
||||
+
|
||||
+ if (test_bit(idx, used_mask))
|
||||
+ return -EAGAIN;
|
||||
+
|
||||
+ set_bit(idx, used_mask);
|
||||
+
|
||||
+ return idx;
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_enable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 0 to enable interrupt */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
+ val &= ~(1 << hwc->idx);
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_disable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 1 to mask interrupt */
|
||||
+ val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_lpddrc_pmu_v1_get_int_status(struct hisi_pmu *lpddrc_pmu)
|
||||
+{
|
||||
+ return readl(lpddrc_pmu->base + LPDDRC_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_lpddrc_pmu_v1_clear_int_status(struct hisi_pmu *lpddrc_pmu,
|
||||
+ int idx)
|
||||
+{
|
||||
+ writel(1 << idx, lpddrc_pmu->base + LPDDRC_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id hisi_lpddrc_pmu_acpi_match[] = {
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, hisi_lpddrc_pmu_acpi_match);
|
||||
+
|
||||
+static const struct of_device_id lpddrc_of_match[] = {
|
||||
+ { .compatible = "hisilicon,lpddrc-pmu", },
|
||||
+ {},
|
||||
+};
|
||||
+
|
||||
+static int hisi_lpddrc_pmu_init_data(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *lpddrc_pmu)
|
||||
+{
|
||||
+ /*
|
||||
+ * Use the SCCL_ID and LPDDRC channel ID to identify the
|
||||
+ * LPDDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
||||
+ */
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,ch-id",
|
||||
+ &lpddrc_pmu->index_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read lpddrc channel-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
+ &lpddrc_pmu->sccl_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read lpddrc sccl-id!\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ /* LPDDRC PMUs only share the same SCCL */
|
||||
+ lpddrc_pmu->ccl_id = -1;
|
||||
+
|
||||
+ lpddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(lpddrc_pmu->base)) {
|
||||
+ dev_err(&pdev->dev, "ioremap failed for lpddrc_pmu resource\n");
|
||||
+ return PTR_ERR(lpddrc_pmu->base);
|
||||
+ }
|
||||
+
|
||||
+ lpddrc_pmu->identifier = readl(lpddrc_pmu->base + LPDDRC_VERSION);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct attribute *hisi_lpddrc_pmu_v1_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-4"),
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_lpddrc_pmu_v1_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_lpddrc_pmu_v1_format_attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute *hisi_lpddrc_pmu_v1_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
||||
+ HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
||||
+ HISI_PMU_EVENT_ATTR(flux_wcmd, 0x02),
|
||||
+ HISI_PMU_EVENT_ATTR(flux_rcmd, 0x03),
|
||||
+ HISI_PMU_EVENT_ATTR(pre_cmd, 0x04),
|
||||
+ HISI_PMU_EVENT_ATTR(act_cmd, 0x05),
|
||||
+ HISI_PMU_EVENT_ATTR(rnk_chg, 0x06),
|
||||
+ HISI_PMU_EVENT_ATTR(rw_chg, 0x07),
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_lpddrc_pmu_v1_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_lpddrc_pmu_v1_events_attr,
|
||||
+};
|
||||
+
|
||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_lpddrc_pmu_cpumask_attrs[] = {
|
||||
+ &dev_attr_cpumask.attr,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_lpddrc_pmu_cpumask_attr_group = {
|
||||
+ .attrs = hisi_lpddrc_pmu_cpumask_attrs,
|
||||
+};
|
||||
+
|
||||
+static struct device_attribute hisi_lpddrc_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_lpddrc_pmu_identifier_attrs[] = {
|
||||
+ &hisi_lpddrc_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group hisi_lpddrc_pmu_identifier_group = {
|
||||
+ .attrs = hisi_lpddrc_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *hisi_lpddrc_pmu_v1_attr_groups[] = {
|
||||
+ &hisi_lpddrc_pmu_v1_format_group,
|
||||
+ &hisi_lpddrc_pmu_v1_events_group,
|
||||
+ &hisi_lpddrc_pmu_cpumask_attr_group,
|
||||
+ &hisi_lpddrc_pmu_identifier_group,
|
||||
+ NULL,
|
||||
+};
|
||||
+
|
||||
+static const struct hisi_uncore_ops hisi_uncore_lpddrc_v1_ops = {
|
||||
+ .write_evtype = hisi_lpddrc_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_lpddrc_pmu_v1_get_event_idx,
|
||||
+ .start_counters = hisi_lpddrc_pmu_v1_start_counters,
|
||||
+ .stop_counters = hisi_lpddrc_pmu_v1_stop_counters,
|
||||
+ .enable_counter = hisi_lpddrc_pmu_v1_enable_counter,
|
||||
+ .disable_counter = hisi_lpddrc_pmu_v1_disable_counter,
|
||||
+ .enable_counter_int = hisi_lpddrc_pmu_v1_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_lpddrc_pmu_v1_disable_counter_int,
|
||||
+ .write_counter = hisi_lpddrc_pmu_v1_write_counter,
|
||||
+ .read_counter = hisi_lpddrc_pmu_v1_read_counter,
|
||||
+ .get_int_status = hisi_lpddrc_pmu_v1_get_int_status,
|
||||
+ .clear_int_status = hisi_lpddrc_pmu_v1_clear_int_status,
|
||||
+};
|
||||
+
|
||||
+static int hisi_lpddrc_pmu_dev_probe(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *lpddrc_pmu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hisi_lpddrc_pmu_init_data(pdev, lpddrc_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = hisi_uncore_pmu_init_irq(lpddrc_pmu, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ lpddrc_pmu->counter_bits = 32;
|
||||
+ lpddrc_pmu->check_event = LPDDRC_V1_NR_EVENTS;
|
||||
+ lpddrc_pmu->pmu_events.attr_groups = hisi_lpddrc_pmu_v1_attr_groups;
|
||||
+ lpddrc_pmu->ops = &hisi_uncore_lpddrc_v1_ops;
|
||||
+
|
||||
+ lpddrc_pmu->num_counters = LPDDRC_NR_COUNTERS;
|
||||
+ lpddrc_pmu->dev = &pdev->dev;
|
||||
+ lpddrc_pmu->on_cpu = -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hisi_lpddrc_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *lpddrc_pmu;
|
||||
+ char *name;
|
||||
+ int ret;
|
||||
+
|
||||
+ lpddrc_pmu = devm_kzalloc(&pdev->dev, sizeof(*lpddrc_pmu), GFP_KERNEL);
|
||||
+ if (!lpddrc_pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, lpddrc_pmu);
|
||||
+
|
||||
+ ret = hisi_lpddrc_pmu_dev_probe(pdev, lpddrc_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
+ "hisi_sccl%u_lpddrc%u", lpddrc_pmu->sccl_id,
|
||||
+ lpddrc_pmu->index_id);
|
||||
+
|
||||
+ lpddrc_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = lpddrc_pmu->pmu_events.attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
+ };
|
||||
+
|
||||
+ /* Pick one core to use for cpumask attributes */
|
||||
+ cpumask_set_cpu(smp_processor_id(), &lpddrc_pmu->associated_cpus);
|
||||
+
|
||||
+ lpddrc_pmu->on_cpu = cpumask_first(&lpddrc_pmu->associated_cpus);
|
||||
+ if (lpddrc_pmu->on_cpu >= nr_cpu_ids)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ret = perf_pmu_register(&lpddrc_pmu->pmu, name, -1);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hisi_lpddrc_pmu_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *lpddrc_pmu = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ perf_pmu_unregister(&lpddrc_pmu->pmu);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver hisi_lpddrc_pmu_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "hisi_lpddrc_pmu",
|
||||
+ .acpi_match_table = ACPI_PTR(hisi_lpddrc_pmu_acpi_match),
|
||||
+ .of_match_table = lpddrc_of_match,
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+ .probe = hisi_lpddrc_pmu_probe,
|
||||
+ .remove = hisi_lpddrc_pmu_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init hisi_lpddrc_pmu_module_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = platform_driver_register(&hisi_lpddrc_pmu_driver);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+module_init(hisi_lpddrc_pmu_module_init);
|
||||
+
|
||||
+static void __exit hisi_lpddrc_pmu_module_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&hisi_lpddrc_pmu_driver);
|
||||
+}
|
||||
+module_exit(hisi_lpddrc_pmu_module_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("HiSilicon SoC LPDDRC uncore PMU driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
||||
+MODULE_AUTHOR("Anurup M <anurup.m@huawei.com>");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From 91e203d62a15728846824029f1eb18fa8eb03aeb Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Mon, 23 May 2022 21:18:33 +0800
|
||||
Subject: [PATCH 27/55] perf: hisi: Fix unexpected modifications in
|
||||
hisi_uncore_l3c_pmu.c
|
||||
|
||||
hulk inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I584X2
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
the name passed to cpuhp_setup_state_multi in hisi_uncore_l3c_pmu.c was
|
||||
modification unexpected.
|
||||
|
||||
Fixes: 744d0990ad13 ("perf: hisi: Add support for HiSilicon SoC L3TPMU")
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Reviewed-by: Weilong Chen <chenweilong@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index bb39b44761a5..d70a01587d72 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -611,7 +611,7 @@ static int __init hisi_l3c_pmu_module_init(void)
|
||||
int ret;
|
||||
|
||||
ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_L3T_ONLINE",
|
||||
+ "AP_PERF_ARM_HISI_L3_ONLINE",
|
||||
hisi_uncore_pmu_online_cpu,
|
||||
hisi_uncore_pmu_offline_cpu);
|
||||
if (ret) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
114
patches/0069-PCI-Add-pci_dev_id-helper.patch
Normal file
114
patches/0069-PCI-Add-pci_dev_id-helper.patch
Normal file
@ -0,0 +1,114 @@
|
||||
From 5fe54aa034e28dc979d147c3cf4a2ae25c529ff7 Mon Sep 17 00:00:00 2001
|
||||
From: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Date: Wed, 24 Apr 2019 21:11:58 +0200
|
||||
Subject: [PATCH 28/55] PCI: Add pci_dev_id() helper
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit 4e544bac8267f65a0bf06aed1bde9964da4812ed
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e544bac8267f65a0bf06aed1bde9964da4812ed
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
In several places in the kernel we find PCI_DEVID used like this:
|
||||
|
||||
PCI_DEVID(dev->bus->number, dev->devfn)
|
||||
|
||||
Add a "pci_dev_id(struct pci_dev *dev)" helper to simplify callers.
|
||||
|
||||
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/pci/msi.c | 6 +++---
|
||||
drivers/pci/search.c | 10 +++-------
|
||||
include/linux/pci.h | 5 +++++
|
||||
3 files changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
|
||||
index bf560dcf8dd4..8138f67123a1 100644
|
||||
--- a/drivers/pci/msi.c
|
||||
+++ b/drivers/pci/msi.c
|
||||
@@ -1385,7 +1385,7 @@ irq_hw_number_t pci_msi_domain_calc_hwirq(struct pci_dev *dev,
|
||||
struct msi_desc *desc)
|
||||
{
|
||||
return (irq_hw_number_t)desc->msi_attrib.entry_nr |
|
||||
- PCI_DEVID(dev->bus->number, dev->devfn) << 11 |
|
||||
+ pci_dev_id(dev) << 11 |
|
||||
(pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27;
|
||||
}
|
||||
|
||||
@@ -1555,7 +1555,7 @@ static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data)
|
||||
u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
|
||||
{
|
||||
struct device_node *of_node;
|
||||
- u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
||||
+ u32 rid = pci_dev_id(pdev);
|
||||
|
||||
pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
|
||||
|
||||
@@ -1578,7 +1578,7 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev)
|
||||
struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev)
|
||||
{
|
||||
struct irq_domain *dom;
|
||||
- u32 rid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
||||
+ u32 rid = pci_dev_id(pdev);
|
||||
|
||||
pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid);
|
||||
dom = of_msi_map_get_device_domain(&pdev->dev, rid);
|
||||
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
|
||||
index 2b5f720862d3..5c7922612733 100644
|
||||
--- a/drivers/pci/search.c
|
||||
+++ b/drivers/pci/search.c
|
||||
@@ -33,7 +33,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
|
||||
struct pci_bus *bus;
|
||||
int ret;
|
||||
|
||||
- ret = fn(pdev, PCI_DEVID(pdev->bus->number, pdev->devfn), data);
|
||||
+ ret = fn(pdev, pci_dev_id(pdev), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -88,9 +88,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
|
||||
return ret;
|
||||
continue;
|
||||
case PCI_EXP_TYPE_PCIE_BRIDGE:
|
||||
- ret = fn(tmp,
|
||||
- PCI_DEVID(tmp->bus->number,
|
||||
- tmp->devfn), data);
|
||||
+ ret = fn(tmp, pci_dev_id(tmp), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
continue;
|
||||
@@ -101,9 +99,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
|
||||
PCI_DEVID(tmp->subordinate->number,
|
||||
PCI_DEVFN(0, 0)), data);
|
||||
else
|
||||
- ret = fn(tmp,
|
||||
- PCI_DEVID(tmp->bus->number,
|
||||
- tmp->devfn), data);
|
||||
+ ret = fn(tmp, pci_dev_id(tmp), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
diff --git a/include/linux/pci.h b/include/linux/pci.h
|
||||
index bc49349fcc53..bfc26f8d5552 100644
|
||||
--- a/include/linux/pci.h
|
||||
+++ b/include/linux/pci.h
|
||||
@@ -633,6 +633,11 @@ struct pci_bus {
|
||||
|
||||
#define to_pci_bus(n) container_of(n, struct pci_bus, dev)
|
||||
|
||||
+static inline u16 pci_dev_id(struct pci_dev *dev)
|
||||
+{
|
||||
+ return PCI_DEVID(dev->bus->number, dev->devfn);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Returns true if the PCI bus is root (behind host-PCI bridge),
|
||||
* false otherwise
|
||||
--
|
||||
2.27.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,116 @@
|
||||
From 0b7b0513121aea4c200c8cd639edf3d1eda1c248 Mon Sep 17 00:00:00 2001
|
||||
From: Qi Liu <liuqi115@huawei.com>
|
||||
Date: Tue, 9 Aug 2022 23:06:42 +0800
|
||||
Subject: [PATCH 30/55] drivers/perf: hisi: Associate PMUs in SICL with CPUs
|
||||
online
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.19-rc1
|
||||
commit 807907dae9701c4b0593d5195d4839f17d103314
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5AZ87
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=807907dae970
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
If a PMU is in a SICL (Super IO cluster), it is not appropriate to
|
||||
associate this PMU with a CPU die. So we associate it with all CPUs
|
||||
online, rather than CPUs in the nearest SCCL.
|
||||
|
||||
As the firmware of Hip09 platform hasn't been published yet, change
|
||||
of PMU driver will not influence backwards compatibility between
|
||||
driver and firmware.
|
||||
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20220415102352.6665-2-liuqi115@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
||||
Reviewed-by: Junhao He <hejunhao3@huawei.com>
|
||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 18 +++++++-----------
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 4 ++++
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 1 +
|
||||
3 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index 390e59f4ef60..f1e6b5cee075 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -258,13 +258,12 @@ static int hisi_pa_pmu_init_data(struct platform_device *pdev,
|
||||
struct hisi_pmu *pa_pmu)
|
||||
{
|
||||
/*
|
||||
- * Use the SCCL_ID and the index ID to identify the PA PMU,
|
||||
- * while SCCL_ID is the nearst SCCL_ID from this SICL and
|
||||
- * CPU core is chosen from this SCCL to manage this PMU.
|
||||
+ * As PA PMU is in a SICL, use the SICL_ID and the index ID
|
||||
+ * to identify the PA PMU.
|
||||
*/
|
||||
if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
- &pa_pmu->sccl_id)) {
|
||||
- dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
||||
+ &pa_pmu->sicl_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read sicl-id!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -275,6 +274,7 @@ static int hisi_pa_pmu_init_data(struct platform_device *pdev,
|
||||
}
|
||||
|
||||
pa_pmu->ccl_id = -1;
|
||||
+ pa_pmu->sccl_id = -1;
|
||||
|
||||
pa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pa_pmu->base)) {
|
||||
@@ -399,13 +399,9 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
ret = hisi_pa_pmu_dev_probe(pdev, pa_pmu);
|
||||
if (ret)
|
||||
return ret;
|
||||
- /*
|
||||
- * PA is attached in SICL and the CPU core is chosen to manage this
|
||||
- * PMU which is the nearest SCCL, while its SCCL_ID is greater than
|
||||
- * one with the SICL_ID.
|
||||
- */
|
||||
+
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%u_pa%u",
|
||||
- pa_pmu->sccl_id - 1, pa_pmu->index_id);
|
||||
+ pa_pmu->sicl_id, pa_pmu->index_id);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 4a781c2e1992..9aaaf9cf2b2a 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -468,6 +468,10 @@ static bool hisi_pmu_cpu_is_associated_pmu(struct hisi_pmu *hisi_pmu)
|
||||
{
|
||||
int sccl_id, ccl_id;
|
||||
|
||||
+ /* If SCCL_ID is -1, the PMU is in a SICL and has no CPU affinity */
|
||||
+ if (hisi_pmu->sccl_id == -1)
|
||||
+ return true;
|
||||
+
|
||||
if (hisi_pmu->ccl_id == -1) {
|
||||
/* If CCL_ID is -1, the PMU only shares the same SCCL */
|
||||
hisi_read_sccl_and_ccl_id(&sccl_id, NULL);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index de6aa17a1355..75dfc12e6497 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -84,6 +84,7 @@ struct hisi_pmu {
|
||||
struct device *dev;
|
||||
struct hlist_node node;
|
||||
int sccl_id;
|
||||
+ int sicl_id;
|
||||
int ccl_id;
|
||||
void __iomem *base;
|
||||
/* the ID of the PMU modules */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,75 @@
|
||||
From 55424d384fb9dab1f8ac81c7fdfce3260ec255e7 Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Thu, 19 Oct 2023 15:08:35 +0800
|
||||
Subject: [PATCH 31/55] driver/perf: hisi: fix kabi broken for struct hisi_pmu
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
fix kabi broken in struct hisi_uncore_ops, hisi_pmu_hwevents,
|
||||
and hisi_pmu, then keep function "hisi_uncore_pmu_counter_valid" interface
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 75dfc12e6497..6a78c13176c2 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -59,16 +59,20 @@ struct hisi_uncore_ops {
|
||||
void (*disable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
|
||||
void (*start_counters)(struct hisi_pmu *);
|
||||
void (*stop_counters)(struct hisi_pmu *);
|
||||
+#ifndef __GENKSYMS__
|
||||
u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
|
||||
void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
|
||||
void (*enable_filter)(struct perf_event *event);
|
||||
void (*disable_filter)(struct perf_event *event);
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct hisi_pmu_hwevents {
|
||||
struct perf_event *hw_events[HISI_MAX_COUNTERS];
|
||||
DECLARE_BITMAP(used_mask, HISI_MAX_COUNTERS);
|
||||
+#ifndef __GENKSYMS__
|
||||
const struct attribute_group **attr_groups;
|
||||
+#endif
|
||||
};
|
||||
|
||||
/* Generic pmu struct for different pmu types */
|
||||
@@ -84,20 +88,27 @@ struct hisi_pmu {
|
||||
struct device *dev;
|
||||
struct hlist_node node;
|
||||
int sccl_id;
|
||||
+#ifndef __GENKSYMS__
|
||||
int sicl_id;
|
||||
+#endif
|
||||
int ccl_id;
|
||||
void __iomem *base;
|
||||
/* the ID of the PMU modules */
|
||||
u32 index_id;
|
||||
+#ifndef __GENKSYMS__
|
||||
/* For DDRC PMU v2: each DDRC has more than one DMC */
|
||||
u32 sub_id;
|
||||
+#endif
|
||||
int num_counters;
|
||||
int counter_bits;
|
||||
/* check event code range */
|
||||
int check_event;
|
||||
+#ifndef __GENKSYMS__
|
||||
u32 identifier;
|
||||
+#endif
|
||||
};
|
||||
|
||||
+int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx);
|
||||
int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
|
||||
void hisi_uncore_pmu_read(struct perf_event *event);
|
||||
int hisi_uncore_pmu_add(struct perf_event *event, int flags);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
486
patches/0073-drivers-perf-hisi-Add-Support-for-CPA-PMU.patch
Normal file
486
patches/0073-drivers-perf-hisi-Add-Support-for-CPA-PMU.patch
Normal file
@ -0,0 +1,486 @@
|
||||
From a75b20496157f6605843bf6399c7d082ec2a37b2 Mon Sep 17 00:00:00 2001
|
||||
From: Qi Liu <liuqi115@huawei.com>
|
||||
Date: Tue, 9 Aug 2022 23:06:43 +0800
|
||||
Subject: [PATCH 32/55] drivers/perf: hisi: Add Support for CPA PMU
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.19-rc1
|
||||
commit 6b79738b6ed91a2d0fe958819469eeedac3bca81
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5AZ87
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6b79738b6ed9
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
On HiSilicon Hip09 platform, there is a CPA (Coherency Protocol Agent) on
|
||||
each SICL (Super IO Cluster) which implements packet format translation,
|
||||
route parsing and traffic statistics.
|
||||
|
||||
CPA PMU has 8 PMU counters and interrupt is supported to handle counter
|
||||
overflow. Let's support its driver under the framework of HiSilicon PMU
|
||||
driver.
|
||||
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20220415102352.6665-3-liuqi115@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
||||
Reviewed-by: Junhao He <hejunhao3@huawei.com>
|
||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/Makefile | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c | 409 +++++++++++++++++++
|
||||
include/linux/cpuhotplug.h | 3 +
|
||||
3 files changed, 413 insertions(+), 1 deletion(-)
|
||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index ad0e8110f373..a3522abb3975 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
||||
- hisi_uncore_pa_pmu.o \
|
||||
+ hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o \
|
||||
hisi_uncore_l3t_pmu.o \
|
||||
hisi_uncore_lpddrc_pmu.o
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
new file mode 100644
|
||||
index 000000000000..a9bb73f76be4
|
||||
--- /dev/null
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
@@ -0,0 +1,409 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * HiSilicon SoC CPA(Coherency Protocol Agent) hardware event counters support
|
||||
+ *
|
||||
+ * Copyright (C) 2022 HiSilicon Limited
|
||||
+ * Author: Qi Liu <liuqi115@huawei.com>
|
||||
+ *
|
||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
||||
+ */
|
||||
+
|
||||
+#define pr_fmt(fmt) "cpa pmu: " fmt
|
||||
+#include <linux/acpi.h>
|
||||
+#include <linux/bug.h>
|
||||
+#include <linux/cpuhotplug.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/smp.h>
|
||||
+
|
||||
+#include "hisi_uncore_pmu.h"
|
||||
+
|
||||
+/* CPA register definition */
|
||||
+#define CPA_PERF_CTRL 0x1c00
|
||||
+#define CPA_EVENT_CTRL 0x1c04
|
||||
+#define CPA_INT_MASK 0x1c70
|
||||
+#define CPA_INT_STATUS 0x1c78
|
||||
+#define CPA_INT_CLEAR 0x1c7c
|
||||
+#define CPA_EVENT_TYPE0 0x1c80
|
||||
+#define CPA_VERSION 0x1cf0
|
||||
+#define CPA_CNT0_LOWER 0x1d00
|
||||
+#define CPA_CFG_REG 0x0534
|
||||
+
|
||||
+/* CPA operation command */
|
||||
+#define CPA_PERF_CTRL_EN BIT_ULL(0)
|
||||
+#define CPA_EVTYPE_MASK 0xffUL
|
||||
+#define CPA_PM_CTRL BIT_ULL(9)
|
||||
+
|
||||
+/* CPA has 8-counters */
|
||||
+#define CPA_NR_COUNTERS 0x8
|
||||
+#define CPA_COUNTER_BITS 64
|
||||
+#define CPA_NR_EVENTS 0xff
|
||||
+#define CPA_REG_OFFSET 0x8
|
||||
+
|
||||
+static u32 hisi_cpa_pmu_get_counter_offset(int idx)
|
||||
+{
|
||||
+ return (CPA_CNT0_LOWER + idx * CPA_REG_OFFSET);
|
||||
+}
|
||||
+
|
||||
+static u64 hisi_cpa_pmu_read_counter(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ return readq(cpa_pmu->base + hisi_cpa_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_write_counter(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc, u64 val)
|
||||
+{
|
||||
+ writeq(val, cpa_pmu->base + hisi_cpa_pmu_get_counter_offset(hwc->idx));
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_write_evtype(struct hisi_pmu *cpa_pmu, int idx,
|
||||
+ u32 type)
|
||||
+{
|
||||
+ u32 reg, reg_idx, shift, val;
|
||||
+
|
||||
+ /*
|
||||
+ * Select the appropriate event select register(CPA_EVENT_TYPE0/1).
|
||||
+ * There are 2 event select registers for the 8 hardware counters.
|
||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
||||
+ * CPA_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
||||
+ * CPA_EVENT_TYPE1 is chosen.
|
||||
+ */
|
||||
+ reg = CPA_EVENT_TYPE0 + (idx / 4) * 4;
|
||||
+ reg_idx = idx % 4;
|
||||
+ shift = CPA_REG_OFFSET * reg_idx;
|
||||
+
|
||||
+ /* Write event code to CPA_EVENT_TYPEx Register */
|
||||
+ val = readl(cpa_pmu->base + reg);
|
||||
+ val &= ~(CPA_EVTYPE_MASK << shift);
|
||||
+ val |= type << shift;
|
||||
+ writel(val, cpa_pmu->base + reg);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_start_counters(struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(cpa_pmu->base + CPA_PERF_CTRL);
|
||||
+ val |= CPA_PERF_CTRL_EN;
|
||||
+ writel(val, cpa_pmu->base + CPA_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_stop_counters(struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(cpa_pmu->base + CPA_PERF_CTRL);
|
||||
+ val &= ~(CPA_PERF_CTRL_EN);
|
||||
+ writel(val, cpa_pmu->base + CPA_PERF_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_disable_pm(struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(cpa_pmu->base + CPA_CFG_REG);
|
||||
+ val |= CPA_PM_CTRL;
|
||||
+ writel(val, cpa_pmu->base + CPA_CFG_REG);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_enable_pm(struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ val = readl(cpa_pmu->base + CPA_CFG_REG);
|
||||
+ val &= ~(CPA_PM_CTRL);
|
||||
+ writel(val, cpa_pmu->base + CPA_CFG_REG);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_enable_counter(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Enable counter index in CPA_EVENT_CTRL register */
|
||||
+ val = readl(cpa_pmu->base + CPA_EVENT_CTRL);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, cpa_pmu->base + CPA_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_disable_counter(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Clear counter index in CPA_EVENT_CTRL register */
|
||||
+ val = readl(cpa_pmu->base + CPA_EVENT_CTRL);
|
||||
+ val &= ~(1UL << hwc->idx);
|
||||
+ writel(val, cpa_pmu->base + CPA_EVENT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_enable_counter_int(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 0 to enable interrupt */
|
||||
+ val = readl(cpa_pmu->base + CPA_INT_MASK);
|
||||
+ val &= ~(1UL << hwc->idx);
|
||||
+ writel(val, cpa_pmu->base + CPA_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_disable_counter_int(struct hisi_pmu *cpa_pmu,
|
||||
+ struct hw_perf_event *hwc)
|
||||
+{
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* Write 1 to mask interrupt */
|
||||
+ val = readl(cpa_pmu->base + CPA_INT_MASK);
|
||||
+ val |= 1 << hwc->idx;
|
||||
+ writel(val, cpa_pmu->base + CPA_INT_MASK);
|
||||
+}
|
||||
+
|
||||
+static u32 hisi_cpa_pmu_get_int_status(struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ return readl(cpa_pmu->base + CPA_INT_STATUS);
|
||||
+}
|
||||
+
|
||||
+static void hisi_cpa_pmu_clear_int_status(struct hisi_pmu *cpa_pmu, int idx)
|
||||
+{
|
||||
+ writel(1 << idx, cpa_pmu->base + CPA_INT_CLEAR);
|
||||
+}
|
||||
+
|
||||
+static const struct acpi_device_id hisi_cpa_pmu_acpi_match[] = {
|
||||
+ { "HISI0281", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(acpi, hisi_cpa_pmu_acpi_match);
|
||||
+
|
||||
+static int hisi_cpa_pmu_init_data(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
||||
+ &cpa_pmu->sicl_id)) {
|
||||
+ dev_err(&pdev->dev, "Can not read sicl-id\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
||||
+ &cpa_pmu->index_id)) {
|
||||
+ dev_err(&pdev->dev, "Cannot read idx-id\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ cpa_pmu->ccl_id = -1;
|
||||
+ cpa_pmu->sccl_id = -1;
|
||||
+ cpa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(cpa_pmu->base))
|
||||
+ return PTR_ERR(cpa_pmu->base);
|
||||
+
|
||||
+ cpa_pmu->identifier = readl(cpa_pmu->base + CPA_VERSION);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct attribute *hisi_cpa_pmu_format_attr[] = {
|
||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-15"),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_cpa_pmu_format_group = {
|
||||
+ .name = "format",
|
||||
+ .attrs = hisi_cpa_pmu_format_attr,
|
||||
+};
|
||||
+
|
||||
+static struct attribute *hisi_cpa_pmu_events_attr[] = {
|
||||
+ HISI_PMU_EVENT_ATTR(cpa_cycles, 0x00),
|
||||
+ HISI_PMU_EVENT_ATTR(cpa_p1_wr_dat, 0x61),
|
||||
+ HISI_PMU_EVENT_ATTR(cpa_p1_rd_dat, 0x62),
|
||||
+ HISI_PMU_EVENT_ATTR(cpa_p0_wr_dat, 0xE1),
|
||||
+ HISI_PMU_EVENT_ATTR(cpa_p0_rd_dat, 0xE2),
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_cpa_pmu_events_group = {
|
||||
+ .name = "events",
|
||||
+ .attrs = hisi_cpa_pmu_events_attr,
|
||||
+};
|
||||
+
|
||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_cpa_pmu_cpumask_attrs[] = {
|
||||
+ &dev_attr_cpumask.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_cpa_pmu_cpumask_attr_group = {
|
||||
+ .attrs = hisi_cpa_pmu_cpumask_attrs,
|
||||
+};
|
||||
+
|
||||
+static struct device_attribute hisi_cpa_pmu_identifier_attr =
|
||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
||||
+
|
||||
+static struct attribute *hisi_cpa_pmu_identifier_attrs[] = {
|
||||
+ &hisi_cpa_pmu_identifier_attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group hisi_cpa_pmu_identifier_group = {
|
||||
+ .attrs = hisi_cpa_pmu_identifier_attrs,
|
||||
+};
|
||||
+
|
||||
+static const struct attribute_group *hisi_cpa_pmu_attr_groups[] = {
|
||||
+ &hisi_cpa_pmu_format_group,
|
||||
+ &hisi_cpa_pmu_events_group,
|
||||
+ &hisi_cpa_pmu_cpumask_attr_group,
|
||||
+ &hisi_cpa_pmu_identifier_group,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static const struct hisi_uncore_ops hisi_uncore_cpa_pmu_ops = {
|
||||
+ .write_evtype = hisi_cpa_pmu_write_evtype,
|
||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
||||
+ .start_counters = hisi_cpa_pmu_start_counters,
|
||||
+ .stop_counters = hisi_cpa_pmu_stop_counters,
|
||||
+ .enable_counter = hisi_cpa_pmu_enable_counter,
|
||||
+ .disable_counter = hisi_cpa_pmu_disable_counter,
|
||||
+ .enable_counter_int = hisi_cpa_pmu_enable_counter_int,
|
||||
+ .disable_counter_int = hisi_cpa_pmu_disable_counter_int,
|
||||
+ .write_counter = hisi_cpa_pmu_write_counter,
|
||||
+ .read_counter = hisi_cpa_pmu_read_counter,
|
||||
+ .get_int_status = hisi_cpa_pmu_get_int_status,
|
||||
+ .clear_int_status = hisi_cpa_pmu_clear_int_status,
|
||||
+};
|
||||
+
|
||||
+static int hisi_cpa_pmu_dev_probe(struct platform_device *pdev,
|
||||
+ struct hisi_pmu *cpa_pmu)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = hisi_cpa_pmu_init_data(pdev, cpa_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = hisi_uncore_pmu_init_irq(cpa_pmu, pdev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ cpa_pmu->counter_bits = CPA_COUNTER_BITS;
|
||||
+ cpa_pmu->check_event = CPA_NR_EVENTS;
|
||||
+ cpa_pmu->pmu_events.attr_groups = hisi_cpa_pmu_attr_groups;
|
||||
+ cpa_pmu->ops = &hisi_uncore_cpa_pmu_ops;
|
||||
+ cpa_pmu->num_counters = CPA_NR_COUNTERS;
|
||||
+ cpa_pmu->dev = &pdev->dev;
|
||||
+ cpa_pmu->on_cpu = -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int hisi_cpa_pmu_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *cpa_pmu;
|
||||
+ char *name;
|
||||
+ int ret;
|
||||
+
|
||||
+ cpa_pmu = devm_kzalloc(&pdev->dev, sizeof(*cpa_pmu), GFP_KERNEL);
|
||||
+ if (!cpa_pmu)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = hisi_cpa_pmu_dev_probe(pdev, cpa_pmu);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%d_cpa%u",
|
||||
+ cpa_pmu->sicl_id, cpa_pmu->index_id);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ cpa_pmu->pmu = (struct pmu) {
|
||||
+ .name = name,
|
||||
+ .module = THIS_MODULE,
|
||||
+ .task_ctx_nr = perf_invalid_context,
|
||||
+ .event_init = hisi_uncore_pmu_event_init,
|
||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
||||
+ .add = hisi_uncore_pmu_add,
|
||||
+ .del = hisi_uncore_pmu_del,
|
||||
+ .start = hisi_uncore_pmu_start,
|
||||
+ .stop = hisi_uncore_pmu_stop,
|
||||
+ .read = hisi_uncore_pmu_read,
|
||||
+ .attr_groups = cpa_pmu->pmu_events.attr_groups,
|
||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
+ };
|
||||
+
|
||||
+ /* Power Management should be disabled before using CPA PMU. */
|
||||
+ hisi_cpa_pmu_disable_pm(cpa_pmu);
|
||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
+ &cpa_pmu->node);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
+ hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = perf_pmu_register(&cpa_pmu->pmu, name, -1);
|
||||
+ if (ret) {
|
||||
+ dev_err(cpa_pmu->dev, "PMU register failed\n");
|
||||
+ cpuhp_state_remove_instance_nocalls(
|
||||
+ CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, &cpa_pmu->node);
|
||||
+ hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ platform_set_drvdata(pdev, cpa_pmu);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int hisi_cpa_pmu_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct hisi_pmu *cpa_pmu = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ perf_pmu_unregister(&cpa_pmu->pmu);
|
||||
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
+ &cpa_pmu->node);
|
||||
+ hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver hisi_cpa_pmu_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "hisi_cpa_pmu",
|
||||
+ .acpi_match_table = ACPI_PTR(hisi_cpa_pmu_acpi_match),
|
||||
+ .suppress_bind_attrs = true,
|
||||
+ },
|
||||
+ .probe = hisi_cpa_pmu_probe,
|
||||
+ .remove = hisi_cpa_pmu_remove,
|
||||
+};
|
||||
+
|
||||
+static int __init hisi_cpa_pmu_module_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
+ "AP_PERF_ARM_HISI_CPA_ONLINE",
|
||||
+ hisi_uncore_pmu_online_cpu,
|
||||
+ hisi_uncore_pmu_offline_cpu);
|
||||
+ if (ret) {
|
||||
+ pr_err("setup hotplug failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = platform_driver_register(&hisi_cpa_pmu_driver);
|
||||
+ if (ret)
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+module_init(hisi_cpa_pmu_module_init);
|
||||
+
|
||||
+static void __exit hisi_cpa_pmu_module_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&hisi_cpa_pmu_driver);
|
||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE);
|
||||
+}
|
||||
+module_exit(hisi_cpa_pmu_module_exit);
|
||||
+
|
||||
+MODULE_DESCRIPTION("HiSilicon SoC CPA PMU driver");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");
|
||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
||||
index f4078abc061f..ee782c3cb7f3 100644
|
||||
--- a/include/linux/cpuhotplug.h
|
||||
+++ b/include/linux/cpuhotplug.h
|
||||
@@ -158,6 +158,9 @@ enum cpuhp_state {
|
||||
CPUHP_AP_PERF_S390_SF_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_CCI_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_CCN_ONLINE,
|
||||
+ #ifndef __GENKSYMS__
|
||||
+ CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
+ #endif
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From b860fa9563bef6669732959cf9fc9733b40a9721 Mon Sep 17 00:00:00 2001
|
||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Date: Thu, 17 Nov 2022 16:41:33 +0800
|
||||
Subject: [PATCH 33/55] drivers/perf: hisi: Fix some event id for hisi-pcie-pmu
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.2-rc1
|
||||
commit 6b4bb4f38dbfe85247f006f06135ba46450d5bf0
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6b4bb4f38dbfe85247f006f06135ba46450d5bf0
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Some event id of hisi-pcie-pmu is incorrect, fix them.
|
||||
|
||||
Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20221117084136.53572-2-yangyicong@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_pcie_pmu.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
index 1e9e841cfe95..c115f5c77acb 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
@@ -696,10 +696,10 @@ static struct attribute *hisi_pcie_pmu_events_attr[] = {
|
||||
HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_cnt, 0x10210),
|
||||
HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_latency, 0x0011),
|
||||
HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_cnt, 0x10011),
|
||||
- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x1005),
|
||||
- HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x11005),
|
||||
- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x2004),
|
||||
- HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x12004),
|
||||
+ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_flux, 0x0804),
|
||||
+ HISI_PCIE_PMU_EVENT_ATTR(rx_mrd_time, 0x10804),
|
||||
+ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_flux, 0x0405),
|
||||
+ HISI_PCIE_PMU_EVENT_ATTR(tx_mrd_time, 0x10405),
|
||||
NULL
|
||||
};
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
129
patches/0075-docs-perf-move-to-the-admin-guide.patch
Normal file
129
patches/0075-docs-perf-move-to-the-admin-guide.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From 73bd937d975076c3f7754919d49d2610401dcf1b Mon Sep 17 00:00:00 2001
|
||||
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
Date: Tue, 18 Jun 2019 16:06:08 -0300
|
||||
Subject: [PATCH 34/55] docs: perf: move to the admin-guide
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.3-rc1
|
||||
commit 59809fe88224db24432ad50e62fd8d5f0df738a1
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59809fe88224db24432ad50e62fd8d5f0df738a1
|
||||
|
||||
-------------------------------------------------------------
|
||||
|
||||
The perf infrastructure is used for userspace to track issues.
|
||||
At least a good part of what's described here is related to
|
||||
it.
|
||||
|
||||
So, add it to the admin-guide.
|
||||
|
||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
Documentation/admin-guide/index.rst | 1 +
|
||||
Documentation/{ => admin-guide}/perf/arm-ccn.rst | 0
|
||||
Documentation/{ => admin-guide}/perf/arm_dsu_pmu.rst | 0
|
||||
Documentation/{ => admin-guide}/perf/hisi-pmu.rst | 0
|
||||
Documentation/{ => admin-guide}/perf/index.rst | 2 --
|
||||
Documentation/{ => admin-guide}/perf/qcom_l2_pmu.rst | 0
|
||||
Documentation/{ => admin-guide}/perf/qcom_l3_pmu.rst | 0
|
||||
Documentation/{ => admin-guide}/perf/xgene-pmu.rst | 0
|
||||
MAINTAINERS | 4 ++--
|
||||
drivers/perf/qcom_l3_pmu.c | 2 +-
|
||||
10 files changed, 4 insertions(+), 5 deletions(-)
|
||||
rename Documentation/{ => admin-guide}/perf/arm-ccn.rst (100%)
|
||||
rename Documentation/{ => admin-guide}/perf/arm_dsu_pmu.rst (100%)
|
||||
rename Documentation/{ => admin-guide}/perf/hisi-pmu.rst (100%)
|
||||
rename Documentation/{ => admin-guide}/perf/index.rst (95%)
|
||||
rename Documentation/{ => admin-guide}/perf/qcom_l2_pmu.rst (100%)
|
||||
rename Documentation/{ => admin-guide}/perf/qcom_l3_pmu.rst (100%)
|
||||
rename Documentation/{ => admin-guide}/perf/xgene-pmu.rst (100%)
|
||||
|
||||
diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst
|
||||
index 89abc5057349..b75b6ae6f662 100644
|
||||
--- a/Documentation/admin-guide/index.rst
|
||||
+++ b/Documentation/admin-guide/index.rst
|
||||
@@ -38,6 +38,7 @@ problems and bugs in particular.
|
||||
ramoops
|
||||
dynamic-debug-howto
|
||||
init
|
||||
+ perf/index
|
||||
|
||||
This is the beginning of a section with information of interest to
|
||||
application developers. Documents covering various aspects of the kernel
|
||||
diff --git a/Documentation/perf/arm-ccn.rst b/Documentation/admin-guide/perf/arm-ccn.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/arm-ccn.rst
|
||||
rename to Documentation/admin-guide/perf/arm-ccn.rst
|
||||
diff --git a/Documentation/perf/arm_dsu_pmu.rst b/Documentation/admin-guide/perf/arm_dsu_pmu.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/arm_dsu_pmu.rst
|
||||
rename to Documentation/admin-guide/perf/arm_dsu_pmu.rst
|
||||
diff --git a/Documentation/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/hisi-pmu.rst
|
||||
rename to Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
diff --git a/Documentation/perf/index.rst b/Documentation/admin-guide/perf/index.rst
|
||||
similarity index 95%
|
||||
rename from Documentation/perf/index.rst
|
||||
rename to Documentation/admin-guide/perf/index.rst
|
||||
index 4bf848e27f26..9d445451ea18 100644
|
||||
--- a/Documentation/perf/index.rst
|
||||
+++ b/Documentation/admin-guide/perf/index.rst
|
||||
@@ -1,5 +1,3 @@
|
||||
-:orphan:
|
||||
-
|
||||
===========================
|
||||
Performance monitor support
|
||||
===========================
|
||||
diff --git a/Documentation/perf/qcom_l2_pmu.rst b/Documentation/admin-guide/perf/qcom_l2_pmu.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/qcom_l2_pmu.rst
|
||||
rename to Documentation/admin-guide/perf/qcom_l2_pmu.rst
|
||||
diff --git a/Documentation/perf/qcom_l3_pmu.rst b/Documentation/admin-guide/perf/qcom_l3_pmu.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/qcom_l3_pmu.rst
|
||||
rename to Documentation/admin-guide/perf/qcom_l3_pmu.rst
|
||||
diff --git a/Documentation/perf/xgene-pmu.rst b/Documentation/admin-guide/perf/xgene-pmu.rst
|
||||
similarity index 100%
|
||||
rename from Documentation/perf/xgene-pmu.rst
|
||||
rename to Documentation/admin-guide/perf/xgene-pmu.rst
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 600f432e2e16..e9302e09600b 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -1040,7 +1040,7 @@ APPLIED MICRO (APM) X-GENE SOC PMU
|
||||
M: Tai Nguyen <ttnguyen@apm.com>
|
||||
S: Supported
|
||||
F: drivers/perf/xgene_pmu.c
|
||||
-F: Documentation/perf/xgene-pmu.rst
|
||||
+F: Documentation/admin-guide/perf/xgene-pmu.rst
|
||||
F: Documentation/devicetree/bindings/perf/apm-xgene-pmu.txt
|
||||
|
||||
APTINA CAMERA SENSOR PLL
|
||||
@@ -6666,7 +6666,7 @@ W: http://www.hisilicon.com
|
||||
F: Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
F: Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
F: drivers/perf/hisilicon
|
||||
-F: Documentation/perf/hisi-pmu.rst
|
||||
+F: Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
|
||||
HISILICON PTT DRIVER
|
||||
M: Yicong Yang <yangyicong@hisilicon.com>
|
||||
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
|
||||
index cc88dc92577e..6cefee509e57 100644
|
||||
--- a/drivers/perf/qcom_l3_pmu.c
|
||||
+++ b/drivers/perf/qcom_l3_pmu.c
|
||||
@@ -7,7 +7,7 @@
|
||||
* the slices. User space needs to aggregate to individual counts to provide
|
||||
* a global picture.
|
||||
*
|
||||
- * See Documentation/perf/qcom_l3_pmu.rst for more details.
|
||||
+ * See Documentation/admin-guide/perf/qcom_l3_pmu.rst for more details.
|
||||
*
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
From 4f573c490bf3b2880b8c93a20d2a9ef0d0b90c90 Mon Sep 17 00:00:00 2001
|
||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Date: Mon, 8 Mar 2021 14:50:37 +0800
|
||||
Subject: [PATCH 35/55] docs: perf: Add new description on HiSilicon uncore PMU
|
||||
v2
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.13-rc1
|
||||
commit 9b86b1b41e0f48b5b25918e07aeceb00e13d1ce2
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9b86b1b41e0f48b5b25918e07aeceb00e13d1ce2
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
Some news functions are added on HiSilicon uncore PMUs. Document them
|
||||
to provide guidance on how to use them.
|
||||
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: John Garry <john.garry@huawei.com>
|
||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/1615186237-22263-10-git-send-email-zhangshaokun@hisilicon.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst | 49 +++++++++++++++++++++
|
||||
1 file changed, 49 insertions(+)
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
index 404a5c3d9d00..3b3120e2dd9e 100644
|
||||
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
@@ -53,6 +53,55 @@ Example usage of perf::
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02/ sleep 5
|
||||
|
||||
+For HiSilicon uncore PMU v2 whose identifier is 0x30, the topology is the same
|
||||
+as PMU v1, but some new functions are added to the hardware.
|
||||
+
|
||||
+(a) L3C PMU supports filtering by core/thread within the cluster which can be
|
||||
+specified as a bitmap.
|
||||
+ $# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_core=0x3/ sleep 5
|
||||
+This will only count the operations from core/thread 0 and 1 in this cluster.
|
||||
+
|
||||
+(b) Tracetag allow the user to chose to count only read, write or atomic
|
||||
+operations via the tt_req parameeter in perf. The default value counts all
|
||||
+operations. tt_req is 3bits, 3'b100 represents read operations, 3'b101
|
||||
+represents write operations, 3'b110 represents atomic store operations and
|
||||
+3'b111 represents atomic non-store operations, other values are reserved.
|
||||
+ $# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_req=0x4/ sleep 5
|
||||
+This will only count the read operations in this cluster.
|
||||
+
|
||||
+(c) Datasrc allows the user to check where the data comes from. It is 5 bits.
|
||||
+Some important codes are as follows:
|
||||
+5'b00001: comes from L3C in this die;
|
||||
+5'b01000: comes from L3C in the cross-die;
|
||||
+5'b01001: comes from L3C which is in another socket;
|
||||
+5'b01110: comes from the local DDR;
|
||||
+5'b01111: comes from the cross-die DDR;
|
||||
+5'b10000: comes from cross-socket DDR;
|
||||
+etc, it is mainly helpful to find that the data source is nearest from the CPU
|
||||
+cores. If datasrc_cfg is used in the multi-chips, the datasrc_skt shall be
|
||||
+configured in perf command.
|
||||
+ $# perf stat -a -e hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xE/,
|
||||
+ hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xF/ sleep 5
|
||||
+
|
||||
+(d)Some HiSilicon SoCs encapsulate multiple CPU and IO dies. Each CPU die
|
||||
+contains several Compute Clusters (CCLs). The I/O dies are called Super I/O
|
||||
+clusters (SICL) containing multiple I/O clusters (ICLs). Each CCL/ICL in the
|
||||
+SoC has a unique ID. Each ID is 11bits, include a 6-bit SCCL-ID and 5-bit
|
||||
+CCL/ICL-ID. For I/O die, the ICL-ID is followed by:
|
||||
+5'b00000: I/O_MGMT_ICL;
|
||||
+5'b00001: Network_ICL;
|
||||
+5'b00011: HAC_ICL;
|
||||
+5'b10000: PCIe_ICL;
|
||||
+
|
||||
+Users could configure IDs to count data come from specific CCL/ICL, by setting
|
||||
+srcid_cmd & srcid_msk, and data desitined for specific CCL/ICL by setting
|
||||
+tgtid_cmd & tgtid_msk. A set bit in srcid_msk/tgtid_msk means the PMU will not
|
||||
+check the bit when matching against the srcid_cmd/tgtid_cmd.
|
||||
+
|
||||
+If all of these options are disabled, it can works by the default value that
|
||||
+doesn't distinguish the filter condition and ID information and will return
|
||||
+the total counter values in the PMU counters.
|
||||
+
|
||||
The current driver does not support sampling. So "perf record" is unsupported.
|
||||
Also attach to a task is unsupported as the events are all uncore.
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,145 @@
|
||||
From 3f70f78b4853cac77143fe82e99e5375628f8702 Mon Sep 17 00:00:00 2001
|
||||
From: Qi Liu <liuqi115@huawei.com>
|
||||
Date: Thu, 2 Dec 2021 16:06:32 +0800
|
||||
Subject: [PATCH 36/55] docs: perf: Add description for HiSilicon PCIe PMU
|
||||
driver
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.17-rc1
|
||||
commit c8602008e247f5603317c16f076565a96715e1ba
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c8602008e247f5603317c16f076565a96715e1ba
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
PCIe PMU Root Complex Integrated End Point(RCiEP) device is supported on
|
||||
HiSilicon HIP09 platform. Document it to provide guidance on how to
|
||||
use it.
|
||||
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20211202080633.2919-2-liuqi115@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../admin-guide/perf/hisi-pcie-pmu.rst | 106 ++++++++++++++++++
|
||||
1 file changed, 106 insertions(+)
|
||||
create mode 100644 Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
new file mode 100644
|
||||
index 000000000000..294ebbdb22af
|
||||
--- /dev/null
|
||||
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
@@ -0,0 +1,106 @@
|
||||
+================================================
|
||||
+HiSilicon PCIe Performance Monitoring Unit (PMU)
|
||||
+================================================
|
||||
+
|
||||
+On Hip09, HiSilicon PCIe Performance Monitoring Unit (PMU) could monitor
|
||||
+bandwidth, latency, bus utilization and buffer occupancy data of PCIe.
|
||||
+
|
||||
+Each PCIe Core has a PMU to monitor multi Root Ports of this PCIe Core and
|
||||
+all Endpoints downstream these Root Ports.
|
||||
+
|
||||
+
|
||||
+HiSilicon PCIe PMU driver
|
||||
+=========================
|
||||
+
|
||||
+The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
|
||||
+Core id.::
|
||||
+
|
||||
+ /sys/bus/event_source/hisi_pcie<sicl>_<core>
|
||||
+
|
||||
+PMU driver provides description of available events and filter options in sysfs,
|
||||
+see /sys/bus/event_source/devices/hisi_pcie<sicl>_<core>.
|
||||
+
|
||||
+The "format" directory describes all formats of the config (events) and config1
|
||||
+(filter options) fields of the perf_event_attr structure. The "events" directory
|
||||
+describes all documented events shown in perf list.
|
||||
+
|
||||
+The "identifier" sysfs file allows users to identify the version of the
|
||||
+PMU hardware device.
|
||||
+
|
||||
+The "bus" sysfs file allows users to get the bus number of Root Ports
|
||||
+monitored by PMU.
|
||||
+
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf list
|
||||
+ hisi_pcie0_0/rx_mwr_latency/ [kernel PMU event]
|
||||
+ hisi_pcie0_0/rx_mwr_cnt/ [kernel PMU event]
|
||||
+ ------------------------------------------
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mwr_latency/
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mwr_cnt/
|
||||
+ $# perf stat -g -e hisi_pcie0_0/rx_mwr_latency/ -e hisi_pcie0_0/rx_mwr_cnt/
|
||||
+
|
||||
+The current driver does not support sampling. So "perf record" is unsupported.
|
||||
+Also attach to a task is unsupported for PCIe PMU.
|
||||
+
|
||||
+Filter options
|
||||
+--------------
|
||||
+
|
||||
+1. Target filter
|
||||
+PMU could only monitor the performance of traffic downstream target Root Ports
|
||||
+or downstream target Endpoint. PCIe PMU driver support "port" and "bdf"
|
||||
+interfaces for users, and these two interfaces aren't supported at the same
|
||||
+time.
|
||||
+
|
||||
+-port
|
||||
+"port" filter can be used in all PCIe PMU events, target Root Port can be
|
||||
+selected by configuring the 16-bits-bitmap "port". Multi ports can be selected
|
||||
+for AP-layer-events, and only one port can be selected for TL/DL-layer-events.
|
||||
+
|
||||
+For example, if target Root Port is 0000:00:00.0 (x8 lanes), bit0 of bitmap
|
||||
+should be set, port=0x1; if target Root Port is 0000:00:04.0 (x4 lanes),
|
||||
+bit8 is set, port=0x100; if these two Root Ports are both monitored, port=0x101.
|
||||
+
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mwr_latency,port=0x1/ sleep 5
|
||||
+
|
||||
+-bdf
|
||||
+
|
||||
+"bdf" filter can only be used in bandwidth events, target Endpoint is selected
|
||||
+by configuring BDF to "bdf". Counter only counts the bandwidth of message
|
||||
+requested by target Endpoint.
|
||||
+
|
||||
+For example, "bdf=0x3900" means BDF of target Endpoint is 0000:39:00.0.
|
||||
+
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mrd_flux,bdf=0x3900/ sleep 5
|
||||
+
|
||||
+2. Trigger filter
|
||||
+Event statistics start when the first time TLP length is greater/smaller
|
||||
+than trigger condition. You can set the trigger condition by writing "trig_len",
|
||||
+and set the trigger mode by writing "trig_mode". This filter can only be used
|
||||
+in bandwidth events.
|
||||
+
|
||||
+For example, "trig_len=4" means trigger condition is 2^4 DW, "trig_mode=0"
|
||||
+means statistics start when TLP length > trigger condition, "trig_mode=1"
|
||||
+means start when TLP length < condition.
|
||||
+
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
|
||||
+
|
||||
+3. Threshold filter
|
||||
+Counter counts when TLP length within the specified range. You can set the
|
||||
+threshold by writing "thr_len", and set the threshold mode by writing
|
||||
+"thr_mode". This filter can only be used in bandwidth events.
|
||||
+
|
||||
+For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
|
||||
+counter counts when TLP length >= threshold, and "thr_mode=1" means counts
|
||||
+when TLP length < threshold.
|
||||
+
|
||||
+Example usage of perf::
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
From d1ff276b62baa5fd8138f2432bed59773702df7a Mon Sep 17 00:00:00 2001
|
||||
From: Qi Liu <liuqi115@huawei.com>
|
||||
Date: Mon, 29 Mar 2021 20:32:01 +0800
|
||||
Subject: [PATCH 37/55] docs: perf: Address some html build warnings
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.13-rc1
|
||||
commit b88f5e9792cc320a511697dcba8890d032ee3ed3
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b88f5e9792cc320a511697dcba8890d032ee3ed3
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Fix following html build warnings:
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst:61: WARNING: Unexpected indentation.
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst:62: WARNING: Block quote ends without a blank line; unexpected unindent.
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst:69: WARNING: Unexpected indentation.
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst:70: WARNING: Block quote ends without a blank line; unexpected unindent.
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst:83: WARNING: Unexpected indentation.
|
||||
|
||||
Fixes: 9b86b1b41e0f ("docs: perf: Add new description on HiSilicon uncore PMU v2")
|
||||
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
||||
Link: https://lore.kernel.org/r/1617021121-31450-1-git-send-email-liuqi115@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
Documentation/admin-guide/perf/hisi-pmu.rst | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
index 3b3120e2dd9e..546979360513 100644
|
||||
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
|
||||
@@ -57,16 +57,20 @@ For HiSilicon uncore PMU v2 whose identifier is 0x30, the topology is the same
|
||||
as PMU v1, but some new functions are added to the hardware.
|
||||
|
||||
(a) L3C PMU supports filtering by core/thread within the cluster which can be
|
||||
-specified as a bitmap.
|
||||
+specified as a bitmap::
|
||||
+
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_core=0x3/ sleep 5
|
||||
+
|
||||
This will only count the operations from core/thread 0 and 1 in this cluster.
|
||||
|
||||
(b) Tracetag allow the user to chose to count only read, write or atomic
|
||||
operations via the tt_req parameeter in perf. The default value counts all
|
||||
operations. tt_req is 3bits, 3'b100 represents read operations, 3'b101
|
||||
represents write operations, 3'b110 represents atomic store operations and
|
||||
-3'b111 represents atomic non-store operations, other values are reserved.
|
||||
+3'b111 represents atomic non-store operations, other values are reserved::
|
||||
+
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_req=0x4/ sleep 5
|
||||
+
|
||||
This will only count the read operations in this cluster.
|
||||
|
||||
(c) Datasrc allows the user to check where the data comes from. It is 5 bits.
|
||||
@@ -79,7 +83,8 @@ Some important codes are as follows:
|
||||
5'b10000: comes from cross-socket DDR;
|
||||
etc, it is mainly helpful to find that the data source is nearest from the CPU
|
||||
cores. If datasrc_cfg is used in the multi-chips, the datasrc_skt shall be
|
||||
-configured in perf command.
|
||||
+configured in perf command::
|
||||
+
|
||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xE/,
|
||||
hisi_sccl3_l3c0/config=0xb9,datasrc_cfg=0xF/ sleep 5
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
43
patches/0079-docs-fix-make-htmldocs-warning-in-perf.patch
Normal file
43
patches/0079-docs-fix-make-htmldocs-warning-in-perf.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 73918c84177dc0867dafd8bb3826fead1289425f Mon Sep 17 00:00:00 2001
|
||||
From: Wan Jiabing <wanjiabing@vivo.com>
|
||||
Date: Mon, 28 Feb 2022 11:16:56 +0800
|
||||
Subject: [PATCH 38/55] docs: fix 'make htmldocs' warning in perf
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.18-rc1
|
||||
commit 0d6356d6cdd0afeb546f4e8ca653748a8ec3ba26
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0d6356d6cdd0afeb546f4e8ca653748a8ec3ba26
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Fix following 'make htmldocs' warnings:
|
||||
./Documentation/admin-guide/perf/hisi-pcie-pmu.rst: WARNING:
|
||||
document isn't included in any toctree
|
||||
|
||||
Fixes: c8602008e247 ("docs: perf: Add description for HiSilicon PCIe PMU driver")
|
||||
Signed-off-by: Wan Jiabing <wanjiabing@vivo.com>
|
||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20220228031700.1669086-1-wanjiabing@vivo.com
|
||||
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
Documentation/admin-guide/perf/index.rst | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/index.rst b/Documentation/admin-guide/perf/index.rst
|
||||
index 9d445451ea18..5a9afa1263f6 100644
|
||||
--- a/Documentation/admin-guide/perf/index.rst
|
||||
+++ b/Documentation/admin-guide/perf/index.rst
|
||||
@@ -6,6 +6,7 @@ Performance monitor support
|
||||
:maxdepth: 1
|
||||
|
||||
hisi-pmu
|
||||
+ hisi-pcie-pmu
|
||||
qcom_l2_pmu
|
||||
qcom_l3_pmu
|
||||
arm-ccn
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
From f6ad3073186b182d495dc42c48baac26cb1c16f2 Mon Sep 17 00:00:00 2001
|
||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Date: Thu, 17 Nov 2022 16:41:34 +0800
|
||||
Subject: [PATCH 39/55] docs: perf: Fix PMU instance name of hisi-pcie-pmu
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.2-rc1
|
||||
commit eb79f12b4c41dd2403a0d16772ee72fcd6416015
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eb79f12b4c41dd2403a0d16772ee72fcd6416015
|
||||
|
||||
--------------------------------------------------------------------
|
||||
|
||||
The PMU instance will be called hisi_pcie<sicl>_core<core> rather than
|
||||
hisi_pcie<sicl>_<core>. Fix this in the documentation.
|
||||
|
||||
Fixes: c8602008e247 ("docs: perf: Add description for HiSilicon PCIe PMU driver")
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20221117084136.53572-3-yangyicong@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../admin-guide/perf/hisi-pcie-pmu.rst | 22 +++++++++----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
index 294ebbdb22af..bbe66480ff85 100644
|
||||
--- a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
@@ -15,10 +15,10 @@ HiSilicon PCIe PMU driver
|
||||
The PCIe PMU driver registers a perf PMU with the name of its sicl-id and PCIe
|
||||
Core id.::
|
||||
|
||||
- /sys/bus/event_source/hisi_pcie<sicl>_<core>
|
||||
+ /sys/bus/event_source/hisi_pcie<sicl>_core<core>
|
||||
|
||||
PMU driver provides description of available events and filter options in sysfs,
|
||||
-see /sys/bus/event_source/devices/hisi_pcie<sicl>_<core>.
|
||||
+see /sys/bus/event_source/devices/hisi_pcie<sicl>_core<core>.
|
||||
|
||||
The "format" directory describes all formats of the config (events) and config1
|
||||
(filter options) fields of the perf_event_attr structure. The "events" directory
|
||||
@@ -33,13 +33,13 @@ monitored by PMU.
|
||||
Example usage of perf::
|
||||
|
||||
$# perf list
|
||||
- hisi_pcie0_0/rx_mwr_latency/ [kernel PMU event]
|
||||
- hisi_pcie0_0/rx_mwr_cnt/ [kernel PMU event]
|
||||
+ hisi_pcie0_core0/rx_mwr_latency/ [kernel PMU event]
|
||||
+ hisi_pcie0_core0/rx_mwr_cnt/ [kernel PMU event]
|
||||
------------------------------------------
|
||||
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mwr_latency/
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mwr_cnt/
|
||||
- $# perf stat -g -e hisi_pcie0_0/rx_mwr_latency/ -e hisi_pcie0_0/rx_mwr_cnt/
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mwr_latency/
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mwr_cnt/
|
||||
+ $# perf stat -g -e hisi_pcie0_core0/rx_mwr_latency/ -e hisi_pcie0_core0/rx_mwr_cnt/
|
||||
|
||||
The current driver does not support sampling. So "perf record" is unsupported.
|
||||
Also attach to a task is unsupported for PCIe PMU.
|
||||
@@ -64,7 +64,7 @@ bit8 is set, port=0x100; if these two Root Ports are both monitored, port=0x101.
|
||||
|
||||
Example usage of perf::
|
||||
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mwr_latency,port=0x1/ sleep 5
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mwr_latency,port=0x1/ sleep 5
|
||||
|
||||
-bdf
|
||||
|
||||
@@ -76,7 +76,7 @@ For example, "bdf=0x3900" means BDF of target Endpoint is 0000:39:00.0.
|
||||
|
||||
Example usage of perf::
|
||||
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mrd_flux,bdf=0x3900/ sleep 5
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,bdf=0x3900/ sleep 5
|
||||
|
||||
2. Trigger filter
|
||||
Event statistics start when the first time TLP length is greater/smaller
|
||||
@@ -90,7 +90,7 @@ means start when TLP length < condition.
|
||||
|
||||
Example usage of perf::
|
||||
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,trig_len=0x4,trig_mode=1/ sleep 5
|
||||
|
||||
3. Threshold filter
|
||||
Counter counts when TLP length within the specified range. You can set the
|
||||
@@ -103,4 +103,4 @@ when TLP length < threshold.
|
||||
|
||||
Example usage of perf::
|
||||
|
||||
- $# perf stat -e hisi_pcie0_0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
|
||||
--
|
||||
2.27.0
|
||||
|
||||
132
patches/0081-drivers-perf-hisi-Add-TLP-filter-support.patch
Normal file
132
patches/0081-drivers-perf-hisi-Add-TLP-filter-support.patch
Normal file
@ -0,0 +1,132 @@
|
||||
From 57b8735c25b887a4233ddf7930c821acc78ca3f1 Mon Sep 17 00:00:00 2001
|
||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Date: Thu, 17 Nov 2022 16:41:36 +0800
|
||||
Subject: [PATCH 40/55] drivers/perf: hisi: Add TLP filter support
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.2-rc1
|
||||
commit 17d573984d4d5ad73c7cb5edcf2024c585475b0c
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=17d573984d4d5ad73c7cb5edcf2024c585475b0c
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
The PMU support to filter the TLP when counting the bandwidth with below
|
||||
options:
|
||||
|
||||
- only count the TLP headers
|
||||
- only count the TLP payloads
|
||||
- count both TLP headers and payloads
|
||||
|
||||
In the current driver it's default to count the TLP payloads only, which
|
||||
will have an implicity side effects that on the traffic only have header
|
||||
only TLPs, we'll get no data.
|
||||
|
||||
Make this user configuration through "len_mode" parameter and make it
|
||||
default to count both TLP headers and payloads when user not specified.
|
||||
Also update the documentation for it.
|
||||
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20221117084136.53572-5-yangyicong@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
.../admin-guide/perf/hisi-pcie-pmu.rst | 22 +++++++++++++++++--
|
||||
drivers/perf/hisilicon/hisi_pcie_pmu.c | 14 +++++++++++-
|
||||
2 files changed, 33 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
index bbe66480ff85..6bace0e24c3f 100644
|
||||
--- a/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
+++ b/Documentation/admin-guide/perf/hisi-pcie-pmu.rst
|
||||
@@ -101,6 +101,24 @@ For example, "thr_len=4" means threshold is 2^4 DW, "thr_mode=0" means
|
||||
counter counts when TLP length >= threshold, and "thr_mode=1" means counts
|
||||
when TLP length < threshold.
|
||||
|
||||
-Example usage of perf::
|
||||
+ Example usage of perf::
|
||||
+
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
|
||||
+
|
||||
+4. TLP Length filter
|
||||
+
|
||||
+ When counting bandwidth, the data can be composed of certain parts of TLP
|
||||
+ packets. You can specify it through "len_mode":
|
||||
+
|
||||
+ - 2'b00: Reserved (Do not use this since the behaviour is undefined)
|
||||
+ - 2'b01: Bandwidth of TLP payloads
|
||||
+ - 2'b10: Bandwidth of TLP headers
|
||||
+ - 2'b11: Bandwidth of both TLP payloads and headers
|
||||
+
|
||||
+ For example, "len_mode=2" means only counting the bandwidth of TLP headers
|
||||
+ and "len_mode=3" means the final bandwidth data is composed of both TLP
|
||||
+ headers and payloads. Default value if not specified is 2'b11.
|
||||
+
|
||||
+ Example usage of perf::
|
||||
|
||||
- $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,thr_len=0x4,thr_mode=1/ sleep 5
|
||||
+ $# perf stat -e hisi_pcie0_core0/rx_mrd_flux,len_mode=0x1/ sleep 5
|
||||
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
index c115f5c77acb..6ded72383bb6 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
@@ -47,10 +47,14 @@
|
||||
#define HISI_PCIE_EVENT_M GENMASK_ULL(15, 0)
|
||||
#define HISI_PCIE_THR_MODE_M GENMASK_ULL(27, 27)
|
||||
#define HISI_PCIE_THR_M GENMASK_ULL(31, 28)
|
||||
+#define HISI_PCIE_LEN_M GENMASK_ULL(35, 34)
|
||||
#define HISI_PCIE_TARGET_M GENMASK_ULL(52, 36)
|
||||
#define HISI_PCIE_TRIG_MODE_M GENMASK_ULL(53, 53)
|
||||
#define HISI_PCIE_TRIG_M GENMASK_ULL(59, 56)
|
||||
|
||||
+/* Default config of TLP length mode, will count both TLP headers and payloads */
|
||||
+#define HISI_PCIE_LEN_M_DEFAULT 3ULL
|
||||
+
|
||||
#define HISI_PCIE_MAX_COUNTERS 8
|
||||
#define HISI_PCIE_REG_STEP 8
|
||||
#define HISI_PCIE_THR_MAX_VAL 10
|
||||
@@ -91,6 +95,7 @@ HISI_PCIE_PMU_FILTER_ATTR(thr_len, config1, 3, 0);
|
||||
HISI_PCIE_PMU_FILTER_ATTR(thr_mode, config1, 4, 4);
|
||||
HISI_PCIE_PMU_FILTER_ATTR(trig_len, config1, 8, 5);
|
||||
HISI_PCIE_PMU_FILTER_ATTR(trig_mode, config1, 9, 9);
|
||||
+HISI_PCIE_PMU_FILTER_ATTR(len_mode, config1, 11, 10);
|
||||
HISI_PCIE_PMU_FILTER_ATTR(port, config2, 15, 0);
|
||||
HISI_PCIE_PMU_FILTER_ATTR(bdf, config2, 31, 16);
|
||||
|
||||
@@ -218,8 +223,8 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
|
||||
{
|
||||
struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu);
|
||||
struct hw_perf_event *hwc = &event->hw;
|
||||
+ u64 port, trig_len, thr_len, len_mode;
|
||||
u64 reg = HISI_PCIE_INIT_SET;
|
||||
- u64 port, trig_len, thr_len;
|
||||
|
||||
/* Config HISI_PCIE_EVENT_CTRL according to event. */
|
||||
reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event));
|
||||
@@ -248,6 +253,12 @@ static void hisi_pcie_pmu_config_filter(struct perf_event *event)
|
||||
reg |= HISI_PCIE_THR_EN;
|
||||
}
|
||||
|
||||
+ len_mode = hisi_pcie_get_len_mode(event);
|
||||
+ if (len_mode)
|
||||
+ reg |= FIELD_PREP(HISI_PCIE_LEN_M, len_mode);
|
||||
+ else
|
||||
+ reg |= FIELD_PREP(HISI_PCIE_LEN_M, HISI_PCIE_LEN_M_DEFAULT);
|
||||
+
|
||||
hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EVENT_CTRL, hwc->idx, reg);
|
||||
}
|
||||
|
||||
@@ -714,6 +725,7 @@ static struct attribute *hisi_pcie_pmu_format_attr[] = {
|
||||
HISI_PCIE_PMU_FORMAT_ATTR(thr_mode, "config1:4"),
|
||||
HISI_PCIE_PMU_FORMAT_ATTR(trig_len, "config1:5-8"),
|
||||
HISI_PCIE_PMU_FORMAT_ATTR(trig_mode, "config1:9"),
|
||||
+ HISI_PCIE_PMU_FORMAT_ATTR(len_mode, "config1:10-11"),
|
||||
HISI_PCIE_PMU_FORMAT_ATTR(port, "config2:0-15"),
|
||||
HISI_PCIE_PMU_FORMAT_ATTR(bdf, "config2:16-31"),
|
||||
NULL
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
From b6b92242583b60e26a251765356143092000674a Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Thu, 8 Jun 2023 14:07:55 +0800
|
||||
Subject: [PATCH 41/55] drivers/perf: hisi: Don't migrate perf to the CPU going
|
||||
to teardown
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.5-rc1
|
||||
commit 7a6a9f1c5a0a875a421db798d4b2ee022dc1ee1a
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7a6a9f1c5a0a875a421db798d4b2ee022dc1ee1a
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
The driver needs to migrate the perf context if the current using CPU going
|
||||
to teardown. By the time calling the cpuhp::teardown() callback the
|
||||
cpu_online_mask() hasn't updated yet and still includes the CPU going to
|
||||
teardown. In current driver's implementation we may migrate the context
|
||||
to the teardown CPU and leads to the below calltrace:
|
||||
|
||||
...
|
||||
[ 368.104662][ T932] task:cpuhp/0 state:D stack: 0 pid: 15 ppid: 2 flags:0x00000008
|
||||
[ 368.113699][ T932] Call trace:
|
||||
[ 368.116834][ T932] __switch_to+0x7c/0xbc
|
||||
[ 368.120924][ T932] __schedule+0x338/0x6f0
|
||||
[ 368.125098][ T932] schedule+0x50/0xe0
|
||||
[ 368.128926][ T932] schedule_preempt_disabled+0x18/0x24
|
||||
[ 368.134229][ T932] __mutex_lock.constprop.0+0x1d4/0x5dc
|
||||
[ 368.139617][ T932] __mutex_lock_slowpath+0x1c/0x30
|
||||
[ 368.144573][ T932] mutex_lock+0x50/0x60
|
||||
[ 368.148579][ T932] perf_pmu_migrate_context+0x84/0x2b0
|
||||
[ 368.153884][ T932] hisi_pcie_pmu_offline_cpu+0x90/0xe0 [hisi_pcie_pmu]
|
||||
[ 368.160579][ T932] cpuhp_invoke_callback+0x2a0/0x650
|
||||
[ 368.165707][ T932] cpuhp_thread_fun+0xe4/0x190
|
||||
[ 368.170316][ T932] smpboot_thread_fn+0x15c/0x1a0
|
||||
[ 368.175099][ T932] kthread+0x108/0x13c
|
||||
[ 368.179012][ T932] ret_from_fork+0x10/0x18
|
||||
...
|
||||
|
||||
Use function cpumask_any_but() to find one correct active cpu to fixes
|
||||
this issue.
|
||||
|
||||
Fixes: 8404b0fbc7fb ("drivers/perf: hisi: Add driver for HiSilicon PCIe PMU")
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
||||
Link: https://lore.kernel.org/r/20230608114326.27649-1-hejunhao3@huawei.com
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_pcie_pmu.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
index 6ded72383bb6..b4335bdb3c3e 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
@@ -686,7 +686,7 @@ static int hisi_pcie_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
|
||||
pcie_pmu->on_cpu = -1;
|
||||
/* Choose a new CPU from all online cpus. */
|
||||
- target = cpumask_first(cpu_online_mask);
|
||||
+ target = cpumask_any_but(cpu_online_mask, cpu);
|
||||
if (target >= nr_cpu_ids) {
|
||||
pci_err(pcie_pmu->pdev, "There is no CPU to set\n");
|
||||
return 0;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,210 @@
|
||||
From fa73221de60d9d632d6a233f0a1a99b4350e0190 Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Mon, 21 Nov 2022 22:03:05 +0800
|
||||
Subject: [PATCH 42/55] drivers/perf: fixed the issue that the kabi value
|
||||
changed
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5KAX7
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Fixed the issue that the kabi value changed when the HiSilicon PMU driver
|
||||
added the enum variable in "enum cpuhp_state{}".
|
||||
|
||||
The hisi_pcie_pmu and hisi_cpa_pmu drivers to replace the explicit specify
|
||||
hotplug events with dynamic allocation hotplug events(CPUHP_AP_ONLINE_DYN).
|
||||
The states between *CPUHP_AP_ONLINE_DYN* and *CPUHP_AP_ONLINE_DYN_END* are
|
||||
reserved for the dynamic allocation.
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
|
||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
||||
Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_pcie_pmu.c | 22 ++++++++++---------
|
||||
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c | 23 ++++++++++----------
|
||||
include/linux/cpuhotplug.h | 6 -----
|
||||
3 files changed, 24 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_pcie_pmu.c b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
index b4335bdb3c3e..ccbe995db1e4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_pcie_pmu.c
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
||||
+/* Dynamic CPU hotplug state used by PCIe PMU */
|
||||
+static enum cpuhp_state hisi_pcie_pmu_online;
|
||||
+
|
||||
#define DRV_NAME "hisi_pcie_pmu"
|
||||
/* Define registers */
|
||||
#define HISI_PCIE_GLOBAL_CTRL 0x00
|
||||
@@ -830,7 +833,7 @@ static int hisi_pcie_init_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_p
|
||||
if (ret)
|
||||
goto err_iounmap;
|
||||
|
||||
- ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
|
||||
+ ret = cpuhp_state_add_instance(hisi_pcie_pmu_online, &pcie_pmu->node);
|
||||
if (ret) {
|
||||
pci_err(pdev, "Failed to register hotplug: %d\n", ret);
|
||||
goto err_irq_unregister;
|
||||
@@ -845,8 +848,7 @@ static int hisi_pcie_init_pmu(struct pci_dev *pdev, struct hisi_pcie_pmu *pcie_p
|
||||
return ret;
|
||||
|
||||
err_hotplug_unregister:
|
||||
- cpuhp_state_remove_instance_nocalls(
|
||||
- CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_pcie_pmu_online, &pcie_pmu->node);
|
||||
|
||||
err_irq_unregister:
|
||||
hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
|
||||
@@ -862,8 +864,7 @@ static void hisi_pcie_uninit_pmu(struct pci_dev *pdev)
|
||||
struct hisi_pcie_pmu *pcie_pmu = pci_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&pcie_pmu->pmu);
|
||||
- cpuhp_state_remove_instance_nocalls(
|
||||
- CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE, &pcie_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_pcie_pmu_online, &pcie_pmu->node);
|
||||
hisi_pcie_pmu_irq_unregister(pdev, pcie_pmu);
|
||||
iounmap(pcie_pmu->base);
|
||||
}
|
||||
@@ -934,18 +935,19 @@ static int __init hisi_pcie_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_PCIE_PMU_ONLINE",
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
|
||||
+ "perf/hisi/pcie:online",
|
||||
hisi_pcie_pmu_online_cpu,
|
||||
hisi_pcie_pmu_offline_cpu);
|
||||
- if (ret) {
|
||||
+ if (ret < 0) {
|
||||
pr_err("Failed to setup PCIe PMU hotplug: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
+ hisi_pcie_pmu_online = ret;
|
||||
|
||||
ret = pci_register_driver(&hisi_pcie_pmu_driver);
|
||||
if (ret)
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_pcie_pmu_online);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -954,7 +956,7 @@ module_init(hisi_pcie_module_init);
|
||||
static void __exit hisi_pcie_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&hisi_pcie_pmu_driver);
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_pcie_pmu_online);
|
||||
}
|
||||
module_exit(hisi_pcie_module_exit);
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
index a9bb73f76be4..09839dae9b7c 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
#include "hisi_uncore_pmu.h"
|
||||
|
||||
+/* Dynamic CPU hotplug state used by CPA PMU */
|
||||
+static enum cpuhp_state hisi_cpa_pmu_online;
|
||||
+
|
||||
/* CPA register definition */
|
||||
#define CPA_PERF_CTRL 0x1c00
|
||||
#define CPA_EVENT_CTRL 0x1c04
|
||||
@@ -334,8 +337,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
/* Power Management should be disabled before using CPA PMU. */
|
||||
hisi_cpa_pmu_disable_pm(cpa_pmu);
|
||||
- ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
- &cpa_pmu->node);
|
||||
+ ret = cpuhp_state_add_instance(hisi_cpa_pmu_online, &cpa_pmu->node);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
@@ -345,8 +347,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
|
||||
ret = perf_pmu_register(&cpa_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(cpa_pmu->dev, "PMU register failed\n");
|
||||
- cpuhp_state_remove_instance_nocalls(
|
||||
- CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE, &cpa_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_cpa_pmu_online, &cpa_pmu->node);
|
||||
hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
return ret;
|
||||
}
|
||||
@@ -360,8 +361,7 @@ static int hisi_cpa_pmu_remove(struct platform_device *pdev)
|
||||
struct hisi_pmu *cpa_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&cpa_pmu->pmu);
|
||||
- cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
- &cpa_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_cpa_pmu_online, &cpa_pmu->node);
|
||||
hisi_cpa_pmu_enable_pm(cpa_pmu);
|
||||
return 0;
|
||||
}
|
||||
@@ -380,18 +380,19 @@ static int __init hisi_cpa_pmu_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_CPA_ONLINE",
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
|
||||
+ "pmu/hisi/cpa:online",
|
||||
hisi_uncore_pmu_online_cpu,
|
||||
hisi_uncore_pmu_offline_cpu);
|
||||
- if (ret) {
|
||||
+ if (ret < 0) {
|
||||
pr_err("setup hotplug failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
+ hisi_cpa_pmu_online = ret;
|
||||
|
||||
ret = platform_driver_register(&hisi_cpa_pmu_driver);
|
||||
if (ret)
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_cpa_pmu_online);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -400,7 +401,7 @@ module_init(hisi_cpa_pmu_module_init);
|
||||
static void __exit hisi_cpa_pmu_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hisi_cpa_pmu_driver);
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_cpa_pmu_online);
|
||||
}
|
||||
module_exit(hisi_cpa_pmu_module_exit);
|
||||
|
||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
||||
index ee782c3cb7f3..225b095a96db 100644
|
||||
--- a/include/linux/cpuhotplug.h
|
||||
+++ b/include/linux/cpuhotplug.h
|
||||
@@ -158,17 +158,11 @@ enum cpuhp_state {
|
||||
CPUHP_AP_PERF_S390_SF_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_CCI_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_CCN_ONLINE,
|
||||
- #ifndef __GENKSYMS__
|
||||
- CPUHP_AP_PERF_ARM_HISI_CPA_ONLINE,
|
||||
- #endif
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
- #ifndef __GENKSYMS__
|
||||
- CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
|
||||
- #endif
|
||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,200 @@
|
||||
From ed7d3223d519f6749ef72cb295e9ce61d55d722b Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Wed, 25 Oct 2023 17:49:20 +0800
|
||||
Subject: [PATCH 43/55] drivers/perf: fixed kabi broken for SLLC and PA PMU
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Fixed the issue that the kabi value changed when the HiSilicon PMU driver
|
||||
added the enum variable in "enum cpuhp_state{}".
|
||||
|
||||
The hisi_sllc_pmu and hisi_pa_pmu drivers to replace the explicit specify
|
||||
hotplug events with dynamic allocation hotplug events(CPUHP_AP_ONLINE_DYN).
|
||||
The states between *CPUHP_AP_ONLINE_DYN* and *CPUHP_AP_ONLINE_DYN_END* are
|
||||
reserved for the dynamic allocation.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 25 +++++++++++--------
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 25 +++++++++++--------
|
||||
include/linux/cpuhotplug.h | 2 --
|
||||
3 files changed, 28 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index f1e6b5cee075..8bab65d50316 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -46,6 +46,9 @@ HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
||||
HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
||||
HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
||||
|
||||
+/* Dynamic CPU hotplug state used by PA PMU */
|
||||
+static enum cpuhp_state hisi_pa_pmu_online;
|
||||
+
|
||||
static void hisi_pa_pmu_enable_tracetag(struct perf_event *event)
|
||||
{
|
||||
struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
||||
@@ -405,8 +408,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
- ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
- &pa_pmu->node);
|
||||
+ ret = cpuhp_state_add_instance(hisi_pa_pmu_online, &pa_pmu->node);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
return ret;
|
||||
@@ -430,8 +432,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
- &pa_pmu->node);
|
||||
+ cpuhp_state_remove_instance(hisi_pa_pmu_online, &pa_pmu->node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -444,8 +445,8 @@ static int hisi_pa_pmu_remove(struct platform_device *pdev)
|
||||
struct hisi_pmu *pa_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&pa_pmu->pmu);
|
||||
- cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
- &pa_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_pa_pmu_online, &pa_pmu->node);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -463,18 +464,20 @@ static int __init hisi_pa_pmu_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_PA_ONLINE",
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
|
||||
+ "perf/hisi/pa:online",
|
||||
hisi_uncore_pmu_online_cpu,
|
||||
hisi_uncore_pmu_offline_cpu);
|
||||
- if (ret) {
|
||||
+ if (ret < 0) {
|
||||
pr_err("PA PMU: cpuhp state setup failed, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ hisi_pa_pmu_online = ret;
|
||||
+
|
||||
ret = platform_driver_register(&hisi_pa_pmu_driver);
|
||||
if (ret)
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_pa_pmu_online);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -483,7 +486,7 @@ module_init(hisi_pa_pmu_module_init);
|
||||
static void __exit hisi_pa_pmu_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hisi_pa_pmu_driver);
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_pa_pmu_online);
|
||||
}
|
||||
module_exit(hisi_pa_pmu_module_exit);
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
index 835ec3e2178f..71b199ec447a 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -48,6 +48,9 @@ HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
||||
HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
||||
HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
||||
|
||||
+/* Dynamic CPU hotplug state used by SLLC PMU */
|
||||
+static enum cpuhp_state hisi_sllc_pmu_online;
|
||||
+
|
||||
static bool tgtid_is_valid(u32 max, u32 min)
|
||||
{
|
||||
return max > 0 && max >= min;
|
||||
@@ -438,8 +441,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
- ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
- &sllc_pmu->node);
|
||||
+ ret = cpuhp_state_add_instance(hisi_sllc_pmu_online, &sllc_pmu->node);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
||||
return ret;
|
||||
@@ -463,8 +465,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
- cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
- &sllc_pmu->node);
|
||||
+ cpuhp_state_remove_instance(hisi_sllc_pmu_online, &sllc_pmu->node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -478,8 +479,8 @@ static int hisi_sllc_pmu_remove(struct platform_device *pdev)
|
||||
struct hisi_pmu *sllc_pmu = platform_get_drvdata(pdev);
|
||||
|
||||
perf_pmu_unregister(&sllc_pmu->pmu);
|
||||
- cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
- &sllc_pmu->node);
|
||||
+ cpuhp_state_remove_instance_nocalls(hisi_sllc_pmu_online, &sllc_pmu->node);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -497,18 +498,20 @@ static int __init hisi_sllc_pmu_module_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
- "AP_PERF_ARM_HISI_SLLC_ONLINE",
|
||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
|
||||
+ "perf/hisi/sllc:online",
|
||||
hisi_uncore_pmu_online_cpu,
|
||||
hisi_uncore_pmu_offline_cpu);
|
||||
- if (ret) {
|
||||
+ if (ret < 0) {
|
||||
pr_err("SLLC PMU: cpuhp state setup failed, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ hisi_sllc_pmu_online = ret;
|
||||
+
|
||||
ret = platform_driver_register(&hisi_sllc_pmu_driver);
|
||||
if (ret)
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_sllc_pmu_online);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -517,7 +520,7 @@ module_init(hisi_sllc_pmu_module_init);
|
||||
static void __exit hisi_sllc_pmu_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&hisi_sllc_pmu_driver);
|
||||
- cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
||||
+ cpuhp_remove_multi_state(hisi_sllc_pmu_online);
|
||||
}
|
||||
module_exit(hisi_sllc_pmu_module_exit);
|
||||
|
||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
||||
index 225b095a96db..d67c0035165c 100644
|
||||
--- a/include/linux/cpuhotplug.h
|
||||
+++ b/include/linux/cpuhotplug.h
|
||||
@@ -161,8 +161,6 @@ enum cpuhp_state {
|
||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
- CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
||||
- CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
||||
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 2ee9d506673f6abaee074312d2ae189fd941e58c Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Wed, 4 Jan 2023 19:55:09 +0800
|
||||
Subject: [PATCH 44/55] perf: hisi: Fix read sccl_id and ccl_id error in TSV200
|
||||
|
||||
driver inclusion
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I68F5A
|
||||
CVE: NA
|
||||
|
||||
--------------------------------
|
||||
|
||||
In TSV200 platform, SCCL is Aff3[7:0], CCL is Aff2[7:0] if mt.
|
||||
Fixes: 1af26389a3 ("perf: hisi: Fix read sccl_id and ccl_id error in some platform")
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Reviewed-by: Yang Shen <shenyang39@huawei.com>
|
||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 9aaaf9cf2b2a..91d2da895924 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -440,7 +440,6 @@ static void hisi_read_sccl_and_ccl_id(int *scclp, int *cclp)
|
||||
if (mt) {
|
||||
switch (read_cpuid_part_number()) {
|
||||
case HISI_CPU_PART_TSV110:
|
||||
- case HISI_CPU_PART_TSV200:
|
||||
case ARM_CPU_PART_CORTEX_A55:
|
||||
sccl = aff2 >> 3;
|
||||
ccl = aff2 & 0x7;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
86
patches/0086-perf-hisi-Add-configs-for-PMU-isolation.patch
Normal file
86
patches/0086-perf-hisi-Add-configs-for-PMU-isolation.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 2bbf35baac46c41879f770e2273134192a565f86 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Date: Sat, 4 Mar 2023 07:24:36 +0000
|
||||
Subject: [PATCH 45/55] perf: hisi: Add configs for PMU isolation
|
||||
|
||||
hulk inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I6HRGK
|
||||
|
||||
------------------------------------------
|
||||
|
||||
Add CONFIG_HISI_L3T_PMU and CONFIG_HISI_LPDDRC_PMU to isolate features
|
||||
of hisi pmu driver.
|
||||
|
||||
This patch isolates commit 0edc58409e30 and 6bf896bea639.
|
||||
|
||||
Signed-off-by: Zhang Zekun <zhangzekun11@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
drivers/perf/hisilicon/Kconfig
|
||||
drivers/perf/hisilicon/Makefile
|
||||
---
|
||||
arch/arm64/configs/openeuler_defconfig | 2 ++
|
||||
drivers/perf/hisilicon/Kconfig | 18 ++++++++++++++++++
|
||||
drivers/perf/hisilicon/Makefile | 6 +++---
|
||||
3 files changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
|
||||
index 6a7497f2df95..db461e4c2dae 100644
|
||||
--- a/arch/arm64/configs/openeuler_defconfig
|
||||
+++ b/arch/arm64/configs/openeuler_defconfig
|
||||
@@ -5108,6 +5108,8 @@ CONFIG_QCOM_L3_PMU=y
|
||||
CONFIG_XGENE_PMU=y
|
||||
CONFIG_ARM_SPE_PMU=y
|
||||
CONFIG_HISI_PMU=m
|
||||
+CONFIG_HISI_L3T_PMU=m
|
||||
+CONFIG_HISI_LPDDRC_PMU=m
|
||||
CONFIG_HISI_PCIE_PMU=m
|
||||
CONFIG_RAS=y
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/Kconfig b/drivers/perf/hisilicon/Kconfig
|
||||
index 5546218b5598..91a6e2463180 100644
|
||||
--- a/drivers/perf/hisilicon/Kconfig
|
||||
+++ b/drivers/perf/hisilicon/Kconfig
|
||||
@@ -14,3 +14,21 @@ config HISI_PCIE_PMU
|
||||
RCiEP devices.
|
||||
Adds the PCIe PMU into perf events system for monitoring latency,
|
||||
bandwidth etc.
|
||||
+
|
||||
+config HISI_L3T_PMU
|
||||
+ tristate "HiSilicon SoC L3T PMU drivers"
|
||||
+ depends on HISI_PMU
|
||||
+ default n
|
||||
+ help
|
||||
+ Support for HiSilicon SoC L3 Cache performance monitor, Hydra Home
|
||||
+ Agent performance monitor and DDR Controller performance monitor.
|
||||
+ L3T is a specialized PMU driver.
|
||||
+
|
||||
+config HISI_LPDDRC_PMU
|
||||
+ tristate "HiSilicon SoC LDPPRC PMU drivers"
|
||||
+ depends on HISI_PMU
|
||||
+ default n
|
||||
+ help
|
||||
+ Support for HiSilicon SoC L3 Cache performance monitor, Hydra Home
|
||||
+ Agent performance monitor and DDR Controller performance monitor.
|
||||
+ LPDDRC is a specialize PMU driver.
|
||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
||||
index a3522abb3975..26d678eb3250 100644
|
||||
--- a/drivers/perf/hisilicon/Makefile
|
||||
+++ b/drivers/perf/hisilicon/Makefile
|
||||
@@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
||||
hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
||||
- hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o \
|
||||
- hisi_uncore_l3t_pmu.o \
|
||||
- hisi_uncore_lpddrc_pmu.o
|
||||
+ hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o
|
||||
|
||||
obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
|
||||
+obj-$(CONFIG_HISI_L3T_PMU) += hisi_uncore_l3t_pmu.o
|
||||
+obj-$(CONFIG_HISI_LPDDRC_PMU) += hisi_uncore_lpddrc_pmu.o
|
||||
--
|
||||
2.27.0
|
||||
|
||||
208
patches/0087-perf-hisi-Extract-hisi_pmu_init.patch
Normal file
208
patches/0087-perf-hisi-Extract-hisi_pmu_init.patch
Normal file
@ -0,0 +1,208 @@
|
||||
From 021c239865727a9e633d04f3fc490426b51012ad Mon Sep 17 00:00:00 2001
|
||||
From: Chen Jun <chenjun102@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:24 +0800
|
||||
Subject: [PATCH 46/55] perf: hisi: Extract hisi_pmu_init
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.0-rc1
|
||||
commit e500405dd15d956790859fa532c64d8186445372
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e500405dd15d956790859fa532c64d8186445372
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Extract the initialization code of hisi_pmu->pmu into a function
|
||||
|
||||
Signed-off-by: Chen Jun <chenjun102@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20220516131601.48383-1-chenjun102@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 16 +---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 16 +---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 16 +---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 16 +---------------
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 18 ++++++++++++++++++
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 2 ++
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 15 +--------------
|
||||
7 files changed, 25 insertions(+), 74 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 457ac6a1ad64..69d2b08847e2 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -519,21 +519,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
"hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
||||
ddrc_pmu->index_id);
|
||||
|
||||
- ddrc_pmu->pmu = (struct pmu) {
|
||||
- .name = name,
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = ddrc_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
+ hisi_pmu_init(&ddrc_pmu->pmu, name, ddrc_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 3b120fc55e01..c5f752f4ff22 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -522,21 +522,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
- hha_pmu->pmu = (struct pmu) {
|
||||
- .name = name,
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = hha_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
+ hisi_pmu_init(&hha_pmu->pmu, name, hha_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index d70a01587d72..d723e008a0f9 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -560,21 +560,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
*/
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
- l3c_pmu->pmu = (struct pmu) {
|
||||
- .name = name,
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = l3c_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
+ hisi_pmu_init(&l3c_pmu->pmu, name, l3c_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index 8bab65d50316..99786ef708a6 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -414,21 +414,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- pa_pmu->pmu = (struct pmu) {
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = pa_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
-
|
||||
+ hisi_pmu_init(&pa_pmu->pmu, name, pa_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 91d2da895924..41640de74072 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -540,4 +540,22 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
|
||||
|
||||
+void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
+ const struct attribute_group **attr_groups, struct module *module)
|
||||
+{
|
||||
+ pmu->name = name;
|
||||
+ pmu->module = module;
|
||||
+ pmu->task_ctx_nr = perf_invalid_context;
|
||||
+ pmu->event_init = hisi_uncore_pmu_event_init;
|
||||
+ pmu->pmu_enable = hisi_uncore_pmu_enable;
|
||||
+ pmu->pmu_disable = hisi_uncore_pmu_disable;
|
||||
+ pmu->add = hisi_uncore_pmu_add;
|
||||
+ pmu->del = hisi_uncore_pmu_del;
|
||||
+ pmu->start = hisi_uncore_pmu_start;
|
||||
+ pmu->stop = hisi_uncore_pmu_stop;
|
||||
+ pmu->read = hisi_uncore_pmu_read;
|
||||
+ pmu->attr_groups = attr_groups;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(hisi_pmu_init);
|
||||
+
|
||||
MODULE_LICENSE("GPL v2");
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 6a78c13176c2..9818e20d36f8 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -135,4 +135,6 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
struct platform_device *pdev);
|
||||
|
||||
+void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
+ const struct attribute_group **attr_groups, struct module *module);
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
index 71b199ec447a..b71de6597016 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -447,20 +447,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- sllc_pmu->pmu = (struct pmu) {
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = sllc_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
+ hisi_pmu_init(&sllc_pmu->pmu, name, sllc_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 31854a763b417d8f751691e9e4fc81b3523c569d Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:25 +0800
|
||||
Subject: [PATCH 47/55] drivers/perf: hisi: Advertise the
|
||||
PERF_PMU_CAP_NO_EXCLUDE capability
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.3-rc1
|
||||
commit 7f95da9d2dc4c20bb374c281ceb8fa40b6208f4b
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7f95da9d2dc4c20bb374c281ceb8fa40b6208f4b
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Missed initialization the variable of pmu::capabilities when extract
|
||||
the initialization code of hisi_pmu->pmu into a function.
|
||||
|
||||
HISI UNCORE PMU drivers counters that not support context exclusion.
|
||||
So we have to advertise the PERF_PMU_CAP_NO_EXCLUDE capability.
|
||||
This ensures that perf will prevent us from handling events where
|
||||
any exclusion flags are set.
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20230119100307.3660-2-hejunhao3@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 41640de74072..c5860912d765 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -555,6 +555,7 @@ void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
pmu->stop = hisi_uncore_pmu_stop;
|
||||
pmu->read = hisi_uncore_pmu_read;
|
||||
pmu->attr_groups = attr_groups;
|
||||
+ pmu->capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_pmu_init);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,142 @@
|
||||
From 8c346b56153744591b51dadcde8b603b8b872e2d Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:26 +0800
|
||||
Subject: [PATCH 48/55] drivers/perf: hisi: Simplify the parameters of
|
||||
hisi_pmu_init()
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.3-rc1
|
||||
commit 053b5579dacfc5763dda0c073ee14147421d32d7
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=053b5579dacfc5763dda0c073ee14147421d32d7
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Use "hisi_pmu" to simplify the parameter list for the hisi_pmu_init()
|
||||
function.
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20230119100307.3660-3-hejunhao3@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 8 +++++---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 4 ++--
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 2 +-
|
||||
7 files changed, 12 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 69d2b08847e2..3a1b3919c736 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -519,7 +519,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
"hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
||||
ddrc_pmu->index_id);
|
||||
|
||||
- hisi_pmu_init(&ddrc_pmu->pmu, name, ddrc_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
+ hisi_pmu_init(ddrc_pmu, name, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index c5f752f4ff22..9aa951bdf417 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -522,7 +522,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
- hisi_pmu_init(&hha_pmu->pmu, name, hha_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
+ hisi_pmu_init(hha_pmu, name, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index d723e008a0f9..0406c034e7c4 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -560,7 +560,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
*/
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
- hisi_pmu_init(&l3c_pmu->pmu, name, l3c_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
+ hisi_pmu_init(l3c_pmu, name, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index 99786ef708a6..df8605a0b24d 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -414,7 +414,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- hisi_pmu_init(&pa_pmu->pmu, name, pa_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
+ hisi_pmu_init(pa_pmu, name, THIS_MODULE);
|
||||
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index c5860912d765..13e54e458f9a 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -540,9 +540,11 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
|
||||
|
||||
-void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
- const struct attribute_group **attr_groups, struct module *module)
|
||||
+void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name,
|
||||
+ struct module *module)
|
||||
{
|
||||
+ struct pmu *pmu = &hisi_pmu->pmu;
|
||||
+
|
||||
pmu->name = name;
|
||||
pmu->module = module;
|
||||
pmu->task_ctx_nr = perf_invalid_context;
|
||||
@@ -554,7 +556,7 @@ void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
pmu->start = hisi_uncore_pmu_start;
|
||||
pmu->stop = hisi_uncore_pmu_stop;
|
||||
pmu->read = hisi_uncore_pmu_read;
|
||||
- pmu->attr_groups = attr_groups;
|
||||
+ pmu->attr_groups = hisi_pmu->pmu_events.attr_groups;
|
||||
pmu->capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_pmu_init);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 9818e20d36f8..27951213c9e8 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -135,6 +135,6 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
struct platform_device *pdev);
|
||||
|
||||
-void hisi_pmu_init(struct pmu *pmu, const char *name,
|
||||
- const struct attribute_group **attr_groups, struct module *module);
|
||||
+void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name,
|
||||
+ struct module *module);
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
index b71de6597016..c1b038fc534e 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -447,7 +447,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- hisi_pmu_init(&sllc_pmu->pmu, name, sllc_pmu->pmu_events.attr_groups, THIS_MODULE);
|
||||
+ hisi_pmu_init(sllc_pmu, name, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 6a6aa532c3e4951259c5c024aa560afe4798e22a Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:27 +0800
|
||||
Subject: [PATCH 49/55] drivers/perf: hisi: Extract initialization of
|
||||
"cpa_pmu->pmu"
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.3-rc1
|
||||
commit e126f6f42f89baee09e088ab6bc48f83ac3a0eae
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e126f6f42f89baee09e088ab6bc48f83ac3a0eae
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Use hisi_pmu_init() function to simplify initialization of "cpa_pmu->pmu".
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Link: https://lore.kernel.org/r/20230119100307.3660-4-hejunhao3@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c | 16 +---------------
|
||||
1 file changed, 1 insertion(+), 15 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
index 09839dae9b7c..1a75351013f1 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
@@ -319,21 +319,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
- cpa_pmu->pmu = (struct pmu) {
|
||||
- .name = name,
|
||||
- .module = THIS_MODULE,
|
||||
- .task_ctx_nr = perf_invalid_context,
|
||||
- .event_init = hisi_uncore_pmu_event_init,
|
||||
- .pmu_enable = hisi_uncore_pmu_enable,
|
||||
- .pmu_disable = hisi_uncore_pmu_disable,
|
||||
- .add = hisi_uncore_pmu_add,
|
||||
- .del = hisi_uncore_pmu_del,
|
||||
- .start = hisi_uncore_pmu_start,
|
||||
- .stop = hisi_uncore_pmu_stop,
|
||||
- .read = hisi_uncore_pmu_read,
|
||||
- .attr_groups = cpa_pmu->pmu_events.attr_groups,
|
||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
||||
- };
|
||||
+ hisi_pmu_init(cpa_pmu, name, THIS_MODULE);
|
||||
|
||||
/* Power Management should be disabled before using CPA PMU. */
|
||||
hisi_cpa_pmu_disable_pm(cpa_pmu);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,144 @@
|
||||
From 2ccc10a1b9770a9205a8ababd910a08dd8512b96 Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:28 +0800
|
||||
Subject: [PATCH 50/55] drivers/perf: hisi: Remove redundant initialized of
|
||||
pmu->name
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.4-rc1
|
||||
commit 25d8c25025a46e7621edde2eb6d5f55c6d29ee86
|
||||
category: cleanup
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=25d8c25025a46e7621edde2eb6d5f55c6d29ee86
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
"pmu->name" is initialized by perf_pmu_register() function, so remove
|
||||
the redundant initialized in hisi_pmu_init().
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 2 +-
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 4 +---
|
||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 3 +--
|
||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 2 +-
|
||||
8 files changed, 8 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
index 1a75351013f1..9322fc3dac07 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_cpa_pmu.c
|
||||
@@ -319,7 +319,7 @@ static int hisi_cpa_pmu_probe(struct platform_device *pdev)
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
- hisi_pmu_init(cpa_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(cpa_pmu, THIS_MODULE);
|
||||
|
||||
/* Power Management should be disabled before using CPA PMU. */
|
||||
hisi_cpa_pmu_disable_pm(cpa_pmu);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index 3a1b3919c736..eddeb76ce4c5 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -519,7 +519,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
"hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
||||
ddrc_pmu->index_id);
|
||||
|
||||
- hisi_pmu_init(ddrc_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(ddrc_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 9aa951bdf417..1b8f44dada6d 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -522,7 +522,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
- hisi_pmu_init(hha_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(hha_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index 0406c034e7c4..b2ac90e9f2cd 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -560,7 +560,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
*/
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
- hisi_pmu_init(l3c_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(l3c_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
index df8605a0b24d..cf10c84ada41 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
||||
@@ -414,7 +414,7 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- hisi_pmu_init(pa_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(pa_pmu, THIS_MODULE);
|
||||
ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
index 13e54e458f9a..aed38a8c582c 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
||||
@@ -540,12 +540,10 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu);
|
||||
|
||||
-void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name,
|
||||
- struct module *module)
|
||||
+void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module)
|
||||
{
|
||||
struct pmu *pmu = &hisi_pmu->pmu;
|
||||
|
||||
- pmu->name = name;
|
||||
pmu->module = module;
|
||||
pmu->task_ctx_nr = perf_invalid_context;
|
||||
pmu->event_init = hisi_uncore_pmu_event_init;
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
index 27951213c9e8..93b672d9731e 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
||||
@@ -135,6 +135,5 @@ ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
||||
int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
||||
struct platform_device *pdev);
|
||||
|
||||
-void hisi_pmu_init(struct hisi_pmu *hisi_pmu, const char *name,
|
||||
- struct module *module);
|
||||
+void hisi_pmu_init(struct hisi_pmu *hisi_pmu, struct module *module);
|
||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
index c1b038fc534e..149a0d8f403f 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
||||
@@ -447,7 +447,7 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- hisi_pmu_init(sllc_pmu, name, THIS_MODULE);
|
||||
+ hisi_pmu_init(sllc_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
||||
if (ret) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
127
patches/0092-drivers-perf-hisi-add-NULL-check-for-name.patch
Normal file
127
patches/0092-drivers-perf-hisi-add-NULL-check-for-name.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From 158cb44475a0c6d29c08716ccb3a868262388e55 Mon Sep 17 00:00:00 2001
|
||||
From: Junhao He <hejunhao3@huawei.com>
|
||||
Date: Tue, 23 May 2023 14:44:29 +0800
|
||||
Subject: [PATCH 51/55] drivers/perf: hisi: add NULL check for name
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.4-rc1
|
||||
commit 257aedb72e731082ab514058e57b132f0b29d707
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I77IH6
|
||||
CVE: NA
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=257aedb72e731082ab514058e57b132f0b29d707
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
When allocations fails that can be NULL now.
|
||||
|
||||
If the name provided is NULL, then the initialization process of the PMU
|
||||
type and dev will be skipped in function perf_pmu_register().
|
||||
Consequently, the PMU will not be able to register into the kernel.
|
||||
Moreover, in the case of unregister the PMU, the function device_del()
|
||||
will need to handle NULL pointers, which potentially can cause issues.
|
||||
|
||||
So move this allocation above the cpuhp_state_add_instance() and directly
|
||||
return if it does fail.
|
||||
|
||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 17 ++++++++++-------
|
||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 7 +++++--
|
||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 11 +++++------
|
||||
3 files changed, 20 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
index eddeb76ce4c5..184f2f986c98 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
||||
@@ -502,13 +502,6 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
- &ddrc_pmu->node);
|
||||
- if (ret) {
|
||||
- dev_err(&pdev->dev, "Error %d registering hotplug;\n", ret);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
if (ddrc_pmu->identifier >= HISI_PMU_V2)
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"hisi_sccl%u_ddrc%u_%u",
|
||||
@@ -519,6 +512,16 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
||||
"hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
||||
ddrc_pmu->index_id);
|
||||
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
||||
+ &ddrc_pmu->node);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "Error %d registering hotplug;\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
hisi_pmu_init(ddrc_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
index 1b8f44dada6d..16038ebf08b6 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
||||
@@ -513,6 +513,11 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
+ hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
||||
&hha_pmu->node);
|
||||
if (ret) {
|
||||
@@ -520,8 +525,6 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
||||
- hha_pmu->sccl_id, hha_pmu->index_id);
|
||||
hisi_pmu_init(hha_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
index b2ac90e9f2cd..f9640dbd4095 100644
|
||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
||||
@@ -547,6 +547,11 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
+ l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
+ if (!name)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
||||
&l3c_pmu->node);
|
||||
if (ret) {
|
||||
@@ -554,12 +559,6 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * CCL_ID is used to identify the L3C in the same SCCL which was
|
||||
- * used _UID by mistake.
|
||||
- */
|
||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
||||
- l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
||||
hisi_pmu_init(l3c_pmu, THIS_MODULE);
|
||||
|
||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,162 @@
|
||||
From 418fb2ed339c7856662bb6244ac5477cba81f80f Mon Sep 17 00:00:00 2001
|
||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
||||
Date: Fri, 27 Oct 2023 18:49:23 +0800
|
||||
Subject: [PATCH 52/55] Revert "perf/smmuv3_pmu: Enable HiSilicon Erratum
|
||||
162001800 quirk"
|
||||
|
||||
driver inclusion
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
This reverts commit 68088650bec0647cef4d822b31f818a094f5eead.
|
||||
We inclusion it again from upstream later.
|
||||
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/acpi/arm64/iort.c | 16 +-----------
|
||||
drivers/perf/arm_smmuv3_pmu.c | 48 +++++------------------------------
|
||||
include/linux/acpi_iort.h | 1 -
|
||||
3 files changed, 8 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
|
||||
index 9ad4ee8884de..d507556d508f 100644
|
||||
--- a/drivers/acpi/arm64/iort.c
|
||||
+++ b/drivers/acpi/arm64/iort.c
|
||||
@@ -1476,23 +1476,9 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
|
||||
ACPI_EDGE_SENSITIVE, &res[2]);
|
||||
}
|
||||
|
||||
-static struct acpi_platform_list pmcg_plat_info[] __initdata = {
|
||||
- /* HiSilicon Hip08 Platform */
|
||||
- {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal, 0,
|
||||
- IORT_SMMU_V3_PMCG_HISI_HIP08},
|
||||
- { }
|
||||
-};
|
||||
-
|
||||
static int __init arm_smmu_v3_pmcg_add_platdata(struct platform_device *pdev)
|
||||
{
|
||||
- u32 model;
|
||||
- int idx;
|
||||
-
|
||||
- idx = acpi_match_platform_list(pmcg_plat_info);
|
||||
- if (idx >= 0)
|
||||
- model = pmcg_plat_info[idx].data;
|
||||
- else
|
||||
- model = IORT_SMMU_V3_PMCG_GENERIC;
|
||||
+ u32 model = IORT_SMMU_V3_PMCG_GENERIC;
|
||||
|
||||
return platform_device_add_data(pdev, &model, sizeof(model));
|
||||
}
|
||||
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
|
||||
index bda901e2a5fc..e9cd120f4268 100644
|
||||
--- a/drivers/perf/arm_smmuv3_pmu.c
|
||||
+++ b/drivers/perf/arm_smmuv3_pmu.c
|
||||
@@ -35,7 +35,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
-#include <linux/acpi_iort.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
@@ -94,8 +93,6 @@
|
||||
|
||||
#define SMMU_PMCG_PA_SHIFT 12
|
||||
|
||||
-#define SMMU_PMCG_EVCNTR_RDONLY BIT(0)
|
||||
-
|
||||
static int cpuhp_state_num;
|
||||
|
||||
struct smmu_pmu {
|
||||
@@ -110,7 +107,6 @@ struct smmu_pmu {
|
||||
struct device *dev;
|
||||
void __iomem *reg_base;
|
||||
void __iomem *reloc_base;
|
||||
- u32 options;
|
||||
u64 counter_mask;
|
||||
bool global_filter;
|
||||
};
|
||||
@@ -224,27 +220,15 @@ static void smmu_pmu_set_period(struct smmu_pmu *smmu_pmu,
|
||||
u32 idx = hwc->idx;
|
||||
u64 new;
|
||||
|
||||
- if (smmu_pmu->options & SMMU_PMCG_EVCNTR_RDONLY) {
|
||||
- /*
|
||||
- * On platforms that require this quirk, if the counter starts
|
||||
- * at < half_counter value and wraps, the current logic of
|
||||
- * handling the overflow may not work. It is expected that,
|
||||
- * those platforms will have full 64 counter bits implemented
|
||||
- * so that such a possibility is remote(eg: HiSilicon HIP08).
|
||||
- */
|
||||
- new = smmu_pmu_counter_get_value(smmu_pmu, idx);
|
||||
- } else {
|
||||
- /*
|
||||
- * We limit the max period to half the max counter value
|
||||
- * of the counter size, so that even in the case of extreme
|
||||
- * interrupt latency the counter will (hopefully) not wrap
|
||||
- * past its initial value.
|
||||
- */
|
||||
- new = smmu_pmu->counter_mask >> 1;
|
||||
- smmu_pmu_counter_set_value(smmu_pmu, idx, new);
|
||||
- }
|
||||
+ /*
|
||||
+ * We limit the max period to half the max counter value of the counter
|
||||
+ * size, so that even in the case of extreme interrupt latency the
|
||||
+ * counter will (hopefully) not wrap past its initial value.
|
||||
+ */
|
||||
+ new = smmu_pmu->counter_mask >> 1;
|
||||
|
||||
local64_set(&hwc->prev_count, new);
|
||||
+ smmu_pmu_counter_set_value(smmu_pmu, idx, new);
|
||||
}
|
||||
|
||||
static void smmu_pmu_set_event_filter(struct perf_event *event,
|
||||
@@ -718,22 +702,6 @@ static void smmu_pmu_reset(struct smmu_pmu *smmu_pmu)
|
||||
smmu_pmu->reloc_base + SMMU_PMCG_OVSCLR0);
|
||||
}
|
||||
|
||||
-static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
|
||||
-{
|
||||
- u32 model;
|
||||
-
|
||||
- model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
|
||||
-
|
||||
- switch (model) {
|
||||
- case IORT_SMMU_V3_PMCG_HISI_HIP08:
|
||||
- /* HiSilicon Erratum 162001800 */
|
||||
- smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- dev_notice(smmu_pmu->dev, "option mask 0x%x\n", smmu_pmu->options);
|
||||
-}
|
||||
-
|
||||
static int smmu_pmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct smmu_pmu *smmu_pmu;
|
||||
@@ -813,8 +781,6 @@ static int smmu_pmu_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- smmu_pmu_get_acpi_options(smmu_pmu);
|
||||
-
|
||||
/* Pick one CPU to be the preferred one to use */
|
||||
smmu_pmu->on_cpu = raw_smp_processor_id();
|
||||
WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu)));
|
||||
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
|
||||
index bdb69125854e..832bd6ae9ad4 100644
|
||||
--- a/include/linux/acpi_iort.h
|
||||
+++ b/include/linux/acpi_iort.h
|
||||
@@ -31,7 +31,6 @@
|
||||
* that, this is not part of the IORT specification.
|
||||
*/
|
||||
#define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
|
||||
-#define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
|
||||
|
||||
int iort_register_domain_token(int trans_id, phys_addr_t base,
|
||||
struct fwnode_handle *fw_node);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,197 @@
|
||||
From b917df0a2ab2eba9cc49d2019f5222e70f42dc60 Mon Sep 17 00:00:00 2001
|
||||
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Date: Tue, 26 Mar 2019 15:17:53 +0000
|
||||
Subject: [PATCH 53/55] perf/smmuv3: Enable HiSilicon Erratum 162001800 quirk
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v5.2-rc1
|
||||
commit 24062fe85860debfdae0eeaa495f27c9971ec163
|
||||
category: feature
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=24062fe85860debfdae0eeaa495f27c9971ec163
|
||||
|
||||
----------------------------------------------------------
|
||||
|
||||
HiSilicon erratum 162001800 describes the limitation of
|
||||
SMMUv3 PMCG implementation on HiSilicon Hip08 platforms.
|
||||
|
||||
On these platforms, the PMCG event counter registers
|
||||
(SMMU_PMCG_EVCNTRn) are read only and as a result it
|
||||
is not possible to set the initial counter period value
|
||||
on event monitor start.
|
||||
|
||||
To work around this, the current value of the counter
|
||||
is read and used for delta calculations. OEM information
|
||||
from ACPI header is used to identify the affected hardware
|
||||
platforms.
|
||||
|
||||
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
|
||||
Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
|
||||
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
|
||||
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
|
||||
[will: update silicon-errata.txt and add reason string to acpi match]
|
||||
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
Documentation/arm64/silicon-errata.txt
|
||||
---
|
||||
Documentation/arm64/silicon-errata.txt | 1 +
|
||||
drivers/acpi/arm64/iort.c | 16 ++++++++-
|
||||
drivers/perf/arm_smmuv3_pmu.c | 48 ++++++++++++++++++++++----
|
||||
include/linux/acpi_iort.h | 1 +
|
||||
4 files changed, 58 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
|
||||
index 5016158f5e67..e733d13d7b98 100644
|
||||
--- a/Documentation/arm64/silicon-errata.txt
|
||||
+++ b/Documentation/arm64/silicon-errata.txt
|
||||
@@ -79,6 +79,7 @@ stable kernels.
|
||||
| Hisilicon | Hip07 | #161600802 | HISILICON_ERRATUM_161600802 |
|
||||
| Hisilicon | TSV{110,200} | #1980005 | HISILICON_ERRATUM_1980005 |
|
||||
| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_161600801 |
|
||||
+| Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
|
||||
| | | | |
|
||||
| Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
||||
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
||||
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
|
||||
index d507556d508f..abc62558e818 100644
|
||||
--- a/drivers/acpi/arm64/iort.c
|
||||
+++ b/drivers/acpi/arm64/iort.c
|
||||
@@ -1476,9 +1476,23 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
|
||||
ACPI_EDGE_SENSITIVE, &res[2]);
|
||||
}
|
||||
|
||||
+static struct acpi_platform_list pmcg_plat_info[] __initdata = {
|
||||
+ /* HiSilicon Hip08 Platform */
|
||||
+ {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
+ "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
|
||||
+ { }
|
||||
+};
|
||||
+
|
||||
static int __init arm_smmu_v3_pmcg_add_platdata(struct platform_device *pdev)
|
||||
{
|
||||
- u32 model = IORT_SMMU_V3_PMCG_GENERIC;
|
||||
+ u32 model;
|
||||
+ int idx;
|
||||
+
|
||||
+ idx = acpi_match_platform_list(pmcg_plat_info);
|
||||
+ if (idx >= 0)
|
||||
+ model = pmcg_plat_info[idx].data;
|
||||
+ else
|
||||
+ model = IORT_SMMU_V3_PMCG_GENERIC;
|
||||
|
||||
return platform_device_add_data(pdev, &model, sizeof(model));
|
||||
}
|
||||
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
|
||||
index e9cd120f4268..3df836fd2f70 100644
|
||||
--- a/drivers/perf/arm_smmuv3_pmu.c
|
||||
+++ b/drivers/perf/arm_smmuv3_pmu.c
|
||||
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
+#include <linux/acpi_iort.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
@@ -93,6 +94,8 @@
|
||||
|
||||
#define SMMU_PMCG_PA_SHIFT 12
|
||||
|
||||
+#define SMMU_PMCG_EVCNTR_RDONLY BIT(0)
|
||||
+
|
||||
static int cpuhp_state_num;
|
||||
|
||||
struct smmu_pmu {
|
||||
@@ -108,6 +111,7 @@ struct smmu_pmu {
|
||||
void __iomem *reg_base;
|
||||
void __iomem *reloc_base;
|
||||
u64 counter_mask;
|
||||
+ u32 options;
|
||||
bool global_filter;
|
||||
};
|
||||
|
||||
@@ -220,15 +224,27 @@ static void smmu_pmu_set_period(struct smmu_pmu *smmu_pmu,
|
||||
u32 idx = hwc->idx;
|
||||
u64 new;
|
||||
|
||||
- /*
|
||||
- * We limit the max period to half the max counter value of the counter
|
||||
- * size, so that even in the case of extreme interrupt latency the
|
||||
- * counter will (hopefully) not wrap past its initial value.
|
||||
- */
|
||||
- new = smmu_pmu->counter_mask >> 1;
|
||||
+ if (smmu_pmu->options & SMMU_PMCG_EVCNTR_RDONLY) {
|
||||
+ /*
|
||||
+ * On platforms that require this quirk, if the counter starts
|
||||
+ * at < half_counter value and wraps, the current logic of
|
||||
+ * handling the overflow may not work. It is expected that,
|
||||
+ * those platforms will have full 64 counter bits implemented
|
||||
+ * so that such a possibility is remote(eg: HiSilicon HIP08).
|
||||
+ */
|
||||
+ new = smmu_pmu_counter_get_value(smmu_pmu, idx);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * We limit the max period to half the max counter value
|
||||
+ * of the counter size, so that even in the case of extreme
|
||||
+ * interrupt latency the counter will (hopefully) not wrap
|
||||
+ * past its initial value.
|
||||
+ */
|
||||
+ new = smmu_pmu->counter_mask >> 1;
|
||||
+ smmu_pmu_counter_set_value(smmu_pmu, idx, new);
|
||||
+ }
|
||||
|
||||
local64_set(&hwc->prev_count, new);
|
||||
- smmu_pmu_counter_set_value(smmu_pmu, idx, new);
|
||||
}
|
||||
|
||||
static void smmu_pmu_set_event_filter(struct perf_event *event,
|
||||
@@ -702,6 +718,22 @@ static void smmu_pmu_reset(struct smmu_pmu *smmu_pmu)
|
||||
smmu_pmu->reloc_base + SMMU_PMCG_OVSCLR0);
|
||||
}
|
||||
|
||||
+static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
|
||||
+{
|
||||
+ u32 model;
|
||||
+
|
||||
+ model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
|
||||
+
|
||||
+ switch (model) {
|
||||
+ case IORT_SMMU_V3_PMCG_HISI_HIP08:
|
||||
+ /* HiSilicon Erratum 162001800 */
|
||||
+ smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ dev_notice(smmu_pmu->dev, "option mask 0x%x\n", smmu_pmu->options);
|
||||
+}
|
||||
+
|
||||
static int smmu_pmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct smmu_pmu *smmu_pmu;
|
||||
@@ -781,6 +813,8 @@ static int smmu_pmu_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ smmu_pmu_get_acpi_options(smmu_pmu);
|
||||
+
|
||||
/* Pick one CPU to be the preferred one to use */
|
||||
smmu_pmu->on_cpu = raw_smp_processor_id();
|
||||
WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu)));
|
||||
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
|
||||
index 832bd6ae9ad4..bdb69125854e 100644
|
||||
--- a/include/linux/acpi_iort.h
|
||||
+++ b/include/linux/acpi_iort.h
|
||||
@@ -31,6 +31,7 @@
|
||||
* that, this is not part of the IORT specification.
|
||||
*/
|
||||
#define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
|
||||
+#define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
|
||||
|
||||
int iort_register_domain_token(int trans_id, phys_addr_t base,
|
||||
struct fwnode_handle *fw_node);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,170 @@
|
||||
From 081bfa93450c8b4aa3f483eb14ec7a1bae34f9d4 Mon Sep 17 00:00:00 2001
|
||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Date: Mon, 14 Aug 2023 20:40:12 +0800
|
||||
Subject: [PATCH 54/55] perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk
|
||||
for HIP08/09
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.6-rc1
|
||||
commit 0242737dc4eb9f6e9a5ea594b3f93efa0b12f28d
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0242737dc4eb9f6e9a5ea594b3f93efa0b12f28d
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
Some HiSilicon SMMU PMCG suffers the erratum 162001900 that the PMU
|
||||
disable control sometimes fail to disable the counters. This will lead
|
||||
to error or inaccurate data since before we enable the counters the
|
||||
counter's still counting for the event used in last perf session.
|
||||
|
||||
This patch tries to fix this by hardening the global disable process.
|
||||
Before disable the PMU, writing an invalid event type (0xffff) to
|
||||
focibly stop the counters. Correspondingly restore each events on
|
||||
pmu::pmu_enable().
|
||||
|
||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20230814124012.58013-1-yangyicong@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
|
||||
Conflicts:
|
||||
Documentation/arch/arm64/silicon-errata.rst
|
||||
---
|
||||
Documentation/arm64/silicon-errata.txt | 3 ++
|
||||
drivers/acpi/arm64/iort.c | 5 ++-
|
||||
drivers/perf/arm_smmuv3_pmu.c | 46 +++++++++++++++++++++++++-
|
||||
include/linux/acpi_iort.h | 1 +
|
||||
4 files changed, 53 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
|
||||
index e733d13d7b98..c5aad5509a5a 100644
|
||||
--- a/Documentation/arm64/silicon-errata.txt
|
||||
+++ b/Documentation/arm64/silicon-errata.txt
|
||||
@@ -80,6 +80,9 @@ stable kernels.
|
||||
| Hisilicon | TSV{110,200} | #1980005 | HISILICON_ERRATUM_1980005 |
|
||||
| Hisilicon | Hip09 | #162100801 | HISILICON_ERRATUM_161600801 |
|
||||
| Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A |
|
||||
+| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A
|
||||
+|
|
||||
+| | Hip09 SMMU PMCG | |
|
||||
| | | | |
|
||||
| Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
|
||||
| Qualcomm Tech. | Falkor v1 | E1009 | QCOM_FALKOR_ERRATUM_1009 |
|
||||
diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
|
||||
index abc62558e818..7cfbf52055f8 100644
|
||||
--- a/drivers/acpi/arm64/iort.c
|
||||
+++ b/drivers/acpi/arm64/iort.c
|
||||
@@ -1479,7 +1479,10 @@ static void __init arm_smmu_v3_pmcg_init_resources(struct resource *res,
|
||||
static struct acpi_platform_list pmcg_plat_info[] __initdata = {
|
||||
/* HiSilicon Hip08 Platform */
|
||||
{"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
- "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
|
||||
+ "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08},
|
||||
+ /* HiSilicon Hip09 Platform */
|
||||
+ {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
+ "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
|
||||
{ }
|
||||
};
|
||||
|
||||
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
|
||||
index 3df836fd2f70..56e6f6773675 100644
|
||||
--- a/drivers/perf/arm_smmuv3_pmu.c
|
||||
+++ b/drivers/perf/arm_smmuv3_pmu.c
|
||||
@@ -95,6 +95,7 @@
|
||||
#define SMMU_PMCG_PA_SHIFT 12
|
||||
|
||||
#define SMMU_PMCG_EVCNTR_RDONLY BIT(0)
|
||||
+#define SMMU_PMCG_HARDEN_DISABLE BIT(1)
|
||||
|
||||
static int cpuhp_state_num;
|
||||
|
||||
@@ -138,6 +139,20 @@ static inline void smmu_pmu_enable(struct pmu *pmu)
|
||||
writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR);
|
||||
}
|
||||
|
||||
+static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
|
||||
+ struct perf_event *event, int idx);
|
||||
+
|
||||
+static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu)
|
||||
+{
|
||||
+ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
|
||||
+ unsigned int idx;
|
||||
+
|
||||
+ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
|
||||
+ smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx);
|
||||
+
|
||||
+ smmu_pmu_enable(pmu);
|
||||
+}
|
||||
+
|
||||
static inline void smmu_pmu_disable(struct pmu *pmu)
|
||||
{
|
||||
struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
|
||||
@@ -146,6 +161,22 @@ static inline void smmu_pmu_disable(struct pmu *pmu)
|
||||
writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL);
|
||||
}
|
||||
|
||||
+static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu)
|
||||
+{
|
||||
+ struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
|
||||
+ unsigned int idx;
|
||||
+
|
||||
+ /*
|
||||
+ * The global disable of PMU sometimes fail to stop the counting.
|
||||
+ * Harden this by writing an invalid event type to each used counter
|
||||
+ * to forcibly stop counting.
|
||||
+ */
|
||||
+ for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
|
||||
+ writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx));
|
||||
+
|
||||
+ smmu_pmu_disable(pmu);
|
||||
+}
|
||||
+
|
||||
static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu,
|
||||
u32 idx, u64 value)
|
||||
{
|
||||
@@ -727,7 +758,10 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
|
||||
switch (model) {
|
||||
case IORT_SMMU_V3_PMCG_HISI_HIP08:
|
||||
/* HiSilicon Erratum 162001800 */
|
||||
- smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
|
||||
+ smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE;
|
||||
+ break;
|
||||
+ case IORT_SMMU_V3_PMCG_HISI_HIP09:
|
||||
+ smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -815,6 +849,16 @@ static int smmu_pmu_probe(struct platform_device *pdev)
|
||||
|
||||
smmu_pmu_get_acpi_options(smmu_pmu);
|
||||
|
||||
+ /*
|
||||
+ * For platforms suffer this quirk, the PMU disable sometimes fails to
|
||||
+ * stop the counters. This will leads to inaccurate or error counting.
|
||||
+ * Forcibly disable the counters with these quirk handler.
|
||||
+ */
|
||||
+ if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) {
|
||||
+ smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09;
|
||||
+ smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09;
|
||||
+ }
|
||||
+
|
||||
/* Pick one CPU to be the preferred one to use */
|
||||
smmu_pmu->on_cpu = raw_smp_processor_id();
|
||||
WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu)));
|
||||
diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h
|
||||
index bdb69125854e..b1c1c84a422e 100644
|
||||
--- a/include/linux/acpi_iort.h
|
||||
+++ b/include/linux/acpi_iort.h
|
||||
@@ -32,6 +32,7 @@
|
||||
*/
|
||||
#define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
|
||||
#define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
|
||||
+#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */
|
||||
|
||||
int iort_register_domain_token(int trans_id, phys_addr_t base,
|
||||
struct fwnode_handle *fw_node);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 381dea7a1598760dcffcbce4f819bbe7035a3b13 Mon Sep 17 00:00:00 2001
|
||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Date: Mon, 14 Aug 2023 21:16:42 +0800
|
||||
Subject: [PATCH 55/55] perf/smmuv3: Add MODULE_ALIAS for module auto loading
|
||||
|
||||
mainline inclusion
|
||||
from mainline-v6.6-rc1
|
||||
commit 1b0e3ea9301a422003d385cda8f8dee6c878ad05
|
||||
category: bugfix
|
||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
||||
|
||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1b0e3ea9301a422003d385cda8f8dee6c878ad05
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
On my ACPI based arm64 server, if the SMMUv3 PMU is configured as
|
||||
module it won't be loaded automatically after booting even if the
|
||||
device has already been scanned and added. It's because the module
|
||||
lacks a platform alias, the uevent mechanism and userspace tools
|
||||
like udevd make use of this to find the target driver module of the
|
||||
device. This patch adds the missing platform alias of the module,
|
||||
then module will be loaded automatically if device exists.
|
||||
|
||||
Before this patch:
|
||||
[root@localhost tmp]# modinfo arm_smmuv3_pmu | grep alias
|
||||
alias: of:N*T*Carm,smmu-v3-pmcgC*
|
||||
alias: of:N*T*Carm,smmu-v3-pmcg
|
||||
|
||||
After this patch:
|
||||
[root@localhost tmp]# modinfo arm_smmuv3_pmu | grep alias
|
||||
alias: platform:arm-smmu-v3-pmcg
|
||||
alias: of:N*T*Carm,smmu-v3-pmcgC*
|
||||
alias: of:N*T*Carm,smmu-v3-pmcg
|
||||
|
||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
||||
Link: https://lore.kernel.org/r/20230814131642.65263-1-yangyicong@huawei.com
|
||||
Signed-off-by: Will Deacon <will@kernel.org>
|
||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
||||
---
|
||||
drivers/perf/arm_smmuv3_pmu.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
|
||||
index 56e6f6773675..1fae44c24ff9 100644
|
||||
--- a/drivers/perf/arm_smmuv3_pmu.c
|
||||
+++ b/drivers/perf/arm_smmuv3_pmu.c
|
||||
@@ -941,6 +941,7 @@ static void __exit arm_smmu_pmu_exit(void)
|
||||
|
||||
module_exit(arm_smmu_pmu_exit);
|
||||
|
||||
+MODULE_ALIAS("platform:arm-smmu-v3-pmcg");
|
||||
MODULE_DESCRIPTION("PMU driver for ARM SMMUv3 Performance Monitors Extension");
|
||||
MODULE_AUTHOR("Neil Leeder <nleeder@codeaurora.org>");
|
||||
MODULE_AUTHOR("Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
55
series.conf
55
series.conf
@ -43,3 +43,58 @@ patches/0038-perf-arm-spe-Add-more-sub-classes-for-operation-pack.patch
|
||||
patches/0039-perf-arm_spe-Decode-memory-tagging-properties.patch
|
||||
patches/0040-perf-arm-spe-Add-support-for-ARMv8.3-SPE.patch
|
||||
patches/0041-drivers-perf-Add-support-for-ARMv8.3-SPE.patch
|
||||
patches/0042-Revert-perf-hisi-Fix-compile-error-if-defined-MODULE.patch
|
||||
patches/0043-Revert-perf-hisi-Add-support-for-HiSilicon-SoC-L3T-P.patch
|
||||
patches/0044-Revert-perf-hisi-Add-support-for-HiSilicon-SoC-LPDDR.patch
|
||||
patches/0045-Revert-perf-hisi-Add-support-for-HiSilicon-SoC-PMU-d.patch
|
||||
patches/0046-Revert-drivers-perf-Fix-kernel-panic-when-rmmod-PMU-.patch
|
||||
patches/0047-Revert-perf-hisi-remove-duplicated-code.patch
|
||||
patches/0048-docs-perf-convert-to-ReST.patch
|
||||
patches/0049-drivers-perf-Fix-kernel-panic-when-rmmod-PMU-modules.patch
|
||||
patches/0050-For-drivers-that-do-not-support-context-exclusion-le.patch
|
||||
patches/0051-drivers-provide-devm_platform_ioremap_resource.patch
|
||||
patches/0052-perf-hisi-use-devm_platform_ioremap_resource-to-simp.patch
|
||||
patches/0053-drivers-perf-hisi-Add-identifier-sysfs-file.patch
|
||||
patches/0054-drivers-perf-hisi-Remove-unnecessary-check-of-counte.patch
|
||||
patches/0055-drivers-perf-hisi-Refactor-code-for-more-uncore-PMUs.patch
|
||||
patches/0056-drivers-perf-hisi-Add-PMU-version-for-uncore-PMU-dri.patch
|
||||
patches/0057-drivers-perf-hisi-Add-new-functions-for-L3C-PMU.patch
|
||||
patches/0058-drivers-perf-hisi-Add-new-functions-for-HHA-PMU.patch
|
||||
patches/0059-drivers-perf-hisi-Update-DDRC-PMU-for-programmable-c.patch
|
||||
patches/0060-drivers-perf-hisi-Add-support-for-HiSilicon-SLLC-PMU.patch
|
||||
patches/0061-drivers-perf-hisi-Add-support-for-HiSilicon-PA-PMU-d.patch
|
||||
patches/0062-perf-hisi-Use-irq_set_affinity.patch
|
||||
patches/0063-drivers-perf-hisi-Fix-data-source-control.patch
|
||||
patches/0064-perf-hisi-Make-irq-shared.patch
|
||||
patches/0065-perf-hisi-Fix-read-sccl_id-and-ccl_id-error-in-some-.patch
|
||||
patches/0066-perf-hisi-Add-support-for-HiSilicon-SoC-L3T-PMU.patch
|
||||
patches/0067-perf-hisi-Add-support-for-HiSilicon-SoC-LPDDRC-PMU.patch
|
||||
patches/0068-perf-hisi-Fix-unexpected-modifications-in-hisi_uncor.patch
|
||||
patches/0069-PCI-Add-pci_dev_id-helper.patch
|
||||
patches/0070-drivers-perf-hisi-Add-driver-for-HiSilicon-PCIe-PMU.patch
|
||||
patches/0071-drivers-perf-hisi-Associate-PMUs-in-SICL-with-CPUs-o.patch
|
||||
patches/0072-driver-perf-hisi-fix-kabi-broken-for-struct-hisi_pmu.patch
|
||||
patches/0073-drivers-perf-hisi-Add-Support-for-CPA-PMU.patch
|
||||
patches/0074-drivers-perf-hisi-Fix-some-event-id-for-hisi-pcie-pm.patch
|
||||
patches/0075-docs-perf-move-to-the-admin-guide.patch
|
||||
patches/0076-docs-perf-Add-new-description-on-HiSilicon-uncore-PM.patch
|
||||
patches/0077-docs-perf-Add-description-for-HiSilicon-PCIe-PMU-dri.patch
|
||||
patches/0078-docs-perf-Address-some-html-build-warnings.patch
|
||||
patches/0079-docs-fix-make-htmldocs-warning-in-perf.patch
|
||||
patches/0080-docs-perf-Fix-PMU-instance-name-of-hisi-pcie-pmu.patch
|
||||
patches/0081-drivers-perf-hisi-Add-TLP-filter-support.patch
|
||||
patches/0082-drivers-perf-hisi-Don-t-migrate-perf-to-the-CPU-goin.patch
|
||||
patches/0083-drivers-perf-fixed-the-issue-that-the-kabi-value-cha.patch
|
||||
patches/0084-drivers-perf-fixed-kabi-broken-for-SLLC-and-PA-PMU.patch
|
||||
patches/0085-perf-hisi-Fix-read-sccl_id-and-ccl_id-error-in-TSV20.patch
|
||||
patches/0086-perf-hisi-Add-configs-for-PMU-isolation.patch
|
||||
patches/0087-perf-hisi-Extract-hisi_pmu_init.patch
|
||||
patches/0088-drivers-perf-hisi-Advertise-the-PERF_PMU_CAP_NO_EXCL.patch
|
||||
patches/0089-drivers-perf-hisi-Simplify-the-parameters-of-hisi_pm.patch
|
||||
patches/0090-drivers-perf-hisi-Extract-initialization-of-cpa_pmu-.patch
|
||||
patches/0091-drivers-perf-hisi-Remove-redundant-initialized-of-pm.patch
|
||||
patches/0092-drivers-perf-hisi-add-NULL-check-for-name.patch
|
||||
patches/0093-Revert-perf-smmuv3_pmu-Enable-HiSilicon-Erratum-1620.patch
|
||||
patches/0094-perf-smmuv3-Enable-HiSilicon-Erratum-162001800-quirk.patch
|
||||
patches/0095-perf-smmuv3-Enable-HiSilicon-Erratum-162001900-quirk.patch
|
||||
patches/0096-perf-smmuv3-Add-MODULE_ALIAS-for-module-auto-loading.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user