Commit 0c564931 authored by Wang ShaoBo's avatar Wang ShaoBo Committed by Zheng Zengkai
Browse files

arm64/mpam: Split header files into suitable location



hulk inclusion
category: feature
feature: ARM MPAM support
bugzilla: 48265
CVE: NA

--------------------------------

So far there are some declarations shared by resctrlfs.c and mpam
core module files under kernel/mpam directory scattered in mpam.h
and resctrl.h, this is organized like this:

-- asm/
   +-- resctrl.h        +
   +-- mpam.h           |    +
   +-- mpam_resource.h  |    |    +
                        |    |    |
-- fs/                  |    |    +-> mpam/
   +-- resctrlfs.c <----+----+------> +-- mpam_resctrl.c ...

We move this declarations shared by resctrlfs.c and mpam/ to resctrl.h
and split another declarations into mpam_internal.h, also including
moving mpam_resource.h to mpam/ directory, currently this is organized
like this:

-- asm/
   +-- mpam.h           +----> export to other modules(e.g. SMMU master io)
   +-- resctrl.h        +
                        |
-- mpam/                |
   +-- mpam_internal.h  |    +
   +-- mpam_resource.h  |    |    +
                        |    |    |
-- fs/                  |    +----+-> mpam/
   +-- resctrlfs.c <----+-----------> +-- mpam_resctrl.c ...

In this way can we build a clearer framework for MPAM usage.

Signed-off-by: default avatarWang ShaoBo <bobo.shaobowang@huawei.com>
Reviewed-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: default avatarCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 9d39dad1
Loading
Loading
Loading
Loading
+6 −374
Original line number Diff line number Diff line
@@ -2,381 +2,13 @@
#ifndef _ASM_ARM64_MPAM_H
#define _ASM_ARM64_MPAM_H

#include <linux/sched.h>
#include <linux/kernfs.h>
#include <linux/jump_label.h>

#include <linux/seq_buf.h>
#include <linux/seq_file.h>
#include <linux/resctrlfs.h>

/* MPAM register */
#define SYS_MPAM0_EL1			sys_reg(3, 0, 10, 5, 1)
#define SYS_MPAM1_EL1			sys_reg(3, 0, 10, 5, 0)
#define SYS_MPAM2_EL2			sys_reg(3, 4, 10, 5, 0)
#define SYS_MPAM3_EL3			sys_reg(3, 6, 10, 5, 0)
#define SYS_MPAM1_EL12			sys_reg(3, 5, 10, 5, 0)
#define SYS_MPAMHCR_EL2			sys_reg(3, 4, 10, 4, 0)
#define SYS_MPAMVPMV_EL2		sys_reg(3, 4, 10, 4, 1)
#define SYS_MPAMVPMn_EL2(n)		sys_reg(3, 4, 10, 6, n)
#define SYS_MPAMIDR_EL1			sys_reg(3, 0, 10, 4, 4)

#define MPAM_MASK(n)			((1UL << n) - 1)
/* plan to use GENMASK(n, 0) instead */

/*
 * MPAMx_ELn:
 * 15:0		PARTID_I
 * 31:16	PARTID_D
 * 39:32	PMG_I
 * 47:40	PMG_D
 * 48		TRAPMPAM1EL1
 * 49		TRAPMPAM0EL1
 * 61:49	Reserved
 * 62		TRAPLOWER
 * 63		MPAMEN
 */
#define PARTID_BITS			(16)
#define PMG_BITS			(8)
#define PARTID_MASK			MPAM_MASK(PARTID_BITS)
#define PMG_MASK			MPAM_MASK(PMG_BITS)

#define PARTID_I_SHIFT			(0)
#define PARTID_D_SHIFT			(PARTID_I_SHIFT + PARTID_BITS)
#define PMG_I_SHIFT			(PARTID_D_SHIFT + PARTID_BITS)
#define PMG_D_SHIFT			(PMG_I_SHIFT + PMG_BITS)

