Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Documentation/devicetree/bindings/riscv/extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ properties:
ratified at commit d70011dde6c2 ("Update to ratified state")
of riscv-j-extension.

- const: ssqosid
description: |
The Ssqosid extension for Quality of Service ID is ratified
as v1.0 in commit 5059e0ca641c ("Merge pull request #7 from
ved-rivos/Ratified") of riscv-ssqosid.

- const: ssstateen
description: |
The standard Ssstateen extension for supervisor-mode view of the
Expand Down
11 changes: 11 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -22769,6 +22769,17 @@ F: drivers/perf/riscv_pmu.c
F: drivers/perf/riscv_pmu_legacy.c
F: drivers/perf/riscv_pmu_sbi.c

RISC-V QOS RESCTRL SUPPORT
M: Drew Fustini <fustini@kernel.org>
R: yunhui cui <cuiyunhui@bytedance.com>
L: linux-riscv@lists.infradead.org
S: Supported
F: arch/riscv/include/asm/qos.h
F: arch/riscv/include/asm/resctrl.h
F: arch/riscv/kernel/qos/
F: drivers/acpi/riscv/rqsc.c
F: include/linux/riscv_qos.h

RISC-V RPMI AND MPXY DRIVERS
M: Rahul Pathak <rahul@summations.net>
M: Anup Patel <anup@brainfault.org>
Expand Down
20 changes: 20 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,26 @@ config RISCV_ISA_SVNAPOT

If you don't know what to do here, say Y.

config RISCV_ISA_SSQOSID
bool "Ssqosid extension support for supervisor mode Quality of Service ID"
depends on MISC_FILESYSTEMS
default n
select ARCH_HAS_CPU_RESCTRL
select RESCTRL_FS
help
Adds support for the Ssqosid ISA extension (Supervisor-mode
Quality of Service ID).

Ssqosid defines the srmcfg CSR which allows the system to tag the
running process with an RCID (Resource Control ID) and MCID
(Monitoring Counter ID). The RCID is used to determine resource
allocation. The MCID is used to track resource usage in event
counters.

For example, a cache controller may use the RCID to apply a
cache partitioning scheme and use the MCID to track how much
cache a process, or a group of processes, is using.

config RISCV_ISA_SVPBMT
bool "Svpbmt extension support for supervisor mode page-based memory types"
depends on 64BIT && MMU
Expand Down
10 changes: 10 additions & 0 deletions arch/riscv/include/asm/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ int acpi_get_riscv_isa(struct acpi_table_header *table,

void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size,
u32 *cboz_size, u32 *cbop_size);

#ifdef CONFIG_RISCV_ISA_SSQOSID
int __init acpi_parse_rqsc(struct acpi_table_header *table);
#else
static inline int acpi_parse_rqsc(struct acpi_table_header *table)
{
return -EINVAL;
}
#endif /* CONFIG_RISCV_ISA_SSQOSID */

#else
static inline void acpi_init_rintc_map(void) { }
static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
Expand Down
6 changes: 6 additions & 0 deletions arch/riscv/include/asm/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@
#define SATP_ASID_MASK _AC(0xFFFF, UL)
#endif

/* SRMCFG fields */
#define SRMCFG_RCID_MASK _AC(0x00000FFF, UL)
#define SRMCFG_MCID_MASK _AC(0x00000FFF, UL)
#define SRMCFG_MCID_SHIFT 16

/* Exception cause high bit - is an interrupt if set */
#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))

Expand Down Expand Up @@ -328,6 +333,7 @@
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
#define CSR_SATP 0x180
#define CSR_SRMCFG 0x181

#define CSR_STIMECMP 0x14D
#define CSR_STIMECMPH 0x15D
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/include/asm/hwcap.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
#define RISCV_ISA_EXT_ZCLSD 103
#define RISCV_ISA_EXT_ZICFILP 104
#define RISCV_ISA_EXT_ZICFISS 105
#define RISCV_ISA_EXT_SSQOSID 106

#define RISCV_ISA_EXT_XLINUXENVCFG 127

Expand Down
3 changes: 3 additions & 0 deletions arch/riscv/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ struct thread_struct {
/* A forced icache flush is not needed if migrating to the previous cpu. */
unsigned int prev_cpu;
#endif
#ifdef CONFIG_RISCV_ISA_SSQOSID
u32 srmcfg;
#endif
};

/* Whitelist the fstate from the task_struct for hardened usercopy */
Expand Down
52 changes: 52 additions & 0 deletions arch/riscv/include/asm/qos.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_RISCV_QOS_H
#define _ASM_RISCV_QOS_H

#ifdef CONFIG_RISCV_ISA_SSQOSID

#include <linux/sched.h>

#include <asm/csr.h>
#include <asm/hwcap.h>

/* cached value of srmcfg csr for each cpu */
DECLARE_PER_CPU(u32, cpu_srmcfg);

/* default srmcfg value for each cpu, set via resctrl cpu assignment */
DECLARE_PER_CPU(u32, cpu_srmcfg_default);

static inline void __switch_to_srmcfg(struct task_struct *next)
{
u32 thread_srmcfg;

thread_srmcfg = READ_ONCE(next->thread.srmcfg);

/*
* Tasks in the default resource group have closid=0 and rmid=0,
* so thread.srmcfg is 0. For these tasks, use this CPU's default
* srmcfg instead. This implements resctrl rule 2: a default-group
* task running on a CPU assigned to a specific group uses that
* group's allocations.
*/
if (thread_srmcfg == 0)
thread_srmcfg = __this_cpu_read(cpu_srmcfg_default);

if (thread_srmcfg != __this_cpu_read(cpu_srmcfg)) {
__this_cpu_write(cpu_srmcfg, thread_srmcfg);
csr_write(CSR_SRMCFG, thread_srmcfg);
}
}

static __always_inline bool has_srmcfg(void)
{
return riscv_has_extension_unlikely(RISCV_ISA_EXT_SSQOSID);
}

#else /* ! CONFIG_RISCV_ISA_SSQOSID */

struct task_struct;
static __always_inline bool has_srmcfg(void) { return false; }
static inline void __switch_to_srmcfg(struct task_struct *next) { }

#endif /* CONFIG_RISCV_ISA_SSQOSID */
#endif /* _ASM_RISCV_QOS_H */
7 changes: 7 additions & 0 deletions arch/riscv/include/asm/resctrl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_RISCV_RESCTRL_H
#define _ASM_RISCV_RESCTRL_H

#include <linux/riscv_qos.h>

#endif /* _ASM_RISCV_RESCTRL_H */
3 changes: 3 additions & 0 deletions arch/riscv/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/csr.h>
#include <asm/qos.h>

#ifdef CONFIG_FPU
extern void __fstate_save(struct task_struct *save_to);
Expand Down Expand Up @@ -119,6 +120,8 @@ do { \
__switch_to_fpu(__prev, __next); \
if (has_vector() || has_xtheadvector()) \
__switch_to_vector(__prev, __next); \
if (has_srmcfg()) \
__switch_to_srmcfg(__next); \
if (switch_to_should_flush_icache(__next)) \
local_flush_icache_all(); \
__switch_to_envcfg(__next); \
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o

obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += bugs.o
obj-$(CONFIG_RISCV_USER_CFI) += usercfi.o

obj-$(CONFIG_RISCV_ISA_SSQOSID) += qos/
1 change: 1 addition & 0 deletions arch/riscv/kernel/cpufeature.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = {
__RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA),
__RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF),
__RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_exts),
__RISCV_ISA_EXT_DATA(ssqosid, RISCV_ISA_EXT_SSQOSID),
__RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC),
__RISCV_ISA_EXT_DATA(svade, RISCV_ISA_EXT_SVADE),
__RISCV_ISA_EXT_DATA_VALIDATE(svadu, RISCV_ISA_EXT_SVADU, riscv_ext_svadu_validate),
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/kernel/qos/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_RISCV_ISA_SSQOSID) += qos.o qos_resctrl.o
81 changes: 81 additions & 0 deletions arch/riscv/kernel/qos/internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _ASM_RISCV_QOS_INTERNAL_H
#define _ASM_RISCV_QOS_INTERNAL_H

