forked from Minki/linux
RISC-V Patches for the 6.1 Merge Window, Part 1
* Improvements to the CPU topology subsystem, which fix some issues where RISC-V would report bad topology information. * The default NR_CPUS has increased to XLEN, and the maximum configurable value is 512. * The CD-ROM filesystems have been enabled in the defconfig. * Support for THP_SWAP has been added for rv64 systems. There are also a handful of cleanups and fixes throughout the tree. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAmNAWgwTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYicSiEACmuB9WuGZmAasKvmPgz7thyLqakg7/ cE4YK0MxgJxkhsXzYSAv1Fn+WUfX7DSzhK4OOM5wEngAYul7QoFdc84MF0DYKO+E InjdOvVavzUsWYqETNCuMHPRK6xyzvfHCqqBDDxKHx5jUoicCQfFwJyHLw+cvouR 7WSJoFdvOEV01QyN5Qw9bQp7ASx61ZZX1yE6OAPc2/EJlDEA2QSnjBAi4M+n2ZCx ZsQz+Dp9RfSU8/nIr13oGiL3Zm+kyXwdOS/8PaDqtrkyiGh6+vSeGqZZwRLVITP/ oUxqGEgnn2eFBD1y8vjsQNWMLWoi9Av4746Fxr8CEHX+jX1cp9CCkU2OkkLxaFcv 6XFtXPJIh/UjzVgPmjZxK+ArEX28QOM5IVyBFxsSl0dNtvyVqKpBXCV1RQ+fFHkO ntHF3ZxibqOn8ZJmziCn0nzWSOqugNTdAhD4dJAbl58RB/IQtQT0OnHpmpXCG3xh +/JBzy//xkr7u2HMqU69PzwPtWwZrENUV6jl5SHUDUoW8pySng2Pl4pbmTFqgWty JTfc5EdyWOWyshhoSCtK2//bnVFryl2ntwGr3LIZrZxkiUiOeYjn+C/YedXZIRob yy2CN+QanW/FXdIa4GMNeGc9sGDApd3/RtP+8L9mV1kWK6OE0EVskkI1UMCGXrIP 5JoE1jLMVhjcKQ== =LJg6 -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-6.1-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux Pull RISC-V updates from Palmer Dabbelt: - Improvements to the CPU topology subsystem, which fix some issues where RISC-V would report bad topology information. - The default NR_CPUS has increased to XLEN, and the maximum configurable value is 512. - The CD-ROM filesystems have been enabled in the defconfig. - Support for THP_SWAP has been added for rv64 systems. There are also a handful of cleanups and fixes throughout the tree. * tag 'riscv-for-linus-6.1-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: enable THP_SWAP for RV64 RISC-V: Print SSTC in canonical order riscv: compat: s/failed/unsupported if compat mode isn't supported RISC-V: Increase range and default value of NR_CPUS cpuidle: riscv-sbi: Fix CPU_PM_CPU_IDLE_ENTER_xyz() macro usage perf: RISC-V: throttle perf events perf: RISC-V: exclude invalid pmu counters from SBI calls riscv: enable CD-ROM file systems in defconfig riscv: topology: fix default topology reporting arm64: topology: move store_cpu_topology() to shared code
This commit is contained in:
commit
2e64066dab
@ -22,46 +22,6 @@
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/topology.h>
|
||||
|
||||
void store_cpu_topology(unsigned int cpuid)
|
||||
{
|
||||
struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
|
||||
u64 mpidr;
|
||||
|
||||
if (cpuid_topo->package_id != -1)
|
||||
goto topology_populated;
|
||||
|
||||
mpidr = read_cpuid_mpidr();
|
||||
|
||||
/* Uniprocessor systems can rely on default topology values */
|
||||
if (mpidr & MPIDR_UP_BITMASK)
|
||||
return;
|
||||
|
||||
/*
|
||||
* This would be the place to create cpu topology based on MPIDR.
|
||||
*
|
||||
* However, it cannot be trusted to depict the actual topology; some
|
||||
* pieces of the architecture enforce an artificial cap on Aff0 values
|
||||
* (e.g. GICv3's ICC_SGI1R_EL1 limits it to 15), leading to an
|
||||
* artificial cycling of Aff1, Aff2 and Aff3 values. IOW, these end up
|
||||
* having absolutely no relationship to the actual underlying system
|
||||
* topology, and cannot be reasonably used as core / package ID.
|
||||
*
|
||||
* If the MT bit is set, Aff0 *could* be used to define a thread ID, but
|
||||
* we still wouldn't be able to obtain a sane core ID. This means we
|
||||
* need to entirely ignore MPIDR for any topology deduction.
|
||||
*/
|
||||
cpuid_topo->thread_id = -1;
|
||||
cpuid_topo->core_id = cpuid;
|
||||
cpuid_topo->package_id = cpu_to_node(cpuid);
|
||||
|
||||
pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
|
||||
cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
|
||||
cpuid_topo->thread_id, mpidr);
|
||||
|
||||
topology_populated:
|
||||
update_siblings_masks(cpuid);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static bool __init acpi_cpu_is_threaded(int cpu)
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ config RISCV
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select ARCH_WANT_GENERAL_HUGETLB
|
||||
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
|
||||
select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select BINFMT_FLAT_NO_DATA_START_OFFSET if !MMU
|
||||
select BUILDTIME_TABLE_SORT if MMU
|
||||
select CLONE_BACKWARDS
|
||||
@ -52,7 +53,7 @@ config RISCV
|
||||
select COMMON_CLK
|
||||
select CPU_PM if CPU_IDLE
|
||||
select EDAC_SUPPORT
|
||||
select GENERIC_ARCH_TOPOLOGY if SMP
|
||||
select GENERIC_ARCH_TOPOLOGY
|
||||
select GENERIC_ATOMIC64 if !64BIT
|
||||
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
|
||||
select GENERIC_EARLY_IOREMAP
|
||||
@ -309,10 +310,13 @@ config SMP
|
||||
If you don't know what to do here, say N.
|
||||
|
||||
config NR_CPUS
|
||||
int "Maximum number of CPUs (2-32)"
|
||||
range 2 32
|
||||
int "Maximum number of CPUs (2-512)"
|
||||
depends on SMP
|
||||
default "8"
|
||||
range 2 512 if !SBI_V01
|
||||
range 2 32 if SBI_V01 && 32BIT
|
||||
range 2 64 if SBI_V01 && 64BIT
|
||||
default "32" if 32BIT
|
||||
default "64" if 64BIT
|
||||
|
||||
config HOTPLUG_CPU
|
||||
bool "Support for hot-pluggable CPUs"
|
||||
|
@ -166,6 +166,9 @@ CONFIG_BTRFS_FS=m
|
||||
CONFIG_BTRFS_FS_POSIX_ACL=y
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
CONFIG_OVERLAY_FS=m
|
||||
CONFIG_ISO9660_FS=y
|
||||
CONFIG_JOLIET=y
|
||||
CONFIG_ZISOFS=y
|
||||
CONFIG_MSDOS_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
|
@ -92,10 +92,10 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
|
||||
*/
|
||||
static struct riscv_isa_ext_data isa_ext_arr[] = {
|
||||
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
|
||||
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
|
||||
__RISCV_ISA_EXT_DATA(svpbmt, RISCV_ISA_EXT_SVPBMT),
|
||||
__RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM),
|
||||
__RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE),
|
||||
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
|
||||
__RISCV_ISA_EXT_DATA("", RISCV_ISA_EXT_MAX),
|
||||
};
|
||||
|
||||
|
@ -105,7 +105,7 @@ static int __init compat_mode_detect(void)
|
||||
csr_write(CSR_STATUS, tmp);
|
||||
|
||||
pr_info("riscv: ELF compat mode %s",
|
||||
compat_mode_supported ? "supported" : "failed");
|
||||
compat_mode_supported ? "supported" : "unsupported");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
unsigned int curr_cpuid;
|
||||
|
||||
curr_cpuid = smp_processor_id();
|
||||
store_cpu_topology(curr_cpuid);
|
||||
numa_store_cpu_info(curr_cpuid);
|
||||
numa_add_cpu(curr_cpuid);
|
||||
|
||||
@ -162,9 +163,9 @@ asmlinkage __visible void smp_callin(void)
|
||||
mmgrab(mm);
|
||||
current->active_mm = mm;
|
||||
|
||||
store_cpu_topology(curr_cpuid);
|
||||
notify_cpu_starting(curr_cpuid);
|
||||
numa_add_cpu(curr_cpuid);
|
||||
update_siblings_masks(curr_cpuid);
|
||||
set_cpu_online(curr_cpuid, 1);
|
||||
|
||||
/*
|
||||
|
@ -841,4 +841,23 @@ void __init init_cpu_topology(void)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void store_cpu_topology(unsigned int cpuid)
|
||||
{
|
||||
struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
|
||||
|
||||
if (cpuid_topo->package_id != -1)
|
||||
goto topology_populated;
|
||||
|
||||
cpuid_topo->thread_id = -1;
|
||||
cpuid_topo->core_id = cpuid;
|
||||
cpuid_topo->package_id = cpu_to_node(cpuid);
|
||||
|
||||
pr_debug("CPU%u: package %d core %d thread %d\n",
|
||||
cpuid, cpuid_topo->package_id, cpuid_topo->core_id,
|
||||
cpuid_topo->thread_id);
|
||||
|
||||
topology_populated:
|
||||
update_siblings_masks(cpuid);
|
||||
}
|
||||
#endif
|
||||
|
@ -97,8 +97,13 @@ static int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int idx)
|
||||
{
|
||||
u32 *states = __this_cpu_read(sbi_cpuidle_data.states);
|
||||
u32 state = states[idx];
|
||||
|
||||
return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, states[idx]);
|
||||
if (state & SBI_HSM_SUSP_NON_RET_BIT)
|
||||
return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, state);
|
||||
else
|
||||
return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(sbi_suspend,
|
||||
idx, state);
|
||||
}
|
||||
|
||||
static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#define RISCV_PMU_LEGACY_CYCLE 0
|
||||
#define RISCV_PMU_LEGACY_INSTRET 1
|
||||
#define RISCV_PMU_LEGACY_NUM_CTR 2
|
||||
|
||||
static bool pmu_init_done;
|
||||
|
||||
@ -83,7 +82,8 @@ static void pmu_legacy_init(struct riscv_pmu *pmu)
|
||||
{
|
||||
pr_info("Legacy PMU implementation is available\n");
|
||||
|
||||
pmu->num_counters = RISCV_PMU_LEGACY_NUM_CTR;
|
||||
pmu->cmask = BIT(RISCV_PMU_LEGACY_CYCLE) |
|
||||
BIT(RISCV_PMU_LEGACY_INSTRET);
|
||||
pmu->ctr_start = pmu_legacy_ctr_start;
|
||||
pmu->ctr_stop = NULL;
|
||||
pmu->event_map = pmu_legacy_event_map;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/sched/clock.h>
|
||||
|
||||
#include <asm/sbi.h>
|
||||
#include <asm/hwcap.h>
|
||||
@ -271,7 +272,6 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
||||
struct sbiret ret;
|
||||
int idx;
|
||||
uint64_t cbase = 0;
|
||||
uint64_t cmask = GENMASK_ULL(rvpmu->num_counters - 1, 0);
|
||||
unsigned long cflags = 0;
|
||||
|
||||
if (event->attr.exclude_kernel)
|
||||
@ -281,11 +281,12 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
||||
|
||||
/* 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);
|
||||
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
rvpmu->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,
|
||||
cflags, hwc->event_base, hwc->config, 0);
|
||||
ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
|
||||
rvpmu->cmask, cflags, hwc->event_base, hwc->config, 0);
|
||||
#endif
|
||||
if (ret.error) {
|
||||
pr_debug("Not able to find a counter for event %lx config %llx\n",
|
||||
@ -294,7 +295,7 @@ static int pmu_sbi_ctr_get_idx(struct perf_event *event)
|
||||
}
|
||||
|
||||
idx = ret.value;
|
||||
if (idx >= rvpmu->num_counters || !pmu_ctr_list[idx].value)
|
||||
if (!test_bit(idx, &rvpmu->cmask) || !pmu_ctr_list[idx].value)
|
||||
return -ENOENT;
|
||||
|
||||
/* Additional sanity check for the counter id */
|
||||
@ -463,7 +464,7 @@ static int pmu_sbi_find_num_ctrs(void)
|
||||
return sbi_err_map_linux_errno(ret.error);
|
||||
}
|
||||
|
||||
static int pmu_sbi_get_ctrinfo(int nctr)
|
||||
static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask)
|
||||
{
|
||||
struct sbiret ret;
|
||||
int i, num_hw_ctr = 0, num_fw_ctr = 0;
|
||||
@ -478,6 +479,9 @@ static int pmu_sbi_get_ctrinfo(int nctr)
|
||||
if (ret.error)
|
||||
/* The logical counter ids are not expected to be contiguous */
|
||||
continue;
|
||||
|
||||
*mask |= BIT(i);
|
||||
|
||||
cinfo.value = ret.value;
|
||||
if (cinfo.type == SBI_PMU_CTR_TYPE_FW)
|
||||
num_fw_ctr++;
|
||||
@ -498,7 +502,7 @@ static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
|
||||
* which may include counters that are not enabled yet.
|
||||
*/
|
||||
sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
|
||||
0, GENMASK_ULL(pmu->num_counters - 1, 0), 0, 0, 0, 0);
|
||||
0, pmu->cmask, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
|
||||
@ -567,6 +571,7 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
|
||||
unsigned long overflow;
|
||||
unsigned long overflowed_ctrs = 0;
|
||||
struct cpu_hw_events *cpu_hw_evt = dev;
|
||||
u64 start_clock = sched_clock();
|
||||
|
||||
if (WARN_ON_ONCE(!cpu_hw_evt))
|
||||
return IRQ_NONE;
|
||||
@ -635,7 +640,9 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
|
||||
perf_event_overflow(event, &data, regs);
|
||||
}
|
||||
}
|
||||
|
||||
pmu_sbi_start_overflow_mask(pmu, overflowed_ctrs);
|
||||
perf_sample_event_took(sched_clock() - start_clock);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -788,8 +795,9 @@ static void riscv_pmu_destroy(struct riscv_pmu *pmu)
|
||||
static int pmu_sbi_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct riscv_pmu *pmu = NULL;
|
||||
int num_counters;
|
||||
unsigned long cmask = 0;
|
||||
int ret = -ENODEV;
|
||||
int num_counters;
|
||||
|
||||
pr_info("SBI PMU extension is available\n");
|
||||
pmu = riscv_pmu_alloc();
|
||||
@ -803,7 +811,7 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* cache all the information about counters now */
|
||||
if (pmu_sbi_get_ctrinfo(num_counters))
|
||||
if (pmu_sbi_get_ctrinfo(num_counters, &cmask))
|
||||
goto out_free;
|
||||
|
||||
ret = pmu_sbi_setup_irqs(pmu, pdev);
|
||||
@ -812,8 +820,9 @@ static int pmu_sbi_device_probe(struct platform_device *pdev)
|
||||
pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
|
||||
pmu->pmu.capabilities |= PERF_PMU_CAP_NO_EXCLUDE;
|
||||
}
|
||||
|
||||
pmu->pmu.attr_groups = riscv_pmu_attr_groups;
|
||||
pmu->num_counters = num_counters;
|
||||
pmu->cmask = cmask;
|
||||
pmu->ctr_start = pmu_sbi_ctr_start;
|
||||
pmu->ctr_stop = pmu_sbi_ctr_stop;
|
||||
pmu->event_map = pmu_sbi_event_map;
|
||||
|
@ -45,7 +45,7 @@ struct riscv_pmu {
|
||||
|
||||
irqreturn_t (*handle_irq)(int irq_num, void *dev);
|
||||
|
||||
int num_counters;
|
||||
unsigned long cmask;
|
||||
u64 (*ctr_read)(struct perf_event *event);
|
||||
int (*ctr_get_idx)(struct perf_event *event);
|
||||
int (*ctr_get_width)(int idx);
|
||||
|
Loading…
Reference in New Issue
Block a user