#define PARTID_I_MASK			(PARTID_MASK << PARTID_I_SHIFT)
#define PARTID_D_MASK			(PARTID_MASK << PARTID_D_SHIFT)
#define PARTID_I_CLR(r)			((r) & ~PARTID_I_MASK)
#define PARTID_D_CLR(r)			((r) & ~PARTID_D_MASK)
#define PARTID_CLR(r)			(PARTID_I_CLR(r) & PARTID_D_CLR(r))

#define PARTID_I_SET(r, id)		(PARTID_I_CLR(r) | ((id) << PARTID_I_SHIFT))
#define PARTID_D_SET(r, id)		(PARTID_D_CLR(r) | ((id) << PARTID_D_SHIFT))
#define PARTID_SET(r, id)		(PARTID_CLR(r) | ((id) << PARTID_I_SHIFT) | ((id) << PARTID_D_SHIFT))

#define PMG_I_MASK			(PMG_MASK << PMG_I_SHIFT)
#define PMG_D_MASK			(PMG_MASK << PMG_D_SHIFT)
#define PMG_I_CLR(r)			((r) & ~PMG_I_MASK)
#define PMG_D_CLR(r)			((r) & ~PMG_D_MASK)
#define PMG_CLR(r)			(PMG_I_CLR(r) & PMG_D_CLR(r))

#define PMG_I_SET(r, id)		(PMG_I_CLR(r) | ((id) << PMG_I_SHIFT))
#define PMG_D_SET(r, id)		(PMG_D_CLR(r) | ((id) << PMG_D_SHIFT))
#define PMG_SET(r, id)			(PMG_CLR(r) | ((id) << PMG_I_SHIFT) | ((id) << PMG_D_SHIFT))

#define TRAPMPAM1EL1_SHIFT		(PMG_D_SHIFT + PMG_BITS)
#define TRAPMPAM0EL1_SHIFT		(TRAPMPAM1EL1_SHIFT + 1)
#define TRAPLOWER_SHIFT			(TRAPMPAM0EL1_SHIFT + 13)
#define MPAMEN_SHIFT			(TRAPLOWER_SHIFT + 1)

/*
 * MPAMHCR_EL2:
 * 0		EL0_VPMEN
 * 1		EL1_VPMEN
 * 7:2		Reserved
 * 8		GSTAPP_PLK
 * 30:9		Reserved
 * 31		TRAP_MPAMIDR_EL1
 * 63:32	Reserved
 */
#define EL0_VPMEN_SHIFT			(0)
#define EL1_VPMEN_SHIFT			(EL0_VPMEN_SHIFT + 1)
#define GSTAPP_PLK_SHIFT		(8)
#define TRAP_MPAMIDR_EL1_SHIFT		(31)

/*
 * MPAMIDR_EL1:
 * 15:0		PARTID_MAX
 * 16		Reserved
 * 17		HAS_HCR
 * 20:18	VPMR_MAX
 * 31:21	Reserved
 * 39:32	PMG_MAX
 * 63:40	Reserved
 */
#define VPMR_MAX_BITS			(3)
#define PARTID_MAX_SHIFT		(0)
#define PARTID_MAX_MASK		(MPAM_MASK(PARTID_BITS) << PARTID_MAX_SHIFT)
#define HAS_HCR_SHIFT			(PARTID_MAX_SHIFT + PARTID_BITS + 1)
#define VPMR_MAX_SHIFT			(HAS_HCR_SHIFT + 1)
#define PMG_MAX_SHIFT			(VPMR_MAX_SHIFT + VPMR_MAX_BITS + 11)
#define PMG_MAX_MASK			(MPAM_MASK(PMG_BITS) << PMG_MAX_SHIFT)
#define VPMR_MASK			MPAM_MASK(VPMR_MAX_BITS)

/*
 * MPAMVPMV_EL2:
 * 31:0		VPM_V
 * 63:32	Reserved
 */
#define VPM_V_BITS			32

DECLARE_STATIC_KEY_FALSE(resctrl_enable_key);
DECLARE_STATIC_KEY_FALSE(resctrl_mon_enable_key);

extern int max_name_width, max_data_width;