#include <linux/bitfield.h>
#include <linux/resctrl.h>
#include <linux/riscv_qos.h>

#define RISCV_RESCTRL_EMPTY_CLOSID ((u32)~0)

#define CBQRI_CC_CAPABILITIES_OFF 0
#define CBQRI_CC_MON_CTL_OFF 8
#define CBQRI_CC_MON_CTL_VAL_OFF 16
#define CBQRI_CC_ALLOC_CTL_OFF 24
#define CBQRI_CC_BLOCK_MASK_OFF 32

#define CBQRI_BC_CAPABILITIES_OFF 0
#define CBQRI_BC_MON_CTL_OFF 8
#define CBQRI_BC_MON_CTR_VAL_OFF 16
#define CBQRI_BC_ALLOC_CTL_OFF 24
#define CBQRI_BC_BW_ALLOC_OFF 32

#define CBQRI_CC_CAPABILITIES_VER_MINOR_MASK GENMASK(3, 0)
#define CBQRI_CC_CAPABILITIES_VER_MAJOR_MASK GENMASK(7, 4)

#define CBQRI_CC_CAPABILITIES_NCBLKS_MASK GENMASK(23, 8)
#define CBQRI_CC_CAPABILITIES_FRCID_MASK GENMASK(24, 24)

#define CBQRI_BC_CAPABILITIES_VER_MINOR_MASK GENMASK(3, 0)
#define CBQRI_BC_CAPABILITIES_VER_MAJOR_MASK GENMASK(7, 4)

