Line data Source code
1 : #ifndef HEADER_fd_src_disco_topo_fd_topob_layout_h 2 : #define HEADER_fd_src_disco_topo_fd_topob_layout_h 3 : 4 : /* fd_topob_layout assigns topology tiles to CPUs. Configs with an 5 : explicit [layout.affinity] are parsed by fd_topob_parse_affinity_cstr 6 : instead; "auto" runs fd_topob_auto_layout. 7 : 8 : Auto layout walks CPUs in NUMA node order with each CPU's HT sibling 9 : right after it, skipping blocklisted and offline CPUs. Each tile's 10 : class (FD_TOPOB_TILE_*, keyed by name) decides its placement: 11 : 12 : - ALWAYS tiles are placed first. STARTUP and POSTSTART tiles are 13 : then placed over the same remaining CPUs, since startup tiles 14 : exit before post-start tiles wake. 15 : - FLOATING tiles get no CPU and run wherever the kernel puts them, 16 : kept off pinned cores and their siblings by the launcher. 17 : - With a physical core per tile, every tile gets a whole core. 18 : Otherwise SMT_CRITICAL tiles still get one, DEDICATED tiles get 19 : one while spare logical CPUs last, and the rest share cores. 20 : Firedancer ranks the steady tiles instead and shares only as 21 : many cores as needed, lowest ranked first. Startup tiles then 22 : get whole cores free during snapshot load. 23 : 24 : In efficient mode (tiles park when idle), only SMT_CRITICAL, 25 : THROUGHPUT and PIN_EFFICIENT tiles are pinned; the rest float over 26 : a pool and cpu_idx only picks its NUMA node. Pinned tiles prefer 27 : CPUs isolated by isolcpus= and floaters never use them. Every 28 : choice is checked to leave room for the tiles still to place, and 29 : preferences relax rather than fail. On hosts with a complete cache 30 : topology and room to spare, the tiles that wake each other the most 31 : are first packed onto whole cores in as few L3 domains as possible. */ 32 : 33 : #include "fd_topo.h" 34 : #include "fd_cpu_topo.h" 35 : 36 : /* Affinity entries prefixed with 's' ("s2", "s2-3") are shared, the 37 : tile is homed at that CPU but floats over the shared CPUs on the 38 : same NUMA node. The bit is set in the parsed CPU index, and only 39 : callers passing allow_shared accept it. */ 40 0 : #define FD_TOPOB_CPU_SHARED (0x8000UL) 41 : 42 : /* Tile priority types used by fd_topob_auto_layout to classify tiles 43 : into scheduling categories. */ 44 0 : #define FD_TOPOB_PRIORITY_FLOATING (1) 45 0 : #define FD_TOPOB_PRIORITY_STARTUP (2) 46 0 : #define FD_TOPOB_PRIORITY_NORMAL (3) 47 0 : #define FD_TOPOB_PRIORITY_CRITICAL (4) 48 : 49 : /* Tile classes for the auto layout and the CPU isolation stages. 50 : 51 : Phases, exactly one per known tile: 52 : - ALWAYS: runs for the whole process lifetime 53 : - STARTUP: shuts down after snapshot load 54 : - POSTSTART: sleeps until snapshot load finishes 55 : - FLOATING: yields to the kernel scheduler 56 : 57 : Placement flags, any combination: 58 : - SMT_CRITICAL: hyperthread sibling kept idle 59 : - DEDICATED: whole core while spare logical CPUs last 60 : - THROUGHPUT: pinned in efficient mode, with an idle sibling 61 : - PIN_EFFICIENT: pinned in efficient mode */ 62 : 63 0 : #define FD_TOPOB_TILE_ALWAYS (1U<<0) 64 0 : #define FD_TOPOB_TILE_STARTUP (1U<<1) 65 0 : #define FD_TOPOB_TILE_POSTSTART (1U<<2) 66 0 : #define FD_TOPOB_TILE_FLOATING (1U<<3) 67 0 : #define FD_TOPOB_TILE_SMT_CRITICAL (1U<<4) 68 0 : #define FD_TOPOB_TILE_DEDICATED (1U<<5) 69 0 : #define FD_TOPOB_TILE_THROUGHPUT (1U<<6) 70 0 : #define FD_TOPOB_TILE_PIN_EFFICIENT (1U<<7) 71 : 72 : #define FD_TOPOB_TILE_PHASE (FD_TOPOB_TILE_ALWAYS|FD_TOPOB_TILE_STARTUP|FD_TOPOB_TILE_POSTSTART|FD_TOPOB_TILE_FLOATING) 73 0 : #define FD_TOPOB_TILE_EFFICIENT_PINNED (FD_TOPOB_TILE_SMT_CRITICAL|FD_TOPOB_TILE_THROUGHPUT|FD_TOPOB_TILE_PIN_EFFICIENT) 74 : 75 : FD_PROTOTYPES_BEGIN 76 : 77 : /* fd_topob_tile_class returns the FD_TOPOB_TILE_* flags of the tile 78 : named name, 0 if the tile is unknown. */ 79 : 80 : FD_FN_PURE uint 81 : fd_topob_tile_class( char const * name ); 82 : 83 : /* Automatically layout the tiles onto CPUs in the topology for a 84 : best effort. fd_topob_auto_layout reads CPU topology from the OS. 85 : fd_topob_auto_layout_cpus takes a pre-built CPU topology, useful 86 : for testing. */ 87 : 88 : void 89 : fd_topob_auto_layout( fd_topo_t * topo ); 90 : 91 : void 92 : fd_topob_auto_layout_cpus( fd_topo_t * topo, 93 : fd_topo_cpus_t * cpus ); 94 : 95 : /* Classify a tile into one of the FD_TOPOB_PRIORITY_* categories. */ 96 : int 97 : fd_topob_tile_priority_type( fd_topo_tile_t const * tile ); 98 : 99 : int 100 : fd_topob_cpu_overlap_allowed( fd_topo_tile_t const * a, 101 : fd_topo_tile_t const * b, 102 : int floats_share ); 103 : 104 : void 105 : fd_topob_validate_cpu_overlaps( fd_topo_t const * topo ); 106 : 107 : ulong 108 : fd_topob_parse_affinity_cstr( char const * cstr, 109 : ushort * tile_to_cpu, 110 : int allow_repeats, 111 : int allow_shared ); 112 : 113 : FD_PROTOTYPES_END 114 : 115 : #endif /* HEADER_fd_src_disco_topo_fd_topob_layout_h */