Skip to contentSkip to conversation

x86/resctrl : Support AMD Assignable Bandwidth Monitoring Counters (ABMC)

PATCH Superseded Babu Moger 4 participants 66 messages May 24, 2024 – Jun 27, 2024

Subsystems (3)

v4 of 18 Superseded Latest is v18 →

lore
Share & tools
lore

Babu Moger

author reviewer
#0 lore raw

v4 cover x86/resctrl : Support AMD Assignable Bandwidth Monitoring Counters (ABMC)

This series adds the support for Assignable Bandwidth Monitoring Counters (ABMC). It is also called QoS RMID Pinning feature

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC). The documentation is available at

The patches are based on top of commit
commit 573c35550b2b ("Merge branch into tip/master: 'x86/percpu'")

# Introduction

Users can create as many monitor groups as RMIDs supported by the hardware. However, bandwidth monitoring feature on AMD system only guarantees that RMIDs currently assigned to a processor will be tracked by hardware. The counters of any other RMIDs which are no longer being tracked will be reset to zero. The MBM event counters return "Unavailable" for the RMIDs that are not tracked by hardware. So, there can be only limited number of groups that can give guaranteed monitoring numbers. With ever changing configurations there is no way to definitely know which of these groups are being tracked for certain point of time. Users do not have the option to monitor a group or set of groups for certain period of time without worrying about RMID being reset in between.

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. The assigned RMID will be tracked by the hardware until the user unassigns it manually. There is no need to worry about counters being reset during this period. Additionally, the user can specify a bitmask identifying the specific bandwidth types from the given source to track with the counter.

Without ABMC enabled, monitoring will work in current mode without assignment option.

# Linux Implementation

Linux resctrl subsystem provides the interface to count maximum of two memory bandwidth events per group, from a combination of available total and local events. Keeping the current interface, users can enable a maximum of 2 ABMC counters per group. User will also have the option to enable only one counter to the group. If the system runs out of assignable ABMC counters, kernel will display an error. Users need to disable an already enabled counter to make space for new assignments.

# Examples

a. Check if ABMC support is available
#mount -t resctrl resctrl /sys/fs/resctrl/

#cat /sys/fs/resctrl/info/L3_MON/mbm_assign [abmc]
mbm_legacy

Linux kernel detected ABMC feature and it is enabled.

b. Check how many ABMC counters are available.

	#cat /sys/fs/resctrl/info/L3_MON/num_cntrs 
	32

c. Create few resctrl groups.

	# mkdir /sys/fs/resctrl/mon_groups/child_default_mon_grp
	# mkdir /sys/fs/resctrl/non_default_ctrl_mon_grp
	# mkdir /sys/fs/resctrl/non_default_ctrl_mon_grp/mon_groups/child_non_default_mon_grp

d. This series adds a new interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control
to list and modify the group's assignment states.

The list follows the following format:

"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

Format for specific type of groups:

* Default CTRL_MON group:
"//<domain_id>=<assignment_flags>"

* Non-default CTRL_MON group:
"<CTRL_MON group>//<domain_id>=<assignment_flags>"

* Child MON group of default CTRL_MON group:
"/<MON group>/<domain_id>=<assignment_flags>"

* Child MON group of non-default CTRL_MON group:
"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

Assignment flags can be one of the following:

t MBM total event is enabled
l MBM local event is enabled
tl Both total and local MBM events are enabled _ None of the MBM events are enabled

Examples:

# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control non_default_ctrl_mon_grp//0=tl;1=tl; non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl; //0=tl;1=tl;
/child_default_mon_grp/0=tl;1=tl;

There are four groups and all the groups have local and total event enabled on domain 0 and 1.

=tl means both total and local events are enabled.

"//" - This is a default CONTROL MON group

"non_default_ctrl_mon_grp//" - This is non default CONTROL MON group

"/child_default_mon_grp/" - This is Child MON group of the defult group

"non_default_ctrl_mon_grp/child_non_default_mon_grp/" - This is child MON group of the non default group

e. Update the group assignment states using the interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control.

	The write format is similar to the above list format with addition of
	op-code for the assignment operation.
	
	* Default CTRL_MON group:
	        "//<domain_id><op-code><assignment_flags>"
	
	* Non-default CTRL_MON group:
	        "<CTRL_MON group>//<domain_id><op-code><assignment_flags>"
	
	* Child MON group of default CTRL_MON group:
	        "/<MON group>/<domain_id><op-code><assignment_flags>"
	
	* Child MON group of non-default CTRL_MON group:
	        "<CTRL_MON group>/<MON group>/<domain_id><op-code><assignment_flags>"
	
	Op-code can be one of the following:
	
	= Update the assignment to match the flags
	+ Assign a new state
	- Unassign a new state
	
	
	Initial group status:
	
	# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	non_default_ctrl_mon_grp//0=tl;1=tl;
	non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	//0=tl;1=tl;
	/child_default_mon_grp/0=tl;1=tl;
	
	 To update the default group to enable only total event on domain 0:
	 # echo "//0=t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	 //0=t;1=tl;
	 /child_default_mon_grp/0=tl;1=tl;
	
	 To update the MON group child_default_mon_grp to remove total event on domain 1:
	 # echo "/child_default_mon_grp/1-t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 $ cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	 //0=t;1=l;
	 /child_default_mon_grp/0=t;1=tl;
	
	 To update the MON group non_default_ctrl_mon_grp/child_non_default_mon_grp to
	 remove both local and total events on domain 1:
	 # echo "non_default_ctrl_mon_grp/child_non_default_mon_grp/1=_" >
	               /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
	 //0=t;1=l;
	 /child_default_mon_grp/0=t;1=tl;
	
	 To update the default group to add a total event domain 1.
	 # echo "//1+t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
	 //0=t;1=tl;
	 /child_default_mon_grp/0=t;1=tl;

f. Read the event mbm_total_bytes and mbm_local_bytes of the default group.
There is no change in reading the evetns with ABMC. If the event is unassigned when reading, then the read will come back as Unavailable.

	# cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes
	779247936
	# cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_local_bytes 
	765207488

g. Users will have the option to go back to legacy_mbm mode if required.
This can be done using the following command.

	# echo "legacy_mbm" > /sys/fs/resctrl/info/L3_MON/mbm_assign
	# cat /sys/fs/resctrl/info/L3_MON/mbm_assign
        abmc
        [mbm_legacy]

h. Check the bandwidth configuration for the group. Note that bandwidth
configuration has a domain scope. Total event defaults to 0x7F (to count all the events) and local event defaults to 0x15 (to count all the local numa events). The event bitmap decoding is available at
https://www.kernel.org/doc/Documentation/x86/resctrl.rst
in section "mbm_total_bytes_config", "mbm_local_bytes_config":

	#cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config 
	0=0x7f;1=0x7f
	
	#cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config 
	0=0x15;1=0x15

j. Change the bandwidth source for domain 0 for the total event to count only reads.
Note that this change effects total events on the domain 0.

	#echo 0=0x33 > /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config 
	#cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config 
	0=0x33;1=0x7F

k. Now read the total event again. The mbm_total_bytes should display
only the read events.

	#cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes
	314101

l. Unmount the resctrl

#umount /sys/fs/resctrl/

---
v4:
Main change is domain specific event assignment.
Kept the ABMC feature as a default.
Dynamcic switching between ABMC and mbm_legacy is still allowed. We are still not clear about mount option.
Moved the monitoring related data in resctrl_mon structure from rdt_resource. Fixed the display of legacy and ABMC mode.
Used bimap APIs when possible.
Removed event configuration read from MSRs. We can use the internal saved data.(patch 12)
Added more comments about L3_QOS_ABMC_CFG MSR.
Added IPIs to read the assignment status for each domain (patch 18 and 19) More details in each patch.

v3:
This series adds the support for global assignment mode discussed in the thread. https://lore.kernel.org/lkml/[email protected]/
Removed the individual assignment mode and included the global assignment interface. Added following interface files.
a. /sys/fs/resctrl/info/L3_MON/mbm_assign
Used for displaying the current assignment mode and switch between ABMC and legacy mode.
b. /sys/fs/resctrl/info/L3_MON/mbm_assign_control
Used for lising the groups assignment mode and modify the assignment states.
c. Most of the changes are related to the new interface.
d. Addressed the comments from Reinette, James and Peter.
e. Hope I have addressed most of the major feedbacks discussed. If I missed
something then it is not intentional. Please feel free to comment.
f. Sending this as an RFC as per Reinette's comment. So, this is still open
for discussion.

v2:
a. Major change is the way ABMC is enabled. Earlier, user needed to remount
with -o abmc to enable ABMC feature. Removed that option now.
Now users can enable ABMC by "$echo 1 to /sys/fs/resctrl/info/L3_MON/mbm_assign_enable".

b. Added new word 21 to x86/cpufeatures.h.

c. Display unsupported if user attempts to read the events when ABMC is enabled
and event is not assigned.

d. Display monitor_state as "Unsupported" when ABMC is disabled.

e. Text updates and rebase to latest tip tree (as of Jan 18).

f. This series is still work in progress. I am yet to hear from ARM developers.

v4:
https://lore.kernel.org/lkml/[email protected]/

v2:
https://lore.kernel.org/lkml/[email protected]/

v1 :
https://lore.kernel.org/lkml/[email protected]/

Babu Moger (17):
x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters

    (ABMC)

x86/resctrl: Add ABMC feature in the command line options x86/resctrl: Detect Assignable Bandwidth Monitoring feature details x86/resctrl: Introduce resctrl_file_fflags_init x86/resctrl: Introduce the interface to display the assignment state x86/resctrl: Introduce interface to display number of ABMC counters x86/resctrl: Add support to enable/disable ABMC feature x86/resctrl: Initialize assignable counters bitmap x86/resctrl: Introduce assign state for the mon group x86/resctrl: Add data structures for ABMC assignment x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg x86/resctrl: Add the functionality to assign the RMID x86/resctrl: Add the functionality to unassign the RMID x86/resctrl: Enable ABMC by default on resctrl mount x86/resctrl: Introduce the interface switch between ABMC and
legacy_mbm
x86/resctrl: Introduce interface to list assignment states of all the
groups
x86/resctrl: Introduce interface to modify assignment states of the
groups

 .../admin-guide/kernel-parameters.txt         |   2 +-
 Documentation/arch/x86/resctrl.rst            | 144 ++++
 arch/x86/include/asm/cpufeatures.h            |   1 +
 arch/x86/include/asm/msr-index.h              |   2 +
 arch/x86/kernel/cpu/cpuid-deps.c              |   3 +
 arch/x86/kernel/cpu/resctrl/core.c            |  25 +-
 arch/x86/kernel/cpu/resctrl/internal.h        |  56 +-
 arch/x86/kernel/cpu/resctrl/monitor.c         |  24 +-
 arch/x86/kernel/cpu/resctrl/rdtgroup.c        | 714 +++++++++++++++++-
 arch/x86/kernel/cpu/scattered.c               |   1 +
 include/linux/resctrl.h                       |  12 +
 11 files changed, 964 insertions(+), 20 deletions(-)
Signature · 84 lines
2.34.1


Babu Moger (17):
  x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters
    (ABMC)
  x86/resctrl: Add ABMC feature in the command line options
  x86/resctrl: Detect Assignable Bandwidth Monitoring feature details
  x86/resctrl: Introduce resctrl_file_fflags_init
  x86/resctrl: Introduce the interface to display the assignment state
  x86/resctrl: Introduce interface to display number of ABMC counters
  x86/resctrl: Add support to enable/disable ABMC feature
  x86/resctrl: Initialize assignable counters bitmap
  x86/resctrl: Introduce assign state for the mon group
  x86/resctrl: Add data structures for ABMC assignment
  x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg
  x86/resctrl: Add the functionality to assign the RMID
  x86/resctrl: Add the functionality to unassign the RMID
  x86/resctrl: Enable ABMC by default on resctrl mount
  x86/resctrl: Introduce the interface switch between ABMC and
    legacy_mbm
  x86/resctrl: Introduce interface to list assignment states of all the
    groups
  x86/resctrl: Introduce interface to modify assignment states of the
    groups

 .../admin-guide/kernel-parameters.txt         |   2 +-
 Documentation/arch/x86/resctrl.rst            | 144 ++++
 arch/x86/include/asm/cpufeatures.h            |   1 +
 arch/x86/include/asm/msr-index.h              |   2 +
 arch/x86/kernel/cpu/cpuid-deps.c              |   3 +
 arch/x86/kernel/cpu/resctrl/core.c            |  25 +-
 arch/x86/kernel/cpu/resctrl/internal.h        |  56 +-
 arch/x86/kernel/cpu/resctrl/monitor.c         |  24 +-
 arch/x86/kernel/cpu/resctrl/rdtgroup.c        | 714 +++++++++++++++++-
 arch/x86/kernel/cpu/scattered.c               |   1 +
 include/linux/resctrl.h                       |  12 +
 11 files changed, 964 insertions(+), 20 deletions(-)

-- 
2.34.1



Babu Moger (19):
  x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters
    (ABMC)
  x86/resctrl: Add ABMC feature in the command line options
  x86/resctrl: Consolidate monitoring related data from rdt_resource
  x86/resctrl: Detect Assignable Bandwidth Monitoring feature details
  x86/resctrl: Introduce resctrl_file_fflags_init to initialize fflags
  x86/resctrl: Introduce interface to display number of ABMC counters
  x86/resctrl: Add support to enable/disable ABMC feature
  x86/resctrl: Introduce the interface to display monitor mode
  x86/resctrl: Initialize ABMC counters bitmap
  x86/resctrl: Introduce ABMC state for the monitor group
  x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg
  x86/resctrl: Remove MSR reading of event configuration value
  x86/resctrl: Add data structures for ABMC assignment
  x86/resctrl: Add the interface to assign ABMC counter
  x86/resctrl: Add the interface to unassign ABMC counter
  x86/resctrl: Enable ABMC by default on resctrl mount
  x86/resctrl: Introduce the interface switch between ABMC and
    mbm_legacy
  x86/resctrl: Introduce interface to list monitor states of all the
    groups
  x86/resctrl: Introduce interface to modify assignment states of the
    groups

 .../admin-guide/kernel-parameters.txt         |   2 +-
 Documentation/arch/x86/resctrl.rst            | 161 ++++
 arch/x86/include/asm/cpufeatures.h            |   1 +
 arch/x86/include/asm/msr-index.h              |   3 +
 arch/x86/kernel/cpu/cpuid-deps.c              |   3 +
 arch/x86/kernel/cpu/resctrl/core.c            |  10 +-
 arch/x86/kernel/cpu/resctrl/internal.h        |  61 +-
 arch/x86/kernel/cpu/resctrl/monitor.c         |  60 +-
 arch/x86/kernel/cpu/resctrl/rdtgroup.c        | 830 +++++++++++++++++-
 arch/x86/kernel/cpu/scattered.c               |   1 +
 include/linux/resctrl.h                       |  20 +-
 11 files changed, 1086 insertions(+), 66 deletions(-)

-- 
2.34.1
author reviewer
#1 lore raw

PATCH v4 1/19 x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters (ABMC)

Users can create as many monitor groups as RMIDs supported by the hardware. However, bandwidth monitoring feature on AMD system only guarantees that RMIDs currently assigned to a processor will be tracked by hardware. The counters of any other RMIDs which are no longer being tracked will be reset to zero. The MBM event counters return "Unavailable" for the RMIDs that are not tracked by hardware. So, there can be only limited number of groups that can give guaranteed monitoring numbers. With ever changing configurations there is no way to definitely know which of these groups are being tracked for certain point of time. Users do not have the option to monitor a group or set of groups for certain period of time without worrying about RMID being reset in between.

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. The assigned RMID will be tracked by the hardware until the user unassigns it manually. There is no need to worry about counters being reset during this period. Additionally, the user can specify a bitmask identifying the specific bandwidth types from the given source to track with the counter.

Without ABMC enabled, monitoring will work in current mode without assignment option.

Linux resctrl subsystem provides the interface to count maximum of two memory bandwidth events per group, from a combination of available total and local events. Keeping the current interface, users can enable a maximum of 2 ABMC counters per group. User will also have the option to enable only one counter to the group. If the system runs out of assignable ABMC counters, kernel will display an error. Users need to disable an already enabled counter to make space for new assignments.

The feature can be detected via CPUID_Fn80000020_EBX_x00 bit 5. Bits Description
5 ABMC (Assignable Bandwidth Monitoring Counters)

The feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

Note: Checkpatch checks/warnings are ignored to maintain coding style.

---
v4: Changes because of rebase. Feature word 21 has few more additions now.
Changed the text to "tracked by hardware" instead of active.

v3: Change because of rebase. Actual patch did not change.

v2: Added dependency on X86_FEATURE_BMEC.

---
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/kernel/cpu/cpuid-deps.c   | 3 +++
 arch/x86/kernel/cpu/scattered.c    | 1 +
 3 files changed, 5 insertions(+)
arch/x86/include/asm/cpufeatures.h +1 -0
index 3c7434329661..fbe118fa7f88 100644
@@ -470,6 +470,7 @@
 #define X86_FEATURE_BHI_CTRL		(21*32+ 2) /* "" BHI_DIS_S HW control available */
 #define X86_FEATURE_CLEAR_BHB_HW	(21*32+ 3) /* "" BHI_DIS_S HW control enabled */
 #define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */
+#define X86_FEATURE_ABMC		(21*32+ 5) /* "" Assignable Bandwidth Monitoring Counters */
 
 /*
  * BUG word(s)
arch/x86/kernel/cpu/cpuid-deps.c +3 -0
index b7d9f530ae16..5227a6232e9e 100644
@@ -70,6 +70,9 @@ static const struct cpuid_dep cpuid_deps[] = {
 	{ X86_FEATURE_CQM_MBM_LOCAL,		X86_FEATURE_CQM_LLC   },
 	{ X86_FEATURE_BMEC,			X86_FEATURE_CQM_MBM_TOTAL   },
 	{ X86_FEATURE_BMEC,			X86_FEATURE_CQM_MBM_LOCAL   },
+	{ X86_FEATURE_ABMC,			X86_FEATURE_CQM_MBM_TOTAL   },
+	{ X86_FEATURE_ABMC,			X86_FEATURE_CQM_MBM_LOCAL   },
+	{ X86_FEATURE_ABMC,			X86_FEATURE_BMEC      },
 	{ X86_FEATURE_AVX512_BF16,		X86_FEATURE_AVX512VL  },
 	{ X86_FEATURE_AVX512_FP16,		X86_FEATURE_AVX512BW  },
 	{ X86_FEATURE_ENQCMD,			X86_FEATURE_XSAVES    },
arch/x86/kernel/cpu/scattered.c +1 -0
index af5aa2c754c2..411b18c962bb 100644
@@ -48,6 +48,7 @@ static const struct cpuid_bit cpuid_bits[] = {
 	{ X86_FEATURE_MBA,		CPUID_EBX,  6, 0x80000008, 0 },
 	{ X86_FEATURE_SMBA,		CPUID_EBX,  2, 0x80000020, 0 },
 	{ X86_FEATURE_BMEC,		CPUID_EBX,  3, 0x80000020, 0 },
+	{ X86_FEATURE_ABMC,		CPUID_EBX,  5, 0x80000020, 0 },
 	{ X86_FEATURE_PERFMON_V2,	CPUID_EAX,  0, 0x80000022, 0 },
 	{ X86_FEATURE_AMD_LBR_V2,	CPUID_EAX,  1, 0x80000022, 0 },
 	{ X86_FEATURE_AMD_LBR_PMC_FREEZE,	CPUID_EAX,  2, 0x80000022, 0 },
Signature · 1 line
2.34.1
maintainer
#2 lore raw

Re: [PATCH v4 01/19] x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters (ABMC)

Hi Babu,

Could you please change shortlog prefix to be "x86/cpufeatures:" to make it obvious where this patch is headed?

Reinette

author reviewer
#3 lore raw

Re: [PATCH v4 01/19] x86/resctrl: Add support for Assignable Bandwidth Monitoring Counters (ABMC)

Quoted 4 lines · Reinette Chatre

Hi Babu,

Could you please change shortlog prefix to be "x86/cpufeatures:" to make it obvious where this patch is headed?

Sure.

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#4 lore raw

PATCH v4 2/19 x86/resctrl: Add ABMC feature in the command line options

In reply to Babu Moger

Add the command line option to enable or disable the new resctrl feature ABMC (Assignable Bandwidth Monitoring Counters).

---
v4: No changes

v3: No changes

v2: No changes

---
 Documentation/admin-guide/kernel-parameters.txt | 2 +-
 Documentation/arch/x86/resctrl.rst              | 1 +
 arch/x86/kernel/cpu/resctrl/core.c              | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +1 -1
index 500cfa776225..66a1be9d0ea6 100644
@@ -5602,7 +5602,7 @@
 	rdt=		[HW,X86,RDT]
 			Turn on/off individual RDT features. List is:
 			cmt, mbmtotal, mbmlocal, l3cat, l3cdp, l2cat, l2cdp,
-			mba, smba, bmec.
+			mba, smba, bmec, abmc.
 			E.g. to turn on cmt and turn off mba use:
 				rdt=cmt,!mba
 
Documentation/arch/x86/resctrl.rst +1 -0
index 627e23869bca..02790efaabcc 100644
@@ -26,6 +26,7 @@ MBM (Memory Bandwidth Monitoring)		"cqm_mbm_total", "cqm_mbm_local"
 MBA (Memory Bandwidth Allocation)		"mba"
 SMBA (Slow Memory Bandwidth Allocation)         ""
 BMEC (Bandwidth Monitoring Event Configuration) ""
+ABMC (Assignable Bandwidth Monitoring Counters) ""
 ===============================================	================================
 
 Historically, new features were made visible by default in /proc/cpuinfo. This
arch/x86/kernel/cpu/resctrl/core.c +2 -0
index a113d9aba553..df1b43fd9f0e 100644
@@ -651,6 +651,7 @@ enum {
 	RDT_FLAG_MBA,
 	RDT_FLAG_SMBA,
 	RDT_FLAG_BMEC,
+	RDT_FLAG_ABMC,
 };
 
 #define RDT_OPT(idx, n, f)	\
@@ -676,6 +677,7 @@ static struct rdt_options rdt_options[]  __initdata = {
 	RDT_OPT(RDT_FLAG_MBA,	    "mba",	X86_FEATURE_MBA),
 	RDT_OPT(RDT_FLAG_SMBA,	    "smba",	X86_FEATURE_SMBA),
 	RDT_OPT(RDT_FLAG_BMEC,	    "bmec",	X86_FEATURE_BMEC),
+	RDT_OPT(RDT_FLAG_ABMC,	    "abmc",	X86_FEATURE_ABMC),
 };
 #define NUM_RDT_OPTIONS ARRAY_SIZE(rdt_options)
 
Signature · 1 line
2.34.1
author reviewer
#5 lore raw

PATCH v4 3/19 x86/resctrl: Consolidate monitoring related data from rdt_resource

In reply to Babu Moger

Consolidate all the data related to monitoring into separate structure for better readability.

---
v4: New patch.

---
 arch/x86/kernel/cpu/resctrl/core.c     |  2 +-
 arch/x86/kernel/cpu/resctrl/monitor.c  | 16 ++++++++--------
 arch/x86/kernel/cpu/resctrl/rdtgroup.c |  8 ++++----
 include/linux/resctrl.h                | 16 ++++++++++++----
 4 files changed, 25 insertions(+), 17 deletions(-)
arch/x86/kernel/cpu/resctrl/core.c +1 -1
index df1b43fd9f0e..6cf3c887c693 100644
@@ -535,7 +535,7 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
 		return;
 	}
 
-	if (r->mon_capable && arch_domain_mbm_alloc(r->num_rmid, hw_dom)) {
+	if (r->mon_capable && arch_domain_mbm_alloc(r->mon.num_rmid, hw_dom)) {
 		domain_free(hw_dom);
 		return;
 	}
arch/x86/kernel/cpu/resctrl/monitor.c +8 -8
index 2345e6836593..b35d04fc761b 100644
@@ -254,11 +254,11 @@ void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d)
 
 	if (is_mbm_total_enabled())
 		memset(hw_dom->arch_mbm_total, 0,
-		       sizeof(*hw_dom->arch_mbm_total) * r->num_rmid);
+		       sizeof(*hw_dom->arch_mbm_total) * r->mon.num_rmid);
 
 	if (is_mbm_local_enabled())
 		memset(hw_dom->arch_mbm_local, 0,
-		       sizeof(*hw_dom->arch_mbm_local) * r->num_rmid);
+		       sizeof(*hw_dom->arch_mbm_local) * r->mon.num_rmid);
 }
 
 static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
@@ -1004,14 +1004,14 @@ static struct mon_evt mbm_local_event = {
  */
 static void l3_mon_evt_init(struct rdt_resource *r)
 {
-	INIT_LIST_HEAD(&r->evt_list);
+	INIT_LIST_HEAD(&r->mon.evt_list);
 
 	if (is_llc_occupancy_enabled())
-		list_add_tail(&llc_occupancy_event.list, &r->evt_list);
+		list_add_tail(&llc_occupancy_event.list, &r->mon.evt_list);
 	if (is_mbm_total_enabled())
-		list_add_tail(&mbm_total_event.list, &r->evt_list);
+		list_add_tail(&mbm_total_event.list, &r->mon.evt_list);
 	if (is_mbm_local_enabled())
-		list_add_tail(&mbm_local_event.list, &r->evt_list);
+		list_add_tail(&mbm_local_event.list, &r->mon.evt_list);
 }
 
 int __init rdt_get_mon_l3_config(struct rdt_resource *r)
@@ -1023,7 +1023,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 
 	resctrl_rmid_realloc_limit = boot_cpu_data.x86_cache_size * 1024;
 	hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale;
-	r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
+	r->mon.num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
 	hw_res->mbm_width = MBM_CNTR_WIDTH_BASE;
 
 	if (mbm_offset > 0 && mbm_offset <= MBM_CNTR_WIDTH_OFFSET_MAX)
@@ -1038,7 +1038,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 	 *
 	 * For a 35MB LLC and 56 RMIDs, this is ~1.8% of the LLC.
 	 */
-	threshold = resctrl_rmid_realloc_limit / r->num_rmid;
+	threshold = resctrl_rmid_realloc_limit / r->mon.num_rmid;
 
 	/*
 	 * Because num_rmid may not be a power of two, round the value
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -4
index 02f213f1c51c..7114d58ef1e3 100644
@@ -1098,7 +1098,7 @@ static int rdt_num_rmids_show(struct kernfs_open_file *of,
 {
 	struct rdt_resource *r = of->kn->parent->priv;
 
-	seq_printf(seq, "%d\n", r->num_rmid);
+	seq_printf(seq, "%d\n", r->mon.num_rmid);
 
 	return 0;
 }
@@ -1109,7 +1109,7 @@ static int rdt_mon_features_show(struct kernfs_open_file *of,
 	struct rdt_resource *r = of->kn->parent->priv;
 	struct mon_evt *mevt;
 
-	list_for_each_entry(mevt, &r->evt_list, list) {
+	list_for_each_entry(mevt, &r->mon.evt_list, list) {
 		seq_printf(seq, "%s\n", mevt->name);
 		if (mevt->configurable)
 			seq_printf(seq, "%s_config\n", mevt->name);
@@ -3042,14 +3042,14 @@ static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
 	if (ret)
 		goto out_destroy;
 
-	if (WARN_ON(list_empty(&r->evt_list))) {
+	if (WARN_ON(list_empty(&r->mon.evt_list))) {
 		ret = -EPERM;
 		goto out_destroy;
 	}
 
 	priv.u.rid = r->rid;
 	priv.u.domid = d->id;
-	list_for_each_entry(mevt, &r->evt_list, list) {
+	list_for_each_entry(mevt, &r->mon.evt_list, list) {
 		priv.u.evtid = mevt->evtid;
 		ret = mon_addfile(kn, mevt->name, priv.priv);
 		if (ret)
include/linux/resctrl.h +12 -4
index a365f67131ec..bf99eb9c6ce4 100644
@@ -150,22 +150,31 @@ struct resctrl_membw {
 struct rdt_parse_data;
 struct resctrl_schema;
 
+/**
+ * struct resctrl_mon - Monitoring related data
+ * @num_rmid:		Number of RMIDs available
+ * @evt_list:		List of monitoring events
+ */
+struct resctrl_mon {
+	int			num_rmid;
+	struct list_head	evt_list;
+};
+
 /**
  * struct rdt_resource - attributes of a resctrl resource
  * @rid:		The index of the resource
  * @alloc_capable:	Is allocation available on this machine
  * @mon_capable:	Is monitor feature available on this machine
- * @num_rmid:		Number of RMIDs available
  * @cache_level:	Which cache level defines scope of this resource
  * @cache:		Cache allocation related data
  * @membw:		If the component has bandwidth controls, their properties.
+ * @mon:		Monitoring related data.
  * @domains:		RCU list of all domains for this resource
  * @name:		Name to use in "schemata" file.
  * @data_width:		Character width of data when displaying
  * @default_ctrl:	Specifies default cache cbm or memory B/W percent.
  * @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
  * @fflags:		flags to choose base and info files
  * @cdp_capable:	Is the CDP feature available on this resource
  */