#define CBQRI_BC_CAPABILITIES_NBWBLKS_MASK GENMASK(23, 8)
#define CBQRI_BC_CAPABILITIES_MRBWB_MASK GENMASK_ULL(47, 32)

#define CBQRI_CONTROL_REGISTERS_OP_MASK GENMASK(4, 0)
#define CBQRI_CONTROL_REGISTERS_AT_MASK GENMASK(7, 5)
#define CBQRI_CONTROL_REGISTERS_AT_DATA 0
#define CBQRI_CONTROL_REGISTERS_AT_CODE 1
#define CBQRI_CONTROL_REGISTERS_RCID_MASK GENMASK(19, 8)
#define CBQRI_CONTROL_REGISTERS_STATUS_MASK GENMASK_ULL(38, 32)
#define CBQRI_CONTROL_REGISTERS_BUSY_MASK GENMASK_ULL(39, 39)
#define CBQRI_CONTROL_REGISTERS_RBWB_MASK GENMASK(15, 0)

#define CBQRI_CC_MON_CTL_OP_CONFIG_EVENT 1
#define CBQRI_CC_MON_CTL_OP_READ_COUNTER 2
#define CBQRI_CC_MON_CTL_STATUS_SUCCESS 1

#define CBQRI_CC_ALLOC_CTL_OP_CONFIG_LIMIT 1
#define CBQRI_CC_ALLOC_CTL_OP_READ_LIMIT 2
#define CBQRI_CC_ALLOC_CTL_OP_FLUSH_RCID 3
#define CBQRI_CC_ALLOC_CTL_STATUS_SUCCESS 1

#define CBQRI_BC_MON_CTL_OP_CONFIG_EVENT 1
#define CBQRI_BC_MON_CTL_OP_READ_COUNTER 2
#define CBQRI_BC_MON_CTL_STATUS_SUCCESS 1

#define CBQRI_BC_ALLOC_CTL_OP_CONFIG_LIMIT 1
#define CBQRI_BC_ALLOC_CTL_OP_READ_LIMIT 2
#define CBQRI_BC_ALLOC_CTL_STATUS_SUCCESS 1

int qos_resctrl_setup(void);
int qos_resctrl_online_cpu(unsigned int cpu);
int qos_resctrl_offline_cpu(unsigned int cpu);

struct cbqri_resctrl_res {
struct rdt_resource resctrl_res;
u32 max_rcid;
u32 max_mcid;
};

struct cbqri_resctrl_dom {
struct rdt_ctrl_domain resctrl_ctrl_dom;
struct cbqri_controller *hw_ctrl;
};

struct cbqri_config {
u64 cbm; /* capacity block mask */
u64 rbwb; /* reserved bandwidth blocks */
};

#endif /* _ASM_RISCV_QOS_INTERNAL_H */
40 changes: 40 additions & 0 deletions arch/riscv/kernel/qos/qos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/riscv_qos.h>

#include <asm/csr.h>
#include <asm/qos.h>

#include "internal.h"

/* cached value of srmcfg csr for each cpu */
DEFINE_PER_CPU(u32, cpu_srmcfg);

/* default srmcfg value for each cpu, set via resctrl cpu assignment */
DEFINE_PER_CPU(u32, cpu_srmcfg_default);

static int __init qos_arch_late_init(void)
{
int err;

if (!riscv_isa_extension_available(NULL, SSQOSID))
return -ENODEV;

err = qos_resctrl_setup();
if (err)
return err;

err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "qos:online",
qos_resctrl_online_cpu,
qos_resctrl_offline_cpu);
if (err < 0) {
resctrl_exit();
return err;
}

return 0;
}
late_initcall(qos_arch_late_init);
Loading