Skip to content

Topology

include/smp/topology.h View source View on GitHub
struct topology_contract (2 fields) source

Contracts essentially state “I will not migrate outside of this scope”, with a set of named, verifiable reasons, so that “self topology” related functions can prove that they are in a safe state (specified), or in the edge case, have TOPOC_NONE contracts to uphold

§ enum topology_level scope
§ enum topology_caller caller
struct topology_cache_info (5 fields) source
TODO

enum this stuff

§ uint8_t level

1, 2, 3

§ uint8_t type

Data, unified, instruction

§ uint32_t size_kb
§ uint32_t line_size
§ uint32_t cores_sharing

Who shares this

struct topology_package_info (2 fields) source
§ uint32_t package_id
§ struct cpu_mask cores
struct topology_node (11 fields) source
§ enum topology_level level
§ uint64_t id

Index in this node

§ uint64_t parent

Parent node index, -1 for root

§ struct topology_node *parent_node
§ int32_t first_child

For cores this is in the cores array. For NUMA this is also in the cores array. For LLC this is in the numa array. For package this is LLC. For machine this is package.

§ int32_t nr_children
§ struct cpu_mask cpus
§ struct cpu_mask idle
§ struct cpu_mask rt_sched_rq_active

For RT scheduler

§ struct core *core

Pointer to this node’s core struct

§ union data
§ struct numa_node *numa
§ struct topology_cache_info *cache
§ struct topology_package_info *package
struct topology (2 fields) source
§ uint16_t count[TOPOLOGY_LEVEL_MAX]
enum topology_level (8 variants) source
§ TOPOLOGY_LEVEL_SMT

Symmetric multiprocessing threads

§ TOPOLOGY_LEVEL_CORE

SMTs under a core

§ TOPOLOGY_LEVEL_NUMA

NUMA node

§ TOPOLOGY_LEVEL_LLC

Last level cache (some processors have multiple L3 caches for a given physical processor)

§ TOPOLOGY_LEVEL_PACKAGE

Physical processor in a socket

§ TOPOLOGY_LEVEL_MACHINE

All processors in a machine

§ TOPOLOGY_LEVEL_MAX

count

§ TOPOLOGY_LEVEL_EX_DOMAIN

This exists solely because the topology_contract has a domain granularity that does not necessarily correspond to one of the others, thus, it is outside of MAX and is its own layer just for that API

enum topology_caller (6 variants) source

This enum is used to verify topology contracts to guarantee a caller cannot be migrated out of a given scope of logical processors.

wrt. naming, we’ll suffix all instances of caller contracts with a C. e.g. SMPC, NODEC, PACKAGEC(specific bits go here)

TODO

we might need to come up with a naming document in docs/ because I’ve been doing this ad-hoc naming scheme stuff a few times

§ TOPC_NONE = 0
§ TOPC_IRQL = 1 << 0
§ TOPC_PINNED = 1 << 1
§ TOPC_IRQ = 1 << 2
§ TOPC_IFLAG = 1 << 3

IRQ, IRQL and IFLAG: IRQ checks in_interrupt, IRQL that >= DISPATCH

void topology_mark_core_idle(cpu_id_t cpu_id, bool idle)
source
struct core * topology_find_idle_core(
    struct core *local_core,
    enum topology_level max_search
)
source
struct core * * topology_get_smts_under_numa(
    struct topology_node *numa,
    size_t *count
)
source
const char * topology_level_name(enum topology_level l)
source
bool topology_contract_verify(struct topology_contract c)
source
#define topology_for_each_id(n_, l_)
source
Expansion
#define topology_for_each_id(n_, l_) \
    for ((n_) = 0; (n_) < global.topology.count[l_]; (n_)++)