@@ -173,10 +182,10 @@ struct rdt_resource {
 	int			rid;
 	bool			alloc_capable;
 	bool			mon_capable;
-	int			num_rmid;
 	int			cache_level;
 	struct resctrl_cache	cache;
 	struct resctrl_membw	membw;
+	struct resctrl_mon	mon;
 	struct list_head	domains;
 	char			*name;
 	int			data_width;
@@ -185,7 +194,6 @@ struct rdt_resource {
 	int			(*parse_ctrlval)(struct rdt_parse_data *data,
 						 struct resctrl_schema *s,
 						 struct rdt_domain *d);
-	struct list_head	evt_list;
 	unsigned long		fflags;
 	bool			cdp_capable;
 };
Signature · 1 line
2.34.1
maintainer
#6 lore raw

Re: [PATCH v4 03/19] x86/resctrl: Consolidate monitoring related data from rdt_resource

Hi Babu,

Quoted 2 lines · Babu Moger

Consolidate all the data related to monitoring into separate structure for better readability.

This needs a better motivation because "better readability" is subjective. You can motivate this work by noting that this is re-organization in preparation for more monitoring specific properties that will clobber the existing resource struct more. To support this organization the pattern of the cache allocation and memory bandwidth allocation features that consolidate the feature specific properties into a struct is followed.

Reinette

author reviewer
#7 lore raw

Re: [PATCH v4 03/19] x86/resctrl: Consolidate monitoring related data from rdt_resource

Hi Reinette,

Quoted 6 lines · Reinette Chatre

Hi Babu,

Quoted 2 lines · Babu Moger

Consolidate all the data related to monitoring into separate structure for better readability.

Quoted 10 lines

This needs a better motivation because "better readability" is subjective. You can motivate this work by noting that this is re-organization in preparation
for more monitoring specific properties that will clobber the existing resource
struct more. To support this organization the pattern of the cache allocation and memory bandwidth allocation features that consolidate the feature specific
properties into a struct is followed.

Sure. Sounds good.

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#8 lore raw

PATCH v4 4/19 x86/resctrl: Detect Assignable Bandwidth Monitoring feature details

In reply to Babu Moger

ABMC feature details are reported via CPUID Fn8000_0020_EBX_x5. Bits Description
15:0 MAX_ABMC Maximum Supported Assignable Bandwidth
Monitoring Counter ID + 1

The feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_has_abmc(). Added all the code inline. We dont
need to separate this as arch code.

v3: Removed changes related to mon_features.
Moved rdt_cpu_has to core.c and added new function resctrl_arch_has_abmc. Also moved the fields mbm_assign_capable and mbm_assign_cntrs to rdt_resource. (James)

v2: Changed the field name to mbm_assign_capable from abmc_capable.

---
 arch/x86/kernel/cpu/resctrl/monitor.c | 14 ++++++++++++++
 include/linux/resctrl.h               |  4 ++++
 2 files changed, 18 insertions(+)
arch/x86/kernel/cpu/resctrl/monitor.c +14 -0
index b35d04fc761b..1602b58ba23d 100644
@@ -1066,6 +1066,20 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 			mbm_local_event.configurable = true;
 			mbm_config_rftype_init("mbm_local_bytes_config");
 		}
+
+		if (rdt_cpu_has(X86_FEATURE_ABMC)) {
+			r->abmc_capable = true;
+			/*
+			 * Query CPUID_Fn80000020_EBX_x05 for number of
+			 * ABMC counters
+			 */
+			cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
+			r->mon.num_cntrs = (ebx & 0xFFFF) + 1;
+			if (r->mon.num_cntrs > 64) {
+				WARN(1, "Cannot support more than 64 ABMC counters\n");
+				r->mon.num_cntrs = 64;
+			}
+		}
 	}
 
 	l3_mon_evt_init(r);
include/linux/resctrl.h +4 -0
index bf99eb9c6ce4..24087e6efbb6 100644
@@ -153,10 +153,12 @@ struct resctrl_schema;
 /**
  * struct resctrl_mon - Monitoring related data
  * @num_rmid:		Number of RMIDs available
+ * @num_cntrs:		Maximum number of abmc counters
  * @evt_list:		List of monitoring events
  */
 struct resctrl_mon {
 	int			num_rmid;
+	int			num_cntrs;
 	struct list_head	evt_list;
 };
 
@@ -177,6 +179,7 @@ struct resctrl_mon {
  * @parse_ctrlval:	Per resource function pointer to parse control values
  * @fflags:		flags to choose base and info files
  * @cdp_capable:	Is the CDP feature available on this resource
+ * @abmc_capable:	Is system capable of supporting monitor assignment?
  */
 struct rdt_resource {
 	int			rid;
@@ -196,6 +199,7 @@ struct rdt_resource {
 						 struct rdt_domain *d);
 	unsigned long		fflags;
 	bool			cdp_capable;
+	bool			abmc_capable;
 };
 
 /**
Signature · 1 line
2.34.1
maintainer
#9 lore raw

Re: [PATCH v4 04/19] x86/resctrl: Detect Assignable Bandwidth Monitoring feature details

Hi Babu,

Quoted 36 lines · Babu Moger

ABMC feature details are reported via CPUID Fn8000_0020_EBX_x5. Bits Description
15:0 MAX_ABMC Maximum Supported Assignable Bandwidth
Monitoring Counter ID + 1

The feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_has_abmc(). Added all the code inline. We dont
need to separate this as arch code.

v3: Removed changes related to mon_features.
Moved rdt_cpu_has to core.c and added new function resctrl_arch_has_abmc. Also moved the fields mbm_assign_capable and mbm_assign_cntrs to rdt_resource. (James)

v2: Changed the field name to mbm_assign_capable from abmc_capable.

---
  arch/x86/kernel/cpu/resctrl/monitor.c | 14 ++++++++++++++
  include/linux/resctrl.h               |  4 ++++
  2 files changed, 18 insertions(+)
arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index b35d04fc761b..1602b58ba23d 100644
@@ -1066,6 +1066,20 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
  			mbm_local_event.configurable = true;
  			mbm_config_rftype_init("mbm_local_bytes_config");
  		}
+

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1079

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/monitor.c +10 -0
+		if (rdt_cpu_has(X86_FEATURE_ABMC)) {
+			r->abmc_capable = true;
+			/*
+			 * Query CPUID_Fn80000020_EBX_x05 for number of
+			 * ABMC counters
+			 */
+			cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
+			r->mon.num_cntrs = (ebx & 0xFFFF) + 1;
+			if (r->mon.num_cntrs > 64) {
+				WARN(1, "Cannot support more than 64 ABMC counters\n");

if (WARN_ON(...))

Quoted 11 lines
arch/x86/kernel/cpu/resctrl/monitor.c +3 -0
+				r->mon.num_cntrs = 64;
+			}
+		}
  	}
 
  	l3_mon_evt_init(r);
include/linux/resctrl.h +0 -0
index bf99eb9c6ce4..24087e6efbb6 100644

include/linux/resctrl.h struct resctrl_schema; · line 156

Quoted 4 lines
include/linux/resctrl.h +1 -0
@@ -153,10 +153,12 @@ struct resctrl_schema;
  /**
   * struct resctrl_mon - Monitoring related data
   * @num_rmid:		Number of RMIDs available
+ * @num_cntrs:		Maximum number of abmc counters

Maximum implies some limit and it is not clear what limit this applies to. Can this just be "Number of monitoring counters".

Thinking ahead ... when switching between different "MBM modes" it may be that one mode has a different number of counters than the other. Since "ABMC" is just one mode it does not seem appropriate to connect the "num_cntrs" property to ABMC.

Quoted 17 lines
include/linux/resctrl.h +2 -0
   * @evt_list:		List of monitoring events
   */
  struct resctrl_mon {
  	int			num_rmid;
+	int			num_cntrs;
  	struct list_head	evt_list;
  };
 
@@ -177,6 +179,7 @@ struct resctrl_mon {
   * @parse_ctrlval:	Per resource function pointer to parse control values
   * @fflags:		flags to choose base and info files
   * @cdp_capable:	Is the CDP feature available on this resource
+ * @abmc_capable:	Is system capable of supporting monitor assignment?
   */
  struct rdt_resource {
  	int			rid;

include/linux/resctrl.h struct rdt_resource { · line 202

Quoted 4 lines
include/linux/resctrl.h +1 -0
@@ -196,6 +199,7 @@ struct rdt_resource {
  						 struct rdt_domain *d);
  	unsigned long		fflags;
  	bool			cdp_capable;
+	bool			abmc_capable;

Shouldn't abmc_capable be a property of the new struct resctrl_mon?

include/linux/resctrl.h struct rdt_resource { · line 205

Quoted 3 lines
include/linux/resctrl.h +0 -0
  };
 
  /**

Reinette

author reviewer
#10 lore raw

Re: [PATCH v4 04/19] x86/resctrl: Detect Assignable Bandwidth Monitoring feature details

Hi Reinette,

Quoted 46 lines · Reinette Chatre

Hi Babu,

Quoted 43 lines · Babu Moger

ABMC feature details are reported via CPUID Fn8000_0020_EBX_x5. Bits Description
15:0 MAX_ABMC Maximum Supported Assignable Bandwidth Monitoring Counter ID + 1

The feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_has_abmc(). Added all the code inline. We dont need to separate this as arch code.

v3: Removed changes related to mon_features.
     Moved rdt_cpu_has to core.c and added new function resctrl_arch_has_abmc.
     Also moved the fields mbm_assign_capable and mbm_assign_cntrs to rdt_resource. (James)

v2: Changed the field name to mbm_assign_capable from abmc_capable.
---
  arch/x86/kernel/cpu/resctrl/monitor.c | 14 ++++++++++++++ include/linux/resctrl.h               |  4 ++++

  2 files changed, 18 insertions(+)
arch/x86/kernel/cpu/resctrl/monitor.c +5 -0
index b35d04fc761b..1602b58ba23d 100644
@@ -1066,6 +1066,20 @@ int __init rdt_get_mon_l3_config(struct
 rdt_resource *r)
               mbm_local_event.configurable = true;
               mbm_config_rftype_init("mbm_local_bytes_config");
           }
+
+        if (rdt_cpu_has(X86_FEATURE_ABMC)) {
+            r->abmc_capable = true;
+            /*
+             * Query CPUID_Fn80000020_EBX_x05 for number of
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1079

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/monitor.c +6 -0
+             * ABMC counters
+             */
+            cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
+            r->mon.num_cntrs = (ebx & 0xFFFF) + 1;
+            if (r->mon.num_cntrs > 64) {
+                WARN(1, "Cannot support more than 64 ABMC counters\n");

if (WARN_ON(...))

Sure..

Quoted 10 lines
Quoted 10 lines
arch/x86/kernel/cpu/resctrl/monitor.c +3 -0
+                r->mon.num_cntrs = 64;
+            }
+        }
       }
         l3_mon_evt_init(r);
include/linux/resctrl.h +0 -0
index bf99eb9c6ce4..24087e6efbb6 100644
Quoted 8 lines

include/linux/resctrl.h struct resctrl_schema; · line 156

Quoted 5 lines
include/linux/resctrl.h +1 -0
@@ -153,10 +153,12 @@ struct resctrl_schema;
   /**
    * struct resctrl_mon - Monitoring related data
    * @num_rmid:        Number of RMIDs available
+ * @num_cntrs:        Maximum number of abmc counters

Maximum implies some limit and it is not clear what limit this applies to. Can this just be "Number of monitoring counters".

Sure.

Quoted 5 lines

Thinking ahead ... when switching between different "MBM modes" it may be that one mode has a different number of counters than the other. Since "ABMC" is just one mode it does not seem appropriate to connect the "num_cntrs" property to ABMC.

Ok

Quoted 17 lines
Quoted 17 lines
include/linux/resctrl.h +1 -0
    * @evt_list:        List of monitoring events
    */
   struct resctrl_mon {
       int            num_rmid;
+    int            num_cntrs;
       struct list_head    evt_list;
   };
   @@ -177,6 +179,7 @@ struct resctrl_mon {

   * @parse_ctrlval:    Per resource function pointer to parse control values
   * @fflags:        flags to choose base and info files
   * @cdp_capable:    Is the CDP feature available on this resource
+ * @abmc_capable:    Is system capable of supporting monitor assignment? */
  struct rdt_resource {

Quoted 8 lines

include/linux/resctrl.h struct rdt_resource { · line 202

Quoted 6 lines

      int            rid;

include/linux/resctrl.h +1 -0
@@ -196,6 +199,7 @@ struct rdt_resource {
                            struct rdt_domain *d);
       unsigned long        fflags;
       bool            cdp_capable;
+    bool            abmc_capable;

Shouldn't abmc_capable be a property of the new struct resctrl_mon?

Sure. We can move it to resctrl_mon.

Quoted 6 lines

include/linux/resctrl.h struct rdt_resource { · line 204

Quoted 3 lines
include/linux/resctrl.h +0 -0
   };
     /**

Reinette

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#11 lore raw

PATCH v4 5/19 x86/resctrl: Introduce resctrl_file_fflags_init to initialize fflags

In reply to Babu Moger

The functions thread_throttle_mode_init() and mbm_config_rftype_init() both initialize fflags for resctrl files. Adding the new files will involve adding another function to initialize the fflags. All of this can be simplified by adding a new function resctrl_file_fflags_init() and passing the file name and flags to be initialized.

Consolidate multiple fflags initialization into resctrl_file_fflags_init() and remove thread_throttle_mode_init() and mbm_config_rftype_init().

---
v4: Commit message update.

v3: New patch to display ABMC capability.

---
 arch/x86/kernel/cpu/resctrl/core.c     |  4 +++-
 arch/x86/kernel/cpu/resctrl/internal.h |  4 ++--
 arch/x86/kernel/cpu/resctrl/monitor.c  |  6 ++++--
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 +++-------------
 4 files changed, 12 insertions(+), 18 deletions(-)
arch/x86/kernel/cpu/resctrl/core.c +3 -1
index 6cf3c887c693..ec93f6a50308 100644
@@ -224,7 +224,9 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
 		r->membw.throttle_mode = THREAD_THROTTLE_PER_THREAD;
 	else
 		r->membw.throttle_mode = THREAD_THROTTLE_MAX;
-	thread_throttle_mode_init();
+
+	resctrl_file_fflags_init("thread_throttle_mode",
+				 RFTYPE_CTRL_INFO | RFTYPE_RES_MB);
 
 	r->alloc_capable = true;
 
arch/x86/kernel/cpu/resctrl/internal.h +2 -2
index f1d926832ec8..d566251094b2 100644
@@ -603,8 +603,8 @@ void cqm_handle_limbo(struct work_struct *work);
 bool has_busy_rmid(struct rdt_domain *d);
 void __check_limbo(struct rdt_domain *d, bool force_free);
 void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
-void __init thread_throttle_mode_init(void);
-void __init mbm_config_rftype_init(const char *config);
+void __init resctrl_file_fflags_init(const char *config,
+				     unsigned long fflags);
 void rdt_staged_configs_clear(void);
 bool closid_allocated(unsigned int closid);
 int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/monitor.c +4 -2
index 1602b58ba23d..0db9f12debb9 100644
@@ -1060,11 +1060,13 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 
 		if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
 			mbm_total_event.configurable = true;
-			mbm_config_rftype_init("mbm_total_bytes_config");
+			resctrl_file_fflags_init("mbm_total_bytes_config",
+						 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
 		}
 		if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) {
 			mbm_local_event.configurable = true;
-			mbm_config_rftype_init("mbm_local_bytes_config");
+			resctrl_file_fflags_init("mbm_local_bytes_config",
+						 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
 		}
 
 		if (rdt_cpu_has(X86_FEATURE_ABMC)) {
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -13
index 7114d58ef1e3..aa3eb6ea059a 100644
@@ -2022,24 +2022,14 @@ static struct rftype *rdtgroup_get_rftype_by_name(const char *name)
 	return NULL;
 }
 
-void __init thread_throttle_mode_init(void)
-{
-	struct rftype *rft;
-
-	rft = rdtgroup_get_rftype_by_name("thread_throttle_mode");
-	if (!rft)
-		return;
-
-	rft->fflags = RFTYPE_CTRL_INFO | RFTYPE_RES_MB;
-}
-
-void __init mbm_config_rftype_init(const char *config)
+void __init resctrl_file_fflags_init(const char *config,
+				     unsigned long fflags)
 {
 	struct rftype *rft;
 
 	rft = rdtgroup_get_rftype_by_name(config);
 	if (rft)
-		rft->fflags = RFTYPE_MON_INFO | RFTYPE_RES_CACHE;
+		rft->fflags = fflags;
 }
 
 /**
Signature · 1 line
2.34.1
maintainer
#12 lore raw

Re: [PATCH v4 05/19] x86/resctrl: Introduce resctrl_file_fflags_init to initialize fflags

Hi Babu,

Shortlog: "Introduce resctrl_file_fflags_init() ..."

Quoted 1 line · Babu Moger

The functions thread_throttle_mode_init() and mbm_config_rftype_init()

You can drop "The functions".

Quoted 1 line

both initialize fflags for resctrl files. Adding the new files will

"Adding the new files" -> "Adding new files"? (this should be in new paragraph)

Quoted 1 line

involve adding another function to initialize the fflags. All of this

Solution should be in new paragraph and written in imperative mood.

Quoted 8 lines

can be simplified by adding a new function resctrl_file_fflags_init() and passing the file name and flags to be initialized.

Consolidate multiple fflags initialization into resctrl_file_fflags_init() and remove thread_throttle_mode_init() and mbm_config_rftype_init().

---

Patch looks good.

Reinette

author reviewer
#13 lore raw

Re: [PATCH v4 05/19] x86/resctrl: Introduce resctrl_file_fflags_init to initialize fflags

Hi Reinette,

Quoted 3 lines · Reinette Chatre

Hi Babu,

Shortlog: "Introduce resctrl_file_fflags_init() ..."

Sure.

Quoted 6 lines · Babu Moger
Quoted 1 line

The functions thread_throttle_mode_init() and mbm_config_rftype_init()

You can drop "The functions".

Sure.

Quoted 5 lines
Quoted 2 lines

both initialize fflags for resctrl files. Adding the new files will

"Adding the new files" -> "Adding new files"? (this should be in new paragraph)

Sure.

Quoted 4 lines
Quoted 2 lines

involve adding another function to initialize the fflags. All of this

Solution should be in new paragraph and written in imperative mood.

ok

Quoted 11 lines
Quoted 9 lines

can be simplified by adding a new function resctrl_file_fflags_init() and passing the file name and flags to be initialized.

Consolidate multiple fflags initialization into resctrl_file_fflags_init() and remove thread_throttle_mode_init() and mbm_config_rftype_init().

---

Patch looks good.

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#14 lore raw

PATCH v4 6/19 x86/resctrl: Introduce interface to display number of ABMC counters

In reply to Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. Number of assignments depend on number of ABMC counters available.

Provide the interface to display the number of ABMC counters supported.

---
v4: Changed the counter name to num_cntrs. And few text changes.

v3: Changed the field name to mbm_assign_cntrs.

v2: Changed the field name to mbm_assignable_counters from abmc_counters.

---
 Documentation/arch/x86/resctrl.rst     |  4 ++++
 arch/x86/kernel/cpu/resctrl/monitor.c  |  1 +
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 ++++++++++++++++
 3 files changed, 21 insertions(+)
Documentation/arch/x86/resctrl.rst +4 -0
index 02790efaabcc..7ab8172ef208 100644
@@ -257,6 +257,10 @@ with the following files:
 	    # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
 	    0=0x30;1=0x30;3=0x15;4=0x15
 
+"num_cntrs":
+	Available when ABMC feature is supported. The number of ABMC counters
+	available for configuration.
+
 "max_threshold_occupancy":
 		Read/write file provides the largest value (in
 		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index 0db9f12debb9..e75a6146068b 100644
@@ -1081,6 +1081,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 				WARN(1, "Cannot support more than 64 ABMC counters\n");
 				r->mon.num_cntrs = 64;
 			}
+			resctrl_file_fflags_init("num_cntrs", RFTYPE_MON_INFO);
 		}
 	}
 
arch/x86/kernel/cpu/resctrl/rdtgroup.c +16 -0
index aa3eb6ea059a..ca692712b393 100644
@@ -846,6 +846,16 @@ static int rdtgroup_rmid_show(struct kernfs_open_file *of,
 	return ret;
 }
 
+static int rdtgroup_num_cntrs_show(struct kernfs_open_file *of,
+				   struct seq_file *s, void *v)
+{
+	struct rdt_resource *r = of->kn->parent->priv;
+
+	seq_printf(s, "%d\n", r->mon.num_cntrs);
+
+	return 0;
+}
+
 #ifdef CONFIG_PROC_CPU_RESCTRL
 
 /*
@@ -1911,6 +1921,12 @@ static struct rftype res_common_files[] = {
 		.seq_show	= rdtgroup_cpus_show,
 		.fflags		= RFTYPE_BASE,
 	},
+	{
+		.name		= "num_cntrs",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_num_cntrs_show,
+	},
 	{
 		.name		= "cpus_list",
 		.mode		= 0644,
Signature · 1 line
2.34.1
maintainer
#15 lore raw

Re: [PATCH v4 06/19] x86/resctrl: Introduce interface to display number of ABMC counters

Hi Babu,

Quoted 4 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. Number of assignments depend on number of ABMC counters available.

Take care that this interface will not just be used by ABMC. I assumed that when the user switches to "soft-RMID" then the value of "num_cntrs" will change?

Quoted 21 lines

Provide the interface to display the number of ABMC counters supported.

---
v4: Changed the counter name to num_cntrs. And few text changes.

v3: Changed the field name to mbm_assign_cntrs.

v2: Changed the field name to mbm_assignable_counters from abmc_counters.

---
  Documentation/arch/x86/resctrl.rst     |  4 ++++
  arch/x86/kernel/cpu/resctrl/monitor.c  |  1 +
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 ++++++++++++++++
  3 files changed, 21 insertions(+)
Documentation/arch/x86/resctrl.rst +0 -0
index 02790efaabcc..7ab8172ef208 100644

Documentation/arch/x86/resctrl.rst with the following files: · line 262

Quoted 6 lines
Documentation/arch/x86/resctrl.rst +3 -0
@@ -257,6 +257,10 @@ with the following files:
  	    # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
  	    0=0x30;1=0x30;3=0x15;4=0x15
 
+"num_cntrs":
+	Available when ABMC feature is supported. The number of ABMC counters
+	available for configuration.

This can only be understood by folks already familiar with AMD's ABMC feature. There is no information about what "ABMC feature" is, what an "ABMC counter" is and what "configuration" can be done with it.

Do you think this num_cntrs will only be used by ABMC? What will happen when user enables "soft-RMID" or some other mode?

Reinette

author reviewer
#16 lore raw

Re: [PATCH v4 06/19] x86/resctrl: Introduce interface to display number of ABMC counters

Hi Reinette,

Quoted 11 lines · Reinette Chatre

Hi Babu,

Quoted 4 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. Number of assignments depend on number of ABMC counters available.

Take care that this interface will not just be used by ABMC. I assumed that when the user switches to "soft-RMID" then the value of "num_cntrs" will change?

It can be used by both ABMC and "soft-RMID". Will update the information to be bit generic.

Quoted 26 lines
Quoted 26 lines

Provide the interface to display the number of ABMC counters supported.

---
v4: Changed the counter name to num_cntrs. And few text changes.

v3: Changed the field name to mbm_assign_cntrs.

v2: Changed the field name to mbm_assignable_counters from abmc_counters.
---
  Documentation/arch/x86/resctrl.rst     |  4 ++++ arch/x86/kernel/cpu/resctrl/monitor.c  |  1 + arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 ++++++++++++++++

  3 files changed, 21 insertions(+)
Documentation/arch/x86/resctrl.rst +0 -0
index 02790efaabcc..7ab8172ef208 100644
@@ -257,6 +257,10 @@ with the following files:
           # cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config

          0=0x30;1=0x30;3=0x15;4=0x15
  +"num_cntrs":

Quoted 8 lines
Quoted 2 lines

+    Available when ABMC feature is supported. The number of ABMC counters +    available for configuration.

This can only be understood by folks already familiar with AMD's ABMC feature. There is
no information about what "ABMC feature" is, what an "ABMC counter" is and what
"configuration" can be done with it.

I can move this patch after 8/19. I will add details on ABMC feature in Patch 8/19. Also, keep the details bit generic.

Quoted 4 lines

Do you think this num_cntrs will only be used by ABMC? What will happen when user
enables "soft-RMID" or some other mode?

This can be used by both the features. But we don't know how soft-RMID will be implemented. But, I can make this explanation bit more generic.

Quoted 3 lines

Reinette

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#17 lore raw

PATCH v4 7/19 x86/resctrl: Add support to enable/disable ABMC feature

In reply to Babu Moger

Add the functionality to enable/disable ABMC feature.

ABMC feature is enabled by setting enabled bit(0) in MSR L3_QOS_EXT_CFG. When the state of ABMC is changed, the MSR needs to be updated on all the logical processors in the QOS Domain.

Hardware counters will reset when ABMC state is changed. Kernel internal counters need to be reset to avoid overflow condition in the next update.

The ABMC feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_set_abmc_enabled and resctrl_arch_get_abmc_enabled.
Directly calling resctrl_abmc_enable and resctrl_abmc_disable. Renamed couple of functions.
resctrl_abmc_msrwrite() -> resctrl_abmc_set_one() resctrl_abmc_setup() -> resctrl_abmc_set_all()
Added rdtgroup_mutex lockdep asserts.
Updated commit log and code comments.

v3: No changes.

v2: Few text changes in commit message.

---
 arch/x86/include/asm/msr-index.h       |  1 +
 arch/x86/kernel/cpu/resctrl/internal.h |  8 ++++
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 62 ++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)
arch/x86/include/asm/msr-index.h +1 -0
index e022e6eb766c..5f9a0139e98c 100644
@@ -1171,6 +1171,7 @@
 #define MSR_IA32_MBA_BW_BASE		0xc0000200
 #define MSR_IA32_SMBA_BW_BASE		0xc0000280
 #define MSR_IA32_EVT_CFG_BASE		0xc0000400
+#define MSR_IA32_L3_QOS_EXT_CFG		0xc00003ff
 
 /* MSR_IA32_VMX_MISC bits */
 #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +8 -0
index d566251094b2..fabe40304798 100644
@@ -97,6 +97,9 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
 	return cpu;
 }
 
+/* Setting bit 0 in L3_QOS_EXT_CFG enables the ABMC feature */
+#define ABMC_ENABLE			BIT(0)
+
 struct rdt_fs_context {
 	struct kernfs_fs_context	kfc;
 	bool				enable_cdpl2;
@@ -436,6 +439,7 @@ struct rdt_parse_data {
  * @mbm_cfg_mask:	Bandwidth sources that can be tracked when Bandwidth
  *			Monitoring Event Configuration (BMEC) is supported.
  * @cdp_enabled:	CDP state of this resource
+ * @abmc_enabled:	ABMC feature is enabled
  *
  * Members of this structure are either private to the architecture
  * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g.
@@ -450,6 +454,7 @@ struct rdt_hw_resource {
 	unsigned int		mbm_width;
 	unsigned int		mbm_cfg_mask;
 	bool			cdp_enabled;
+	bool			abmc_enabled;
 };
 
 static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r)
@@ -493,6 +498,9 @@ static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)
 
 int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable);
 
+int resctrl_abmc_enable(enum resctrl_res_level l);
+void resctrl_abmc_disable(enum resctrl_res_level l);
+
 /*
  * To return the common struct rdt_resource, which is contained in struct
  * rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource.
arch/x86/kernel/cpu/resctrl/rdtgroup.c +62 -0

68 lines not on this page · raw message

Signature · 1 line
2.34.1
maintainer
#18 lore raw

Re: [PATCH v4 07/19] x86/resctrl: Add support to enable/disable ABMC feature

Hi Babu,

Quoted 8 lines · Babu Moger

Add the functionality to enable/disable ABMC feature.

ABMC feature is enabled by setting enabled bit(0) in MSR L3_QOS_EXT_CFG. When the state of ABMC is changed, the MSR needs to be updated on all the logical processors in the QOS Domain.

Hardware counters will reset when ABMC state is changed. Kernel internal counters need to be reset to avoid overflow condition in the next update.

Please note that there are two "ABMC" features introduced in this series. First, there is the "abmc" resctrl fs feature that just happens to have the same name as AMD's "ABMC" (which may be a good motivation to change this name). Second, there is the architecture (AMD) specific "ABMC" feature that is enabled in response to user's request to enable the resctrl "abmc" feature.

Other architectures need to support resctrl fs "abmc" feature with something entirely different.

Please consider this distinction during this series because it is often blurred.

Quoted 61 lines

The ABMC feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_set_abmc_enabled and resctrl_arch_get_abmc_enabled.
Directly calling resctrl_abmc_enable and resctrl_abmc_disable. Renamed couple of functions.
resctrl_abmc_msrwrite() -> resctrl_abmc_set_one() resctrl_abmc_setup() -> resctrl_abmc_set_all()
Added rdtgroup_mutex lockdep asserts.
Updated commit log and code comments.

v3: No changes.

v2: Few text changes in commit message.

---
  arch/x86/include/asm/msr-index.h       |  1 +
  arch/x86/kernel/cpu/resctrl/internal.h |  8 ++++
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 62 ++++++++++++++++++++++++++
  3 files changed, 71 insertions(+)
arch/x86/include/asm/msr-index.h +1 -0
index e022e6eb766c..5f9a0139e98c 100644
@@ -1171,6 +1171,7 @@
  #define MSR_IA32_MBA_BW_BASE		0xc0000200
  #define MSR_IA32_SMBA_BW_BASE		0xc0000280
  #define MSR_IA32_EVT_CFG_BASE		0xc0000400
+#define MSR_IA32_L3_QOS_EXT_CFG		0xc00003ff
 
  /* MSR_IA32_VMX_MISC bits */
  #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +4 -0
index d566251094b2..fabe40304798 100644
@@ -97,6 +97,9 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
  	return cpu;
  }
 
+/* Setting bit 0 in L3_QOS_EXT_CFG enables the ABMC feature */
+#define ABMC_ENABLE			BIT(0)
+
  struct rdt_fs_context {
  	struct kernfs_fs_context	kfc;
  	bool				enable_cdpl2;
@@ -436,6 +439,7 @@ struct rdt_parse_data {
   * @mbm_cfg_mask:	Bandwidth sources that can be tracked when Bandwidth
   *			Monitoring Event Configuration (BMEC) is supported.
   * @cdp_enabled:	CDP state of this resource
+ * @abmc_enabled:	ABMC feature is enabled
   *
   * Members of this structure are either private to the architecture
   * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g.

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_resource { · line 459

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
@@ -450,6 +454,7 @@ struct rdt_hw_resource {
  	unsigned int		mbm_width;
  	unsigned int		mbm_cfg_mask;
  	bool			cdp_enabled;
+	bool			abmc_enabled;
  };
 

ok, so here by making "abmc_enabled" a member of struct rdt_hw_resource this is an architecture specific property. This is reasonable since every architecture will look different. What is _not_ ok is that this causes the rest of the
series to change resctrl fs to reach into the architecture code. For example, this work causes mbm_config_show() to now need to peek into struct rdt_hw_resource to see this value. That is not ok. All of the interactions between this
field and resctrl fs needs to be via arch helpers: resctrl_arch_abmc_enable()/ resctrl_arch_abmc_disable() and resctrl_arch_get_abmc_enabled()/resctrl_arch_set_abmc_enabled().

arch/x86/kernel/cpu/resctrl/internal.h static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l) · line 502

Quoted 7 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
  static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r)
@@ -493,6 +498,9 @@ static inline bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level l)
 
  int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable);
 
+int resctrl_abmc_enable(enum resctrl_res_level l);
+void resctrl_abmc_disable(enum resctrl_res_level l);

Why do these need enum resctrl_res_level parameter?

Quoted 18 lines
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
+
  /*
   * To return the common struct rdt_resource, which is contained in struct
   * rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource.
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
index ca692712b393..9148d1234ede 100644
@@ -2416,6 +2416,68 @@ int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable)
  	return 0;
  }
 
+static void resctrl_abmc_set_one(void *arg)
+{
+	bool *enable = arg;
+	u64 msrval;
+
+	rdmsrl(MSR_IA32_L3_QOS_EXT_CFG, msrval);

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2434

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+
+	if (*enable)
+		msrval |= ABMC_ENABLE;
+	else
+		msrval &= ~ABMC_ENABLE;
+
+	wrmsrl(MSR_IA32_L3_QOS_EXT_CFG, msrval);
+}
+
+static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)

Should this function and resctrl_abmc_set_one() perhaps have "amd" in the name just to enforce that this is not filesystem code at all and specific and unique to AMD.

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2440

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
+{
+	struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
+	struct rdt_domain *d;
+
+	/*
+	 * Update QOS_CFG MSR on all the CPUs associated with the resource

end of sentence needs "."

This comment about the specific register seems more appropriate to resctrl_abmc_set_one() though. This function is a higher level enable/disable of the hardware feature.

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2441

Quoted 1 line
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
+	 * Hardware counters will reset after switching the monotor mode.

monotor -> monitor

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2443

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+	 * Reset the internal counters so that it is not considered as
+	 * an overflow in next update.

For the first time the term "internal counters" is introduced. What does it mean?

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+	 */
+	list_for_each_entry(d, &r->domains, list) {
+		on_each_cpu_mask(&d->cpu_mask, resctrl_abmc_set_one, &enable, 1);
+		resctrl_arch_reset_rmid_all(r, d);
+	}
+
+	return 0;
+}
+
+int resctrl_abmc_enable(enum resctrl_res_level l)

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2463

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+{
+	struct rdt_hw_resource *hw_res = &rdt_resources_all[l];
+	int ret = 0;
+
+	lockdep_assert_held(&rdtgroup_mutex);
+
+	if (!hw_res->abmc_enabled) {
+		ret = resctrl_abmc_set_all(l, true);
+		if (!ret)
+			hw_res->abmc_enabled = true;

This error handling seems useless since resctrl_abmc_set_all() always returns 0 ... perhaps it should return void instead and this error handling dropped? With that this function can never fail either and it can just return void, but this is probably not what we want as the architecture call since other architectures may fail.

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+	}
+
+	return ret;
+}
+
+void resctrl_abmc_disable(enum resctrl_res_level l)
+{
+	struct rdt_hw_resource *hw_res = &rdt_resources_all[l];
+
+	lockdep_assert_held(&rdtgroup_mutex);

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2483

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+
+	if (hw_res->abmc_enabled) {
+		resctrl_abmc_set_all(l, false);
+		hw_res->abmc_enabled = false;
+	}
+}
+
  /*
   * We don't allow rdtgroup directories to be created anywhere
   * except the root directory. Thus when looking for the rdtgroup

Reinette

author reviewer
#19 lore raw

Re: [PATCH v4 07/19] x86/resctrl: Add support to enable/disable ABMC feature

Hi Reinette,

Quoted 19 lines · Reinette Chatre

Hi Babu,

Quoted 8 lines · Babu Moger

Add the functionality to enable/disable ABMC feature.

ABMC feature is enabled by setting enabled bit(0) in MSR L3_QOS_EXT_CFG. When the state of ABMC is changed, the MSR needs to be updated on all the logical processors in the QOS Domain.

Hardware counters will reset when ABMC state is changed. Kernel internal counters need to be reset to avoid overflow condition in the next update.

Please note that there are two "ABMC" features introduced in this series. First, there is the "abmc" resctrl fs feature that just happens to have the same name as AMD's "ABMC" (which may be a good motivation to change this name). Second, there is the architecture (AMD) specific "ABMC" feature that is enabled in response to user's request to enable the resctrl "abmc" feature.

Quoted 5 lines

Other architectures need to support resctrl fs "abmc" feature with something entirely different.

Please consider this distinction during this series because it is often blurred.

I was explainaing the enablement of AMD's ABMC feature here. I can add text about it.

Quoted 76 lines
Quoted 69 lines

The ABMC feature details are documented in APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Removed resctrl_arch_set_abmc_enabled and resctrl_arch_get_abmc_enabled.
     Directly calling resctrl_abmc_enable and resctrl_abmc_disable. Renamed couple of functions. resctrl_abmc_msrwrite() -> resctrl_abmc_set_one() resctrl_abmc_setup() -> resctrl_abmc_set_all() Added rdtgroup_mutex lockdep asserts.
     Updated commit log and code comments.

v3: No changes.

v2: Few text changes in commit message.
---
  arch/x86/include/asm/msr-index.h       |  1 + arch/x86/kernel/cpu/resctrl/internal.h |  8 ++++ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 62 ++++++++++++++++++++++++++

  3 files changed, 71 insertions(+)
arch/x86/include/asm/msr-index.h +1 -0
index e022e6eb766c..5f9a0139e98c 100644
@@ -1171,6 +1171,7 @@
   #define MSR_IA32_MBA_BW_BASE        0xc0000200
   #define MSR_IA32_SMBA_BW_BASE        0xc0000280
   #define MSR_IA32_EVT_CFG_BASE        0xc0000400
+#define MSR_IA32_L3_QOS_EXT_CFG        0xc00003ff
     /* MSR_IA32_VMX_MISC bits */
   #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +0 -0
index d566251094b2..fabe40304798 100644
@@ -97,6 +97,9 @@ cpumask_any_housekeeping(const struct cpumask *mask,
 int exclude_cpu)
       return cpu;
   }

  +/* Setting bit 0 in L3_QOS_EXT_CFG enables the ABMC feature */

arch/x86/kernel/cpu/resctrl/internal.h +2 -0
+#define ABMC_ENABLE            BIT(0)
+

  struct rdt_fs_context {
      struct kernfs_fs_context    kfc;
      bool                enable_cdpl2;

arch/x86/kernel/cpu/resctrl/internal.h +2 -0
@@ -436,6 +439,7 @@ struct rdt_parse_data {
    * @mbm_cfg_mask:    Bandwidth sources that can be tracked when Bandwidth
    *            Monitoring Event Configuration (BMEC) is supported.
    * @cdp_enabled:    CDP state of this resource
+ * @abmc_enabled:    ABMC feature is enabled
    *
    * Members of this structure are either private to the architecture
    * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g.
@@ -450,6 +454,7 @@ struct rdt_hw_resource {
       unsigned int        mbm_width;
       unsigned int        mbm_cfg_mask;
       bool            cdp_enabled;
+    bool            abmc_enabled;
   };
Quoted 1 line

ok, so here by making "abmc_enabled" a member of struct rdt_hw_resource this is
an architecture specific property. This is reasonable since every architecture
will look different. What is _not_ ok is that this causes the rest of the

Quoted 8 lines

series to change resctrl fs to reach into the architecture code. For example, this work causes mbm_config_show() to now need to peek into struct rdt_hw_resource
to see this value. That is not ok. All of the interactions between this field and resctrl fs needs to be via arch helpers:
resctrl_arch_abmc_enable()/
resctrl_arch_abmc_disable() and resctrl_arch_get_abmc_enabled()/resctrl_arch_set_abmc_enabled().

Sure. Will change it.

Quoted 11 lines
Quoted 9 lines

  static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r)

arch/x86/kernel/cpu/resctrl/internal.h +0 -0
@@ -493,6 +498,9 @@ static inline bool resctrl_arch_get_cdp_enabled(enum
 resctrl_res_level l)

    int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable);
  +int resctrl_abmc_enable(enum resctrl_res_level l); +void resctrl_abmc_disable(enum resctrl_res_level l);

Why do these need enum resctrl_res_level parameter?

It is really not required. It is always "RDT_RESOURCE_L3". I can remove it.

Quoted 26 lines
Quoted 26 lines

+
  /*
   * To return the common struct rdt_resource, which is contained in struct
   * rdt_hw_resource, walk the resctrl member of struct rdt_hw_resource.

arch/x86/kernel/cpu/resctrl/rdtgroup.c +11 -0
index ca692712b393..9148d1234ede 100644
@@ -2416,6 +2416,68 @@ int resctrl_arch_set_cdp_enabled(enum
 resctrl_res_level l, bool enable)
       return 0;
   }
   +static void resctrl_abmc_set_one(void *arg)
+{
+    bool *enable = arg;
+    u64 msrval;
+
+    rdmsrl(MSR_IA32_L3_QOS_EXT_CFG, msrval);
+
+    if (*enable)
+        msrval |= ABMC_ENABLE;
+    else
+        msrval &= ~ABMC_ENABLE;
+
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2434

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+    wrmsrl(MSR_IA32_L3_QOS_EXT_CFG, msrval);
+}
+
+static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)

Should this function and resctrl_abmc_set_one() perhaps have "amd" in the name just to enforce that this is not filesystem code at all and specific and unique to AMD.

Sure.

Quoted 9 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2440

Quoted 7 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
+{
+    struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
+    struct rdt_domain *d;
+
+    /*
+     * Update QOS_CFG MSR on all the CPUs associated with the resource

end of sentence needs "."

Sure.

Quoted 4 lines

This comment about the specific register seems more appropriate to resctrl_abmc_set_one() though. This function is a higher level enable/disable of the hardware feature.

Ok.

Quoted 4 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2441

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
+     * Hardware counters will reset after switching the monotor mode.

monotor -> monitor

Sure.

Quoted 6 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2443

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+     * Reset the internal counters so that it is not considered as
+     * an overflow in next update.

For the first time the term "internal counters" is introduced. What does it mean?

How about "mbm counters"?

Quoted 19 lines
Quoted 19 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +18 -0
+     */
+    list_for_each_entry(d, &r->domains, list) {
+        on_each_cpu_mask(&d->cpu_mask, resctrl_abmc_set_one, &enable, 1);
+        resctrl_arch_reset_rmid_all(r, d);
+    }
+
+    return 0;
+}
+
+int resctrl_abmc_enable(enum resctrl_res_level l)
+{
+    struct rdt_hw_resource *hw_res = &rdt_resources_all[l];
+    int ret = 0;
+
+    lockdep_assert_held(&rdtgroup_mutex);
+
+    if (!hw_res->abmc_enabled) {
+        ret = resctrl_abmc_set_all(l, true);
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_arch_set_cdp_enabled(enum resctrl_res_level l, bool enable) · line 2463

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+        if (!ret)
+            hw_res->abmc_enabled = true;

This error handling seems useless since resctrl_abmc_set_all() always returns 0 ... perhaps it should return void instead and this error handling dropped? With that this function can never fail either and it can just return void, but this is probably not what we want as the architecture call since other architectures may fail.

Understood.

Quoted 24 lines
Quoted 20 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +17 -0
+    }
+
+    return ret;
+}
+
+void resctrl_abmc_disable(enum resctrl_res_level l)
+{
+    struct rdt_hw_resource *hw_res = &rdt_resources_all[l];
+
+    lockdep_assert_held(&rdtgroup_mutex);
+
+    if (hw_res->abmc_enabled) {
+        resctrl_abmc_set_all(l, false);
+        hw_res->abmc_enabled = false;
+    }
+}
+
   /*
    * We don't allow rdtgroup directories to be created anywhere
Quoted 1 line

   * except the root directory. Thus when looking for the rdtgroup

Reinette

Signature · 2 lines
Thanks
Babu Moger
maintainer
#20 lore raw

Re: [PATCH v4 07/19] x86/resctrl: Add support to enable/disable ABMC feature

Hi Babu,

Quoted 10 lines · Babu
Quoted 7 lines · Reinette Chatre
Quoted 2 lines · Babu Moger

+     * Reset the internal counters so that it is not considered as +     * an overflow in next update.

For the first time the term "internal counters" is introduced. What does it mean?

How about "mbm counters"?

I think it refers to the state resctrl maintains to be able to catch overflows, so how about just "architectural state" with matching change of something like:

Reset the architectural state so that reading of hardware counter is not considered as an overflow in next update.

Reinette

#21 lore raw

Re: [PATCH v4 07/19] x86/resctrl: Add support to enable/disable ABMC feature

Hi Reinette,

Quoted 12 lines · Reinette Chatre

Hi Babu,

Quoted 9 lines · Babu
Quoted 7 lines · Reinette Chatre
Quoted 2 lines · Babu Moger

+     * Reset the internal counters so that it is not considered as +     * an overflow in next update.

For the first time the term "internal counters" is introduced. What does it mean?

Quoted 7 lines
Quoted 1 line

How about "mbm counters"?

I think it refers to the state resctrl maintains to be able to catch overflows, so how about just "architectural state" with matching change of something like:

    Reset the architectural state so that reading of hardware counter is not considered as an overflow in next update.

Sure. Looks good. thanks

Signature · 1 line
- Babu Moger
author reviewer
#22 lore raw

PATCH v4 8/19 x86/resctrl: Introduce the interface to display monitor mode

In reply to Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. ABMC mode is enabled by default when supported. System can be one mode at a time (Legacy monitor mode or ABMC mode).

Provide an interface to display the monitor mode on the system.

    $cat /sys/fs/resctrl/info/L3_MON/mbm_assign
    [abmc]
    legacy

---
v4: Fixed the checks for legacy and abmc mode. Default it ABMC.

v3: New patch to display ABMC capability.

---
 Documentation/arch/x86/resctrl.rst     | 10 ++++++++++
 arch/x86/kernel/cpu/resctrl/monitor.c  |  1 +
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++
 3 files changed, 34 insertions(+)
Documentation/arch/x86/resctrl.rst +10 -0
index 7ab8172ef208..ab3cde61a124 100644
@@ -261,6 +261,16 @@ with the following files:
 	Available when ABMC feature is supported. The number of ABMC counters
 	available for configuration.
 
+"mbm_assign":
+	Available when ABMC feature is supported. Reports the list of assignable
+	monitoring features supported. The enclosed brackets indicate which
+	feature is enabled.
+	::
+
+	  cat /sys/fs/resctrl/info/L3_MON/mbm_assign
+	  [abmc]
+	  mbm_legacy
+
 "max_threshold_occupancy":
 		Read/write file provides the largest value (in
 		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index e75a6146068b..b1d002e5e93d 100644
@@ -1071,6 +1071,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 
 		if (rdt_cpu_has(X86_FEATURE_ABMC)) {
 			r->abmc_capable = true;
+			resctrl_file_fflags_init("mbm_assign", RFTYPE_MON_INFO);
 			/*
 			 * Query CPUID_Fn80000020_EBX_x05 for number of
 			 * ABMC counters
arch/x86/kernel/cpu/resctrl/rdtgroup.c +23 -0
index 9148d1234ede..3071bbb7a15e 100644
@@ -856,6 +856,23 @@ static int rdtgroup_num_cntrs_show(struct kernfs_open_file *of,
 	return 0;
 }
 
+static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of,
+				    struct seq_file *s, void *v)
+{
+	struct rdt_resource *r = of->kn->parent->priv;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+
+	if (hw_res->abmc_enabled) {
+		seq_puts(s, "[abmc]\n");
+		seq_puts(s, "mbm_legacy\n");
+	} else {
+		seq_puts(s, "abmc\n");
+		seq_puts(s, "[mbm_legacy]\n");
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_PROC_CPU_RESCTRL
 
 /*
@@ -1913,6 +1930,12 @@ static struct rftype res_common_files[] = {
 		.seq_show	= mbm_local_bytes_config_show,
 		.write		= mbm_local_bytes_config_write,
 	},
+	{
+		.name		= "mbm_assign",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_mbm_assign_show,
+	},
 	{
 		.name		= "cpus",
 		.mode		= 0644,
Signature · 1 line
2.34.1
maintainer
#23 lore raw

Re: [PATCH v4 08/19] x86/resctrl: Introduce the interface to display monitor mode

Hi Babu,

Quoted 9 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. ABMC mode is enabled by default when supported. System can be one mode at a time (Legacy monitor mode or ABMC mode).

Provide an interface to display the monitor mode on the system.

     $cat /sys/fs/resctrl/info/L3_MON/mbm_assign
     [abmc]
     legacy

Output is different from cover letter and what this patch implements.

Quoted 17 lines

---
v4: Fixed the checks for legacy and abmc mode. Default it ABMC.

v3: New patch to display ABMC capability.

---
  Documentation/arch/x86/resctrl.rst     | 10 ++++++++++
  arch/x86/kernel/cpu/resctrl/monitor.c  |  1 +
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++
  3 files changed, 34 insertions(+)
Documentation/arch/x86/resctrl.rst +0 -0
index 7ab8172ef208..ab3cde61a124 100644

Documentation/arch/x86/resctrl.rst with the following files: · line 264

Quoted 4 lines
Documentation/arch/x86/resctrl.rst +1 -0
@@ -261,6 +261,16 @@ with the following files:
  	Available when ABMC feature is supported. The number of ABMC counters
  	available for configuration.
 
+"mbm_assign":

This name is not ideal but I am having trouble finding a better one ... I have seen you use "monitor mode" a couple of times (even in shortlog), so maybe that could be the start of a more generic name? "mbm_mode"?

Documentation/arch/x86/resctrl.rst with the following files: · line 265

Quoted 1 line
Documentation/arch/x86/resctrl.rst +1 -0
+	Available when ABMC feature is supported. Reports the list of assignable

Why not always make this file available? At least it will display that legacy mode is supported and it gives user space an always present file to query to determine support.

Quoted 28 lines
Documentation/arch/x86/resctrl.rst +8 -0
+	monitoring features supported. The enclosed brackets indicate which
+	feature is enabled.
+	::
+
+	  cat /sys/fs/resctrl/info/L3_MON/mbm_assign
+	  [abmc]
+	  mbm_legacy
+
  "max_threshold_occupancy":
  		Read/write file provides the largest value (in
  		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index e75a6146068b..b1d002e5e93d 100644
@@ -1071,6 +1071,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 
  		if (rdt_cpu_has(X86_FEATURE_ABMC)) {
  			r->abmc_capable = true;
+			resctrl_file_fflags_init("mbm_assign", RFTYPE_MON_INFO);
  			/*
  			 * Query CPUID_Fn80000020_EBX_x05 for number of
  			 * ABMC counters
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 9148d1234ede..3071bbb7a15e 100644

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_num_cntrs_show(struct kernfs_open_file *of, · line 863

Quoted 8 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
@@ -856,6 +856,23 @@ static int rdtgroup_num_cntrs_show(struct kernfs_open_file *of,
  	return 0;
  }
 
+static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of,
+				    struct seq_file *s, void *v)
+{
+	struct rdt_resource *r = of->kn->parent->priv;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);

Please use arch helper to just get abmc state instead of fs code digging into arch structures.

Quoted 18 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +12 -0
+
+	if (hw_res->abmc_enabled) {
+		seq_puts(s, "[abmc]\n");
+		seq_puts(s, "mbm_legacy\n");
+	} else {
+		seq_puts(s, "abmc\n");
+		seq_puts(s, "[mbm_legacy]\n");
+	}
+
+	return 0;
+}
+
  #ifdef CONFIG_PROC_CPU_RESCTRL
 
  /*
@@ -1913,6 +1930,12 @@ static struct rftype res_common_files[] = {
  		.seq_show	= mbm_local_bytes_config_show,
  		.write		= mbm_local_bytes_config_write,

arch/x86/kernel/cpu/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 1941

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
  	},
+	{
+		.name		= "mbm_assign",
+		.mode		= 0444,
+		.kf_ops		= &rdtgroup_kf_single_ops,
+		.seq_show	= rdtgroup_mbm_assign_show,
+	},
  	{
  		.name		= "cpus",
  		.mode		= 0644,

Reinette

author reviewer
#24 lore raw

Re: [PATCH v4 08/19] x86/resctrl: Introduce the interface to display monitor mode

Hi Reinette,

Quoted 8 lines · Reinette Chatre

Hi Babu,

Quoted 5 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. ABMC mode is enabled by default when supported. System can be one mode at a time (Legacy monitor mode or ABMC mode).

Quoted 6 lines
Quoted 4 lines

Provide an interface to display the monitor mode on the system. $cat /sys/fs/resctrl/info/L3_MON/mbm_assign [abmc]
     legacy

Output is different from cover letter and what this patch implements.

My bad. Will fix it,

Quoted 13 lines
Quoted 13 lines

---
v4: Fixed the checks for legacy and abmc mode. Default it ABMC.

v3: New patch to display ABMC capability.
---
  Documentation/arch/x86/resctrl.rst     | 10 ++++++++++ arch/x86/kernel/cpu/resctrl/monitor.c  |  1 + arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++

  3 files changed, 34 insertions(+)
Quoted 15 lines
Quoted 9 lines
Documentation/arch/x86/resctrl.rst +0 -0
index 7ab8172ef208..ab3cde61a124 100644
@@ -261,6 +261,16 @@ with the following files:

      Available when ABMC feature is supported. The number of ABMC counters available for configuration.
  +"mbm_assign":

This name is not ideal but I am having trouble finding a better one ... I have
seen you use "monitor mode" a couple of times (even in shortlog), so maybe that
could be the start of a more generic name? "mbm_mode"?

mbm_mode sounds good. Like this.

$cat /sys/fs/resctrl/info/L3_MON/mbm_mode
[abmc]
legacy

Keeping just "legacy" vs mbm_legacy.

Quoted 8 lines
Quoted 3 lines

+    Available when ABMC feature is supported. Reports the list of assignable

Why not always make this file available? At least it will display that legacy mode is supported and it gives user space an always present file to query to
determine support.

Ok. Sure.

Quoted 34 lines
Quoted 34 lines

+    monitoring features supported. The enclosed brackets indicate which +    feature is enabled.
+    ::

Documentation/arch/x86/resctrl.rst +5 -0
+
+      cat /sys/fs/resctrl/info/L3_MON/mbm_assign
+      [abmc]
+      mbm_legacy
+

  "max_threshold_occupancy":
          Read/write file provides the largest value (in bytes) at which a previously used LLC_occupancy

arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index e75a6146068b..b1d002e5e93d 100644
@@ -1071,6 +1071,7 @@ int __init rdt_get_mon_l3_config(struct
 rdt_resource *r)
             if (rdt_cpu_has(X86_FEATURE_ABMC)) {
               r->abmc_capable = true;
+            resctrl_file_fflags_init("mbm_assign", RFTYPE_MON_INFO);
               /*
                * Query CPUID_Fn80000020_EBX_x05 for number of
                * ABMC counters
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 9148d1234ede..3071bbb7a15e 100644
@@ -856,6 +856,23 @@ static int rdtgroup_num_cntrs_show(struct
 kernfs_open_file *of,
       return 0;
   }
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_num_cntrs_show(struct kernfs_open_file *of, · line 863

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
   +static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of,
+                    struct seq_file *s, void *v)
+{
+    struct rdt_resource *r = of->kn->parent->priv;
+    struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);

Please use arch helper to just get abmc state instead of fs code digging into arch structures.

Ok. I will use "resctrl_arch_get_abmc_enabled()" to get abmc state.

Quoted 31 lines
Quoted 18 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +12 -0
+
+    if (hw_res->abmc_enabled) {
+        seq_puts(s, "[abmc]\n");
+        seq_puts(s, "mbm_legacy\n");
+    } else {
+        seq_puts(s, "abmc\n");
+        seq_puts(s, "[mbm_legacy]\n");
+    }
+
+    return 0;
+}
+
   #ifdef CONFIG_PROC_CPU_RESCTRL
     /*
@@ -1913,6 +1930,12 @@ static struct rftype res_common_files[] = {
           .seq_show    = mbm_local_bytes_config_show,
           .write        = mbm_local_bytes_config_write,

arch/x86/kernel/cpu/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 1941

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
       },
+    {
+        .name        = "mbm_assign",
+        .mode        = 0444,
+        .kf_ops        = &rdtgroup_kf_single_ops,
+        .seq_show    = rdtgroup_mbm_assign_show,
+    },
       {
           .name        = "cpus",
           .mode        = 0644,

Reinette

Signature · 2 lines
Thanks
Babu Moger
maintainer
#25 lore raw

Re: [PATCH v4 08/19] x86/resctrl: Introduce the interface to display monitor mode

Hi Babu,

Quoted 16 lines · Babu
Quoted 14 lines · Reinette Chatre

Documentation/arch/x86/resctrl.rst with the following files: · line 263

Quoted 6 lines · Babu Moger
Documentation/arch/x86/resctrl.rst +0 -0
@@ -261,6 +261,16 @@ with the following files:
       Available when ABMC feature is supported. The number of ABMC counters
       available for configuration.
   +"mbm_assign":

This name is not ideal but I am having trouble finding a better one ... I have
seen you use "monitor mode" a couple of times (even in shortlog), so maybe that
could be the start of a more generic name? "mbm_mode"?

Quoted 8 lines

mbm_mode sounds good. Like this.

$cat /sys/fs/resctrl/info/L3_MON/mbm_mode
[abmc]
legacy

Keeping just "legacy" vs mbm_legacy.

Looks good to me. This sounds generic enough to build on.

Reinette

#26 lore raw

Re: [PATCH v4 08/19] x86/resctrl: Introduce the interface to display monitor mode

Quoted 21 lines · Reinette Chatre

Hi Babu,

Quoted 18 lines · Babu
Quoted 14 lines · Reinette Chatre
Quoted 6 lines · Babu Moger
Documentation/arch/x86/resctrl.rst +0 -0
@@ -261,6 +261,16 @@ with the following files:

       Available when ABMC feature is supported. The number of ABMC counters available for configuration.
   +"mbm_assign":

This name is not ideal but I am having trouble finding a better one ... I have
seen you use "monitor mode" a couple of times (even in shortlog), so maybe that
could be the start of a more generic name? "mbm_mode"?

mbm_mode sounds good. Like this.

Quoted 8 lines
Quoted 6 lines

$cat /sys/fs/resctrl/info/L3_MON/mbm_mode
[abmc]
legacy

Keeping just "legacy" vs mbm_legacy.

Looks good to me. This sounds generic enough to build on.

Thanks

Signature · 1 line
- Babu Moger
author reviewer
#27 lore raw

PATCH v4 9/19 x86/resctrl: Initialize ABMC counters bitmap

In reply to Babu Moger

Hardware provides a set of counters when the ABMC feature is supported. These counters are used for enabling the events in resctrl group when the feature is supported.

Introduce num_cntrs_free_map bitmap to track available and free counters.

---
v4: Changed the name to num_cntrs where applicable.
Used bitmap apis.
Added more comments for the globals.

v3: Changed the bitmap name to assign_cntrs_free_map. Removed abmc
from the name.

v2: Changed the bitmap name to assignable_counter_free_map from
abmc_counter_free_map.

---
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +23 -0
index 3071bbb7a15e..400ae405e10e 100644
@@ -186,6 +186,23 @@ bool closid_allocated(unsigned int closid)
 	return !test_bit(closid, &closid_free_map);
 }
 
+/*
+ * ABMC Counter bitmap and length for tracking available counters.
+ * ABMC feature provides set of hardware counters for enabling events.
+ * Each event takes one hardware counter. Kernel needs to keep track
+ * of number of available counters.
+ */
+static unsigned long num_cntrs_free_map;
+static u32 num_cntrs_free_map_len;
+
+static void num_cntrs_init(void)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
+	bitmap_fill(&num_cntrs_free_map, r->mon.num_cntrs);
+	num_cntrs_free_map_len = r->mon.num_cntrs;
+}
+
 /**
  * rdtgroup_mode_by_closid - Return mode of resource group with closid
  * @closid: closid if the resource group
@@ -2459,6 +2476,12 @@ static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)
 	struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
 	struct rdt_domain *d;
 
+	/*
+	 * The bitmap num_cntrs_free_map needs to be reset when switching
+	 * the monitor mode.
+	 */
+	num_cntrs_init();
+
 	/*
 	 * Update QOS_CFG MSR on all the CPUs associated with the resource
 	 * Hardware counters will reset after switching the monotor mode.
Signature · 1 line
2.34.1
maintainer
#28 lore raw

Re: [PATCH v4 09/19] x86/resctrl: Initialize ABMC counters bitmap

Hi Babu,

Quoted 26 lines · Babu Moger

Hardware provides a set of counters when the ABMC feature is supported. These counters are used for enabling the events in resctrl group when the feature is supported.

Introduce num_cntrs_free_map bitmap to track available and free counters.

---
v4: Changed the name to num_cntrs where applicable.
Used bitmap apis.
Added more comments for the globals.

v3: Changed the bitmap name to assign_cntrs_free_map. Removed abmc
from the name.

v2: Changed the bitmap name to assignable_counter_free_map from
abmc_counter_free_map.

---
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++
  1 file changed, 23 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 3071bbb7a15e..400ae405e10e 100644

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 195

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
@@ -186,6 +186,23 @@ bool closid_allocated(unsigned int closid)
  	return !test_bit(closid, &closid_free_map);
  }
 
+/*
+ * ABMC Counter bitmap and length for tracking available counters.
+ * ABMC feature provides set of hardware counters for enabling events.
+ * Each event takes one hardware counter. Kernel needs to keep track
+ * of number of available counters.
+ */
+static unsigned long num_cntrs_free_map;

Why does variable have "num" in its name? That seems strange. How about just "mon_cntrs_free_map

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 196

Quoted 1 line
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
+static u32 num_cntrs_free_map_len;

Same comment about "num" ... also, any special reason why u32 is needed?

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 198

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+
+static void num_cntrs_init(void)

mon_cntrs_init() ?

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)

Quoted 11 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
+	bitmap_fill(&num_cntrs_free_map, r->mon.num_cntrs);
+	num_cntrs_free_map_len = r->mon.num_cntrs;
+}
+
  /**
   * rdtgroup_mode_by_closid - Return mode of resource group with closid
   * @closid: closid if the resource group
@@ -2459,6 +2476,12 @@ static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)

resctrl_abmc_set_all() was initially created as a complement of resctrl_abmc_set_one() ... but with more initialization added to resctrl_abmc_set_all() this relationship becomes vague.

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable) · line 2481

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
  	struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
  	struct rdt_domain *d;
 
+	/*
+	 * The bitmap num_cntrs_free_map needs to be reset when switching
+	 * the monitor mode.

This comment puts in words what can be understood by just looking at the code. What would be useful would be to explain _why_ this needs to be done ... what happens to the previously assigned counters?

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable) · line 2487

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
+	 */
+	num_cntrs_init();
+
  	/*
  	 * Update QOS_CFG MSR on all the CPUs associated with the resource
  	 * Hardware counters will reset after switching the monotor mode.

Reinette

author reviewer
#29 lore raw

Re: [PATCH v4 09/19] x86/resctrl: Initialize ABMC counters bitmap

Hi Reinette,

Quoted 34 lines · Reinette Chatre

Hi Babu,

Quoted 31 lines · Babu Moger

Hardware provides a set of counters when the ABMC feature is supported. These counters are used for enabling the events in resctrl group when the feature is supported.

Introduce num_cntrs_free_map bitmap to track available and free counters.

---
v4: Changed the name to num_cntrs where applicable. Used bitmap apis.
     Added more comments for the globals.

v3: Changed the bitmap name to assign_cntrs_free_map. Removed abmc from the name.

v2: Changed the bitmap name to assignable_counter_free_map from abmc_counter_free_map.
---
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 23 +++++++++++++++++++++++

  1 file changed, 23 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 3071bbb7a15e..400ae405e10e 100644
@@ -186,6 +186,23 @@ bool closid_allocated(unsigned int closid)
       return !test_bit(closid, &closid_free_map);
   }

  +/*
+ * ABMC Counter bitmap and length for tracking available counters.

Quoted 8 lines
Quoted 5 lines

+ * ABMC feature provides set of hardware counters for enabling events.
+ * Each event takes one hardware counter. Kernel needs to keep track
+ * of number of available counters.
+ */
+static unsigned long num_cntrs_free_map;

Why does variable have "num" in its name? That seems strange. How about just "mon_cntrs_free_map

It came from patch 4/19.

struct resctrl_mon {
        int                     num_rmid;
+       int                     num_cntrs;
        struct list_head        evt_list;

};

num_cntrs_free_map is a bitmap representing num_cntrs. Kept the matching name for better understanding. Renaming it will loose that connection. If I rename then I will have to rename both.

How about mbm_cntrs and mbm_cntrs_free_map?

Quoted 4 lines
Quoted 2 lines

+static u32 num_cntrs_free_map_len;

Same comment about "num" ... also, any special reason why u32 is needed?

Only reason is, it is supposed to be unsigned. I can change it "unsigned int".

Quoted 5 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 198

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+
+static void num_cntrs_init(void)

mon_cntrs_init() ?

mbm_cntrs_init?

Quoted 10 lines
Quoted 10 lines

+{
+    struct rdt_resource *r =
&rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;

arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+
+    bitmap_fill(&num_cntrs_free_map, r->mon.num_cntrs);
+    num_cntrs_free_map_len = r->mon.num_cntrs;
+}
+

  /**

Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum · line 2476

Quoted 4 lines

   * rdtgroup_mode_by_closid - Return mode of resource group with closid
   * @closid: closid if the resource group

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -2459,6 +2476,12 @@ static int resctrl_abmc_set_all(enum
 resctrl_res_level l, bool enable)

resctrl_abmc_set_all() was initially created as a complement of resctrl_abmc_set_one() ... but with more initialization added to resctrl_abmc_set_all() this relationship becomes vague.

Yes. Understood. Let me know if want me to change anything here.

Quoted 11 lines
Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
       struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
       struct rdt_domain *d;

  +    /*
+     * The bitmap num_cntrs_free_map needs to be reset when switching +     * the monitor mode.

This comment puts in words what can be understood by just looking at the code.
What would be useful would be to explain _why_ this needs to be done ... what happens to the previously assigned counters?

Sure. Will add more details.

Quoted 11 lines
Quoted 8 lines

+     */
+    num_cntrs_init();
+
      /*
       * Update QOS_CFG MSR on all the CPUs associated with the resource
       * Hardware counters will reset after switching the monotor mode.

Reinette

Signature · 2 lines
Thanks
Babu Moger
maintainer
#30 lore raw

Re: [PATCH v4 09/19] x86/resctrl: Initialize ABMC counters bitmap

Hi Babu,

Quoted 2 lines · Babu
Quoted 1 line · Reinette Chatre

On 5/24/24 5:23 AM, Babu Moger wrote:

...

Quoted 21 lines
Quoted 10 lines
Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
index 3071bbb7a15e..400ae405e10e 100644
@@ -186,6 +186,23 @@ bool closid_allocated(unsigned int closid)
       return !test_bit(closid, &closid_free_map);
   }
   +/*
+ * ABMC Counter bitmap and length for tracking available counters.
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 195

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+ * ABMC feature provides set of hardware counters for enabling events.
+ * Each event takes one hardware counter. Kernel needs to keep track
+ * of number of available counters.
+ */
+static unsigned long num_cntrs_free_map;

Why does variable have "num" in its name? That seems strange. How about just "mon_cntrs_free_map

It came from patch 4/19.

Quoted 8 lines
struct resctrl_mon {
         int                     num_rmid;
+       int                     num_cntrs;
         struct list_head        evt_list;

};

num_cntrs_free_map is a bitmap representing num_cntrs. Kept the matching name for better understanding. Renaming it will loose that connection.

I disagree. The "num" in "num_cntrs" indicates that this variable stores the _number_ of a particular entity. In this case "cntrs" or ... counters. This is just like how resctrl uses "num_closid" to indicate how many closid are available and then have a separate "closid_free_map" to actually track now closids are used ... it is _not_ "num_closid_free_map". Similarly, "num_rmid" indicates how many RMID are available and the "rmid_free_lru" tracks how RMID are used ... it is _not_ "num_rmid_free_lru".

Quoted 1 line

If I rename then I will have to rename both.

No, you do not.

Quoted 2 lines

How about mbm_cntrs and mbm_cntrs_free_map?

"mbm_cntrs" does sound good. It is more specific than "cntrs". I would suggest that use "num_mbm_cntrs" to match with "num_rmid" and "num_closid" and then you can introduce "mbm_cntrs_free_map".

Quoted 8 lines
Quoted 3 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 196

Quoted 1 line
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
+static u32 num_cntrs_free_map_len;

Same comment about "num" ... also, any special reason why u32 is needed?

Only reason is, it is supposed to be unsigned. I can change it "unsigned int".

Quoted 1 line
Quoted 6 lines
Quoted 4 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 198

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+
+static void num_cntrs_init(void)

mon_cntrs_init() ?

mbm_cntrs_init?

Sounds good.

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+{
+    struct rdt_resource *r =
 &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
+    bitmap_fill(&num_cntrs_free_map, r->mon.num_cntrs);
+    num_cntrs_free_map_len = r->mon.num_cntrs;
+}
+
   /**
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum · line 2476

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
    * rdtgroup_mode_by_closid - Return mode of resource group with closid
    * @closid: closid if the resource group
@@ -2459,6 +2476,12 @@ static int resctrl_abmc_set_all(enum
 resctrl_res_level l, bool enable)

resctrl_abmc_set_all() was initially created as a complement of resctrl_abmc_set_one() ... but with more initialization added to resctrl_abmc_set_all() this relationship becomes vague.

Quoted 1 line

Yes. Understood. Let me know if want me to change anything here.

How about renaming resctrl_abmc_set_all() to _resctrl_abmc_enable()?

Reinette

#31 lore raw

Re: [PATCH v4 09/19] x86/resctrl: Initialize ABMC counters bitmap

Hi Reinette,

Quoted 48 lines · Reinette Chatre

Hi Babu,

Quoted 2 lines · Babu
Quoted 1 line · Reinette Chatre

On 5/24/24 5:23 AM, Babu Moger wrote:

...

Quoted 21 lines
Quoted 10 lines
Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 3071bbb7a15e..400ae405e10e 100644
@@ -186,6 +186,23 @@ bool closid_allocated(unsigned int closid)
        return !test_bit(closid, &closid_free_map);
    }

   +/*
+ * ABMC Counter bitmap and length for tracking available counters.

Quoted 8 lines
Quoted 5 lines

+ * ABMC feature provides set of hardware counters for enabling events.
+ * Each event takes one hardware counter. Kernel needs to keep track
+ * of number of available counters.
+ */
+static unsigned long num_cntrs_free_map;

Why does variable have "num" in its name? That seems strange. How about just "mon_cntrs_free_map

It came from patch 4/19.

Quoted 8 lines

struct resctrl_mon {
         int                     num_rmid;
+       int                     num_cntrs;
         struct list_head        evt_list;
  };

num_cntrs_free_map is a bitmap representing num_cntrs. Kept the matching name for better understanding. Renaming it will loose that connection.

I disagree. The "num" in "num_cntrs" indicates that this variable stores the _number_ of a particular entity. In this case "cntrs" or ... counters. This is just like how resctrl uses "num_closid" to indicate how many closid are available and then have a separate "closid_free_map" to actually track now closids are used ... it is _not_ "num_closid_free_map". Similarly, "num_rmid" indicates how many RMID are available and the "rmid_free_lru" tracks how RMID are used ... it is _not_ "num_rmid_free_lru".

Quoted 1 line

If I rename then I will have to rename both.

Quoted 8 lines

No, you do not.

Quoted 2 lines

How about mbm_cntrs and mbm_cntrs_free_map?

"mbm_cntrs" does sound good. It is more specific than "cntrs". I would suggest that use "num_mbm_cntrs" to match with "num_rmid" and "num_closid" and then you can introduce "mbm_cntrs_free_map".

Sure.

Quoted 9 lines
Quoted 9 lines
Quoted 4 lines
Quoted 2 lines

+static u32 num_cntrs_free_map_len;

Same comment about "num" ... also, any special reason why u32 is needed?

Only reason is, it is supposed to be unsigned.  I can change it "unsigned int".

Quoted 1 line
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c bool closid_allocated(unsigned int closid) · line 198

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+
+static void num_cntrs_init(void)

mon_cntrs_init() ?

mbm_cntrs_init?

Sounds good.

ok

Quoted 21 lines
Quoted 21 lines
Quoted 20 lines
Quoted 15 lines

+{
+    struct rdt_resource *r =
&rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;

arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+
+    bitmap_fill(&num_cntrs_free_map, r->mon.num_cntrs);
+    num_cntrs_free_map_len = r->mon.num_cntrs;
+}
+

   /**
    * rdtgroup_mode_by_closid - Return mode of resource group with closid
    * @closid: closid if the resource group

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int resctrl_abmc_set_all(enum · line 2476

Quoted 1 line
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -2459,6 +2476,12 @@ static int resctrl_abmc_set_all(enum
 resctrl_res_level l, bool enable)

resctrl_abmc_set_all() was initially created as a complement of resctrl_abmc_set_one() ... but with more initialization added to resctrl_abmc_set_all() this relationship becomes vague.

Quoted 3 lines
Quoted 1 line

Yes. Understood. Let me know if want me to change anything here.

How about renaming resctrl_abmc_set_all() to _resctrl_abmc_enable()?

Sure.

Signature · 1 line
- Babu Moger
author reviewer
#32 lore raw

PATCH v4 10/19 x86/resctrl: Introduce ABMC state for the monitor group

In reply to Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as it is assigned. There are two events per resctrl group, mbm total and mbm local. User have the option to assign or unassign each event individually.

Add a new field mon_state in mongroup data structure to represent the assignment state of the group. Reset the states when switching the monitor mode.

---
v4: Changed ASSIGN_TOTAL and ASSIGN_LOCAL to use QOS_L3_MBM_TOTAL_EVENT_ID
and QOS_L3_MBM_LOCAL_EVENT_ID.
Few more commit text changes.

v3: Changed the field name to mon_state. Also thie state is not visible to
users directly as part of out global assign approach.

v2: Added check to display "Unsupported" when user tries to access
monitor state when ABMC is not enabled.

---
 arch/x86/kernel/cpu/resctrl/internal.h | 9 +++++++++
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 8 ++++++++
 2 files changed, 17 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +9 -0
index fabe40304798..5e7e76cd512f 100644
@@ -100,6 +100,13 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
 /* Setting bit 0 in L3_QOS_EXT_CFG enables the ABMC feature */
 #define ABMC_ENABLE			BIT(0)
 
+/*
+ * monitor group's state when ABMC is supported
+ */
+#define ASSIGN_NONE			0
+#define ASSIGN_TOTAL			BIT(QOS_L3_MBM_TOTAL_EVENT_ID)
+#define ASSIGN_LOCAL			BIT(QOS_L3_MBM_LOCAL_EVENT_ID)
+
 struct rdt_fs_context {
 	struct kernfs_fs_context	kfc;
 	bool				enable_cdpl2;
@@ -203,12 +210,14 @@ enum rdtgrp_mode {
  * @parent:			parent rdtgrp
  * @crdtgrp_list:		child rdtgroup node list
  * @rmid:			rmid for this rdtgroup
+ * @mon_state:			Assignment state of the group
  */
 struct mongroup {
 	struct kernfs_node	*mon_data_kn;
 	struct rdtgroup		*parent;
 	struct list_head	crdtgrp_list;
 	u32			rmid;
+	u32			mon_state;
 };
 
 /**
arch/x86/kernel/cpu/resctrl/rdtgroup.c +8 -0
index 400ae405e10e..c176bacf7ba1 100644
@@ -2474,6 +2474,7 @@ static void resctrl_abmc_set_one(void *arg)
 static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)
 {
 	struct rdt_resource *r = &rdt_resources_all[l].r_resctrl;
+	struct rdtgroup *prgrp, *crgrp;
 	struct rdt_domain *d;
 
 	/*
@@ -2493,6 +2494,13 @@ static int resctrl_abmc_set_all(enum resctrl_res_level l, bool enable)
 		resctrl_arch_reset_rmid_all(r, d);
 	}
 
+	/* Reset assign state for all the monitor groups */
+	list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
+		prgrp->mon.mon_state = ASSIGN_NONE;
+		list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list)
+			crgrp->mon.mon_state = ASSIGN_NONE;
+	}
+
 	return 0;
 }
 
Signature · 1 line
2.34.1
author reviewer
#33 lore raw

PATCH v4 11/19 x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

In reply to Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize.
Added few commit messages.
Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.

---
 arch/x86/kernel/cpu/resctrl/core.c     |  2 ++
 arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++
 arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++
 3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +2 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
 		return;
 	}
 
+	arch_domain_mbm_evt_config(hw_dom);
+
 	list_add_tail_rcu(&d->list, add_pos);
 
 	err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +5 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
  * @ctrl_val:	array of cache or mem ctrl values (indexed by CLOSID)
  * @arch_mbm_total:	arch private state for MBM total bandwidth
  * @arch_mbm_local:	arch private state for MBM local bandwidth
+ * @mbm_total_cfg:	MBM total bandwidth configuration
+ * @mbm_local_cfg:	MBM local bandwidth configuration
  *
  * Members of this structure are accessed via helpers that provide abstraction.
  */
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
 	u32				*ctrl_val;
 	struct arch_mbm_state		*arch_mbm_total;
 	struct arch_mbm_state		*arch_mbm_local;
+	u32				mbm_total_cfg;
+	u32				mbm_local_cfg;
 };
 
 static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)
@@ -622,6 +626,7 @@ void __check_limbo(struct rdt_domain *d, bool force_free);
 void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
 void __init resctrl_file_fflags_init(const char *config,
 				     unsigned long fflags);
+void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
 void rdt_staged_configs_clear(void);
 bool closid_allocated(unsigned int closid);
 int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/monitor.c +21 -0
index b1d002e5e93d..ab0f4bb49bd9 100644
@@ -1093,6 +1093,27 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 	return 0;
 }
 
+void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom)
+{
+	u64 msrval;
+
+	/*
+	 * Read the configuration registers QOS_EVT_CFG_n, where <n> is
+	 * the BMEC event number (EvtID).
+	 * 0 for evtid == QOS_L3_MBM_TOTAL_EVENT_ID
+	 * 1 for evtid == QOS_L3_MBM_LOCAL_EVENT_ID
+	 */
+	if (mbm_total_event.configurable) {
+		rdmsrl(MSR_IA32_EVT_CFG_BASE, msrval);
+		hw_dom->mbm_total_cfg = msrval & MAX_EVT_CONFIG_BITS;
+	}
+
+	if (mbm_local_event.configurable) {
+		rdmsrl(MSR_IA32_EVT_CFG_BASE + 1, msrval);
+		hw_dom->mbm_local_cfg = msrval & MAX_EVT_CONFIG_BITS;
+	}
+}
+
 void __exit rdt_put_mon_l3_config(void)
 {
 	dom_data_exit();
Signature · 1 line
2.34.1
maintainer
#34 lore raw

Re: [PATCH v4 11/19] x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

Hi Babu,

Quoted 54 lines · Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize.
Added few commit messages.
Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.

---
  arch/x86/kernel/cpu/resctrl/core.c     |  2 ++
  arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++
  arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++
  3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +2 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
  		return;
  	}
 
+	arch_domain_mbm_evt_config(hw_dom);
+
  	list_add_tail_rcu(&d->list, add_pos);
 
  	err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
   * @ctrl_val:	array of cache or mem ctrl values (indexed by CLOSID)
   * @arch_mbm_total:	arch private state for MBM total bandwidth
   * @arch_mbm_local:	arch private state for MBM local bandwidth
+ * @mbm_total_cfg:	MBM total bandwidth configuration
+ * @mbm_local_cfg:	MBM local bandwidth configuration
   *
   * Members of this structure are accessed via helpers that provide abstraction.
   */

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_domain { · line 388

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
  	u32				*ctrl_val;
  	struct arch_mbm_state		*arch_mbm_total;
  	struct arch_mbm_state		*arch_mbm_local;
+	u32				mbm_total_cfg;
+	u32				mbm_local_cfg;
  };

Similar to the abmc_enabled member of rdt_hw_resource, these new members of rdt_hw_domain are architecture specific and should never be touched directly by resctrl fs code, for example, from mbm_config_show().

Quoted 17 lines
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
  static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)
@@ -622,6 +626,7 @@ void __check_limbo(struct rdt_domain *d, bool force_free);
  void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
  void __init resctrl_file_fflags_init(const char *config,
  				     unsigned long fflags);
+void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
  void rdt_staged_configs_clear(void);
  bool closid_allocated(unsigned int closid);
  int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/monitor.c +0 -0
index b1d002e5e93d..ab0f4bb49bd9 100644
@@ -1093,6 +1093,27 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
  	return 0;
  }

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1104

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/monitor.c +9 -0
 
+void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom)
+{
+	u64 msrval;
+
+	/*
+	 * Read the configuration registers QOS_EVT_CFG_n, where <n> is
+	 * the BMEC event number (EvtID).
+	 * 0 for evtid == QOS_L3_MBM_TOTAL_EVENT_ID
+	 * 1 for evtid == QOS_L3_MBM_LOCAL_EVENT_ID

This is what mon_event_config_index_get() is for, no?

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/monitor.c +5 -0
+	 */
+	if (mbm_total_event.configurable) {
+		rdmsrl(MSR_IA32_EVT_CFG_BASE, msrval);
+		hw_dom->mbm_total_cfg = msrval & MAX_EVT_CONFIG_BITS;
+	}

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1119

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/monitor.c +7 -0
+
+	if (mbm_local_event.configurable) {
+		rdmsrl(MSR_IA32_EVT_CFG_BASE + 1, msrval);
+		hw_dom->mbm_local_cfg = msrval & MAX_EVT_CONFIG_BITS;
+	}
+}
+
  void __exit rdt_put_mon_l3_config(void)
  {
  	dom_data_exit();

Reinette

author reviewer
#35 lore raw

Re: [PATCH v4 11/19] x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

Hi Reinette,

Quoted 61 lines · Reinette Chatre

Hi Babu,

Quoted 58 lines · Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize. Added few commit messages.
     Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.
---
  arch/x86/kernel/cpu/resctrl/core.c     |  2 ++ arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++ arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++

  3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +1 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct
 rdt_resource *r)
           return;
       }
   +    arch_domain_mbm_evt_config(hw_dom);
+
       list_add_tail_rcu(&d->list, add_pos);
         err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
    * @ctrl_val:    array of cache or mem ctrl values (indexed by CLOSID)
    * @arch_mbm_total:    arch private state for MBM total bandwidth
    * @arch_mbm_local:    arch private state for MBM local bandwidth
+ * @mbm_total_cfg:    MBM total bandwidth configuration
+ * @mbm_local_cfg:    MBM local bandwidth configuration
    *
    * Members of this structure are accessed via helpers that provide

abstraction.
   */

arch/x86/kernel/cpu/resctrl/internal.h +0 -0
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
       u32                *ctrl_val;
       struct arch_mbm_state        *arch_mbm_total;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_domain { · line 388

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
       struct arch_mbm_state        *arch_mbm_local;
+    u32                mbm_total_cfg;
+    u32                mbm_local_cfg;
   };

Similar to the abmc_enabled member of rdt_hw_resource, these new members of rdt_hw_domain are architecture specific and should never be touched directly by resctrl fs code, for example, from mbm_config_show().

Yes. Understood. Will check all the accesses.

Quoted 24 lines
Quoted 24 lines

    static inline struct rdt_hw_domain *resctrl_to_arch_dom(struct rdt_domain *r)

arch/x86/kernel/cpu/resctrl/internal.h +1 -0
@@ -622,6 +626,7 @@ void __check_limbo(struct rdt_domain *d, bool
 force_free);
   void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
   void __init resctrl_file_fflags_init(const char *config,
                        unsigned long fflags);
+void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
   void rdt_staged_configs_clear(void);
   bool closid_allocated(unsigned int closid);

  int resctrl_find_cleanest_closid(void);

arch/x86/kernel/cpu/resctrl/monitor.c +2 -0
index b1d002e5e93d..ab0f4bb49bd9 100644
@@ -1093,6 +1093,27 @@ int __init rdt_get_mon_l3_config(struct
 rdt_resource *r)
       return 0;
   }
   +void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom)
+{
+    u64 msrval;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1104

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/monitor.c +6 -0
+
+    /*
+     * Read the configuration registers QOS_EVT_CFG_n, where <n> is
+     * the BMEC event number (EvtID).
+     * 0 for evtid == QOS_L3_MBM_TOTAL_EVENT_ID
+     * 1 for evtid == QOS_L3_MBM_LOCAL_EVENT_ID

This is what mon_event_config_index_get() is for, no?

Yes, it is. I can change it.

Quoted 19 lines
Quoted 15 lines
arch/x86/kernel/cpu/resctrl/monitor.c +12 -0
+     */
+    if (mbm_total_event.configurable) {
+        rdmsrl(MSR_IA32_EVT_CFG_BASE, msrval);
+        hw_dom->mbm_total_cfg = msrval & MAX_EVT_CONFIG_BITS;
+    }
+
+    if (mbm_local_event.configurable) {
+        rdmsrl(MSR_IA32_EVT_CFG_BASE + 1, msrval);
+        hw_dom->mbm_local_cfg = msrval & MAX_EVT_CONFIG_BITS;
+    }
+}
+
   void __exit rdt_put_mon_l3_config(void)
   {
Quoted 1 line

      dom_data_exit();

Reinette

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#36 lore raw

Re: [PATCH v4 11/19] x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

In reply to Reinette Chatre

Hi Reinette,

Quoted 61 lines · Reinette Chatre

Hi Babu,

Quoted 58 lines · Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize. Added few commit messages.
     Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.
---
  arch/x86/kernel/cpu/resctrl/core.c     |  2 ++ arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++ arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++

  3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +1 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct
 rdt_resource *r)
           return;
       }
   +    arch_domain_mbm_evt_config(hw_dom);
+
       list_add_tail_rcu(&d->list, add_pos);
         err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
    * @ctrl_val:    array of cache or mem ctrl values (indexed by CLOSID)
    * @arch_mbm_total:    arch private state for MBM total bandwidth
    * @arch_mbm_local:    arch private state for MBM local bandwidth
+ * @mbm_total_cfg:    MBM total bandwidth configuration
+ * @mbm_local_cfg:    MBM local bandwidth configuration
    *
    * Members of this structure are accessed via helpers that provide

abstraction.
   */

arch/x86/kernel/cpu/resctrl/internal.h +0 -0
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
       u32                *ctrl_val;
       struct arch_mbm_state        *arch_mbm_total;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_domain { · line 388

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
       struct arch_mbm_state        *arch_mbm_local;
+    u32                mbm_total_cfg;
+    u32                mbm_local_cfg;
   };

Similar to the abmc_enabled member of rdt_hw_resource, these new members of rdt_hw_domain are architecture specific and should never be touched directly by resctrl fs code, for example, from mbm_config_show().

Need some clarification here.

I am thinking you want to introduce architecture specific routines to get and set mbm_total_config/mbm_local_config for the domain. Something like this.

+int arch_get_mbm_evt_cfg(struct rdt_domain *d, enum resctrl_event_id eventid) +{
+ struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+ switch (eventid) {
+ case QOS_L3_OCCUP_EVENT_ID:
+ break;
+ case QOS_L3_MBM_TOTAL_EVENT_ID:
+ return hw_dom->mbm_total_cfg;
+ case QOS_L3_MBM_LOCAL_EVENT_ID:
+ return hw_dom->mbm_local_cfg;
+ }
+
+ /* Never expect to get here */
+ WARN_ON_ONCE(1);
+
+ return -1;
+}
+
+void arch_set_mbm_evt_cfg(struct rdt_domain *d,
+ enum resctrl_event_id eventid, u32 val)
+{
+ struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+ switch (eventid) {
+ case QOS_L3_OCCUP_EVENT_ID:
+ break;
+ case QOS_L3_MBM_TOTAL_EVENT_ID:
+ hw_dom->mbm_total_cfg = val;
+ break;
+ case QOS_L3_MBM_LOCAL_EVENT_ID:
+ hw_dom->mbm_local_cfg = val;
+ }
+
+ return;
+}
+

I have added the functions in rdtgroup.c and prototypes in internal.h. This will be called in mbm)config_show() and mbm_config_write_domain()

Did I understand this correctly?

Thanks
Babu

maintainer
#37 lore raw

Re: [PATCH v4 11/19] x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

Hi Babu,

Quoted 73 lines · Babu

Hi Reinette,

Quoted 61 lines · Reinette Chatre

Hi Babu,

Quoted 58 lines · Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize.
     Added few commit messages.
     Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.