enum resctrl_ctrl_type {
	SCHEMA_COMM = 0,
	SCHEMA_PRI,
	SCHEMA_HDL,
	SCHEMA_NUM_CTRL_TYPE
};

struct resctrl_ctrl_feature {
	enum resctrl_ctrl_type type;
	int        flags;
	const char *name;

	u32        max_wd;

	int        base;
	int        evt;

	int        default_ctrl;

	bool       capable;
	bool       enabled;
};

#define for_each_ctrl_type(t)	\
		for (t = SCHEMA_COMM; t != SCHEMA_NUM_CTRL_TYPE; t++)

#define for_each_extend_ctrl_type(t)	\
		for (t = SCHEMA_PRI; t != SCHEMA_NUM_CTRL_TYPE; t++)

enum resctrl_conf_type {
	CDP_BOTH = 0,
	CDP_CODE,
	CDP_DATA,
	CDP_NUM_CONF_TYPE,
};

static inline int conf_name_to_conf_type(char *name)
#ifdef CONFIG_MPAM
extern int mpam_rmid_to_partid_pmg(int rmid, int *partid, int *pmg);
#else
static inline int mpam_rmid_to_partid_pmg(int rmid, int *partid, int *pmg)
{
	enum resctrl_conf_type t;

	if (!strcmp(name, "L3CODE") || !strcmp(name, "L2CODE"))
		t = CDP_CODE;
	else if (!strcmp(name, "L3DATA") || !strcmp(name, "L2DATA"))
		t = CDP_DATA;
	else
		t = CDP_BOTH;
	return t;
	return 0;
}

#define for_each_conf_type(t) \
		for (t = CDP_BOTH; t < CDP_NUM_CONF_TYPE; t++)

typedef struct { u16 val; } hw_mpamid_t;

#define hw_closid_t hw_mpamid_t
#define hw_monid_t hw_mpamid_t
#define hw_closid_val(__x) (__x.val)
#define hw_monid_val(__x) (__x.val)

