Skip to content

Commit 29b6bd4

Browse files
Fenghua Yusuryasaimadhu
authored andcommitted
x86/resctrl: Enable user to view thread or core throttling mode
Early Intel hardware implementations of Memory Bandwidth Allocation (MBA) could only control bandwidth at the processor core level. This meant that when two processes with different bandwidth allocations ran simultaneously on the same core the hardware had to resolve this difference. It did so by applying the higher throttling value (lower bandwidth) to both processes. Newer implementations can apply different throttling values to each thread on a core. Introduce a new resctrl file, "thread_throttle_mode", on Intel systems that shows to the user how throttling values are allocated, per-core or per-thread. On systems that support per-core throttling, the file will display "max". On newer systems that support per-thread throttling, the file will display "per-thread". AMD confirmed in [1] that AMD bandwidth allocation is already at thread level but that the AMD implementation does not use a memory delay throttle mode. So to avoid confusion the thread throttling mode would be UNDEFINED on AMD systems and the "thread_throttle_mode" file will not be visible. Originally-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Link: https://lkml.kernel.org/r/1598296281-127595-3-git-send-email-fenghua.yu@intel.com Link: [1] https://lore.kernel.org/lkml/18d277fd-6523-319c-d560-66b63ff606b8@amd.com
1 parent e48cb1a commit 29b6bd4

4 files changed

Lines changed: 103 additions & 9 deletions

File tree

Documentation/x86/resctrl_ui.rst

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,18 @@ with respect to allocation:
138138
non-linear. This field is purely informational
139139
only.
140140

141+
"thread_throttle_mode":
142+
Indicator on Intel systems of how tasks running on threads
143+
of a physical core are throttled in cases where they
144+
request different memory bandwidth percentages:
145+
146+
"max":
147+
the smallest percentage is applied
148+
to all threads
149+
"per-thread":
150+
bandwidth percentages are directly applied to
151+
the threads running on the core
152+
141153
If RDT monitoring is available there will be an "L3_MON" directory
142154
with the following files:
143155

@@ -364,8 +376,10 @@ to the next control step available on the hardware.
364376

365377
The bandwidth throttling is a core specific mechanism on some of Intel
366378
SKUs. Using a high bandwidth and a low bandwidth setting on two threads
367-
sharing a core will result in both threads being throttled to use the
368-
low bandwidth. The fact that Memory bandwidth allocation(MBA) is a core
379+
sharing a core may result in both threads being throttled to use the
380+
low bandwidth (see "thread_throttle_mode").
381+
382+
The fact that Memory bandwidth allocation(MBA) may be a core
369383
specific mechanism where as memory bandwidth monitoring(MBM) is done at
370384
the package level may lead to confusion when users try to apply control
371385
via the MBA and then monitor the bandwidth to see if the controls are

arch/x86/kernel/cpu/resctrl/core.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,12 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
273273
}
274274
r->data_width = 3;
275275

276+
if (boot_cpu_has(X86_FEATURE_PER_THREAD_MBA))
277+
r->membw.throttle_mode = THREAD_THROTTLE_PER_THREAD;
278+
else
279+
r->membw.throttle_mode = THREAD_THROTTLE_MAX;
280+
thread_throttle_mode_init();
281+
276282
r->alloc_capable = true;
277283
r->alloc_enabled = true;
278284

@@ -293,6 +299,11 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r)
293299
r->membw.delay_linear = false;
294300
r->membw.arch_needs_linear = false;
295301

302+
/*
303+
* AMD does not use memory delay throttle model to control
304+
* the allocation like Intel does.
305+
*/
306+
r->membw.throttle_mode = THREAD_THROTTLE_UNDEFINED;
296307
r->membw.min_bw = 0;
297308
r->membw.bw_gran = 1;
298309
/* Max value is 2048, Data width should be 4 in decimal */

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,22 +371,39 @@ struct rdt_cache {
371371
bool arch_has_empty_bitmaps;
372372
};
373373

374+
/**
375+
* enum membw_throttle_mode - System's memory bandwidth throttling mode
376+
* @THREAD_THROTTLE_UNDEFINED: Not relevant to the system
377+
* @THREAD_THROTTLE_MAX: Memory bandwidth is throttled at the core
378+
* always using smallest bandwidth percentage
379+
* assigned to threads, aka "max throttling"
380+
* @THREAD_THROTTLE_PER_THREAD: Memory bandwidth is throttled at the thread
381+
*/
382+
enum membw_throttle_mode {
383+
THREAD_THROTTLE_UNDEFINED = 0,
384+
THREAD_THROTTLE_MAX,
385+
THREAD_THROTTLE_PER_THREAD,
386+
};
387+
374388
/**
375389
* struct rdt_membw - Memory bandwidth allocation related data
376390
* @min_bw: Minimum memory bandwidth percentage user can request
377391
* @bw_gran: Granularity at which the memory bandwidth is allocated
378392
* @delay_linear: True if memory B/W delay is in linear scale
379393
* @arch_needs_linear: True if we can't configure non-linear resources
394+
* @throttle_mode: Bandwidth throttling mode when threads request
395+
* different memory bandwidths
380396
* @mba_sc: True if MBA software controller(mba_sc) is enabled
381397
* @mb_map: Mapping of memory B/W percentage to memory B/W delay
382398
*/
383399
struct rdt_membw {
384-
u32 min_bw;
385-
u32 bw_gran;
386-
u32 delay_linear;
387-
bool arch_needs_linear;
388-
bool mba_sc;
389-
u32 *mb_map;
400+
u32 min_bw;
401+
u32 bw_gran;
402+
u32 delay_linear;
403+
bool arch_needs_linear;
404+
enum membw_throttle_mode throttle_mode;
405+
bool mba_sc;
406+
u32 *mb_map;
390407
};
391408

392409
static inline bool is_llc_occupancy_enabled(void)
@@ -607,5 +624,6 @@ void cqm_handle_limbo(struct work_struct *work);
607624
bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
608625
void __check_limbo(struct rdt_domain *d, bool force_free);
609626
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
627+
void __init thread_throttle_mode_init(void);
610628

611629
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */

arch/x86/kernel/cpu/resctrl/rdtgroup.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,19 @@ static int max_threshold_occ_show(struct kernfs_open_file *of,
10271027
return 0;
10281028
}
10291029

1030+
static int rdt_thread_throttle_mode_show(struct kernfs_open_file *of,
1031+
struct seq_file *seq, void *v)
1032+
{
1033+
struct rdt_resource *r = of->kn->parent->priv;
1034+
1035+
if (r->membw.throttle_mode == THREAD_THROTTLE_PER_THREAD)
1036+
seq_puts(seq, "per-thread\n");
1037+
else
1038+
seq_puts(seq, "max\n");
1039+
1040+
return 0;
1041+
}
1042+
10301043
static ssize_t max_threshold_occ_write(struct kernfs_open_file *of,
10311044
char *buf, size_t nbytes, loff_t off)
10321045
{
@@ -1523,6 +1536,17 @@ static struct rftype res_common_files[] = {
15231536
.seq_show = rdt_delay_linear_show,
15241537
.fflags = RF_CTRL_INFO | RFTYPE_RES_MB,
15251538
},
1539+
/*
1540+
* Platform specific which (if any) capabilities are provided by
1541+
* thread_throttle_mode. Defer "fflags" initialization to platform
1542+
* discovery.
1543+
*/
1544+
{
1545+
.name = "thread_throttle_mode",
1546+
.mode = 0444,
1547+
.kf_ops = &rdtgroup_kf_single_ops,
1548+
.seq_show = rdt_thread_throttle_mode_show,
1549+
},
15261550
{
15271551
.name = "max_threshold_occupancy",
15281552
.mode = 0644,
@@ -1593,7 +1617,7 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
15931617
lockdep_assert_held(&rdtgroup_mutex);
15941618

15951619
for (rft = rfts; rft < rfts + len; rft++) {
1596-
if ((fflags & rft->fflags) == rft->fflags) {
1620+
if (rft->fflags && ((fflags & rft->fflags) == rft->fflags)) {
15971621
ret = rdtgroup_add_file(kn, rft);
15981622
if (ret)
15991623
goto error;
@@ -1610,6 +1634,33 @@ static int rdtgroup_add_files(struct kernfs_node *kn, unsigned long fflags)
16101634
return ret;
16111635
}
16121636

1637+
static struct rftype *rdtgroup_get_rftype_by_name(const char *name)
1638+
{
1639+
struct rftype *rfts, *rft;
1640+
int len;
1641+
1642+
rfts = res_common_files;
1643+
len = ARRAY_SIZE(res_common_files);
1644+
1645+
for (rft = rfts; rft < rfts + len; rft++) {
1646+
if (!strcmp(rft->name, name))
1647+
return rft;
1648+
}
1649+
1650+
return NULL;
1651+
}
1652+
1653+
void __init thread_throttle_mode_init(void)
1654+
{
1655+
struct rftype *rft;
1656+
1657+
rft = rdtgroup_get_rftype_by_name("thread_throttle_mode");
1658+
if (!rft)
1659+
return;
1660+
1661+
rft->fflags = RF_CTRL_INFO | RFTYPE_RES_MB;
1662+
}
1663+
16131664
/**
16141665
* rdtgroup_kn_mode_restrict - Restrict user access to named resctrl file
16151666
* @r: The resource group with which the file is associated.

0 commit comments

Comments
 (0)