---
   arch/x86/kernel/cpu/resctrl/core.c     |  2 ++
   arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++
   arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++
   3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +1 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct
 rdt_resource *r)
           return;
       }
   +    arch_domain_mbm_evt_config(hw_dom);
+
       list_add_tail_rcu(&d->list, add_pos);
         err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
    * @ctrl_val:    array of cache or mem ctrl values (indexed by CLOSID)
    * @arch_mbm_total:    arch private state for MBM total bandwidth
    * @arch_mbm_local:    arch private state for MBM local bandwidth
+ * @mbm_total_cfg:    MBM total bandwidth configuration
+ * @mbm_local_cfg:    MBM local bandwidth configuration
    *
    * Members of this structure are accessed via helpers that provide

abstraction.
   */

arch/x86/kernel/cpu/resctrl/internal.h +0 -0
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
       u32                *ctrl_val;
       struct arch_mbm_state        *arch_mbm_total;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_domain { · line 388

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
       struct arch_mbm_state        *arch_mbm_local;
+    u32                mbm_total_cfg;
+    u32                mbm_local_cfg;
   };

Similar to the abmc_enabled member of rdt_hw_resource, these new members of rdt_hw_domain are architecture specific and should never be touched directly by resctrl fs code, for example, from mbm_config_show().

Quoted 7 lines

Need some clarification here.

I am thinking you want to introduce architecture specific routines to get and set mbm_total_config/mbm_local_config for the domain. Something like this.

+int arch_get_mbm_evt_cfg(struct rdt_domain *d, enum resctrl_event_id eventid)

The prefix for arch specific calls converged to "resctrl_arch_".

Quoted 26 lines
(quoted diff) +26 -0
+{
+       struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+       switch (eventid) {
+       case QOS_L3_OCCUP_EVENT_ID:
+               break;
+       case QOS_L3_MBM_TOTAL_EVENT_ID:
+               return hw_dom->mbm_total_cfg;
+       case QOS_L3_MBM_LOCAL_EVENT_ID:
+               return hw_dom->mbm_local_cfg;
+       }
+
+       /* Never expect to get here */
+       WARN_ON_ONCE(1);
+
+       return -1;
+}
+
+void arch_set_mbm_evt_cfg(struct rdt_domain *d,
+                         enum resctrl_event_id eventid, u32 val)
+{
+       struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+       switch (eventid) {
+       case QOS_L3_OCCUP_EVENT_ID:
+               break;

Review

Quoted 10 lines
(quoted diff) +10 -0
+       case QOS_L3_MBM_TOTAL_EVENT_ID:
+               hw_dom->mbm_total_cfg = val;
+               break;
+       case QOS_L3_MBM_LOCAL_EVENT_ID:
+               hw_dom->mbm_local_cfg = val;
+       }
+
+       return;
+}
+

I expected that a call to set the event configuration on an architecture to also interact with the hardware. Essentially what mon_event_config_write() does today, but in addition also sets the cached mbm_total_cfg/mbm_local_cfg.

Part of this is done by the new MPAM portion [1]. With that the post-ABMC implementation of resctrl_arch_mon_event_config_read() may be what you have as arch_get_mbm_evt_cfg() above and resctrl_arch_mon_event_config_write() does the same as in [1] but with addition of updating the cached mbm_local_cfg/mbm_total_cfg within struct rdt_hw_domain. Would this work for ABMC?

Reinette

[1] https://lore.kernel.org/lkml/[email protected]/

#38 lore raw

Re: [PATCH v4 11/19] x86/resctrl: Introduce mbm_total_cfg and mbm_local_cfg

Hi Reinette,

Quoted 119 lines · Reinette Chatre

Hi Babu,

Quoted 73 lines · Babu

Hi Reinette,

Quoted 61 lines · Reinette Chatre

Hi Babu,

Quoted 58 lines · Babu Moger

If the BMEC (Bandwidth Monitoring Event Configuration) feature is supported, the bandwidth events can be configured to track specific events. The event configuration is domain specific. ABMC (Assignable Bandwidth Monitoring Counters) feature needs event configuration information to assign hardware counter to an RMID. Event configurations are not stored in resctrl but instead always read from or written to hardware directly when prompted by user space.

Read the event configuration from the hardware during the domain initialization. Save the configuration information in the rdt_hw_domain, so it can be used for counter assignment.

---
v4: Read the configuration information from the hardware to initialize. Added few commit messages.
      Fixed the tab spaces.

v3: Minor changes related to rebase in mbm_config_write_domain.

v2: No changes.
---
   arch/x86/kernel/cpu/resctrl/core.c     |  2 ++ arch/x86/kernel/cpu/resctrl/internal.h |  5 +++++ arch/x86/kernel/cpu/resctrl/monitor.c  | 21 +++++++++++++++++++++

   3 files changed, 28 insertions(+)
arch/x86/kernel/cpu/resctrl/core.c +1 -0
index ec93f6a50308..856c46d12177 100644
@@ -542,6 +542,8 @@ static void domain_add_cpu(int cpu, struct
 rdt_resource *r)
            return;
        }
    +    arch_domain_mbm_evt_config(hw_dom);
+
        list_add_tail_rcu(&d->list, add_pos);
          err = resctrl_online_domain(r, d);
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index 5e7e76cd512f..60a1ca0a11a7 100644
@@ -373,6 +373,8 @@ struct arch_mbm_state {
     * @ctrl_val:    array of cache or mem ctrl values (indexed by CLOSID)
     * @arch_mbm_total:    arch private state for MBM total bandwidth
     * @arch_mbm_local:    arch private state for MBM local bandwidth
+ * @mbm_total_cfg:    MBM total bandwidth configuration
+ * @mbm_local_cfg:    MBM local bandwidth configuration
     *
     * Members of this structure are accessed via helpers that provide

abstraction.
    */

arch/x86/kernel/cpu/resctrl/internal.h +0 -0
@@ -381,6 +383,8 @@ struct rdt_hw_domain {
        u32                *ctrl_val;
        struct arch_mbm_state        *arch_mbm_total;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h struct rdt_hw_domain { · line 388

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
        struct arch_mbm_state        *arch_mbm_local;
+    u32                mbm_total_cfg;
+    u32                mbm_local_cfg;
    };

Similar to the abmc_enabled member of rdt_hw_resource, these new members of rdt_hw_domain are architecture specific and should never be touched directly by resctrl fs code, for example, from mbm_config_show().

Quoted 8 lines

Need some clarification here.

I am thinking you want to introduce architecture specific routines to get and set mbm_total_config/mbm_local_config for the domain. Something like this.

+int arch_get_mbm_evt_cfg(struct rdt_domain *d, enum resctrl_event_id eventid)

The prefix for arch specific calls converged to "resctrl_arch_".

Quoted 32 lines
(quoted diff) +32 -0
+{
+       struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+       switch (eventid) {
+       case QOS_L3_OCCUP_EVENT_ID:
+               break;
+       case QOS_L3_MBM_TOTAL_EVENT_ID:
+               return hw_dom->mbm_total_cfg;
+       case QOS_L3_MBM_LOCAL_EVENT_ID:
+               return hw_dom->mbm_local_cfg;
+       }
+
+       /* Never expect to get here */
+       WARN_ON_ONCE(1);
+
+       return -1;
+}
+
+void arch_set_mbm_evt_cfg(struct rdt_domain *d,
+                         enum resctrl_event_id eventid, u32 val)
+{
+       struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+
+       switch (eventid) {
+       case QOS_L3_OCCUP_EVENT_ID:
+               break;
+       case QOS_L3_MBM_TOTAL_EVENT_ID:
+               hw_dom->mbm_total_cfg = val;
+               break;
+       case QOS_L3_MBM_LOCAL_EVENT_ID:
+               hw_dom->mbm_local_cfg = val;
+       }
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/monitor.c int __init rdt_get_mon_l3_config(struct rdt_resource *r) · line 1110

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/monitor.c +4 -0
+
+       return;
+}
+

I expected that a call to set the event configuration on an architecture to also interact with the hardware. Essentially what mon_event_config_write() does today, but in addition also sets the cached mbm_total_cfg/mbm_local_cfg.

Yea. Understood.

Quoted 7 lines

Part of this is done by the new MPAM portion [1]. With that the post-ABMC implementation of resctrl_arch_mon_event_config_read() may be what you have as arch_get_mbm_evt_cfg() above and resctrl_arch_mon_event_config_write() does the same as in [1] but with addition of updating the cached mbm_local_cfg/mbm_total_cfg within struct rdt_hw_domain. Would this work for ABMC?

Yes. It does work. I can keep the same name as well. Thanks for the clarifications.

Quoted 6 lines

Reinette

[1] https://lore.kernel.org/lkml/[email protected]/

Signature · 1 line
- Babu Moger
author reviewer
#39 lore raw

PATCH v4 12/19 x86/resctrl: Remove MSR reading of event configuration value

In reply to Babu Moger

The event configuration is domain specific and initialized during domain initialization. It is not required to read the configuration register every time user asks for it. Use the value stored in rdt_hw_domain instead.

---
v4: New patch.

---
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 55 ++++++++++++--------------
 1 file changed, 25 insertions(+), 30 deletions(-)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +25 -30
index c176bacf7ba1..0e425c91fa46 100644
@@ -1618,46 +1618,30 @@ static inline unsigned int mon_event_config_index_get(u32 evtid)
 	}
 }
 
-static void mon_event_config_read(void *info)
-{
-	struct mon_config_info *mon_info = info;
-	unsigned int index;
-	u64 msrval;
-
-	index = mon_event_config_index_get(mon_info->evtid);
-	if (index == INVALID_CONFIG_INDEX) {
-		pr_warn_once("Invalid event id %d\n", mon_info->evtid);
-		return;
-	}
-	rdmsrl(MSR_IA32_EVT_CFG_BASE + index, msrval);
-
-	/* Report only the valid event configuration bits */
-	mon_info->mon_config = msrval & MAX_EVT_CONFIG_BITS;
-}
-
-static void mondata_config_read(struct rdt_domain *d, struct mon_config_info *mon_info)
-{
-	smp_call_function_any(&d->cpu_mask, mon_event_config_read, mon_info, 1);
-}
-
 static int mbm_config_show(struct seq_file *s, struct rdt_resource *r, u32 evtid)
 {
-	struct mon_config_info mon_info = {0};
 	struct rdt_domain *dom;
 	bool sep = false;
+	u32 val;
 
 	cpus_read_lock();
 	mutex_lock(&rdtgroup_mutex);
 
 	list_for_each_entry(dom, &r->domains, list) {
+		struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(dom);
 		if (sep)
 			seq_puts(s, ";");
 
-		memset(&mon_info, 0, sizeof(struct mon_config_info));
-		mon_info.evtid = evtid;
-		mondata_config_read(dom, &mon_info);
+		if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+			val = hw_dom->mbm_total_cfg;
+		} else if (evtid == QOS_L3_MBM_LOCAL_EVENT_ID) {
+			val = hw_dom->mbm_local_cfg;
+		} else {
+			pr_warn_once("Invalid event id %d\n", evtid);
+			break;
+		}
 
-		seq_printf(s, "%d=0x%02x", dom->id, mon_info.mon_config);
+		seq_printf(s, "%d=0x%02x", dom->id, val);
 		sep = true;
 	}
 	seq_puts(s, "\n");
@@ -1704,17 +1688,28 @@ static void mon_event_config_write(void *info)
 static void mbm_config_write_domain(struct rdt_resource *r,
 				    struct rdt_domain *d, u32 evtid, u32 val)
 {
+	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
 	struct mon_config_info mon_info = {0};
 
 	/*
 	 * Read the current config value first. If both are the same then
 	 * no need to write it again.
 	 */
-	mon_info.evtid = evtid;
-	mondata_config_read(d, &mon_info);
-	if (mon_info.mon_config == val)
+	switch (evtid) {
+	case QOS_L3_MBM_TOTAL_EVENT_ID:
+		if (val == hw_dom->mbm_total_cfg)
+			return;
+		break;
+	case QOS_L3_MBM_LOCAL_EVENT_ID:
+		if (val == hw_dom->mbm_local_cfg)
+			return;
+		break;
+	default:
+		pr_warn_once("Invalid event id %d\n", evtid);
 		return;
+	}
 
+	mon_info.evtid = evtid;
 	mon_info.mon_config = val;
 
 	/*
Signature · 1 line
2.34.1
author reviewer
#40 lore raw

PATCH v4 13/19 x86/resctrl: Add data structures for ABMC assignment

In reply to Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. The bandwidth events will be tracked by the hardware until the user changes the configuration. Each resctrl group can configure maximum two counters, one for total event and one for local event.

The counters are configured by writing to MSR L3_QOS_ABMC_CFG. Configuration is done by setting the counter id, bandwidth source (RMID), bandwidth types. Reading L3_QOS_ABMC_DSC returns the configuration of the counter id specified in L3_QOS_ABMC_CFG.

Attempts to read or write these MSRs when ABMC is not enabled will result in a #GP(0) exception.

MSR L3_QOS_ABMC_CFG (0xC000_03FDh) and L3_QOS_ABMC_DSC (0xC000_03FEh) details.
==========================================================================
Bits Mnemonic Description Access Type Reset Value
==========================================================================
63 CfgEn Configuration Enable R/W 0

62 CtrEn Counter Enable R/W 0

61:53 – Reserved MBZ 0

52:48 CtrID Counter Identifier R/W 0

47 IsCOS BwSrc field is a COS R/W 0
(not an RMID)

46:44 – Reserved MBZ 0

43:32 BwSrc Bandwidth Source R/W 0
(RMID or COS)

31:0 BwType Bandwidth types to R/W 0
track for this counter
==========================================================================

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Added more descriptions.
Changed the name abmc_ctr_id to ctr_id.
Added L3_QOS_ABMC_DSC. Used for reading the configuration.

v3: No changes.

v2: No changes.

---
 arch/x86/include/asm/msr-index.h       |  2 ++
 arch/x86/kernel/cpu/resctrl/internal.h | 30 ++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)
arch/x86/include/asm/msr-index.h +2 -0
index 5f9a0139e98c..6d2fe39ac68f 100644
@@ -1172,6 +1172,8 @@
 #define MSR_IA32_SMBA_BW_BASE		0xc0000280
 #define MSR_IA32_EVT_CFG_BASE		0xc0000400
 #define MSR_IA32_L3_QOS_EXT_CFG		0xc00003ff
+#define MSR_IA32_L3_QOS_ABMC_CFG	0xc00003fd
+#define MSR_IA32_L3_QOS_ABMC_DSC	0xc00003fe
 
 /* MSR_IA32_VMX_MISC bits */
 #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +30 -0
index 60a1ca0a11a7..45ed33f4f0ff 100644
@@ -107,6 +107,9 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
 #define ASSIGN_TOTAL			BIT(QOS_L3_MBM_TOTAL_EVENT_ID)
 #define ASSIGN_LOCAL			BIT(QOS_L3_MBM_LOCAL_EVENT_ID)
 
+/* Maximum assignable counters per resctrl group */
+#define MAX_CNTRS		2
+
 struct rdt_fs_context {
 	struct kernfs_fs_context	kfc;
 	bool				enable_cdpl2;
@@ -211,6 +214,7 @@ enum rdtgrp_mode {
  * @crdtgrp_list:		child rdtgroup node list
  * @rmid:			rmid for this rdtgroup
  * @mon_state:			Assignment state of the group
+ * @ctr_id:			ABMC counter ids assigned to this group
  */
 struct mongroup {
 	struct kernfs_node	*mon_data_kn;
@@ -218,6 +222,7 @@ struct mongroup {
 	struct list_head	crdtgrp_list;
 	u32			rmid;
 	u32			mon_state;
+	u32			ctr_id[MAX_CNTRS];
 };
 
 /**
@@ -568,6 +573,31 @@ union cpuid_0x10_x_edx {
 	unsigned int full;
 };
 
+/*
+ * ABMC counters can be configured  by writing to L3_QOS_ABMC_CFG.
+ * @bw_type		: Bandwidth types to track for this counter
+ * @bw_src		: Bandwidth Source (RMID or CLOSID)
+ * @reserved1		: Reserved
+ * @is_cos		: BwSrc field is a COS (not an RMID)
+ * @ctr_id		: Counter Identifier
+ * @reserved		: Reserved
+ * @ctr_en		: Counter Enable bit
+ * @cfg_en		: Configuration Enable bit
+ */
+union l3_qos_abmc_cfg {
+	struct {
+		unsigned long  bw_type	:32,
+			       bw_src	:12,
+			       reserved1: 3,
+			       is_cos	: 1,
+			       ctr_id	: 5,
+			       reserved	: 9,
+			       ctr_en	: 1,
+			       cfg_en	: 1;
+	} split;
+	unsigned long full;
+};
+
 void rdt_last_cmd_clear(void);
 void rdt_last_cmd_puts(const char *s);
 __printf(1, 2)
Signature · 1 line
2.34.1
maintainer
#41 lore raw

Re: [PATCH v4 13/19] x86/resctrl: Add data structures for ABMC assignment

Hi Babu,

Quoted 9 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. The bandwidth events will be tracked by the hardware until the user changes the configuration. Each resctrl group can configure maximum two counters, one for total event and one for local event.

The counters are configured by writing to MSR L3_QOS_ABMC_CFG. Configuration is done by setting the counter id, bandwidth source (RMID), bandwidth types. Reading L3_QOS_ABMC_DSC returns the configuration of

What is a "bandwidth type" here?

Quoted 21 lines

the counter id specified in L3_QOS_ABMC_CFG.

Attempts to read or write these MSRs when ABMC is not enabled will result in a #GP(0) exception.

MSR L3_QOS_ABMC_CFG (0xC000_03FDh) and L3_QOS_ABMC_DSC (0xC000_03FEh) details.
==========================================================================
Bits Mnemonic Description Access Type Reset Value
==========================================================================
63 CfgEn Configuration Enable R/W 0

62 CtrEn Counter Enable R/W 0

61:53 – Reserved MBZ 0

52:48 CtrID Counter Identifier R/W 0

47 IsCOS BwSrc field is a COS R/W 0
(not an RMID)

Quoted 9 lines

46:44 – Reserved MBZ 0

43:32 BwSrc Bandwidth Source R/W 0
(RMID or COS)

31:0 BwType Bandwidth types to R/W 0
track for this counter
==========================================================================

This is copy&paste from AMD spec but needs some translation to map it to resctrl.

Quoted 56 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Added more descriptions.
Changed the name abmc_ctr_id to ctr_id.
Added L3_QOS_ABMC_DSC. Used for reading the configuration.

v3: No changes.

v2: No changes.

---
  arch/x86/include/asm/msr-index.h       |  2 ++
  arch/x86/kernel/cpu/resctrl/internal.h | 30 ++++++++++++++++++++++++++
  2 files changed, 32 insertions(+)
arch/x86/include/asm/msr-index.h +2 -0
index 5f9a0139e98c..6d2fe39ac68f 100644
@@ -1172,6 +1172,8 @@
  #define MSR_IA32_SMBA_BW_BASE		0xc0000280
  #define MSR_IA32_EVT_CFG_BASE		0xc0000400
  #define MSR_IA32_L3_QOS_EXT_CFG		0xc00003ff
+#define MSR_IA32_L3_QOS_ABMC_CFG	0xc00003fd
+#define MSR_IA32_L3_QOS_ABMC_DSC	0xc00003fe
 
  /* MSR_IA32_VMX_MISC bits */
  #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +4 -0
index 60a1ca0a11a7..45ed33f4f0ff 100644
@@ -107,6 +107,9 @@ cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
  #define ASSIGN_TOTAL			BIT(QOS_L3_MBM_TOTAL_EVENT_ID)
  #define ASSIGN_LOCAL			BIT(QOS_L3_MBM_LOCAL_EVENT_ID)
 
+/* Maximum assignable counters per resctrl group */
+#define MAX_CNTRS		2
+
  struct rdt_fs_context {
  	struct kernfs_fs_context	kfc;
  	bool				enable_cdpl2;
@@ -211,6 +214,7 @@ enum rdtgrp_mode {
   * @crdtgrp_list:		child rdtgroup node list
   * @rmid:			rmid for this rdtgroup
   * @mon_state:			Assignment state of the group
+ * @ctr_id:			ABMC counter ids assigned to this group
   */
  struct mongroup {
  	struct kernfs_node	*mon_data_kn;

arch/x86/kernel/cpu/resctrl/internal.h struct mongroup { · line 225

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
@@ -218,6 +222,7 @@ struct mongroup {
  	struct list_head	crdtgrp_list;
  	u32			rmid;
  	u32			mon_state;
+	u32			ctr_id[MAX_CNTRS];

To match "num_cntrs" it seems "cntr_id" may be more appropriate?

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 577

Quoted 9 lines
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
  };
 
  /**
@@ -568,6 +573,31 @@ union cpuid_0x10_x_edx {
  	unsigned int full;
  };
 
+/*
+ * ABMC counters can be configured  by writing to L3_QOS_ABMC_CFG.

extra space

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 578

Quoted 1 line
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
+ * @bw_type		: Bandwidth types to track for this counter

What is a "Bandwidth type"? What are possible values?

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 581

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
+ * @bw_src		: Bandwidth Source (RMID or CLOSID)
+ * @reserved1		: Reserved
+ * @is_cos		: BwSrc field is a COS (not an RMID)

Please be consistent wrt "CLOS"/"CLOSID" in comment and member name

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 582

Quoted 1 line
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
+ * @ctr_id		: Counter Identifier

Please be consistent with "cntr" vs "ctr". Earlier the series introduces "num_cntrs" so cntr seems appropriate?

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 585

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
+ * @reserved		: Reserved
+ * @ctr_en		: Counter Enable bit
+ * @cfg_en		: Configuration Enable bit

Why are there two enable bits? How are they used?

(please match other kernel doc wrt : usage)

Quoted 8 lines
arch/x86/kernel/cpu/resctrl/internal.h +8 -0
+ */
+union l3_qos_abmc_cfg {
+	struct {
+		unsigned long  bw_type	:32,
+			       bw_src	:12,
+			       reserved1: 3,
+			       is_cos	: 1,
+			       ctr_id	: 5,

arch/x86/kernel/cpu/resctrl/internal.h union cpuid_0x10_x_edx { · line 603

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/internal.h +7 -0
+			       reserved	: 9,
+			       ctr_en	: 1,
+			       cfg_en	: 1;
+	} split;
+	unsigned long full;
+};
+
  void rdt_last_cmd_clear(void);
  void rdt_last_cmd_puts(const char *s);
  __printf(1, 2)

Reinette

author reviewer
#42 lore raw

Re: [PATCH v4 13/19] x86/resctrl: Add data structures for ABMC assignment

Hi Reinette,

Quoted 9 lines · Reinette Chatre

Hi Babu,

Quoted 6 lines · Babu Moger

The ABMC feature provides an option to the user to assign a hardware counter to an RMID and monitor the bandwidth as long as the counter is assigned. The bandwidth events will be tracked by the hardware until the user changes the configuration. Each resctrl group can configure maximum two counters, one for total event and one for local event.

Quoted 5 lines
Quoted 3 lines

The counters are configured by writing to MSR L3_QOS_ABMC_CFG. Configuration is done by setting the counter id, bandwidth source (RMID), bandwidth types. Reading L3_QOS_ABMC_DSC returns the configuration of

What is a "bandwidth type" here?

Its bandwidth configuration(reads, writes etc). It is mbm_total_bytes_config", "mbm_local_bytes_config" in
https://www.kernel.org/doc/Documentation/x86/resctrl.rst

I will add that text.

Quoted 27 lines
Quoted 27 lines

the counter id specified in L3_QOS_ABMC_CFG.

Attempts to read or write these MSRs when ABMC is not enabled will result in a #GP(0) exception.

MSR L3_QOS_ABMC_CFG (0xC000_03FDh) and L3_QOS_ABMC_DSC (0xC000_03FEh) details.
==========================================================================
Bits     Mnemonic    Description        Access Type   Reset Value
==========================================================================
63     CfgEn         Configuration Enable     R/W         0

62     CtrEn         Counter Enable         R/W         0

61:53     –         Reserved         MBZ         0

52:48     CtrID         Counter Identifier    R/W        0

47     IsCOS        BwSrc field is a COS    R/W        0 (not an RMID)

46:44     –        Reserved        MBZ        0

43:32    BwSrc        Bandwidth Source    R/W        0 (RMID or COS)

Quoted 7 lines
Quoted 4 lines

31:0    BwType        Bandwidth types to    R/W        0 track for this counter
==========================================================================

This is copy&paste from AMD spec but needs some translation to map it to resctrl.

Yes. Sure. Will elaborate.

Quoted 56 lines
Quoted 56 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Added more descriptions.
     Changed the name abmc_ctr_id to ctr_id.
     Added L3_QOS_ABMC_DSC. Used for reading the configuration.

v3: No changes.

v2: No changes.
---
  arch/x86/include/asm/msr-index.h       |  2 ++ arch/x86/kernel/cpu/resctrl/internal.h | 30 ++++++++++++++++++++++++++

  2 files changed, 32 insertions(+)
arch/x86/include/asm/msr-index.h +2 -0
index 5f9a0139e98c..6d2fe39ac68f 100644
@@ -1172,6 +1172,8 @@
   #define MSR_IA32_SMBA_BW_BASE        0xc0000280
   #define MSR_IA32_EVT_CFG_BASE        0xc0000400
   #define MSR_IA32_L3_QOS_EXT_CFG        0xc00003ff
+#define MSR_IA32_L3_QOS_ABMC_CFG    0xc00003fd
+#define MSR_IA32_L3_QOS_ABMC_DSC    0xc00003fe
     /* MSR_IA32_VMX_MISC bits */
   #define MSR_IA32_VMX_MISC_INTEL_PT                 (1ULL << 14)
arch/x86/kernel/cpu/resctrl/internal.h +0 -0
index 60a1ca0a11a7..45ed33f4f0ff 100644
@@ -107,6 +107,9 @@ cpumask_any_housekeeping(const struct cpumask *mask,
 int exclude_cpu)
   #define ASSIGN_TOTAL            BIT(QOS_L3_MBM_TOTAL_EVENT_ID)
   #define ASSIGN_LOCAL            BIT(QOS_L3_MBM_LOCAL_EVENT_ID)

  +/* Maximum assignable counters per resctrl group */

arch/x86/kernel/cpu/resctrl/internal.h +2 -0
+#define MAX_CNTRS        2
+

  struct rdt_fs_context {
      struct kernfs_fs_context    kfc;
      bool                enable_cdpl2;

arch/x86/kernel/cpu/resctrl/internal.h +1 -0
@@ -211,6 +214,7 @@ enum rdtgrp_mode {
    * @crdtgrp_list:        child rdtgroup node list
    * @rmid:            rmid for this rdtgroup
    * @mon_state:            Assignment state of the group
+ * @ctr_id:            ABMC counter ids assigned to this group
    */
   struct mongroup {
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/internal.h struct mongroup { · line 225

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/internal.h +1 -0
       struct kernfs_node    *mon_data_kn;
@@ -218,6 +222,7 @@ struct mongroup {
       struct list_head    crdtgrp_list;
       u32            rmid;
       u32            mon_state;
+    u32            ctr_id[MAX_CNTRS];

To match "num_cntrs" it seems "cntr_id" may be more appropriate?

Yes. Will change appropriately.

Quoted 10 lines
Quoted 8 lines
arch/x86/kernel/cpu/resctrl/internal.h +0 -0
   };
     /**
@@ -568,6 +573,31 @@ union cpuid_0x10_x_edx {
       unsigned int full;
   };

  +/*
+ * ABMC counters can be configured  by writing to L3_QOS_ABMC_CFG.

extra space

ok

Quoted 4 lines
Quoted 2 lines

+ * @bw_type        : Bandwidth types to track for this counter

What is a "Bandwidth type"? What are possible values?

Its bandwidth configuration(reads, writes etc). It is mbm_total_bytes_config", "mbm_local_bytes_config" in
https://www.kernel.org/doc/Documentation/x86/resctrl.rst
It is a bitmap. Will clarify that.

Quoted 6 lines
Quoted 4 lines

+ * @bw_src        : Bandwidth Source (RMID or CLOSID)
+ * @reserved1        : Reserved
+ * @is_cos        : BwSrc field is a COS (not an RMID)

Please be consistent wrt "CLOS"/"CLOSID" in comment and member name

Sure. Will change it to CLOSID.

Quoted 5 lines
Quoted 2 lines

+ * @ctr_id        : Counter Identifier

Please be consistent with "cntr" vs "ctr". Earlier the series introduces "num_cntrs" so cntr seems appropriate?

Sure.

Quoted 6 lines
Quoted 4 lines

+ * @reserved        : Reserved
+ * @ctr_en        : Counter Enable bit
+ * @cfg_en        : Configuration Enable bit

Why are there two enable bits? How are they used?

I am setting both these bits when configuring, I need some clarifications on these bits with h/w team. I need to know how different combinations changes the behavior. I will confirm about this.

Quoted 24 lines

(please match other kernel doc wrt : usage)

Quoted 15 lines

+ */

arch/x86/kernel/cpu/resctrl/internal.h +14 -0
+union l3_qos_abmc_cfg {
+    struct {
+        unsigned long  bw_type    :32,
+                   bw_src    :12,
+                   reserved1: 3,
+                   is_cos    : 1,
+                   ctr_id    : 5,
+                   reserved    : 9,
+                   ctr_en    : 1,
+                   cfg_en    : 1;
+    } split;
+    unsigned long full;
+};
+
Quoted 3 lines

  void rdt_last_cmd_clear(void);
  void rdt_last_cmd_puts(const char *s);
  __printf(1, 2)

Reinette

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#43 lore raw

PATCH v4 14/19 x86/resctrl: Add the interface to assign ABMC counter

In reply to Babu Moger

ABMC feature requires to users to assign a hardware counter to an RMID to monitor the events. Provide the interfaces to assign a counter.

Individual counters are configured by writing to L3_QOS_ABMC_CFG MSR and specifying the counter id, bandwidth source, and bandwidth types.

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming

    Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
    Monitoring (ABMC).

---
v4: Commit message update.
User bitmap APIs where applicable.
Changed the interfaces considering MPAM(arm).
Added domain specific assignment.

v3: Removed the static from the prototype of rdtgroup_assign_abmc.
The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: Minor text changes in commit message.

---
 arch/x86/kernel/cpu/resctrl/internal.h |   3 +
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 101 +++++++++++++++++++++++++
 2 files changed, 104 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
index 45ed33f4f0ff..a88c8fc5e4df 100644
@@ -657,6 +657,9 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
 void __init resctrl_file_fflags_init(const char *config,
 				     unsigned long fflags);
 void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+			u32 ctr_id, u32 closid, bool enable);
+int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
 void rdt_staged_configs_clear(void);
 bool closid_allocated(unsigned int closid);
 int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/rdtgroup.c +101 -0

113 lines not on this page · raw message

Signature · 1 line
2.34.1
maintainer
#44 lore raw

Re: [PATCH v4 14/19] x86/resctrl: Add the interface to assign ABMC counter

Hi Babu,

Quoted 1 line · Babu Moger

ABMC feature requires to users to assign a hardware counter to an RMID

"requires to users" -> "requires users"?

Quoted 4 lines

to monitor the events. Provide the interfaces to assign a counter.

Individual counters are configured by writing to L3_QOS_ABMC_CFG MSR and specifying the counter id, bandwidth source, and bandwidth types.

Where is discription of what this patch does and why?

This and following patches seem to introduce building blocks that are only used later in series. These building blocks are introduced without any information about what they do and why and that makes it difficult to understand how this work will fall into place.

Quoted 43 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming

     Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
     Monitoring (ABMC).

---
v4: Commit message update.
User bitmap APIs where applicable. Changed the interfaces considering MPAM(arm). Added domain specific assignment.

v3: Removed the static from the prototype of rdtgroup_assign_abmc.
The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: Minor text changes in commit message.

---
  arch/x86/kernel/cpu/resctrl/internal.h |   3 +
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 101 +++++++++++++++++++++++++
  2 files changed, 104 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
index 45ed33f4f0ff..a88c8fc5e4df 100644
@@ -657,6 +657,9 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
  void __init resctrl_file_fflags_init(const char *config,
  				     unsigned long fflags);
  void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+			u32 ctr_id, u32 closid, bool enable);
+int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
  void rdt_staged_configs_clear(void);
  bool closid_allocated(unsigned int closid);
  int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 0e425c91fa46..48df76499a04 100644

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void num_cntrs_init(void) · line 206

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
@@ -203,6 +203,19 @@ static void num_cntrs_init(void)
  	num_cntrs_free_map_len = r->mon.num_cntrs;
  }
 
+static int assign_cntrs_alloc(void)

Only one counter is allocated and "assign" is unexpected since it seems to imply how this counter will be used.
It can just be "mon_cntr_alloc()"?

Quoted 16 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +12 -0
+{
+	u32 ctr_id = find_first_bit(&num_cntrs_free_map,
+				    num_cntrs_free_map_len);
+
+	if (ctr_id >= num_cntrs_free_map_len)
+		return -ENOSPC;
+
+	__clear_bit(ctr_id, &num_cntrs_free_map);
+
+	return ctr_id;
+}
+
  /**
   * rdtgroup_mode_by_closid - Return mode of resource group with closid
   * @closid: closid if the resource group

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1852

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
@@ -1830,6 +1843,94 @@ static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of,
  	return ret ?: nbytes;
  }
 
+static void rdtgroup_abmc_cfg(void *info)
+{
+	u64 *msrval = info;
+
+	wrmsrl(MSR_IA32_L3_QOS_ABMC_CFG, *msrval);
+}
+

Please add comments to these functions to summarize what they do.

Quoted 17 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +17 -0
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+			u32 ctr_id, u32 closid, bool enable)
+{
+	struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+	union l3_qos_abmc_cfg abmc_cfg = { 0 };
+	struct arch_mbm_state *arch_mbm;
+
+	abmc_cfg.split.cfg_en = 1;
+	abmc_cfg.split.ctr_en = enable ? 1 : 0;
+	abmc_cfg.split.ctr_id = ctr_id;
+	abmc_cfg.split.bw_src = rmid;
+
+	/*
+	 * Read the event configuration from the domain and pass it as
+	 * bw_type.
+	 */
+	if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1879

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+		abmc_cfg.split.bw_type = hw_dom->mbm_total_cfg;
+		arch_mbm = &hw_dom->arch_mbm_total[rmid];
+	} else {
+		abmc_cfg.split.bw_type = hw_dom->mbm_local_cfg;
+		arch_mbm = &hw_dom->arch_mbm_local[rmid];
+	}
+
+	smp_call_function_any(&d->cpu_mask, rdtgroup_abmc_cfg, &abmc_cfg, 1);
+
+	/* Reset the internal counters */

"internal counters"? This needs a definition ... but since this is not a new data structure the comment can be more specific about what is done and why.

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1883

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+	if (arch_mbm)
+		memset(arch_mbm, 0, sizeof(struct arch_mbm_state));
+
+	return 0;

If this function always succeeds then it can just be void?

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1886

Quoted 3 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
+}
+
+int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid)

Please use consistent naming. Note how the filename is "rdtgroup.c" and this function operates on "struct rdtgroup" and if you take a closer look at the functions in this file and the header where you add this function you will notice a distinct pattern of "rdtgroup_" used as prefix. There really is no reason to start a new namespace for this.

Quoted 13 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +13 -0
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	int ctr_id = 0, index;
+	struct rdt_domain *d;
+	u32 mon_state;
+
+	index = mon_event_config_index_get(evtid);
+	if (index == INVALID_CONFIG_INDEX) {
+		rdt_last_cmd_puts("Invalid event id\n");
+		return -EINVAL;
+	}
+
+	if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1909

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+		mon_state = ASSIGN_TOTAL;
+	} else if (evtid == QOS_L3_MBM_LOCAL_EVENT_ID) {
+		mon_state = ASSIGN_LOCAL;
+	} else {
+		rdt_last_cmd_puts("Invalid event id\n");
+		return -EINVAL;
+	}
+
+	/* Nothing to do if event has been assigned already */
+	if (rdtgrp->mon.mon_state & mon_state) {

Why is this mon_state needed? Is it not redundant when considering that struct mongroup has an array of counter IDs that can already be used to see if a counter is assigned or not?
What if there is a new:
#define MON_CNTR_UNSET U32_MAX

When cntr_id[index] == MON_CNTR_UNSET then it is not assigned.

Quoted 17 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +17 -0
+		rdt_last_cmd_puts("ABMC counter is assigned already\n");
+		return 0;
+	}
+
+	/*
+	 * Allocate a new counter and update domains
+	 */
+	ctr_id = assign_cntrs_alloc();
+	if (ctr_id < 0) {
+		rdt_last_cmd_puts("Out of ABMC counters\n");
+		return -ENOSPC;
+	}
+
+	rdtgrp->mon.ctr_id[index] = ctr_id;
+
+	list_for_each_entry(d, &r->domains, list)
+		resctrl_arch_assign(d, evtid, rdtgrp->mon.rmid, ctr_id,

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1936

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+				    rdtgrp->closid, 1);
+
+	rdtgrp->mon.mon_state |= mon_state;
+
+	return 0;
+}
+
  /* rdtgroup information files for one cache resource. */
  static struct rftype res_common_files[] = {
  	{

Reinette

#45 lore raw

Re: [PATCH v4 14/19] x86/resctrl: Add the interface to assign ABMC counter

Hi Reinette,

Quoted 6 lines · Reinette Chatre

Hi Babu,

Quoted 1 line · Babu Moger

ABMC feature requires to users to assign a hardware counter to an RMID

"requires to users" -> "requires users"?

Sure.

Quoted 6 lines
Quoted 5 lines

to monitor the events. Provide the interfaces to assign a counter.

Individual counters are configured by writing to L3_QOS_ABMC_CFG MSR and specifying the counter id, bandwidth source, and bandwidth types.

Quoted 6 lines

Where is discription of what this patch does and why?

This and following patches seem to introduce building blocks that are only used later in series. These building blocks are introduced without any information about what they do and why and that makes it difficult to understand how this work will fall into place.

Ok. Will elaborate this.

Quoted 44 lines
Quoted 44 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth Monitoring (ABMC).

---
v4: Commit message update.
     User bitmap APIs where applicable. Changed the interfaces considering MPAM(arm). Added domain specific assignment.

v3: Removed the static from the prototype of rdtgroup_assign_abmc. The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: Minor text changes in commit message.
---
  arch/x86/kernel/cpu/resctrl/internal.h |   3 + arch/x86/kernel/cpu/resctrl/rdtgroup.c | 101 +++++++++++++++++++++++++

  2 files changed, 104 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +3 -0
index 45ed33f4f0ff..a88c8fc5e4df 100644
@@ -657,6 +657,9 @@ void rdt_domain_reconfigure_cdp(struct 
 rdt_resource *r);
   void __init resctrl_file_fflags_init(const char *config,
                        unsigned long fflags);
   void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+            u32 ctr_id, u32 closid, bool enable);
+int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
   void rdt_staged_configs_clear(void);
   bool closid_allocated(unsigned int closid);

  int resctrl_find_cleanest_closid(void);

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 0e425c91fa46..48df76499a04 100644
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void num_cntrs_init(void) · line 205

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
@@ -203,6 +203,19 @@ static void num_cntrs_init(void)
       num_cntrs_free_map_len = r->mon.num_cntrs;
   }
+static int assign_cntrs_alloc(void)

Only one counter is allocated and "assign" is unexpected since it seems to imply how this counter will be used.
It can just be "mon_cntr_alloc()"?

Sure.

Quoted 22 lines
Quoted 22 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +14 -0
+{
+    u32 ctr_id = find_first_bit(&num_cntrs_free_map,
+                    num_cntrs_free_map_len);
+
+    if (ctr_id >= num_cntrs_free_map_len)
+        return -ENOSPC;
+
+    __clear_bit(ctr_id, &num_cntrs_free_map);
+
+    return ctr_id;
+}
+
   /**
    * rdtgroup_mode_by_closid - Return mode of resource group with closid
    * @closid: closid if the resource group
@@ -1830,6 +1843,94 @@ static ssize_t 
 mbm_local_bytes_config_write(struct kernfs_open_file *of,
       return ret ?: nbytes;
   }
+static void rdtgroup_abmc_cfg(void *info)
+{
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1852

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+    u64 *msrval = info;
+
+    wrmsrl(MSR_IA32_L3_QOS_ABMC_CFG, *msrval);
+}
+

Please add comments to these functions to summarize what they do.

Sure.

Quoted 25 lines
Quoted 25 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +24 -0
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+            u32 ctr_id, u32 closid, bool enable)
+{
+    struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+    union l3_qos_abmc_cfg abmc_cfg = { 0 };
+    struct arch_mbm_state *arch_mbm;
+
+    abmc_cfg.split.cfg_en = 1;
+    abmc_cfg.split.ctr_en = enable ? 1 : 0;
+    abmc_cfg.split.ctr_id = ctr_id;
+    abmc_cfg.split.bw_src = rmid;
+
+    /*
+     * Read the event configuration from the domain and pass it as
+     * bw_type.
+     */
+    if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+        abmc_cfg.split.bw_type = hw_dom->mbm_total_cfg;
+        arch_mbm = &hw_dom->arch_mbm_total[rmid];
+    } else {
+        abmc_cfg.split.bw_type = hw_dom->mbm_local_cfg;
+        arch_mbm = &hw_dom->arch_mbm_local[rmid];
+    }
+
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1879

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
+    smp_call_function_any(&d->cpu_mask, rdtgroup_abmc_cfg, &abmc_cfg, 
 1);
+
+    /* Reset the internal counters */

"internal counters"? This needs a definition ... but since this is not a new data structure the comment can be more specific about what is done and why.

How about?
/* Reset internal mbm event counters. */

Quoted 7 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1883

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+    if (arch_mbm)
+        memset(arch_mbm, 0, sizeof(struct arch_mbm_state));
+
+    return 0;

If this function always succeeds then it can just be void?

Sure. We can do that.

Quoted 10 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1886

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
+}
+
+int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid)

Please use consistent naming. Note how the filename is "rdtgroup.c" and this function operates on "struct rdtgroup" and if you take a closer look at the functions in this file and the header where you add this function you will notice a distinct pattern of "rdtgroup_" used as prefix. There really is no reason to start a new namespace for this.

Sure.

Quoted 32 lines
Quoted 15 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +13 -0
+{
+    struct rdt_resource *r = 
 &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+    int ctr_id = 0, index;
+    struct rdt_domain *d;
+    u32 mon_state;
+
+    index = mon_event_config_index_get(evtid);
+    if (index == INVALID_CONFIG_INDEX) {
+        rdt_last_cmd_puts("Invalid event id\n");
+        return -EINVAL;
+    }
+
+    if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1909

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +10 -0
+        mon_state = ASSIGN_TOTAL;
+    } else if (evtid == QOS_L3_MBM_LOCAL_EVENT_ID) {
+        mon_state = ASSIGN_LOCAL;
+    } else {
+        rdt_last_cmd_puts("Invalid event id\n");
+        return -EINVAL;
+    }
+
+    /* Nothing to do if event has been assigned already */
+    if (rdtgrp->mon.mon_state & mon_state) {

Why is this mon_state needed? Is it not redundant when considering that struct mongroup has an array of counter IDs that can already be used to see if a counter is assigned or not?
What if there is a new:
#define MON_CNTR_UNSET U32_MAX

Quoted 1 line

When cntr_id[index] == MON_CNTR_UNSET then it is not assigned.

Yes. That can be done. That case mon_state is not required. We just need the index. Also, we need to initialize the ctrl_id when the group is created. Hope that should work.

Quoted 31 lines
Quoted 26 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +24 -0
+        rdt_last_cmd_puts("ABMC counter is assigned already\n");
+        return 0;
+    }
+
+    /*
+     * Allocate a new counter and update domains
+     */
+    ctr_id = assign_cntrs_alloc();
+    if (ctr_id < 0) {
+        rdt_last_cmd_puts("Out of ABMC counters\n");
+        return -ENOSPC;
+    }
+
+    rdtgrp->mon.ctr_id[index] = ctr_id;
+
+    list_for_each_entry(d, &r->domains, list)
+        resctrl_arch_assign(d, evtid, rdtgrp->mon.rmid, ctr_id,
+                    rdtgrp->closid, 1);
+
+    rdtgrp->mon.mon_state |= mon_state;
+
+    return 0;
+}
+
   /* rdtgroup information files for one cache resource. */
Quoted 2 lines

  static struct rftype res_common_files[] = {
      {

Reinette

Signature · 1 line
- Babu Moger
maintainer
#46 lore raw

Re: [PATCH v4 14/19] x86/resctrl: Add the interface to assign ABMC counter

Hi Babu,

Quoted 35 lines · Babu
Quoted 25 lines · Reinette Chatre
Quoted 23 lines · Babu Moger
arch/x86/kernel/cpu/resctrl/rdtgroup.c +23 -0
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+            u32 ctr_id, u32 closid, bool enable)
+{
+    struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+    union l3_qos_abmc_cfg abmc_cfg = { 0 };
+    struct arch_mbm_state *arch_mbm;
+
+    abmc_cfg.split.cfg_en = 1;
+    abmc_cfg.split.ctr_en = enable ? 1 : 0;
+    abmc_cfg.split.ctr_id = ctr_id;
+    abmc_cfg.split.bw_src = rmid;
+
+    /*
+     * Read the event configuration from the domain and pass it as
+     * bw_type.
+     */
+    if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+        abmc_cfg.split.bw_type = hw_dom->mbm_total_cfg;
+        arch_mbm = &hw_dom->arch_mbm_total[rmid];
+    } else {
+        abmc_cfg.split.bw_type = hw_dom->mbm_local_cfg;
+        arch_mbm = &hw_dom->arch_mbm_local[rmid];
+    }
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static ssize_t mbm_local_bytes_config_write(struct kernfs_open_file *of, · line 1879

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+
+    smp_call_function_any(&d->cpu_mask, rdtgroup_abmc_cfg, &abmc_cfg, 1);
+
+    /* Reset the internal counters */

"internal counters"? This needs a definition ... but since this is not a new data structure the comment can be more specific about what is done and why.

Quoted 2 lines

How about?
/* Reset internal mbm event counters. */

I think it is potentially confusing to introduce a new concept of "internal counters". This is just the architectural state helping to detect overflows. This commit has no mention of this but I assume that the re-configuration of the counter will reset it, which explains why it is required to reset the state maintained by software.
A similar comment to what can be found in mbm_config_write_domain() would be useful. This does not have to be so elaborate, maybe just something like (please feel free to improve):

Configuring a hardware counter resets it. Reset architectural state to match.

Reinette

#47 lore raw

Re: [PATCH v4 14/19] x86/resctrl: Add the interface to assign ABMC counter

Hi Reinette,

Quoted 51 lines · Reinette Chatre

Hi Babu,

Quoted 36 lines · Babu
Quoted 26 lines · Reinette Chatre
Quoted 24 lines · Babu Moger
arch/x86/kernel/cpu/resctrl/rdtgroup.c +24 -0
+int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
+            u32 ctr_id, u32 closid, bool enable)
+{
+    struct rdt_hw_domain *hw_dom = resctrl_to_arch_dom(d);
+    union l3_qos_abmc_cfg abmc_cfg = { 0 };
+    struct arch_mbm_state *arch_mbm;
+
+    abmc_cfg.split.cfg_en = 1;
+    abmc_cfg.split.ctr_en = enable ? 1 : 0;
+    abmc_cfg.split.ctr_id = ctr_id;
+    abmc_cfg.split.bw_src = rmid;
+
+    /*
+     * Read the event configuration from the domain and pass it as
+     * bw_type.
+     */
+    if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+        abmc_cfg.split.bw_type = hw_dom->mbm_total_cfg;
+        arch_mbm = &hw_dom->arch_mbm_total[rmid];
+    } else {
+        abmc_cfg.split.bw_type = hw_dom->mbm_local_cfg;
+        arch_mbm = &hw_dom->arch_mbm_local[rmid];
+    }
+
Quoted 8 lines
Quoted 4 lines

+    smp_call_function_any(&d->cpu_mask, rdtgroup_abmc_cfg, &abmc_cfg, 1);
+
+    /* Reset the internal counters */

"internal counters"? This needs a definition ... but since this is not a new data structure the comment can be more specific about what is done and why.

Quoted 2 lines

How about?
/* Reset internal mbm event counters. */

I think it is potentially confusing to introduce a new concept of "internal counters". This is just the architectural state helping to detect overflows. This commit has no mention of this but I assume that the re-configuration of the counter will reset it, which explains why it is required to reset the state maintained by software.
A similar comment to what can be found in mbm_config_write_domain() would be useful. This does not have to be so elaborate, maybe just something like (please feel free to improve):

Quoted 3 lines

    Configuring a hardware counter resets it. Reset architectural state to match.

Sure. Thanks
- Babu Moger

author reviewer
#48 lore raw

PATCH v4 15/19 x86/resctrl: Add the interface to unassign ABMC counter

In reply to Babu Moger

Hardware provides a limited number of ABMC counters. Once all the counters are exhausted, counters need to be freed for new assignments.

Provide the interface to unassign the counter.

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming

    Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
    Monitoring (ABMC).

---
v4: Added domain specific unassign feature.
Few name changes.

v3: Removed the static from the prototype of rdtgroup_unassign_abmc.
The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: No changes.

---
 arch/x86/kernel/cpu/resctrl/internal.h |  2 ++
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 42 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index a88c8fc5e4df..e16244895350 100644
@@ -660,6 +660,8 @@ void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
 int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
 			u32 ctr_id, u32 closid, bool enable);
 int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
+int resctrl_grp_unassign(struct rdtgroup *rdtgrp, u32 evtid);
+void num_cntrs_free(u32 ctr_id);
 void rdt_staged_configs_clear(void);
 bool closid_allocated(unsigned int closid);
 int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/rdtgroup.c +42 -0

54 lines not on this page · raw message

Signature · 1 line
2.34.1
maintainer
#49 lore raw

Re: [PATCH v4 15/19] x86/resctrl: Add the interface to unassign ABMC counter

Hi Babu,

Quoted 4 lines · Babu Moger

Hardware provides a limited number of ABMC counters. Once all the counters are exhausted, counters need to be freed for new assignments.

Provide the interface to unassign the counter.

Please write a proper changelog. This needs information that explains what this patch does and why.

Quoted 40 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming

     Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
     Monitoring (ABMC).

---
v4: Added domain specific unassign feature.
Few name changes.

v3: Removed the static from the prototype of rdtgroup_unassign_abmc.
The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: No changes.

---
  arch/x86/kernel/cpu/resctrl/internal.h |  2 ++
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 42 ++++++++++++++++++++++++++
  2 files changed, 44 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index a88c8fc5e4df..e16244895350 100644
@@ -660,6 +660,8 @@ void arch_domain_mbm_evt_config(struct rdt_hw_domain *hw_dom);
  int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
  			u32 ctr_id, u32 closid, bool enable);
  int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
+int resctrl_grp_unassign(struct rdtgroup *rdtgrp, u32 evtid);
+void num_cntrs_free(u32 ctr_id);
  void rdt_staged_configs_clear(void);
  bool closid_allocated(unsigned int closid);
  int resctrl_find_cleanest_closid(void);
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 48df76499a04..5ea1e58c7201 100644

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int assign_cntrs_alloc(void) · line 219

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
@@ -216,6 +216,11 @@ static int assign_cntrs_alloc(void)
  	return ctr_id;
  }
 
+void num_cntrs_free(u32 ctr_id)

The name does not reflect what it does. It neither frees the "num_cntrs" information nor does it free "num_cntrs" of counters. How about "mon_cntr_free()"?

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid) · line 1939

Quoted 12 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+{
+	__set_bit(ctr_id, &num_cntrs_free_map);
+}
+
  /**
   * rdtgroup_mode_by_closid - Return mode of resource group with closid
   * @closid: closid if the resource group
@@ -1931,6 +1936,43 @@ int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid)
  	return 0;
  }
 
+int resctrl_grp_unassign(struct rdtgroup *rdtgrp, u32 evtid)

Same comment wrt namespace. Also this function needs a description.

Quoted 29 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +29 -0
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	struct rdt_domain *d;
+	u32 mon_state;
+	int index;
+
+	index = mon_event_config_index_get(evtid);
+	if (index == INVALID_CONFIG_INDEX) {
+		pr_warn_once("Invalid event id %d\n", evtid);
+		return -EINVAL;
+	}
+
+	if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+		mon_state = ASSIGN_TOTAL;
+	} else if (evtid == QOS_L3_MBM_LOCAL_EVENT_ID) {
+		mon_state = ASSIGN_LOCAL;
+	} else {
+		rdt_last_cmd_puts("Invalid event id\n");
+		return -EINVAL;
+	}
+
+	if (rdtgrp->mon.mon_state & mon_state) {
+		list_for_each_entry(d, &r->domains, list)
+			resctrl_arch_assign(d, evtid, rdtgrp->mon.rmid,
+					    rdtgrp->mon.ctr_id[index],
+					    rdtgrp->closid, 0);
+
+		/* Update the counter bitmap */
+		num_cntrs_free(rdtgrp->mon.ctr_id[index]);

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid) · line 1978

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+	}
+
+	rdtgrp->mon.mon_state &= ~mon_state;
+
+	return 0;
+}
+
  /* rdtgroup information files for one cache resource. */
  static struct rftype res_common_files[] = {
  	{

Reinette

author reviewer
#50 lore raw

Re: [PATCH v4 15/19] x86/resctrl: Add the interface to unassign ABMC counter

Hi Reinette,

Quoted 10 lines · Reinette Chatre

Hi Babu,

Quoted 4 lines · Babu Moger

Hardware provides a limited number of ABMC counters. Once all the counters are exhausted, counters need to be freed for new assignments.

Provide the interface to unassign the counter.

Please write a proper changelog. This needs information that explains what this patch does and why.

Sure. Will elaborate on this.

Quoted 44 lines
Quoted 44 lines

The feature details are documented in the APM listed below [1].
[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming Publication # 24593 Revision 3.41 section 19.3.3.3 Assignable Bandwidth
     Monitoring (ABMC).

---
v4: Added domain specific unassign feature.
     Few name changes.

v3: Removed the static from the prototype of rdtgroup_unassign_abmc. The function is not called directly from user anymore. These changes are related to global assignment interface.

v2: No changes.
---
  arch/x86/kernel/cpu/resctrl/internal.h |  2 ++ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 42 ++++++++++++++++++++++++++

  2 files changed, 44 insertions(+)
arch/x86/kernel/cpu/resctrl/internal.h +2 -0
index a88c8fc5e4df..e16244895350 100644
@@ -660,6 +660,8 @@ void arch_domain_mbm_evt_config(struct rdt_hw_domain
 *hw_dom);
   int resctrl_arch_assign(struct rdt_domain *d, u32 evtid, u32 rmid,
               u32 ctr_id, u32 closid, bool enable);
   int resctrl_grp_assign(struct rdtgroup *rdtgrp, u32 evtid);
+int resctrl_grp_unassign(struct rdtgroup *rdtgrp, u32 evtid);
+void num_cntrs_free(u32 ctr_id);
   void rdt_staged_configs_clear(void);
   bool closid_allocated(unsigned int closid);

  int resctrl_find_cleanest_closid(void);

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index 48df76499a04..5ea1e58c7201 100644
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int assign_cntrs_alloc(void) · line 218

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -216,6 +216,11 @@ static int assign_cntrs_alloc(void)
       return ctr_id;
   }
   +void num_cntrs_free(u32 ctr_id)

The name does not reflect what it does. It neither frees the "num_cntrs" information
nor does it free "num_cntrs" of counters. How about "mon_cntr_free()"?

Sure. If we change the name of num_cntrs to mbm_cntrs, then we can change to mbm_cntr_free().
Here is the comments on name change.
https://lore.kernel.org/lkml/[email protected]/

Quoted 16 lines
Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+{
+    __set_bit(ctr_id, &num_cntrs_free_map);
+}
+
   /**
    * rdtgroup_mode_by_closid - Return mode of resource group with closid
    * @closid: closid if the resource group

arch/x86/kernel/cpu/resctrl/rdtgroup.c int resctrl_grp_assign(struct rdtgroup *rdtgrp, · line 1939

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -1931,6 +1936,43 @@ int resctrl_grp_assign(struct rdtgroup *rdtgrp,
 u32 evtid)
       return 0;
   }
   +int resctrl_grp_unassign(struct rdtgroup *rdtgrp, u32 evtid)

Same comment wrt namespace. Also this function needs a description.

Sure.

Quoted 45 lines
Quoted 39 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +36 -0
+{
+    struct rdt_resource *r =
 &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+    struct rdt_domain *d;
+    u32 mon_state;
+    int index;
+
+    index = mon_event_config_index_get(evtid);
+    if (index == INVALID_CONFIG_INDEX) {
+        pr_warn_once("Invalid event id %d\n", evtid);
+        return -EINVAL;
+    }
+
+    if (evtid == QOS_L3_MBM_TOTAL_EVENT_ID) {
+        mon_state = ASSIGN_TOTAL;
+    } else if (evtid == QOS_L3_MBM_LOCAL_EVENT_ID) {
+        mon_state = ASSIGN_LOCAL;
+    } else {
+        rdt_last_cmd_puts("Invalid event id\n");
+        return -EINVAL;
+    }
+
+    if (rdtgrp->mon.mon_state & mon_state) {
+        list_for_each_entry(d, &r->domains, list)
+            resctrl_arch_assign(d, evtid, rdtgrp->mon.rmid,
+                        rdtgrp->mon.ctr_id[index],
+                        rdtgrp->closid, 0);
+
+        /* Update the counter bitmap */
+        num_cntrs_free(rdtgrp->mon.ctr_id[index]);
+    }
+
+    rdtgrp->mon.mon_state &= ~mon_state;
+
+    return 0;
+}
+
   /* rdtgroup information files for one cache resource. */
Quoted 2 lines

  static struct rftype res_common_files[] = {
      {

Reinette

Signature · 2 lines
Thanks
Babu Moger
author reviewer
#51 lore raw

PATCH v4 16/19 x86/resctrl: Enable ABMC by default on resctrl mount

In reply to Babu Moger

Enable ABMC by default when feature is supported.

Counters are assigned automatically on group creation. If the counters are exhausted, report the warnings and continue. It is not required to fail group creation for assignment failures. Users will have the option to modify the assignments.

---
v4: Few name changes based on the upstream discussion.
Commit message update.

v3: This is a new patch. Patch addresses the upstream comment to enable
ABMC feature by default if the feature is available.

---
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 69 ++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +69 -0
index 5ea1e58c7201..f452b6d9bb99 100644
@@ -2756,6 +2756,7 @@ static void rdt_disable_ctx(void)
 {
 	resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L3, false);
 	resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L2, false);
+	resctrl_abmc_disable(RDT_RESOURCE_L3);
 	set_mba_sc(false);
 
 	resctrl_debug = false;
@@ -2786,6 +2787,8 @@ static int rdt_enable_ctx(struct rdt_fs_context *ctx)
 	if (ctx->enable_debug)
 		resctrl_debug = true;
 
+	resctrl_abmc_enable(RDT_RESOURCE_L3);
+
 	return 0;
 
 out_cdpl3:
@@ -2882,6 +2885,41 @@ static void schemata_list_destroy(void)
 	}
 }
 
+static int resctrl_assign_events(struct rdtgroup *rdtgrp)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+	int ret = 0;
+
+	if (!hw_res->abmc_enabled)
+		return 0;
+
+	if (is_mbm_total_enabled())
+		ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+	if (!ret && is_mbm_local_enabled())
+		ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+
+	return ret;
+}
+
+static int resctrl_unassign_events(struct rdtgroup *rdtgrp)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+	int ret = 0;
+
+	if (!hw_res->abmc_enabled)
+		return 0;
+
+	if (is_mbm_total_enabled())
+		ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+	if (!ret && is_mbm_local_enabled())
+		ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+	return ret;
+}
+
 static int rdt_get_tree(struct fs_context *fc)
 {
 	struct rdt_fs_context *ctx = rdt_fc2context(fc);
@@ -2941,6 +2979,14 @@ static int rdt_get_tree(struct fs_context *fc)
 		if (ret < 0)
 			goto out_mongrp;
 		rdtgroup_default.mon.mon_data_kn = kn_mondata;
+
+		/*
+		 * Assign the monitor counters if it is available. If it fails,
+		 * report the warnings and continue. It is not nessaccery to
+		 * fail here.
+		 */
+		if (resctrl_assign_events(&rdtgroup_default) < 0)
+			rdt_last_cmd_puts("Monitor assignment failed\n");
 	}
 
 	ret = rdt_pseudo_lock_init();
@@ -3214,6 +3260,8 @@ static void rdt_kill_sb(struct super_block *sb)
 	cpus_read_lock();
 	mutex_lock(&rdtgroup_mutex);
 
+	resctrl_unassign_events(&rdtgroup_default);
+
 	rdt_disable_ctx();
 
 	/*Put everything back to default values. */
@@ -3752,6 +3800,14 @@ static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn,
 		goto out_unlock;
 	}
 
+	/*
+	 * Assign the monitor counters if it is available. If it fails,
+	 * report the warnings and continue. It is not nessaccery to
+	 * fail here.
+	 */
+	if (resctrl_assign_events(rdtgrp) < 0)
+		rdt_last_cmd_puts("Monitor assignment failed\n");
+
 	kernfs_activate(rdtgrp->kn);
 
 	/*
@@ -3796,6 +3852,14 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
 	if (ret)
 		goto out_closid_free;
 
+	/*
+	 * Assign the monitor counters if it is available. If it fails,
+	 * report the warnings and continue. It is not nessaccery to
+	 * fail here.
+	 */
+	if (resctrl_assign_events(rdtgrp) < 0)
+		rdt_last_cmd_puts("Monitor assignment failed\n");
+
 	kernfs_activate(rdtgrp->kn);
 
 	ret = rdtgroup_init_alloc(rdtgrp);
@@ -3891,6 +3955,9 @@ static int rdtgroup_rmdir_mon(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	update_closid_rmid(tmpmask, NULL);
 
 	rdtgrp->flags = RDT_DELETED;
+
+	resctrl_unassign_events(rdtgrp);
+
 	free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
 
 	/*
@@ -3937,6 +4004,8 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
 	cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask);
 	update_closid_rmid(tmpmask, NULL);
 
+	resctrl_unassign_events(rdtgrp);
+
 	free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
 	closid_free(rdtgrp->closid);
 
Signature · 1 line
2.34.1
maintainer
#52 lore raw

Re: [PATCH v4 16/19] x86/resctrl: Enable ABMC by default on resctrl mount

Hi Babu,

Quoted 1 line · Babu Moger

Enable ABMC by default when feature is supported.

Why enable/disable it on every mount/unmount cycle though? Why not just enable it at the beginning and only change if requested by user?

Quoted 40 lines

Counters are assigned automatically on group creation. If the counters are exhausted, report the warnings and continue. It is not required to fail group creation for assignment failures. Users will have the option to modify the assignments.

---
v4: Few name changes based on the upstream discussion.
Commit message update.

v3: This is a new patch. Patch addresses the upstream comment to enable
ABMC feature by default if the feature is available.

---
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 69 ++++++++++++++++++++++++++
  1 file changed, 69 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +3 -0
index 5ea1e58c7201..f452b6d9bb99 100644
@@ -2756,6 +2756,7 @@ static void rdt_disable_ctx(void)
  {
  	resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L3, false);
  	resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L2, false);
+	resctrl_abmc_disable(RDT_RESOURCE_L3);
  	set_mba_sc(false);
 
  	resctrl_debug = false;
@@ -2786,6 +2787,8 @@ static int rdt_enable_ctx(struct rdt_fs_context *ctx)
  	if (ctx->enable_debug)
  		resctrl_debug = true;
 
+	resctrl_abmc_enable(RDT_RESOURCE_L3);
+
  	return 0;
 
  out_cdpl3:
@@ -2882,6 +2885,41 @@ static void schemata_list_destroy(void)
  	}

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void schemata_list_destroy(void) · line 2895

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +8 -0
  }
 
+static int resctrl_assign_events(struct rdtgroup *rdtgrp)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+	int ret = 0;
+
+	if (!hw_res->abmc_enabled)
+		return 0;

resctrl fs should not be peeking in arch structure

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void schemata_list_destroy(void) · line 2902

Quoted 7 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+
+	if (is_mbm_total_enabled())
+		ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+	if (!ret && is_mbm_local_enabled())
+		ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+

This function needs a comment about why it is ok to return with error and partial changes.

Quoted 24 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +20 -0
+	return ret;
+}
+
+static int resctrl_unassign_events(struct rdtgroup *rdtgrp)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+	int ret = 0;
+
+	if (!hw_res->abmc_enabled)
+		return 0;
+
+	if (is_mbm_total_enabled())
+		ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+	if (!ret && is_mbm_local_enabled())
+		ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+	return ret;
+}
+
  static int rdt_get_tree(struct fs_context *fc)
  {
  	struct rdt_fs_context *ctx = rdt_fc2context(fc);

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdt_get_tree(struct fs_context *fc) · line 2987

Quoted 9 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
@@ -2941,6 +2979,14 @@ static int rdt_get_tree(struct fs_context *fc)
  		if (ret < 0)
  			goto out_mongrp;
  		rdtgroup_default.mon.mon_data_kn = kn_mondata;
+
+		/*
+		 * Assign the monitor counters if it is available. If it fails,
+		 * report the warnings and continue. It is not nessaccery to
+		 * fail here.
+		 */

nessaccery -> necessary

Please elaborate why it is not necessary to fail.

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdt_get_tree(struct fs_context *fc) · line 2989

Quoted 2 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+		if (resctrl_assign_events(&rdtgroup_default) < 0)
+			rdt_last_cmd_puts("Monitor assignment failed\n");

How will user know that there is a warning? This does not return an error so nothing will prompt user to check the status file. Perhaps add a comment in the docs to help users at least know that this exists. Another helpful thing will be to have the counter return "Unassigned" if it has not been assigned since users familiar with old interface may see "Unavailable" without knowing that user action is required to get a working event.

Quoted 13 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
  	}
 
  	ret = rdt_pseudo_lock_init();
@@ -3214,6 +3260,8 @@ static void rdt_kill_sb(struct super_block *sb)
  	cpus_read_lock();
  	mutex_lock(&rdtgroup_mutex);
 
+	resctrl_unassign_events(&rdtgroup_default);
+
  	rdt_disable_ctx();
 
  	/*Put everything back to default values. */

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn, · line 3807

Quoted 8 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
@@ -3752,6 +3800,14 @@ static int rdtgroup_mkdir_mon(struct kernfs_node *parent_kn,
  		goto out_unlock;
  	}
 
+	/*
+	 * Assign the monitor counters if it is available. If it fails,
+	 * report the warnings and continue. It is not nessaccery to
+	 * fail here.
+	 */

Fix copy&paste here and below.

Quoted 32 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +14 -0
+	if (resctrl_assign_events(rdtgrp) < 0)
+		rdt_last_cmd_puts("Monitor assignment failed\n");
+
  	kernfs_activate(rdtgrp->kn);
 
  	/*
@@ -3796,6 +3852,14 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
  	if (ret)
  		goto out_closid_free;
 
+	/*
+	 * Assign the monitor counters if it is available. If it fails,
+	 * report the warnings and continue. It is not nessaccery to
+	 * fail here.
+	 */
+	if (resctrl_assign_events(rdtgrp) < 0)
+		rdt_last_cmd_puts("Monitor assignment failed\n");
+
  	kernfs_activate(rdtgrp->kn);
 
  	ret = rdtgroup_init_alloc(rdtgrp);
@@ -3891,6 +3955,9 @@ static int rdtgroup_rmdir_mon(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
  	update_closid_rmid(tmpmask, NULL);
 
  	rdtgrp->flags = RDT_DELETED;
+
+	resctrl_unassign_events(rdtgrp);
+
  	free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
 
  	/*

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask) · line 4011

Quoted 8 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
@@ -3937,6 +4004,8 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup *rdtgrp, cpumask_var_t tmpmask)
  	cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask);
  	update_closid_rmid(tmpmask, NULL);
 
+	resctrl_unassign_events(rdtgrp);
+
  	free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
  	closid_free(rdtgrp->closid);
 

Reinette

author reviewer
#53 lore raw

Re: [PATCH v4 16/19] x86/resctrl: Enable ABMC by default on resctrl mount

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 1 line · Babu Moger

Enable ABMC by default when feature is supported.

Why enable/disable it on every mount/unmount cycle though? Why not just enable it at the beginning and only change if requested by user?

I think we can do that. This needs to be done at __init rdt_get_mon_l3_config(). Will let you if i see any issues with that.

Quoted 43 lines
Quoted 43 lines

Counters are assigned automatically on group creation. If the counters are exhausted, report the warnings and continue. It is not required to fail group creation for assignment failures. Users will have the option to modify the assignments.

---
v4: Few name changes based on the upstream discussion. Commit message update.

v3: This is a new patch. Patch addresses the upstream comment to enable ABMC feature by default if the feature is available.
---
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 69 ++++++++++++++++++++++++++

  1 file changed, 69 insertions(+)
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
index 5ea1e58c7201..f452b6d9bb99 100644
@@ -2756,6 +2756,7 @@ static void rdt_disable_ctx(void)
   {
       resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L3, false);
       resctrl_arch_set_cdp_enabled(RDT_RESOURCE_L2, false);
+    resctrl_abmc_disable(RDT_RESOURCE_L3);
       set_mba_sc(false);
         resctrl_debug = false;
@@ -2786,6 +2787,8 @@ static int rdt_enable_ctx(struct rdt_fs_context *ctx)
       if (ctx->enable_debug)
           resctrl_debug = true;
   +    resctrl_abmc_enable(RDT_RESOURCE_L3);
+
       return 0;

    out_cdpl3:

arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
@@ -2882,6 +2885,41 @@ static void schemata_list_destroy(void)
       }
   }
   +static int resctrl_assign_events(struct rdtgroup *rdtgrp)
+{
+    struct rdt_resource *r =
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void schemata_list_destroy(void) · line 2895

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
 &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+    struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+    int ret = 0;
+
+    if (!hw_res->abmc_enabled)
+        return 0;

resctrl fs should not be peeking in arch structure

Sure.

Quoted 11 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static void schemata_list_destroy(void) · line 2902

Quoted 8 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +7 -0
+
+    if (is_mbm_total_enabled())
+        ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+    if (!ret && is_mbm_local_enabled())
+        ret = resctrl_grp_assign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+

This function needs a comment about why it is ok to return with error and partial changes.

Sure.

Quoted 29 lines
Quoted 29 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +20 -0
+    return ret;
+}
+
+static int resctrl_unassign_events(struct rdtgroup *rdtgrp)
+{
+    struct rdt_resource *r =
 &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+    struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
+    int ret = 0;
+
+    if (!hw_res->abmc_enabled)
+        return 0;
+
+    if (is_mbm_total_enabled())
+        ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
+
+    if (!ret && is_mbm_local_enabled())
+        ret = resctrl_grp_unassign(rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
+    return ret;
+}
+
   static int rdt_get_tree(struct fs_context *fc)

  {
      struct rdt_fs_context *ctx = rdt_fc2context(fc);

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -2941,6 +2979,14 @@ static int rdt_get_tree(struct fs_context *fc)
           if (ret < 0)
               goto out_mongrp;
           rdtgroup_default.mon.mon_data_kn = kn_mondata;
Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdt_get_tree(struct fs_context *fc) · line 2987

Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +6 -0
+
+        /*
+         * Assign the monitor counters if it is available. If it fails,
+         * report the warnings and continue. It is not nessaccery to
+         * fail here.
+         */

nessaccery -> necessary

Sure.

Quoted 2 lines

Please elaborate why it is not necessary to fail.

Sure.

Quoted 8 lines

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdt_get_tree(struct fs_context *fc) · line 2989

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
+        if (resctrl_assign_events(&rdtgroup_default) < 0)
+            rdt_last_cmd_puts("Monitor assignment failed\n");

How will user know that there is a warning? This does not return an error so nothing will prompt user to check the status file. Perhaps add a comment in the docs to help users at least know that this exists. Another helpful

Sure. Will add text about this in the documentation.

Quoted 4 lines

thing will be to have the counter return "Unassigned" if it has not been assigned
since users familiar with old interface may see "Unavailable" without knowing that user action is required to get a working event.

Not so sure about interpreting hardware reported error.

Quoted 13 lines
Quoted 13 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +1 -0
       }
         ret = rdt_pseudo_lock_init();
@@ -3214,6 +3260,8 @@ static void rdt_kill_sb(struct super_block *sb)
       cpus_read_lock();
       mutex_lock(&rdtgroup_mutex);
   +    resctrl_unassign_events(&rdtgroup_default);
+
       rdt_disable_ctx();
         /*Put everything back to default values. */
@@ -3752,6 +3800,14 @@ static int rdtgroup_mkdir_mon(struct kernfs_node
 *parent_kn,
           goto out_unlock;
Quoted 8 lines
Quoted 6 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
       }

  +    /*
+     * Assign the monitor counters if it is available. If it fails, +     * report the warnings and continue. It is not nessaccery to +     * fail here.
+     */

Fix copy&paste here and below.

Sure.

Quoted 41 lines
Quoted 37 lines

+    if (resctrl_assign_events(rdtgrp) < 0)
+        rdt_last_cmd_puts("Monitor assignment failed\n"); +
      kernfs_activate(rdtgrp->kn);
        /*

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -3796,6 +3852,14 @@ static int rdtgroup_mkdir_ctrl_mon(struct
 kernfs_node *parent_kn,
       if (ret)
           goto out_closid_free;

  +    /*
+     * Assign the monitor counters if it is available. If it fails, +     * report the warnings and continue. It is not nessaccery to +     * fail here.
+     */
+    if (resctrl_assign_events(rdtgrp) < 0)
+        rdt_last_cmd_puts("Monitor assignment failed\n"); +
      kernfs_activate(rdtgrp->kn);
        ret = rdtgroup_init_alloc(rdtgrp);

arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
@@ -3891,6 +3955,9 @@ static int rdtgroup_rmdir_mon(struct rdtgroup
 *rdtgrp, cpumask_var_t tmpmask)
       update_closid_rmid(tmpmask, NULL);
         rdtgrp->flags = RDT_DELETED;
+
+    resctrl_unassign_events(rdtgrp);
+
       free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
         /*
@@ -3937,6 +4004,8 @@ static int rdtgroup_rmdir_ctrl(struct rdtgroup
 *rdtgrp, cpumask_var_t tmpmask)
       cpumask_or(tmpmask, tmpmask, &rdtgrp->cpu_mask);
       update_closid_rmid(tmpmask, NULL);
   +    resctrl_unassign_events(rdtgrp);
+
       free_rmid(rdtgrp->closid, rdtgrp->mon.rmid);
       closid_free(rdtgrp->closid);
Quoted 1 line

Reinette

Signature · 2 lines
Thanks
Babu Moger
maintainer
#54 lore raw

Re: [PATCH v4 16/19] x86/resctrl: Enable ABMC by default on resctrl mount

Hi Babu,

Quoted 11 lines · Babu
Quoted 9 lines · Reinette Chatre
Quoted 2 lines · Babu Moger

+        if (resctrl_assign_events(&rdtgroup_default) < 0) +            rdt_last_cmd_puts("Monitor assignment failed\n");

How will user know that there is a warning? This does not return an error so nothing will prompt user to check the status file. Perhaps add a comment in the docs to help users at least know that this exists. Another helpful

Quoted 9 lines

Sure. Will add text about this in the documentation.

Quoted 4 lines

thing will be to have the counter return "Unassigned" if it has not been assigned
since users familiar with old interface may see "Unavailable" without knowing that user action is required to get a working event.

Not so sure about interpreting hardware reported error.

I only see "Unavailable" as a hardware error and that is already supported. "Unassigned" is not a hardware error but instead indicates to user space that no hardware counter is backing the queried event.

Reinette

#55 lore raw

Re: [PATCH v4 16/19] x86/resctrl: Enable ABMC by default on resctrl mount

Hi Reinette,

Quoted 21 lines · Reinette Chatre

Hi Babu,

Quoted 18 lines · Babu
Quoted 9 lines · Reinette Chatre
Quoted 2 lines · Babu Moger

+        if (resctrl_assign_events(&rdtgroup_default) < 0) +            rdt_last_cmd_puts("Monitor assignment failed\n");

How will user know that there is a warning? This does not return an error so nothing will prompt user to check the status file. Perhaps add a comment in the docs to help users at least know that this exists. Another helpful

Sure. Will add text about this in the documentation.

Quoted 4 lines

thing will be to have the counter return "Unassigned" if it has not been assigned
since users familiar with old interface may see "Unavailable" without knowing that user action is required to get a working event.

Quoted 7 lines
Quoted 2 lines

Not so sure about interpreting hardware reported error.

I only see "Unavailable" as a hardware error and that is already supported. "Unassigned" is not a hardware error but instead indicates to user space that no hardware counter is backing the queried event.

That is fine. Will change to report "Unassinged" when it queried when event is not assigned. thanks

Signature · 1 line
- Babu Moger
author reviewer
#56 lore raw

PATCH v4 17/19 x86/resctrl: Introduce the interface switch between ABMC and mbm_legacy

In reply to Babu Moger

Introduce interface to switch between ABMC and legacy_mbm modes.

By default ABMC is enabled on resctrl mount if the feature is available. However, user will have the option to go back to legacy_mbm if required.

$ cat /sys/fs/resctrl/info/L3_MON/mbm_assign
[abmc]
mbm_legacy

To enable the legacy monitoring feature:

$ echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign

---
v4: Minor commit text changes. Keep the default to ABMC when supported.

v3: New patch to address the review comments from upstream.

---
 Documentation/arch/x86/resctrl.rst     | 10 +++++++
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 40 +++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 1 deletion(-)
Documentation/arch/x86/resctrl.rst +10 -0
index ab3cde61a124..fd050d4d22cd 100644
@@ -271,6 +271,16 @@ with the following files:
 	  [abmc]
 	  mbm_legacy
 
+	* To enable ABMC feature:
+	  ::
+
+	    # echo  "abmc" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+
+	* To enable the legacy monitoring feature:
+	  ::
+
+	    # echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+
 "max_threshold_occupancy":
 		Read/write file provides the largest value (in
 		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/rdtgroup.c +39 -1
index f452b6d9bb99..d77ff059269a 100644
@@ -908,6 +908,43 @@ static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of,
 	return 0;
 }
 
+/*
+ * rdtgroup_mode_write - Modify the resource group's mode
+ */
+static ssize_t rdtgroup_mbm_assign_write(struct kernfs_open_file *of,
+					 char *buf, size_t nbytes,
+					 loff_t off)
+{
+	struct rdt_resource *r = of->kn->parent->priv;
+	int ret = 0;
+
+	if (!r->abmc_capable)
+		return -EINVAL;
+
+	/* Valid input requires a trailing newline */
+	if (nbytes == 0 || buf[nbytes - 1] != '\n')
+		return -EINVAL;
+
+	buf[nbytes - 1] = '\0';
+
+	cpus_read_lock();
+	mutex_lock(&rdtgroup_mutex);
+
+	rdt_last_cmd_clear();
+
+	if (!strcmp(buf, "mbm_legacy"))
+		resctrl_abmc_disable(RDT_RESOURCE_L3);
+	else if (!strcmp(buf, "abmc"))
+		ret = resctrl_abmc_enable(RDT_RESOURCE_L3);
+	else
+		ret = -EINVAL;
+
+	mutex_unlock(&rdtgroup_mutex);
+	cpus_read_unlock();
+
+	return ret ?: nbytes;
+}
+
 #ifdef CONFIG_PROC_CPU_RESCTRL
 
 /*
@@ -2087,9 +2124,10 @@ static struct rftype res_common_files[] = {
 	},
 	{
 		.name		= "mbm_assign",
-		.mode		= 0444,
+		.mode		= 0644,
 		.kf_ops		= &rdtgroup_kf_single_ops,
 		.seq_show	= rdtgroup_mbm_assign_show,
+		.write		= rdtgroup_mbm_assign_write,
 	},
 	{
 		.name		= "cpus",
Signature · 1 line
2.34.1
maintainer
#57 lore raw

Re: [PATCH v4 17/19] x86/resctrl: Introduce the interface switch between ABMC and mbm_legacy

Hi Babu,

Quoted 1 line · Babu Moger

Introduce interface to switch between ABMC and legacy_mbm modes.

shortlog and first sentence of changelog do not match: mbm_legacy vs legacy_mbm?

Quoted 10 lines

By default ABMC is enabled on resctrl mount if the feature is available. However, user will have the option to go back to legacy_mbm if required.

$ cat /sys/fs/resctrl/info/L3_MON/mbm_assign
[abmc]
mbm_legacy

To enable the legacy monitoring feature:

$ echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign

Missing information about user visible impact to counters/events and any mitigations needed in implementation.

Quoted 19 lines

---
v4: Minor commit text changes. Keep the default to ABMC when supported.

v3: New patch to address the review comments from upstream.

---
  Documentation/arch/x86/resctrl.rst     | 10 +++++++
  arch/x86/kernel/cpu/resctrl/rdtgroup.c | 40 +++++++++++++++++++++++++-
  2 files changed, 49 insertions(+), 1 deletion(-)
Documentation/arch/x86/resctrl.rst +0 -0
index ab3cde61a124..fd050d4d22cd 100644
@@ -271,6 +271,16 @@ with the following files:
  	  [abmc]
  	  mbm_legacy
 

Documentation/arch/x86/resctrl.rst with the following files: · line 283

Quoted 10 lines
Documentation/arch/x86/resctrl.rst +10 -0
+	* To enable ABMC feature:
+	  ::
+
+	    # echo  "abmc" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+
+	* To enable the legacy monitoring feature:
+	  ::
+
+	    # echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+

No information about what the features are or what will happen on such a switch.

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of, · line 912

Quoted 13 lines
Documentation/arch/x86/resctrl.rst +0 -0
  "max_threshold_occupancy":
  		Read/write file provides the largest value (in
  		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -0
index f452b6d9bb99..d77ff059269a 100644
@@ -908,6 +908,43 @@ static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of,
  	return 0;
  }
 
+/*
+ * rdtgroup_mode_write - Modify the resource group's mode

Comment does not match function name. Seems like "mode" is the generic term to use instead of "assign".

Quoted 40 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +35 -0
+ */
+static ssize_t rdtgroup_mbm_assign_write(struct kernfs_open_file *of,
+					 char *buf, size_t nbytes,
+					 loff_t off)
+{
+	struct rdt_resource *r = of->kn->parent->priv;
+	int ret = 0;
+
+	if (!r->abmc_capable)
+		return -EINVAL;
+
+	/* Valid input requires a trailing newline */
+	if (nbytes == 0 || buf[nbytes - 1] != '\n')
+		return -EINVAL;
+
+	buf[nbytes - 1] = '\0';
+
+	cpus_read_lock();
+	mutex_lock(&rdtgroup_mutex);
+
+	rdt_last_cmd_clear();
+
+	if (!strcmp(buf, "mbm_legacy"))
+		resctrl_abmc_disable(RDT_RESOURCE_L3);
+	else if (!strcmp(buf, "abmc"))
+		ret = resctrl_abmc_enable(RDT_RESOURCE_L3);
+	else
+		ret = -EINVAL;
+
+	mutex_unlock(&rdtgroup_mutex);
+	cpus_read_unlock();
+
+	return ret ?: nbytes;
+}
+
  #ifdef CONFIG_PROC_CPU_RESCTRL
 
  /*
@@ -2087,9 +2124,10 @@ static struct rftype res_common_files[] = {
  	},

arch/x86/kernel/cpu/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 2133

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -1
  	{
  		.name		= "mbm_assign",
-		.mode		= 0444,
+		.mode		= 0644,
  		.kf_ops		= &rdtgroup_kf_single_ops,
  		.seq_show	= rdtgroup_mbm_assign_show,
+		.write		= rdtgroup_mbm_assign_write,
  	},
  	{
  		.name		= "cpus",

Reinette

author reviewer
#58 lore raw

Re: [PATCH v4 17/19] x86/resctrl: Introduce the interface switch between ABMC and mbm_legacy

Hi Reinette,

Quoted 7 lines · Reinette Chatre

Hi Babu,

Quoted 1 line · Babu Moger

Introduce interface to switch between ABMC and legacy_mbm modes.

shortlog and first sentence of changelog do not match: mbm_legacy vs legacy_mbm?

Will correct it.

Quoted 9 lines
Quoted 9 lines

By default ABMC is enabled on resctrl mount if the feature is available. However, user will have the option to go back to legacy_mbm if required.

$ cat /sys/fs/resctrl/info/L3_MON/mbm_assign
[abmc]
mbm_legacy
Quoted 5 lines
Quoted 2 lines

To enable the legacy monitoring feature:

$ echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign

Missing information about user visible impact to counters/events and any mitigations needed in implementation.

Sure. Will add the details.

Quoted 25 lines
Quoted 25 lines

---
v4: Minor commit text changes. Keep the default to ABMC when supported.

v3: New patch to address the review comments from upstream.
---
  Documentation/arch/x86/resctrl.rst     | 10 +++++++ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 40 +++++++++++++++++++++++++-

  2 files changed, 49 insertions(+), 1 deletion(-)
Documentation/arch/x86/resctrl.rst +0 -0
index ab3cde61a124..fd050d4d22cd 100644
@@ -271,6 +271,16 @@ with the following files:

        [abmc]
        mbm_legacy
  +    * To enable ABMC feature:
+      ::

Documentation/arch/x86/resctrl.rst +3 -0
+
+        # echo  "abmc" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+
Quoted 8 lines

Documentation/arch/x86/resctrl.rst with the following files: · line 283

Quoted 5 lines

+    * To enable the legacy monitoring feature:
+      ::

Documentation/arch/x86/resctrl.rst +3 -0
+
+        # echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign
+

No information about what the features are or what will happen on such a switch.

Ok. Sure. Will add more documentation.

Quoted 10 lines
Quoted 10 lines

  "max_threshold_occupancy":
          Read/write file provides the largest value (in bytes) at which a previously used LLC_occupancy

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
index f452b6d9bb99..d77ff059269a 100644
@@ -908,6 +908,43 @@ static int rdtgroup_mbm_assign_show(struct
Quoted 8 lines
Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
 kernfs_open_file *of,
       return 0;
   }

  +/*
+ * rdtgroup_mode_write - Modify the resource group's mode

Comment does not match function name. Seems like "mode" is the generic term to use instead of "assign".

Sure. Will fix.

Quoted 54 lines
Quoted 40 lines

+ */

arch/x86/kernel/cpu/resctrl/rdtgroup.c +34 -0
+static ssize_t rdtgroup_mbm_assign_write(struct kernfs_open_file *of,
+                     char *buf, size_t nbytes,
+                     loff_t off)
+{
+    struct rdt_resource *r = of->kn->parent->priv;
+    int ret = 0;
+
+    if (!r->abmc_capable)
+        return -EINVAL;
+
+    /* Valid input requires a trailing newline */
+    if (nbytes == 0 || buf[nbytes - 1] != '\n')
+        return -EINVAL;
+
+    buf[nbytes - 1] = '\0';
+
+    cpus_read_lock();
+    mutex_lock(&rdtgroup_mutex);
+
+    rdt_last_cmd_clear();
+
+    if (!strcmp(buf, "mbm_legacy"))
+        resctrl_abmc_disable(RDT_RESOURCE_L3);
+    else if (!strcmp(buf, "abmc"))
+        ret = resctrl_abmc_enable(RDT_RESOURCE_L3);
+    else
+        ret = -EINVAL;
+
+    mutex_unlock(&rdtgroup_mutex);
+    cpus_read_unlock();
+
+    return ret ?: nbytes;
+}
+

  #ifdef CONFIG_PROC_CPU_RESCTRL
    /*

arch/x86/kernel/cpu/resctrl/rdtgroup.c +0 -0
@@ -2087,9 +2124,10 @@ static struct rftype res_common_files[] = {
       },

arch/x86/kernel/cpu/resctrl/rdtgroup.c static struct rftype res_common_files[] = { · line 2133

Quoted 10 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -1
       {
           .name        = "mbm_assign",
-        .mode        = 0444,
+        .mode        = 0644,
           .kf_ops        = &rdtgroup_kf_single_ops,
           .seq_show    = rdtgroup_mbm_assign_show,
+        .write        = rdtgroup_mbm_assign_write,
       },
       {
           .name        = "cpus",

Reinette

Signature · 2 lines
Thanks
Babu Moger
#59 lore raw

Re: [PATCH v4 17/19] x86/resctrl: Introduce the interface switch between ABMC and mbm_legacy

In reply to Babu Moger

…

Quoted 1 line

+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c

…

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+static ssize_t rdtgroup_mbm_assign_write(struct kernfs_open_file *of,
+					 char *buf, size_t nbytes,
+					 loff_t off)
+{

…

Quoted 4 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +4 -0
+	cpus_read_lock();
+	mutex_lock(&rdtgroup_mutex);
+
+	rdt_last_cmd_clear();

…

arch/x86/kernel/cpu/resctrl/rdtgroup.c static int rdtgroup_mbm_assign_show(struct kernfs_open_file *of, · line 946

Quoted 5 lines
arch/x86/kernel/cpu/resctrl/rdtgroup.c +5 -0
+	mutex_unlock(&rdtgroup_mutex);
+	cpus_read_unlock();
+
+	return ret ?: nbytes;
+}

…

Would you become interested to apply statements like the following?

* guard(cpus_read_lock)();
https://elixir.bootlin.com/linux/v6.10-rc4/source/include/linux/cleanup.h#L133

* guard(mutex)(&rdtgroup_mutex);
https://elixir.bootlin.com/linux/v6.10-rc4/source/include/linux/mutex.h#L196

Regards,
Markus

author reviewer
#60 lore raw

PATCH v4 18/19 x86/resctrl: Introduce interface to list monitor states of all the groups

In reply to Babu Moger

Introduce the interface to list the monitor states of all the resctrl groups.

Example:
$cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control

List follows the following format:

"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

Format for specific type of groups:

- Default CTRL_MON group:
"//<domain_id>=<assignment_flags>"

- Non-default CTRL_MON group:
"<CTRL_MON group>//<domain_id>=<assignment_flags>"

- Child MON group of default CTRL_MON group:
"/<MON group>/<domain_id>=<assignment_flags>"

- Child MON group of non-default CTRL_MON group:
"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

Assignment flags can be one of the following:
t MBM total event is enabled
l MBM local event is enabled
tl Both total and local MBM events are enabled
_ None of the MBM events are enabled

---
v4: Added functionality to query domain specific assigment in.
rdtgroup_abmc_dom_state().

v3: New patch.
Addresses the feedback to provide the global assignment interface.
https://lore.kernel.org/lkml/[email protected]/

---
 Documentation/arch/x86/resctrl.rst     |  55 +++++++++++
 arch/x86/kernel/cpu/resctrl/monitor.c  |   1 +
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 129 +++++++++++++++++++++++++
 3 files changed, 185 insertions(+)
Documentation/arch/x86/resctrl.rst +55 -0
index fd050d4d22cd..255087de568d 100644
@@ -281,6 +281,61 @@ with the following files:
 
 	    # echo  "mbm_legacy" > /sys/fs/resctrl/info/L3_MON/mbm_assign
 
+"mbm_assign_control":
+	Available when ABMC features are supported.
+	Reports the resctrl group and monitor status of each group.
+
+	List follows the following format:
+		"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"
+
+	Format for specific type of grpups:
+
+	* Default CTRL_MON group:
+		"//<domain_id>=<assignment_flags>"
+
+	* Non-default CTRL_MON group:
+		"<CTRL_MON group>//<domain_id>=<assignment_flags>"
+
+	* Child MON group of default CTRL_MON group:
+		"/<MON group>/<domain_id>=<assignment_flags>"
+
+	* Child MON group of non-default CTRL_MON group:
+		"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"
+
+	Assignment flags can be one of the following:
+	::
+
+	 t  MBM total event is enabled
+	 l  MBM local event is enabled
+	 tl Both total and local MBM events are enabled
+	 _  None of the MBM events are enabled
+
+	Examples:
+	::
+
+	 # mkdir /sys/fs/resctrl/mon_groups/child_default_mon_grp
+	 # mkdir /sys/fs/resctrl/non_default_ctrl_mon_grp
+	 # mkdir /sys/fs/resctrl/non_default_ctrl_mon_grp/mon_groups/child_non_default_mon_grp
+
+	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	 non_default_ctrl_mon_grp//0=tl;1=tl;
+	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
+	 //0=tl;1=tl;
+	 /child_default_mon_grp/0=tl;1=tl;
+
+	 There are four resctrl groups. All the groups have total and local events are
+	 enabled on domain 0 and 1.
+
+	 non_default_ctrl_mon_grp// - This is a non default control mon group.
+
+	 non_default_ctrl_mon_grp/child_non_default_mon_grp/ - This is a child monitor
+	 group of the non default control mon group.
+
+	 // - This is a default control mon group.
+
+	 /child_default_mon_grp/ - This is a child monitor group of the default control
+	 mon group.
+
 "max_threshold_occupancy":
 		Read/write file provides the largest value (in
 		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/monitor.c +1 -0
index ab0f4bb49bd9..f4dba02db9c0 100644
@@ -1083,6 +1083,7 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
 				r->mon.num_cntrs = 64;
 			}
 			resctrl_file_fflags_init("num_cntrs", RFTYPE_MON_INFO);
+			resctrl_file_fflags_init("mbm_assign_control", RFTYPE_MON_INFO);
 		}
 	}
 
arch/x86/kernel/cpu/resctrl/rdtgroup.c +129 -0

141 lines not on this page · raw message

Signature · 1 line
2.34.1
author reviewer
#61 lore raw

PATCH v4 19/19 x86/resctrl: Introduce interface to modify assignment states of the groups

In reply to Babu Moger

Introduce the interface to enable events in ABMC mode.

Events can be enabled or disabled by writing to file /sys/fs/resctrl/info/L3_MON/mbm_assign_control

Format is similar to the list format with addition of op-code for the assignment operation.
"<CTRL_MON group>/<MON group>/<op-code><assignment_flags>"

Format for specific type of groups:

* Default CTRL_MON group:

         "//<domain_id><op-code><assignment_flags>"

* Non-default CTRL_MON group:

         "<CTRL_MON group>//<domain_id><op-code><assignment_flags>"

* Child MON group of default CTRL_MON group:

         "/<MON group>/<domain_id><op-code><assignment_flags>"

* Child MON group of non-default CTRL_MON group:

         "<CTRL_MON group>/<MON group>/<domain_id><op-code><assignment_flags>"

Op-code can be one of the following:

= Update the assignment to match the flags
+ enable a new state
- disable a new state

Assignment flags can be one of the following:
t MBM total event is enabled
l MBM local event is enabled
tl Both total and local MBM events are enabled
_ None of the MBM events are enabled

---
v4: Added domain specific assignments. Fixed the opcode parsing.

v3: New patch.
Addresses the feedback to provide the global assignment interface.
https://lore.kernel.org/lkml/[email protected]/

---
 Documentation/arch/x86/resctrl.rst     |  81 +++++++++
 arch/x86/kernel/cpu/resctrl/rdtgroup.c | 242 ++++++++++++++++++++++++-
 2 files changed, 322 insertions(+), 1 deletion(-)
Documentation/arch/x86/resctrl.rst +81 -0
index 255087de568d..89af91805b38 100644
@@ -336,6 +336,87 @@ with the following files:
 	 /child_default_mon_grp/ - This is a child monitor group of the default control
 	 mon group.
 
+	Assignment state can be updated by writing to the interface.
+
+	Format is similar to the list format with addition of op-code for the
+	assignment operation.
+
+		"<CTRL_MON group>/<MON group>/<op-code><assignment_flags>"
+
+	Format for each type of groups:
+
+        * Default CTRL_MON group:
+                "//<domain_id><op-code><assignment_flags>"
+
+        * Non-default CTRL_MON group:
+                "<CTRL_MON group>//<domain_id><op-code><assignment_flags>"
+
+        * Child MON group of default CTRL_MON group:
+                "/<MON group>/<domain_id><op-code><assignment_flags>"
+
+        * Child MON group of non-default CTRL_MON group:
+                "<CTRL_MON group>/<MON group>/<domain_id><op-code><assignment_flags>"
+
+	Op-code can be one of the following:
+	::
+
+	 = Update the assignment to match the flags
+	 + Add a new state
+	 - delete a new state
+
+	Examples:
+	::
+
+	  Initial group status:
+	  # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	  non_default_ctrl_mon_grp//0=tl;1=tl;
+	  non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
+	  //0=tl;1=tl;
+	  /child_default_mon_grp/0=tl;1=tl;
+
+	  To update the default group to enable only total event on domain 0:
+	  # echo "//0=t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+
+	  Assignment status after the update:
+	  # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	  non_default_ctrl_mon_grp//0=tl;1=tl;
+	  non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
+	  //0=t;1=tl;2=tl;
+	  /child_default_mon_grp/0=tl;1=tl;
+
+	  To update the MON group child_default_mon_grp to remove total event on domain 1:
+	  # echo "/child_default_mon_grp/1-t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+
+	  Assignment status after the update:
+	  $ cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	  non_default_ctrl_mon_grp//0=tl;1=tl;
+	  non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
+	  //0=t;1=l;
+	  /child_default_mon_grp/0=t;1=tl;
+
+	  To update the MON group non_default_ctrl_mon_grp/child_non_default_mon_grp to
+	  remove both local and total events on domain 1:
+	  # echo "non_default_ctrl_mon_grp/child_non_default_mon_grp/1=_" >
+			/sys/fs/resctrl/info/L3_MON/mbm_assign_control
+
+	  Assignment status after the update:
+	  # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	  non_default_ctrl_mon_grp//0=tl;1=tl;
+	  non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
+	  //0=t;1=l;
+	  /child_default_mon_grp/0=t;1=tl;
+
+	  To update the default group to add a total event domain 1.
+	  # echo "//1+t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+
+	  Assignment status after the update:
+
+	  # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
+	  non_default_ctrl_mon_grp//0=tl;1=tl;
+	  non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
+	  //0=t;1=tl;
+	  /child_default_mon_grp/0=t;1=tl;
+
 "max_threshold_occupancy":
 		Read/write file provides the largest value (in
 		bytes) at which a previously used LLC_occupancy
arch/x86/kernel/cpu/resctrl/rdtgroup.c +241 -1

256 lines not on this page · raw message

Signature · 1 line
2.34.1
maintainer
#62 lore raw
In reply to Babu Moger

Hi Babu,

Quoted 4 lines · Babu Moger

d. This series adds a new interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control
to list and modify the group's assignment states.

There was a lot of discussion resulting in this centralized file. At first glance this file appears to be very complicated and I believe any reasonable person would wonder if all of this is necessary. I recommend that you add a motivation for why this file is needed. Some items I recall are : it makes it easier for user space to learn how counters are used (no need to traverse resctrl and open()/close() many files), on the resctrl side it makes it possible to support counter re-assignment with a single IPI. There may be other motivations that I am forgetting now.

Also, could the name just be "mbm_control"? What is enabled at this time are "assignable counters" but in the future we may want to add support for other flags that have nothing to do with "assignable counters".

Quoted 4 lines
	The list follows the following format:

	"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

"assignment_flags" -> "flags" ? (throughout)

Quoted 31 lines

Format for specific type of groups:

* Default CTRL_MON group:
"//<domain_id>=<assignment_flags>"

* Non-default CTRL_MON group:
"<CTRL_MON group>//<domain_id>=<assignment_flags>"

* Child MON group of default CTRL_MON group:
"/<MON group>/<domain_id>=<assignment_flags>"

* Child MON group of non-default CTRL_MON group:
"<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

Assignment flags can be one of the following:

t MBM total event is enabled
l MBM local event is enabled
tl Both total and local MBM events are enabled _ None of the MBM events are enabled

Examples:

# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control non_default_ctrl_mon_grp//0=tl;1=tl; non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl; //0=tl;1=tl;
/child_default_mon_grp/0=tl;1=tl;

Quoted 8 lines

There are four groups and all the groups have local and total event enabled on domain 0 and 1.

=tl means both total and local events are enabled.

"//" - This is a default CONTROL MON group

"non_default_ctrl_mon_grp//" - This is non default CONTROL MON group

Be consistent with "non-default" (vs non default) as well as "CTRL_MON" (vs CONTROL MON).

Quoted 2 lines

"/child_default_mon_grp/" - This is Child MON group of the defult group

"Child" -> "child"
"defult" -> "default"

Quoted 3 lines

"non_default_ctrl_mon_grp/child_non_default_mon_grp/" - This is child MON group of the non default group

non-default

Quoted 15 lines

e. Update the group assignment states using the interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control.

The write format is similar to the above list format with addition of op-code for the assignment operation.

* Default CTRL_MON group:
"//<domain_id><op-code><assignment_flags>"

* Non-default CTRL_MON group:
"<CTRL_MON group>//<domain_id><op-code><assignment_flags>"

* Child MON group of default CTRL_MON group:
"/<MON group>/<domain_id><op-code><assignment_flags>"

Quoted 8 lines

* Child MON group of non-default CTRL_MON group:
"<CTRL_MON group>/<MON group>/<domain_id><op-code><assignment_flags>"

Op-code can be one of the following:

= Update the assignment to match the flags
+ Assign a new state
- Unassign a new state

Looking here and the implementation it seems that "+_" and "-_" is supported. I think that should be invalid. Only "=_" seems appropriate to me. Also please take care to not have a catchall "default" that does an unassign. Doing something like that will prevent us from ever being able to add any flags in the future.

Quoted 21 lines
	
	
	Initial group status:
	
	# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	non_default_ctrl_mon_grp//0=tl;1=tl;
	non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	//0=tl;1=tl;
	/child_default_mon_grp/0=tl;1=tl;
	
	 To update the default group to enable only total event on domain 0:
	 # echo "//0=t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	 //0=t;1=tl;
	 /child_default_mon_grp/0=tl;1=tl;
	
	 To update the MON group child_default_mon_grp to remove total event on domain 1:
Quoted 8 lines
	 # echo "/child_default_mon_grp/1-t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 $ cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
	 //0=t;1=l;
	 /child_default_mon_grp/0=t;1=tl;

This does not look right. Why did domain #1 of the default CTRL_MON group change also?

Quoted 16 lines
	
	 To update the MON group non_default_ctrl_mon_grp/child_non_default_mon_grp to
	 remove both local and total events on domain 1:
	 # echo "non_default_ctrl_mon_grp/child_non_default_mon_grp/1=_" >
	               /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	
	 Assignment status after the update:
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
	 //0=t;1=l;
	 /child_default_mon_grp/0=t;1=tl;
	
	 To update the default group to add a total event domain 1.
	 # echo "//1+t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control

Unclear where "t" flag was removed.

Quoted 10 lines
	 Assignment status after the update:
	
	 # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
	 non_default_ctrl_mon_grp//0=tl;1=tl;
	 non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
	 //0=t;1=tl;
	 /child_default_mon_grp/0=t;1=tl;

f. Read the event mbm_total_bytes and mbm_local_bytes of the default group.
There is no change in reading the evetns with ABMC. If the event is unassigned

"evetns" -> "events"

Quoted 1 line

when reading, then the read will come back as Unavailable.

Should this not rather be "Unassigned"? According to the docs the counters will return "Unavailable" right after reconfigure so it seems that there are scenarios where an "assigned" counter returns "Unavailable". It seems more useful to return "Unassigned" that will have a new specific meaning that overloading existing "Unavailable" that has original meaning of "try again" .... but in this case trying again will be futile.

Quoted 6 lines
	
	# cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes
	779247936
	# cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_local_bytes
	765207488
Quoted 7 lines

g. Users will have the option to go back to legacy_mbm mode if required.
This can be done using the following command.

# echo "legacy_mbm" > /sys/fs/resctrl/info/L3_MON/mbm_assign # cat /sys/fs/resctrl/info/L3_MON/mbm_assign
abmc
[mbm_legacy]

It is confusing for the value written by user space to be different from the value displayed: "legacy_mbm" vs "mbm_legacy.

This is still missing information about what happens to the counters/events on such a switch. Will events just keep counting? Will they be reset? ...?

I also think we should try to find a more generic name for this file. "mbm_cntr_mode" or "mbm_mode" maybe?

Quoted 21 lines

h. Check the bandwidth configuration for the group. Note that bandwidth

    configuration has a domain scope. Total event defaults to 0x7F (to
    count all the events) and local event defaults to 0x15 (to count all
    the local numa events). The event bitmap decoding is available at
    https://www.kernel.org/doc/Documentation/x86/resctrl.rst
    in section "mbm_total_bytes_config", "mbm_local_bytes_config":
	
	#cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
	0=0x7f;1=0x7f
	
	#cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config
	0=0x15;1=0x15

j. Change the bandwidth source for domain 0 for the total event to count only reads.

    Note that this change effects total events on the domain 0.
	
	#echo 0=0x33 > /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
	#cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config
	0=0x33;1=0x7F
Quoted 5 lines

k. Now read the total event again. The mbm_total_bytes should display

    only the read events.
	
	#cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes
	314101

According to doc, right after a BMEC change the counter will read "Unavailable" is this not the case here?

Quoted 4 lines

l. Unmount the resctrl

#umount /sys/fs/resctrl/

Reinette

author reviewer
#63 lore raw

Hi Reinette,

Thanks for the feedback for the series.

Quoted 9 lines · Reinette Chatre

Hi Babu,

Quoted 5 lines · Babu Moger

d. This series adds a new interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control to list and modify the group's assignment states.

Quoted 13 lines

There was a lot of discussion resulting in this centralized file. At first glance this
file appears to be very complicated and I believe any reasonable person would wonder if
all of this is necessary. I recommend that you add a motivation for why this file is needed.
Some items I recall are : it makes it easier for user space to learn how counters are used (no
need to traverse resctrl and open()/close() many files), on the resctrl side it makes
it possible to support counter re-assignment with a single IPI. There may be other motivations
that I am forgetting now.

Sure. Will add those details.

Quoted 6 lines

Also, could the name just be "mbm_control"? What is enabled at this time are "assignable
counters" but in the future we may want to add support for other flags that have nothing to
do with "assignable counters".

Yes. Sure.

Quoted 7 lines
Quoted 5 lines

    The list follows the following format:

    "<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

"assignment_flags" -> "flags" ? (throughout)

Yes.

Quoted 36 lines
Quoted 36 lines

    Format for specific type of groups:

    * Default CTRL_MON group:
     "//<domain_id>=<assignment_flags>"

        * Non-default CTRL_MON group:
                "<CTRL_MON group>//<domain_id>=<assignment_flags>"

        * Child MON group of default CTRL_MON group:
                "/<MON group>/<domain_id>=<assignment_flags>"

        * Child MON group of non-default CTRL_MON group:
                "<CTRL_MON group>/<MON group>/<domain_id>=<assignment_flags>"

        Assignment flags can be one of the following:

         t  MBM total event is enabled
         l  MBM local event is enabled
         tl Both total and local MBM events are enabled _  None of the MBM events are enabled

    Examples:

    # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
    non_default_ctrl_mon_grp//0=tl;1=tl;
    non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
    //0=tl;1=tl;
    /child_default_mon_grp/0=tl;1=tl;

    There are four groups and all the groups have local and total event enabled on domain 0 and 1.

Quoted 8 lines
Quoted 5 lines

    =tl means both total and local events are enabled.

    "//" - This is a default CONTROL MON group

    "non_default_ctrl_mon_grp//" - This is non default CONTROL MON group

Be consistent with "non-default" (vs non default) as well as "CTRL_MON" (vs CONTROL MON).

Sure.

Quoted 7 lines
Quoted 4 lines

    "/child_default_mon_grp/"  - This is Child MON group of the defult group

"Child" -> "child"
"defult" -> "default"

Yes.

Quoted 6 lines
Quoted 4 lines

    "non_default_ctrl_mon_grp/child_non_default_mon_grp/" - This is child MON group of the non default group

non-default

Sure.

Quoted 27 lines
Quoted 21 lines

e. Update the group assignment states using the interface file /sys/fs/resctrl/info/L3_MON/mbm_assign_control.

    The write format is similar to the above list format with addition of op-code for the assignment operation.

    * Default CTRL_MON group:
            "//<domain_id><op-code><assignment_flags>"

    * Non-default CTRL_MON group:
            "<CTRL_MON group>//<domain_id><op-code><assignment_flags>"

    * Child MON group of default CTRL_MON group:
            "/<MON group>/<domain_id><op-code><assignment_flags>"

    * Child MON group of non-default CTRL_MON group:
            "<CTRL_MON group>/<MON group>/<domain_id><op-code><assignment_flags>"

Quoted 5 lines

    Op-code can be one of the following:

    = Update the assignment to match the flags
    + Assign a new state
    - Unassign a new state

Quoted 5 lines

Looking here and the implementation it seems that "+_" and "-_" is supported. I think that should be invalid. Only "=_" seems appropriate to me. Also please take care to not have a catchall "default" that does an unassign. Doing something like that will prevent us from ever being able to add any flags in the future.

Yes. Good catch.. Will fix it.

Quoted 33 lines
Quoted 26 lines

    Initial group status:

    # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
    non_default_ctrl_mon_grp//0=tl;1=tl;
    non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
    //0=tl;1=tl;
    /child_default_mon_grp/0=tl;1=tl;

     To update the default group to enable only total event on domain 0:

     # echo "//0=t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control

     Assignment status after the update:

     # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
     non_default_ctrl_mon_grp//0=tl;1=tl;
     non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
     //0=t;1=tl;
     /child_default_mon_grp/0=tl;1=tl;

     To update the MON group child_default_mon_grp to remove total event on domain 1:

     # echo "/child_default_mon_grp/1-t" >
/sys/fs/resctrl/info/L3_MON/mbm_assign_control
Quoted 6 lines

     Assignment status after the update:

     $ cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
     non_default_ctrl_mon_grp//0=tl;1=tl;
     non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=tl;
     //0=t;1=l;
     /child_default_mon_grp/0=t;1=tl;
Quoted 2 lines

This does not look right. Why did domain #1 of the default CTRL_MON group change also?

Will correct it.

Quoted 15 lines
Quoted 15 lines

     To update the MON group non_default_ctrl_mon_grp/child_non_default_mon_grp to remove both local and total events on domain 1:

     # echo "non_default_ctrl_mon_grp/child_non_default_mon_grp/1=_" >
                   /sys/fs/resctrl/info/L3_MON/mbm_assign_control

     Assignment status after the update:

     # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
     non_default_ctrl_mon_grp//0=tl;1=tl;
     non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
     //0=t;1=l;
     /child_default_mon_grp/0=t;1=tl;
Quoted 5 lines
Quoted 3 lines

     To update the default group to add a total event domain 1.

     # echo "//1+t" > /sys/fs/resctrl/info/L3_MON/mbm_assign_control

Unclear where "t" flag was removed.

Yes. Will correct.

Quoted 9 lines
Quoted 9 lines

     Assignment status after the update:

     # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_control
     non_default_ctrl_mon_grp//0=tl;1=tl;
     non_default_ctrl_mon_grp/child_non_default_mon_grp/0=tl;1=_;
     //0=t;1=tl;
     /child_default_mon_grp/0=t;1=tl;
Quoted 5 lines
Quoted 3 lines

f. Read the event mbm_total_bytes and mbm_local_bytes of the default group. There is no change in reading the evetns with ABMC. If the event is unassigned

"evetns" -> "events"

Sure.

Quoted 11 lines
Quoted 2 lines

    when reading, then the read will come back as Unavailable.

Should this not rather be "Unassigned"? According to the docs the counters will return "Unavailable" right after reconfigure so it seems that there are scenarios where an "assigned" counter returns "Unavailable". It seems more
useful to return "Unassigned" that will have a new specific meaning that overloading existing "Unavailable" that has original meaning of "try again" ....
but in this case trying again will be futile.

Hardware returns "Unavailable" in both the cases. So, thought of reporting the same without any interpretation.

Quoted 10 lines
Quoted 10 lines
    
    # cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes
    779247936
    # cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_local_bytes
    765207488

g. Users will have the option to go back to legacy_mbm mode if required. This can be done using the following command.

Quoted 7 lines
Quoted 4 lines
    # echo "legacy_mbm" > /sys/fs/resctrl/info/L3_MON/mbm_assign
    # cat /sys/fs/resctrl/info/L3_MON/mbm_assign
         abmc
         [mbm_legacy]

It is confusing for the value written by user space to be different from the value displayed: "legacy_mbm" vs "mbm_legacy.

My bad. Both should have been "legacy_mbm"

Quoted 4 lines

This is still missing information about what happens to the counters/events on
such a switch. Will events just keep counting? Will they be reset? ...?

It will all reset.

Quoted 3 lines

I also think we should try to find a more generic name for this file. "mbm_cntr_mode" or "mbm_mode" maybe?

"mbm_mode" looks better. Then I will change "legacy_mbm" to "mbm_legacy".

Quoted 26 lines
Quoted 26 lines

h. Check the bandwidth configuration for the group. Note that bandwidth configuration has a domain scope. Total event defaults to 0x7F (to count all the events) and local event defaults to 0x15 (to count all the local numa events). The event bitmap decoding is available at
    https://www.kernel.org/doc/Documentation/x86/resctrl.rst
    in section "mbm_total_bytes_config", "mbm_local_bytes_config":

    #cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config 0=0x7f;1=0x7f

    #cat /sys/fs/resctrl/info/L3_MON/mbm_local_bytes_config 0=0x15;1=0x15

j. Change the bandwidth source for domain 0 for the total event to count only reads.
    Note that this change effects total events on the domain 0.

    #echo 0=0x33 > /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config #cat /sys/fs/resctrl/info/L3_MON/mbm_total_bytes_config 0=0x33;1=0x7F

k. Now read the total event again. The mbm_total_bytes should display only the read events.

Quoted 6 lines
Quoted 2 lines

    #cat /sys/fs/resctrl/mon_data/mon_L3_00/mbm_total_bytes 314101

According to doc, right after a BMEC change the counter will read "Unavailable"
is this not the case here?

Yes. First read will come back with "Unavailable". Will have add one line about that here.

Quoted 9 lines
Quoted 5 lines

l. Unmount the resctrl

    #umount /sys/fs/resctrl/

Reinette

Signature · 2 lines
Thanks
Babu Moger
maintainer
#64 lore raw

Hi Babu,

Quoted 14 lines · Babu
Quoted 4 lines · Reinette Chatre
Quoted 1 line · Babu Moger

    when reading, then the read will come back as Unavailable.

Quoted 8 lines

Should this not rather be "Unassigned"? According to the docs the counters will return "Unavailable" right after reconfigure so it seems that there are scenarios where an "assigned" counter returns "Unavailable". It seems more
useful to return "Unassigned" that will have a new specific meaning that overloading existing "Unavailable" that has original meaning of "try again" ....
but in this case trying again will be futile.

Quoted 2 lines

Hardware returns "Unavailable" in both the cases. So, thought of reporting the same without any interpretation.

I do not see these as the same. When a counter is assigned and its read returns "Unavailable" then the user reasonably expects that retry will work.
When a counter is not assigned then no amount of retries will result in data. How is user space expected to distinguish between the two scenarios that return the same error with such significantly different meaning? rdtgroup_mondata_shows() can just peek into the monitor group state and see if a counter is assigned and immediately return "Unassigned" if no counter is assigned, no? I see no need for it to IPI another CPU and try to read a counter that it already knows will be futile. This seems unnecessary and the generic "Unavailable" is not helpful to user space.

Reinette

#65 lore raw

Hi Reinette,

Quoted 20 lines · Reinette Chatre

Hi Babu,

Quoted 14 lines · Babu
Quoted 4 lines · Reinette Chatre
Quoted 1 line · Babu Moger

    when reading, then the read will come back as Unavailable.

Quoted 8 lines

Should this not rather be "Unassigned"? According to the docs the counters will return "Unavailable" right after reconfigure so it seems that there are scenarios where an "assigned" counter returns "Unavailable". It seems more
useful to return "Unassigned" that will have a new specific meaning that overloading existing "Unavailable" that has original meaning of "try again" ....
but in this case trying again will be futile.

Quoted 2 lines

Hardware returns "Unavailable" in both the cases. So, thought of reporting the same without any interpretation.

Quoted 13 lines

I do not see these as the same. When a counter is assigned and its read returns "Unavailable" then the user reasonably expects that retry will work.
When a counter is not assigned then no amount of retries will result in data. How is user space expected to distinguish between the two scenarios that return the same error with such significantly different meaning? rdtgroup_mondata_shows() can just peek into the monitor group state and see if a counter is assigned and immediately return "Unassigned" if no counter is assigned, no? I see no need for it to IPI another CPU and try to read a counter that it already knows will be futile. This seems unnecessary and the generic "Unavailable" is not helpful to user space.

Sure. Will change it to report "Unassigned" in these cases. Thanks

Signature · 1 line
- Babu Moger