#define as_hw_t(__name, __x) \
			((hw_##__name##id_t){(__x)})
#define hw_val(__name, __x) \
			hw_##__name##id_val(__x)

/**
 * When cdp enabled, give (closid + 1) to Cache LxDATA.
 */
#define resctrl_cdp_map(__name, __closid, __type, __result)    \
do {   \
	if (__type == CDP_CODE) \
		__result = as_hw_t(__name, __closid); \
	else if (__type == CDP_DATA)     \
		__result = as_hw_t(__name, __closid + 1); \
	else    \
		__result = as_hw_t(__name, __closid); \
} while (0)

bool is_resctrl_cdp_enabled(void);

#define hw_alloc_times_validate(__times, __flag) \
do {   \
	__flag = is_resctrl_cdp_enabled();	\
	__times = flag ? 2 : 1;	\
} while (0)


/**
 * struct resctrl_staged_config - parsed configuration to be applied
 * @hw_closid:      raw closid for this configuration, regardless of CDP
 * @new_ctrl:       new ctrl value to be loaded
 * @have_new_ctrl:  did user provide new_ctrl for this domain
 * @new_ctrl_type:  CDP property of the new ctrl
 * @cdp_both_ctrl:   did cdp both control if cdp enabled
 */
struct resctrl_staged_config {
	hw_closid_t     hw_closid;
	u32             new_ctrl[SCHEMA_NUM_CTRL_TYPE];
	bool            have_new_ctrl;
	enum resctrl_conf_type  conf_type;
	enum resctrl_ctrl_type  ctrl_type;
	bool            cdp_both_ctrl;
};

/* later move to resctrl common directory */
#define RESCTRL_NAME_LEN    15

struct resctrl_schema_ctrl {
	struct list_head       list;
	char name[RESCTRL_NAME_LEN];
	enum resctrl_ctrl_type     ctrl_type;
};

/**
 * @list:   Member of resctrl's schema list
 * @name:   Name visible in the schemata file
 * @conf_type:  Type of configuration, e.g. code/data/both
 * @res:    The rdt_resource for this entry
 * @schemata_ctrl_list:   Type of ctrl configuration. e.g. priority/hardlimit
 * @cdp_mc_both:   did cdp both mon/ctrl if cdp enabled
 */
struct resctrl_schema {
	struct list_head        list;
	char                    name[RESCTRL_NAME_LEN];
	enum resctrl_conf_type      conf_type;
	struct resctrl_resource     *res;
	struct list_head        schema_ctrl_list;
	bool                cdp_mc_both;
};

extern struct list_head resctrl_all_schema;

/**
 * struct rdt_domain - group of cpus sharing an RDT resource
 * @list:	all instances of this resource
 * @id:		unique id for this instance
 * @cpu_mask:	which cpus share this resource
 * @rmid_busy_llc:
 *		bitmap of which limbo RMIDs are above threshold
 * @mbm_total:	saved state for MBM total bandwidth
 * @mbm_local:	saved state for MBM local bandwidth
 * @mbm_over:	worker to periodically read MBM h/w counters
 * @cqm_limbo:	worker to periodically read CQM h/w counters
 * @mbm_work_cpu:
 *		worker cpu for MBM h/w counters
 * @cqm_work_cpu:
 *		worker cpu for CQM h/w counters
 * @ctrl_val:	array of cache or mem ctrl values (indexed by CLOSID)
 * @new_ctrl:	new ctrl value to be loaded
 * @have_new_ctrl: did user provide new_ctrl for this domain
 */
struct rdt_domain {
	struct list_head	list;
	int			id;
	struct cpumask		cpu_mask;
	void __iomem		*base;

	/* arch specific fields */
	u32			*ctrl_val[SCHEMA_NUM_CTRL_TYPE];
	bool			have_new_ctrl;

	/* for debug */
	char			*cpus_list;

	struct resctrl_staged_config staged_cfg[CDP_NUM_CONF_TYPE];
};

#define RESCTRL_SHOW_DOM_MAX_NUM 8

int __init resctrl_group_init(void);

int resctrl_group_mondata_show(struct seq_file *m, void *arg);
void rmdir_mondata_subdir_allrdtgrp(struct resctrl_resource *r,
				    unsigned int dom_id);

int cdp_enable(int level, int data_type, int code_type);

void post_resctrl_mount(void);

#define mpam_read_sysreg_s(reg, name) read_sysreg_s(reg)
#define mpam_write_sysreg_s(v, r, n) write_sysreg_s(v, r)
#define mpam_readl(addr) readl(addr)
#define mpam_writel(v, addr) writel(v, addr)

struct sd_closid;

struct msr_param {
	enum resctrl_ctrl_type type;
	struct sd_closid *closid;
};

/**
 * struct resctrl_resource - attributes of an RDT resource
 * @rid:		The index of the resource
 * @alloc_enabled:	Is allocation enabled on this machine
 * @mon_enabled:		Is monitoring enabled for this feature
 * @alloc_capable:	Is allocation available on this machine
 * @mon_capable:		Is monitor feature available on this machine
 * @name:		Name to use in "schemata" file
 * @num_closid:		Number of CLOSIDs available
 * @cache_level:	Which cache level defines scope of this resource
 * @msr_base:		Base MSR address for CBMs
 * @msr_update:		Function pointer to update QOS MSRs
 * @data_width:		Character width of data when displaying
 * @domains:		All domains for this resource
 * @cache:		Cache allocation related data
 * @format_str:		Per resource format string to show domain value
 * @parse_ctrlval:	Per resource function pointer to parse control values
 * @evt_list:			List of monitoring events
 * @num_rmid:			Number of RMIDs available
 * @mon_scale:			cqm counter * mon_scale = occupancy in bytes
 * @fflags:			flags to choose base and info files
 */

struct raw_resctrl_resource {
	u16                 num_partid;
	u16                 num_intpartid;
	u16                 num_pmg;

	void (*msr_update)(struct resctrl_resource *r, struct rdt_domain *d,
				struct msr_param *para);
	u64 (*msr_read)(struct resctrl_resource *r, struct rdt_domain *d,
				struct msr_param *para);

	int			data_width;
	const char		*format_str;
	int (*parse_ctrlval)(char *buf, struct resctrl_resource *r,
				struct resctrl_staged_config *cfg,
				enum resctrl_ctrl_type ctrl_type);

	u16                num_mon;
	u64 (*mon_read)(struct rdt_domain *d, void *md_priv);
	int (*mon_write)(struct rdt_domain *d, void *md_priv);

	struct resctrl_ctrl_feature ctrl_features[SCHEMA_NUM_CTRL_TYPE];

	unsigned long       fflags;
};

/* 64bit arm64 specified */
union mon_data_bits {
	void *priv;
	struct {
		u8	rid;
		u8	domid;
		u8	partid;
		u8	pmg;
		u8	mon;
		u8	cdp_both_mon;
	} u;
};

ssize_t resctrl_group_schemata_write(struct kernfs_open_file *of,
				char *buf, size_t nbytes, loff_t off);

int resctrl_group_schemata_show(struct kernfs_open_file *of,
				struct seq_file *s, void *v);

struct rdt_domain *mpam_find_domain(struct resctrl_resource *r, int id,
		struct list_head **pos);

extern int mpam_rmid_to_partid_pmg(int rmid, int *partid, int *pmg);
#endif

#endif /* _ASM_ARM64_MPAM_H */
+317 −16
Original line number Diff line number Diff line
#ifndef _ASM_ARM64_RESCTRL_H
#define _ASM_ARM64_RESCTRL_H

#include <linux/resctrlfs.h>
#include <asm/mpam_sched.h>
#include <asm/mpam.h>

#if defined(CONFIG_RESCTRL) && defined(CONFIG_MPAM)

#define resctrl_group rdtgroup
#define resctrl_alloc_capable rdt_alloc_capable
#define resctrl_mon_capable rdt_mon_capable
@@ -40,13 +43,81 @@ enum rdt_group_type {
	RDT_NUM_GROUP,
};

/**
 * struct resctrl_cache - Cache allocation related data
 * @cbm_len:        Length of the cache bit mask
 * @min_cbm_bits:   Minimum number of consecutive bits to be set
 * @shareable_bits: Bitmask of shareable resource with other
 *          executing entities
 */
struct resctrl_cache {
	u32     cbm_len;
	u32     shareable_bits;
	u32     min_cbm_bits;
};

/**
 * struct resctrl_membw - Memory bandwidth allocation related data
 * @min_bw:     Minimum memory bandwidth percentage user can request
 * @bw_gran:        Granularity at which the memory bandwidth is allocated
 * @delay_linear:   True if memory B/W delay is in linear scale
 * @ctrl_extend_bits: Indicates if there are extra ctrl capabilities supported.
 *          e.g. priority/hardlimit.
 */
struct resctrl_membw {
	u32     min_bw;
	u32     bw_gran;
	u32     delay_linear;
};

/**
 * struct resctrl_resource - attributes of an RDT resource
 * @rid:		The index of the resource
 * @alloc_enabled:		Is allocation enabled on this machine
 * @mon_enabled:		Is monitoring enabled for this feature
 * @alloc_capable:		Is allocation available on this machine
 * @mon_capable:		Is monitor feature available on this machine
 * @name:		Name to use in "schemata" file
 * @domains:	All domains for this resource
 * @cache:		Cache allocation related data
 * @mbw:		Memory Bandwidth allocation related data
 * @evt_list:	List of monitoring events
 * @fflags:		flags to choose base and info files
 */
struct resctrl_resource {
	int             rid;
	bool            alloc_enabled;
	bool            mon_enabled;
	bool            alloc_capable;
	bool            mon_capable;
	char            *name;
	struct list_head    domains;
	u32             dom_num;
	struct list_head    evt_list;
	unsigned long   fflags;

	struct resctrl_cache cache;
	struct resctrl_membw mbw;

	bool            cdp_capable;
	bool            cdp_enable;
	u32             *default_ctrl;

	u32             ctrl_extend_bits;

	void            *res;
};

/* List of all resource groups */
extern struct list_head resctrl_all_groups;

/**
 * struct mongroup - store mon group's data in resctrl fs.
 * @mon_data_kn     kernlfs node for the mon_data directory
 * @parent:         parent rdtgrp
 * @crdtgrp_list:       child rdtgroup node list
 * @rmid:           rmid for this rdtgroup
 * @mon:            monnitor id
 * @init:           init flag
 */
struct mongroup {
	struct kernfs_node  *mon_data_kn;
@@ -59,7 +130,7 @@ struct mongroup {
/**
 * struct sd_closid - software defined closid
 * @intpartid:  closid for this rdtgroup only for allocation
 * @weak_closid:    closid for synchronizing configuration and monitoring
 * @reqpartid:  closid for synchronizing configuration and monitoring
 */
struct sd_closid {
	u32         intpartid;
@@ -70,6 +141,7 @@ struct sd_closid {
 * struct rdtgroup - store rdtgroup's data in resctrl file system.
 * @kn:             kernfs node
 * @resctrl_group_list:     linked list for all rdtgroups
 * @closid:             software defined closid
 * @cpu_mask:           CPUs assigned to this rdtgroup
 * @flags:          status bits
 * @waitcount:          how many cpus expect to find this
@@ -89,11 +161,214 @@ struct rdtgroup {
	struct mongroup     mon;
};

enum resctrl_ctrl_type {
	SCHEMA_COMM = 0,
	SCHEMA_PRI,
	SCHEMA_HDL,
	SCHEMA_NUM_CTRL_TYPE
};

#define for_each_ctrl_type(t)	\
		for (t = SCHEMA_COMM; t != SCHEMA_NUM_CTRL_TYPE; t++)

#define for_each_extend_ctrl_type(t)	\
		for (t = SCHEMA_PRI; t != SCHEMA_NUM_CTRL_TYPE; t++)

/**
 * struct resctrl_ctrl_feature - ctrl feature member live in schema list
 * @flags:    Does what ctrl types can this feature server for
 * @name:     Name of this ctrl feature
 * @max_wd:   Max width of this feature can be input from outter space
 * @base:     Base of integer from outter space
 * @evt:      rdt_event_id event owned for applying configuration
 * @capable:  Does this feature support
 * @enabled:  Enabled or not.
 * @default_ctrl:  Default ctrl value of this feature
 */
struct resctrl_ctrl_feature {
	enum resctrl_ctrl_type type;
	int        flags;
	const char *name;
	u32        max_wd;
	int        base;
	enum rdt_event_id   evt;
	int        default_ctrl;
	bool       capable;
	bool       enabled;
};

struct msr_param {
	enum resctrl_ctrl_type type;
	struct sd_closid *closid;
};

enum resctrl_conf_type {
	CDP_BOTH = 0,
	CDP_CODE,
	CDP_DATA,
	CDP_NUM_CONF_TYPE,
};

static inline int conf_name_to_conf_type(char *name)
{
	enum resctrl_conf_type t;

	if (!strcmp(name, "L3CODE") || !strcmp(name, "L2CODE"))
		t = CDP_CODE;
	else if (!strcmp(name, "L3DATA") || !strcmp(name, "L2DATA"))
		t = CDP_DATA;
	else
		t = CDP_BOTH;
	return t;
}

#define for_each_conf_type(t) \
		for (t = CDP_BOTH; t < CDP_NUM_CONF_TYPE; t++)

typedef struct { u16 val; } hw_def_t;

#define hw_closid_t hw_def_t
#define hw_monid_t hw_def_t
#define hw_closid_val(__x) (__x.val)
#define hw_monid_val(__x) (__x.val)

#define as_hw_t(__name, __x) \
			((hw_##__name##id_t){(__x)})
#define hw_val(__name, __x) \
			hw_##__name##id_val(__x)

/**
 * When cdp enabled, give (closid + 1) to Cache LxDATA.
 */
#define resctrl_cdp_map(__name, __closid, __type, __result)    \
do {   \
	if (__type == CDP_CODE) \
		__result = as_hw_t(__name, __closid); \
	else if (__type == CDP_DATA)     \
		__result = as_hw_t(__name, __closid + 1); \
	else    \
		__result = as_hw_t(__name, __closid); \
} while (0)

bool is_resctrl_cdp_enabled(void);

#define hw_alloc_validate(__flag) \
do {   \
	if (is_resctrl_cdp_enabled()) \
		__flag = true;  \
	else    \
		__flag = false; \
} while (0)

#define hw_alloc_times_validate(__times, __flag) \
do {   \
	hw_alloc_validate(__flag); \
	if (__flag) \
		__times = 2;    \
	else    \
		__times = 1;    \
} while (0)

/**
 * struct resctrl_staged_config - parsed configuration to be applied
 * @hw_closid:      raw closid for this configuration, regardless of CDP
 * @new_ctrl:       new ctrl value to be loaded
 * @have_new_ctrl:  did user provide new_ctrl for this domain
 * @new_ctrl_type:  CDP property of the new ctrl
 * @cdp_both_ctrl:   did cdp both control if cdp enabled
 */
struct resctrl_staged_config {
	hw_closid_t     hw_closid;
	u32             new_ctrl[SCHEMA_NUM_CTRL_TYPE];
	bool            have_new_ctrl;
	enum resctrl_conf_type  conf_type;
	enum resctrl_ctrl_type  ctrl_type;
	bool            cdp_both_ctrl;
};

/* later move to resctrl common directory */
#define RESCTRL_NAME_LEN    15

struct resctrl_schema_ctrl {
	struct list_head       list;
	char name[RESCTRL_NAME_LEN];
	enum resctrl_ctrl_type     ctrl_type;
};

/**
 * @list:   Member of resctrl's schema list
 * @name:   Name visible in the schemata file
 * @conf_type:  Type of configuration, e.g. code/data/both
 * @res:    The rdt_resource for this entry
 * @schemata_ctrl_list:   Type of ctrl configuration. e.g. priority/hardlimit
 * @cdp_mc_both:   did cdp both mon/ctrl if cdp enabled
 */
struct resctrl_schema {
	struct list_head        list;
	char                name[RESCTRL_NAME_LEN];
	enum resctrl_conf_type      conf_type;
	struct resctrl_resource     *res;
	struct list_head        schema_ctrl_list;
	bool                cdp_mc_both;
};

int schemata_list_init(void);

void schemata_list_destroy(void);

int resctrl_lru_request_mon(void);
/**
 * struct rdt_domain - group of cpus sharing an RDT resource
 * @list:	all instances of this resource
 * @id:		unique id for this instance
 * @cpu_mask:	which cpus share this resource
 * @base        MMIO base address
 * @ctrl_val:	array of cache or mem ctrl values (indexed by CLOSID)
 * @have_new_ctrl: did user provide new_ctrl for this domain
 */
struct rdt_domain {
	struct list_head	list;
	int			id;
	struct cpumask		cpu_mask;
	void __iomem		*base;

	/* arch specific fields */
	u32			*ctrl_val[SCHEMA_NUM_CTRL_TYPE];
	bool			have_new_ctrl;

	/* for debug */
	char			*cpus_list;

	struct resctrl_staged_config staged_cfg[CDP_NUM_CONF_TYPE];
};

/*
 * Internal struct of resctrl_resource structure,
 * for static initialization.
 */
struct raw_resctrl_resource {
	u16		num_partid;
	u16		num_intpartid;
	u16		num_pmg;

	u16		extend_ctrls_wd[SCHEMA_NUM_CTRL_TYPE];

	void (*msr_update)(struct resctrl_resource *r, struct rdt_domain *d,
					struct msr_param *para);
	u64 (*msr_read)(struct resctrl_resource *r, struct rdt_domain *d,
					struct msr_param *para);

	int			data_width;
	const char		*format_str;
	int (*parse_ctrlval)(char *buf, struct resctrl_resource *r,
			struct resctrl_staged_config *cfg, enum resctrl_ctrl_type ctrl_type);

	u16			num_mon;
	u64 (*mon_read)(struct rdt_domain *d, void *md_priv);
	int (*mon_write)(struct rdt_domain *d, void *md_priv);
	unsigned long       fflags;

	struct resctrl_ctrl_feature ctrl_features[SCHEMA_NUM_CTRL_TYPE];
};

int rmid_alloc(int entry_idx);
void rmid_free(int rmid);
@@ -103,7 +378,8 @@ int closid_alloc(void);
void closid_free(int closid);

void update_cpu_closid_rmid(void *info);
void update_closid_rmid(const struct cpumask *cpu_mask, struct resctrl_group *r);
void update_closid_rmid(const struct cpumask *cpu_mask,
				struct resctrl_group *r);
int __resctrl_group_move_task(struct task_struct *tsk,
				struct resctrl_group *rdtgrp);

@@ -117,18 +393,11 @@ void rdt_last_cmd_clear(void);
void rdt_last_cmd_puts(const char *s);
void rdt_last_cmd_printf(const char *fmt, ...);

extern struct mutex resctrl_group_mutex;

void release_rdtgroupfs_options(void);
int parse_rdtgroupfs_options(char *data);

void resctrl_resource_reset(void);

#define release_resctrl_group_fs_options release_rdtgroupfs_options
#define parse_resctrl_group_fs_options parse_rdtgroupfs_options

int mpam_get_mon_config(struct resctrl_resource *r);

int resctrl_group_init_alloc(struct rdtgroup *rdtgrp);

static inline int __resctrl_group_show_options(struct seq_file *seq)
@@ -136,15 +405,46 @@ static inline int __resctrl_group_show_options(struct seq_file *seq)
	return 0;
}

int resctrl_update_groups_config(struct rdtgroup *rdtgrp);

#define RESCTRL_MAX_CLOSID 32

int __init resctrl_group_init(void);

void post_resctrl_mount(void);

extern struct mutex resctrl_group_mutex;
DECLARE_STATIC_KEY_FALSE(resctrl_alloc_enable_key);
extern struct rdtgroup resctrl_group_default;
int resctrl_mkdir_mondata_all_subdir(struct kernfs_node *parent_kn,
		struct resctrl_group *prgrp);

struct resctrl_resource *
mpam_resctrl_get_resource(enum resctrl_resource_level level);
int resctrl_group_create_info_dir(struct kernfs_node *parent_kn,
		struct kernfs_node **kn_info);

int resctrl_update_groups_config(struct rdtgroup *rdtgrp);
int register_resctrl_specific_files(struct rftype *files, size_t len);
extern struct kernfs_ops resctrl_group_kf_single_ops;

#define RESCTRL_MAX_CLOSID 32
extern struct rdtgroup *resctrl_group_kn_lock_live(struct kernfs_node *kn);
void resctrl_group_kn_unlock(struct kernfs_node *kn);

void release_rdtgroupfs_options(void);
int parse_rdtgroupfs_options(char *data);

int resctrl_group_add_files(struct kernfs_node *kn, unsigned long fflags);

#define RESCTRL_MAX_CBM 32

struct resctrl_fs_context {
	struct kernfs_fs_context        kfc;
};

static inline struct resctrl_fs_context *resctrl_fc2context(struct fs_context *fc)
{
	struct kernfs_fs_context *kfc = fc->fs_private;

	return container_of(kfc, struct resctrl_fs_context, kfc);
}

/*
 * This is only for avoiding unnecessary cost in mpam_sched_in()
@@ -178,4 +478,5 @@ static inline u32 resctrl_navie_closid(struct sd_closid closid)
	return closid.intpartid;
}

#endif
#endif /* _ASM_ARM64_RESCTRL_H */
+95 −1

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@
#include <linux/cpu.h>
#include <linux/cacheinfo.h>
#include <linux/arm_mpam.h>
#include <asm/mpam_resource.h>

#include "mpam_resource.h"
#include "mpam_device.h"
#include "mpam_internal.h"

+140 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading