mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/common: add cache coloring common code
Last Level Cache (LLC) coloring allows to partition the cache in smaller chunks called cache colors. Since not all architectures can actually implement it, add a HAS_LLC_COLORING Kconfig option. LLC_COLORS_ORDER Kconfig option has a range maximum of 10 (2^10 = 1024) because that's the number of colors that fit in a 4 KiB page when integers are 4 bytes long. LLC colors are a property of the domain, so struct domain has to be extended. Based on original work from: Luca Miccio <lucmiccio@gmail.com> Signed-off-by: Carlo Nonato <carlo.nonato@minervasys.tech> Signed-off-by: Marco Solieri <marco.solieri@minervasys.tech> Acked-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
8089e4ba44
commit
44dd6d4a12
11 files changed
+358
No files matched your search
@@ -401,6 +401,13 @@ by maintaining multiple physical to machine (p2m) memory mappings.
|
||||
Status, x86 HVM: Tech Preview
|
||||
Status, ARM: Tech Preview
|
||||
|
||||
### Cache coloring
|
||||
|
||||
Allows to reserve Last Level Cache (LLC) partitions for Dom0, DomUs and Xen
|
||||
itself.
|
||||
|
||||
Status, Arm64: Experimental
|
||||
|
||||
## Resource Management
|
||||
|
||||
### CPU Pools
|
||||
|
||||
@@ -66,6 +66,7 @@ Documents in need of some rearranging.
|
||||
misc/xen-makefiles/makefiles
|
||||
misra/index
|
||||
fusa/index
|
||||
misc/cache-coloring
|
||||
|
||||
|
||||
Miscellanea
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
.. SPDX-License-Identifier: CC-BY-4.0
|
||||
|
||||
Xen cache coloring user guide
|
||||
=============================
|
||||
|
||||
The cache coloring support in Xen allows to reserve Last Level Cache (LLC)
|
||||
partitions for Dom0, DomUs and Xen itself. Currently only ARM64 is supported.
|
||||
Cache coloring realizes per-set cache partitioning in software and is applicable
|
||||
to shared LLCs as implemented in Cortex-A53, Cortex-A72 and similar CPUs.
|
||||
|
||||
To compile LLC coloring support set ``CONFIG_LLC_COLORING=y``.
|
||||
|
||||
If needed, change the maximum number of colors with
|
||||
``CONFIG_LLC_COLORS_ORDER=<n>``.
|
||||
|
||||
Runtime configuration is done via `Command line parameters`_.
|
||||
|
||||
Background
|
||||
**********
|
||||
|
||||
Cache hierarchy of a modern multi-core CPU typically has first levels dedicated
|
||||
to each core (hence using multiple cache units), while the last level is shared
|
||||
among all of them. Such configuration implies that memory operations on one
|
||||
core (e.g. running a DomU) are able to generate interference on another core
|
||||
(e.g. hosting another DomU). Cache coloring realizes per-set cache-partitioning
|
||||
in software and mitigates this, guaranteeing more predictable performances for
|
||||
memory accesses.
|
||||
Software-based cache coloring is particularly useful in those situations where
|
||||
no hardware mechanisms (e.g., DSU-based way partitioning) are available to
|
||||
partition caches. This is the case for e.g., Cortex-A53, A57 and A72 CPUs that
|
||||
feature a L2 LLC cache shared among all cores.
|
||||
|
||||
The key concept underlying cache coloring is a fragmentation of the memory
|
||||
space into a set of sub-spaces called colors that are mapped to disjoint cache
|
||||
partitions. Technically, the whole memory space is first divided into a number
|
||||
of subsequent regions. Then each region is in turn divided into a number of
|
||||
subsequent sub-colors. The generic i-th color is then obtained by all the
|
||||
i-th sub-colors in each region.
|
||||
|
||||
::
|
||||
|
||||
Region j Region j+1
|
||||
..................... ............
|
||||
. . .
|
||||
. .
|
||||
_ _ _______________ _ _____________________ _ _
|
||||
| | | | | | |
|
||||
| c_0 | c_1 | | c_n | c_0 | c_1 |
|
||||
_ _ _|_____|_____|_ _ _|_____|_____|_____|_ _ _
|
||||
: :
|
||||
: :... ... .
|
||||
: color 0
|
||||
:........................... ... .
|
||||
:
|
||||
. . ..................................:
|
||||
|
||||
How colors are actually defined depends on the function that maps memory to
|
||||
cache lines. In case of physically-indexed, physically-tagged caches with linear
|
||||
mapping, the set index is found by extracting some contiguous bits from the
|
||||
physical address. This allows colors to be defined as shown in figure: they
|
||||
appear in memory as subsequent blocks of equal size and repeats themselves after
|
||||
``n`` different colors, where ``n`` is the total number of colors.
|
||||
|
||||
If some kind of bit shuffling appears in the mapping function, then colors
|
||||
assume a different layout in memory. Those kind of caches aren't supported by
|
||||
the current implementation.
|
||||
|
||||
**Note**: Finding the exact cache mapping function can be a really difficult
|
||||
task since it's not always documented in the CPU manual. As said Cortex-A53, A57
|
||||
and A72 are known to work with the current implementation.
|
||||
|
||||
How to compute the number of colors
|
||||
###################################
|
||||
|
||||
Given the linear mapping from physical memory to cache lines for granted, the
|
||||
number of available colors for a specific platform is computed using three
|
||||
parameters:
|
||||
|
||||
- the size of the LLC.
|
||||
- the number of the LLC ways.
|
||||
- the page size used by Xen.
|
||||
|
||||
The first two parameters can be found in the processor manual, while the third
|
||||
one is the minimum mapping granularity. Dividing the cache size by the number of
|
||||
its ways we obtain the size of a way. Dividing this number by the page size,
|
||||
the number of total cache colors is found. So for example an Arm Cortex-A53
|
||||
with a 16-ways associative 1 MiB LLC can isolate up to 16 colors when pages are
|
||||
4 KiB in size.
|
||||
|
||||
Effective colors assignment
|
||||
###########################
|
||||
|
||||
When assigning colors, if one wants to avoid cache interference between two
|
||||
domains, different colors needs to be used for their memory.
|
||||
|
||||
Command line parameters
|
||||
***********************
|
||||
|
||||
Specific documentation is available at `docs/misc/xen-command-line.pandoc`.
|
||||
|
||||
+----------------------+-------------------------------+
|
||||
| **Parameter** | **Description** |
|
||||
+----------------------+-------------------------------+
|
||||
| ``llc-coloring`` | Enable coloring at runtime |
|
||||
+----------------------+-------------------------------+
|
||||
| ``llc-size`` | Set the LLC size |
|
||||
+----------------------+-------------------------------+
|
||||
| ``llc-nr-ways`` | Set the LLC number of ways |
|
||||
+----------------------+-------------------------------+
|
||||
|
||||
Auto-probing of LLC specs
|
||||
#########################
|
||||
|
||||
LLC size and number of ways are probed automatically by default.
|
||||
|
||||
LLC specs can be manually set via the above command line parameters. This
|
||||
bypasses any auto-probing and it's used to overcome failing situations, such as
|
||||
flawed probing logic, or for debugging/testing purposes.
|
||||
@@ -1710,6 +1710,45 @@ This option is intended for debugging purposes only. Enable MSR_DEBUGCTL.LBR
|
||||
in hypervisor context to be able to dump the Last Interrupt/Exception To/From
|
||||
record with other registers.
|
||||
|
||||
### llc-coloring (arm64)
|
||||
> `= <boolean>`
|
||||
|
||||
> Default: `false`
|
||||
|
||||
Flag to enable or disable LLC coloring support at runtime. This option is
|
||||
available only when `CONFIG_LLC_COLORING` is enabled. See the general
|
||||
cache coloring documentation for more info.
|
||||
|
||||
### llc-nr-ways (arm64)
|
||||
> `= <integer>`
|
||||
|
||||
> Default: `Obtained from hardware`
|
||||
|
||||
Specify the number of ways of the Last Level Cache. This option is available
|
||||
only when `CONFIG_LLC_COLORING` is enabled. LLC size and number of ways are used
|
||||
to find the number of supported cache colors. By default the value is
|
||||
automatically computed by probing the hardware, but in case of specific needs,
|
||||
it can be manually set. Those include failing probing and debugging/testing
|
||||
purposes so that it's possible to emulate platforms with different number of
|
||||
supported colors. If set, also "llc-size" must be set, otherwise the default
|
||||
will be used. Note that using both options implies "llc-coloring=on" unless an
|
||||
earlier "llc-coloring=off" is there.
|
||||
|
||||
### llc-size (arm64)
|
||||
> `= <size>`
|
||||
|
||||
> Default: `Obtained from hardware`
|
||||
|
||||
Specify the size of the Last Level Cache. This option is available only when
|
||||
`CONFIG_LLC_COLORING` is enabled. LLC size and number of ways are used to find
|
||||
the number of supported cache colors. By default the value is automatically
|
||||
computed by probing the hardware, but in case of specific needs, it can be
|
||||
manually set. Those include failing probing and debugging/testing purposes so
|
||||
that it's possible to emulate platforms with different number of supported
|
||||
colors. If set, also "llc-nr-ways" must be set, otherwise the default will be
|
||||
used. Note that using both options implies "llc-coloring=on" unless an
|
||||
earlier "llc-coloring=off" is there.
|
||||
|
||||
### lock-depth-size
|
||||
> `= <integer>`
|
||||
|
||||
|
||||
@@ -71,6 +71,9 @@ config HAS_IOPORTS
|
||||
config HAS_KEXEC
|
||||
bool
|
||||
|
||||
config HAS_LLC_COLORING
|
||||
bool
|
||||
|
||||
config HAS_PIRQ
|
||||
bool
|
||||
|
||||
@@ -516,4 +519,22 @@ config TRACEBUFFER
|
||||
to be collected at run time for debugging or performance analysis.
|
||||
Memory and execution overhead when not active is minimal.
|
||||
|
||||
config LLC_COLORING
|
||||
bool "Last Level Cache (LLC) coloring" if EXPERT
|
||||
depends on HAS_LLC_COLORING
|
||||
|
||||
config LLC_COLORS_ORDER
|
||||
int "Maximum number of LLC colors (base-2 exponent)"
|
||||
range 1 10
|
||||
default 7
|
||||
depends on LLC_COLORING
|
||||
help
|
||||
Controls the build-time size of various arrays associated with LLC
|
||||
coloring. The value is a base-2 exponent. Refer to cache coloring
|
||||
documentation for how to compute the number of colors supported by the
|
||||
platform. This is only an upper bound. The runtime value is autocomputed
|
||||
or manually set via cmdline parameters.
|
||||
The default value corresponds to an 8 MiB 16-ways LLC, which should be
|
||||
more than what's needed in the general case.
|
||||
|
||||
endmenu
|
||||
@@ -25,6 +25,7 @@ obj-y += keyhandler.o
|
||||
obj-$(CONFIG_KEXEC) += kexec.o
|
||||
obj-$(CONFIG_KEXEC) += kimage.o
|
||||
obj-$(CONFIG_LIVEPATCH) += livepatch.o livepatch_elf.o
|
||||
obj-$(CONFIG_LLC_COLORING) += llc-coloring.o
|
||||
obj-$(CONFIG_MEM_ACCESS) += mem_access.o
|
||||
obj-y += memory.o
|
||||
obj-y += multicall.o
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <asm/regs.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/keyhandler.h>
|
||||
#include <xen/llc-coloring.h>
|
||||
#include <xen/param.h>
|
||||
#include <xen/sections.h>
|
||||
#include <xen/shutdown.h>
|
||||
@@ -304,6 +305,8 @@ static void cf_check dump_domains(unsigned char key)
|
||||
|
||||
arch_dump_domain_info(d);
|
||||
|
||||
domain_dump_llc_colors(d);
|
||||
|
||||
rangeset_domain_printk(d);
|
||||
|
||||
dump_pageframe_info(d);
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Last Level Cache (LLC) coloring common code
|
||||
*
|
||||
* Copyright (C) 2024, Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2024, Minerva Systems SRL
|
||||
*/
|
||||
#include <xen/keyhandler.h>
|
||||
#include <xen/llc-coloring.h>
|
||||
#include <xen/param.h>
|
||||
|
||||
#define NR_LLC_COLORS (1U << CONFIG_LLC_COLORS_ORDER)
|
||||
|
||||
/*
|
||||
* -1: not specified (disabled unless llc-size and llc-nr-ways present)
|
||||
* 0: explicitly disabled through cmdline
|
||||
* 1: explicitly enabled through cmdline
|
||||
*/
|
||||
static int8_t __initdata opt_llc_coloring = -1;
|
||||
boolean_param("llc-coloring", opt_llc_coloring);
|
||||
|
||||
static bool __ro_after_init llc_coloring_enabled;
|
||||
|
||||
static unsigned int __initdata llc_size;
|
||||
size_param("llc-size", llc_size);
|
||||
static unsigned int __initdata llc_nr_ways;
|
||||
integer_param("llc-nr-ways", llc_nr_ways);
|
||||
/* Number of colors available in the LLC */
|
||||
static unsigned int __ro_after_init max_nr_colors;
|
||||
|
||||
static void print_colors(const unsigned int colors[], unsigned int num_colors)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
printk("{ ");
|
||||
for ( i = 0; i < num_colors; i++ )
|
||||
{
|
||||
unsigned int start = colors[i], end = start;
|
||||
|
||||
printk("%u", start);
|
||||
|
||||
for ( ; i < num_colors - 1 && end + 1 == colors[i + 1]; i++, end++ )
|
||||
;
|
||||
|
||||
if ( start != end )
|
||||
printk("-%u", end);
|
||||
|
||||
if ( i < num_colors - 1 )
|
||||
printk(", ");
|
||||
}
|
||||
printk(" }\n");
|
||||
}
|
||||
|
||||
void __init llc_coloring_init(void)
|
||||
{
|
||||
unsigned int way_size;
|
||||
|
||||
llc_coloring_enabled = (opt_llc_coloring >= 1);
|
||||
if ( (opt_llc_coloring != 0) && llc_size && llc_nr_ways )
|
||||
{
|
||||
llc_coloring_enabled = true;
|
||||
way_size = llc_size / llc_nr_ways;
|
||||
}
|
||||
else if ( !llc_coloring_enabled )
|
||||
return;
|
||||
else
|
||||
{
|
||||
way_size = get_llc_way_size();
|
||||
if ( !way_size )
|
||||
panic("LLC probing failed and 'llc-size' or 'llc-nr-ways' missing\n");
|
||||
}
|
||||
|
||||
if ( way_size & ~PAGE_MASK )
|
||||
panic("LLC way size must be a multiple of PAGE_SIZE\n");
|
||||
|
||||
/*
|
||||
* The maximum number of colors must be a power of 2 in order to correctly
|
||||
* map them to bits of an address.
|
||||
*/
|
||||
max_nr_colors = way_size >> PAGE_SHIFT;
|
||||
|
||||
if ( max_nr_colors & (max_nr_colors - 1) )
|
||||
panic("Number of LLC colors (%u) isn't a power of 2\n", max_nr_colors);
|
||||
|
||||
if ( max_nr_colors > NR_LLC_COLORS )
|
||||
{
|
||||
printk(XENLOG_WARNING
|
||||
"Number of LLC colors (%u) too big. Using configured max %u\n",
|
||||
max_nr_colors, NR_LLC_COLORS);
|
||||
max_nr_colors = NR_LLC_COLORS;
|
||||
}
|
||||
else if ( max_nr_colors < 2 )
|
||||
panic("Number of LLC colors %u < 2\n", max_nr_colors);
|
||||
|
||||
arch_llc_coloring_init();
|
||||
}
|
||||
|
||||
void dump_llc_coloring_info(void)
|
||||
{
|
||||
if ( !llc_coloring_enabled )
|
||||
return;
|
||||
|
||||
printk("LLC coloring info:\n");
|
||||
printk(" Number of LLC colors supported: %u\n", max_nr_colors);
|
||||
}
|
||||
|
||||
void domain_dump_llc_colors(const struct domain *d)
|
||||
{
|
||||
if ( !llc_coloring_enabled )
|
||||
return;
|
||||
|
||||
printk("%u LLC colors: ", d->num_llc_colors);
|
||||
print_colors(d->llc_colors, d->num_llc_colors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-file-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -126,6 +126,7 @@
|
||||
#include <xen/irq.h>
|
||||
#include <xen/keyhandler.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/llc-coloring.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/nodemask.h>
|
||||
#include <xen/numa.h>
|
||||
@@ -2651,6 +2652,8 @@ static void cf_check pagealloc_info(unsigned char key)
|
||||
}
|
||||
|
||||
printk(" Dom heap: %lukB free\n", total << (PAGE_SHIFT-10));
|
||||
|
||||
dump_llc_coloring_info();
|
||||
}
|
||||
|
||||
static __init int cf_check pagealloc_keyhandler_init(void)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Last Level Cache (LLC) coloring common header
|
||||
*
|
||||
* Copyright (C) 2024, Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2024, Minerva Systems SRL
|
||||
*/
|
||||
#ifndef __XEN_LLC_COLORING_H__
|
||||
#define __XEN_LLC_COLORING_H__
|
||||
|
||||
struct domain;
|
||||
|
||||
#ifdef CONFIG_LLC_COLORING
|
||||
void llc_coloring_init(void);
|
||||
void dump_llc_coloring_info(void);
|
||||
void domain_dump_llc_colors(const struct domain *d);
|
||||
#else
|
||||
static inline void llc_coloring_init(void) {}
|
||||
static inline void dump_llc_coloring_info(void) {}
|
||||
static inline void domain_dump_llc_colors(const struct domain *d) {}
|
||||
#endif
|
||||
|
||||
unsigned int get_llc_way_size(void);
|
||||
void arch_llc_coloring_init(void);
|
||||
|
||||
#endif /* __XEN_LLC_COLORING_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-file-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -640,6 +640,11 @@ struct domain
|
||||
|
||||
/* Holding CDF_* constant. Internal flags for domain creation. */
|
||||
unsigned int cdf;
|
||||
|
||||
#ifdef CONFIG_LLC_COLORING
|
||||
unsigned int num_llc_colors;
|
||||
const unsigned int *llc_colors;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct page_list_head *page_to_list(
|
||||
|
||||