Commit 9801002f authored by Palmer Dabbelt's avatar Palmer Dabbelt

perf: riscv_pmu{,_sbi}: Miscallenous improvement & fixes

A series of mostly-independent fixes and cleanups for the RISC-V PMU
drivers.

Link: https://lore.kernel.org/lkml/CAAhSdy23vE8+HxU5Jxy2rBMjy3rBTrJt_4sriuROac_sEESSVw@mail.gmail.com/T/#m9de15aef1b65ae6155fa33ea1239578ef463c2a2

* palmer/riscv-pmu:
  RISC-V: Improve SBI definitions
  RISC-V: Move counter info definition to sbi header file
  RISC-V: Fix SBI PMU calls for RV32
  RISC-V: Update user page mapping only once during start
  RISC-V: Fix counter restart during overflow for RV32
parents 7ab52f75 f829ee75
...@@ -122,7 +122,21 @@ enum sbi_ext_pmu_fid { ...@@ -122,7 +122,21 @@ enum sbi_ext_pmu_fid {
SBI_EXT_PMU_COUNTER_FW_READ, SBI_EXT_PMU_COUNTER_FW_READ,
}; };
#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(55, 0) union sbi_pmu_ctr_info {
unsigned long value;
struct {
unsigned long csr:12;
unsigned long width:6;
#if __riscv_xlen == 32
unsigned long reserved:13;
#else
unsigned long reserved:45;
#endif
unsigned long type:1;
};
};
#define RISCV_PMU_RAW_EVENT_MASK GENMASK_ULL(47, 0)
#define RISCV_PMU_RAW_EVENT_IDX 0x20000 #define RISCV_PMU_RAW_EVENT_IDX 0x20000
/** General pmu event codes specified in SBI PMU extension */ /** General pmu event codes specified in SBI PMU extension */
...@@ -189,12 +203,26 @@ enum sbi_pmu_ctr_type { ...@@ -189,12 +203,26 @@ enum sbi_pmu_ctr_type {
SBI_PMU_CTR_TYPE_FW, SBI_PMU_CTR_TYPE_FW,
}; };
/* Helper macros to decode event idx */
#define SBI_PMU_EVENT_IDX_OFFSET 20
#define SBI_PMU_EVENT_IDX_MASK 0xFFFFF
#define SBI_PMU_EVENT_IDX_CODE_MASK 0xFFFF
#define SBI_PMU_EVENT_IDX_TYPE_MASK 0xF0000
#define SBI_PMU_EVENT_RAW_IDX 0x20000
#define SBI_PMU_FIXED_CTR_MASK 0x07
#define SBI_PMU_EVENT_CACHE_ID_CODE_MASK 0xFFF8
#define SBI_PMU_EVENT_CACHE_OP_ID_CODE_MASK 0x06
#define SBI_PMU_EVENT_CACHE_RESULT_ID_CODE_MASK 0x01
#define SBI_PMU_EVENT_IDX_INVALID 0xFFFFFFFF
/* Flags defined for config matching function */ /* Flags defined for config matching function */
#define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0) #define SBI_PMU_CFG_FLAG_SKIP_MATCH (1 << 0)
#define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1) #define SBI_PMU_CFG_FLAG_CLEAR_VALUE (1 << 1)
#define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2) #define SBI_PMU_CFG_FLAG_AUTO_START (1 << 2)
#define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3) #define SBI_PMU_CFG_FLAG_SET_VUINH (1 << 3)
#define SBI_PMU_CFG_FLAG_SET_VSNH (1 << 4) #define SBI_PMU_CFG_FLAG_SET_VSINH (1 << 4)
#define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5) #define SBI_PMU_CFG_FLAG_SET_UINH (1 << 5)
#define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6) #define SBI_PMU_CFG_FLAG_SET_SINH (1 << 6)
#define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7) #define SBI_PMU_CFG_FLAG_SET_MINH (1 << 7)
......
...@@ -170,7 +170,6 @@ int riscv_pmu_event_set_period(struct perf_event *event) ...@@ -170,7 +170,6 @@ int riscv_pmu_event_set_period(struct perf_event *event)
left = (max_period >> 1); left = (max_period >> 1);
local64_set(&hwc->prev_count, (u64)-left); local64_set(&hwc->prev_count, (u64)-left);
perf_event_update_userpage(event);
return overflow; return overflow;
} }
......
...@@ -41,20 +41,6 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = { ...@@ -41,20 +41,6 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = {
NULL, NULL,
}; };
union sbi_pmu_ctr_info {
unsigned long value;
struct {
unsigned long csr:12;
unsigned long width:6;
#if __riscv_xlen == 32
unsigned long reserved:13;
#else
unsigned long reserved:45;
#endif
unsigned long type:1;
};
};
/* /*
* RISC-V doesn't have hetergenous harts yet. This need to be part of * RISC-V doesn't have hetergenous harts yet. This need to be part of
* per_cpu in case of harts with different pmu counters * per_cpu in case of harts with different pmu counters
...@@ -294,8 +280,13 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event) ...@@ -294,8 +280,13 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
cflags |= SBI_PMU_CFG_FLAG_SET_UINH; cflags |= SBI_PMU_CFG_FLAG_SET_UINH;
/* retrieve the available counter index */ /* retrieve the available counter index */
#if defined(CONFIG_32BIT)
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask,
cflags, hwc->event_base, hwc->config, hwc->config >> 32);
#else
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask, ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase, cmask,
cflags, hwc->event_base, hwc->config, 0); cflags, hwc->event_base, hwc->config, 0);
#endif
if (ret.error) { if (ret.error) {
pr_debug("Not able to find a counter for event %lx config %llx\n", pr_debug("Not able to find a counter for event %lx config %llx\n",
hwc->event_base, hwc->config); hwc->event_base, hwc->config);
...@@ -437,8 +428,13 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival) ...@@ -437,8 +428,13 @@ static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
struct hw_perf_event *hwc = &event->hw; struct hw_perf_event *hwc = &event->hw;
unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE; unsigned long flag = SBI_PMU_START_FLAG_SET_INIT_VALUE;
#if defined(CONFIG_32BIT)
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx, ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx,
1, flag, ival, ival >> 32, 0); 1, flag, ival, ival >> 32, 0);
#else
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, hwc->idx,
1, flag, ival, 0, 0);
#endif
if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED)) if (ret.error && (ret.error != SBI_ERR_ALREADY_STARTED))
pr_err("Starting counter idx %d failed with error %d\n", pr_err("Starting counter idx %d failed with error %d\n",
hwc->idx, sbi_err_map_linux_errno(ret.error)); hwc->idx, sbi_err_map_linux_errno(ret.error));
...@@ -545,8 +541,14 @@ static inline void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu, ...@@ -545,8 +541,14 @@ static inline void pmu_sbi_start_overflow_mask(struct riscv_pmu *pmu,
hwc = &event->hw; hwc = &event->hw;
max_period = riscv_pmu_ctr_get_width_mask(event); max_period = riscv_pmu_ctr_get_width_mask(event);
init_val = local64_read(&hwc->prev_count) & max_period; init_val = local64_read(&hwc->prev_count) & max_period;
#if defined(CONFIG_32BIT)
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1,
flag, init_val, init_val >> 32, 0);
#else
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1, sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_START, idx, 1,
flag, init_val, 0, 0); flag, init_val, 0, 0);
#endif
perf_event_update_userpage(event);
} }
ctr_ovf_mask = ctr_ovf_mask >> 1; ctr_ovf_mask = ctr_ovf_mask >> 1;
idx++; idx++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment