smp.h revision 189903
1/*- 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 * 9 * $FreeBSD: head/sys/sys/smp.h 189903 2009-03-17 00:48:11Z jkim $ 10 */ 11 12#ifndef _SYS_SMP_H_ 13#define _SYS_SMP_H_ 14 15#ifdef _KERNEL 16 17#ifndef LOCORE 18 19#ifdef SMP 20 21/* 22 * Topology of a NUMA or HTT system. 23 * 24 * The top level topology is an array of pointers to groups. Each group 25 * contains a bitmask of cpus in its group or subgroups. It may also 26 * contain a pointer to an array of child groups. 27 * 28 * The bitmasks at non leaf groups may be used by consumers who support 29 * a smaller depth than the hardware provides. 30 * 31 * The topology may be omitted by systems where all CPUs are equal. 32 */ 33 34struct cpu_group { 35 struct cpu_group *cg_parent; /* Our parent group. */ 36 struct cpu_group *cg_child; /* Optional children groups. */ 37 cpumask_t cg_mask; /* Mask of cpus in this group. */ 38 int8_t cg_count; /* Count of cpus in this group. */ 39 int8_t cg_children; /* Number of children groups. */ 40 int8_t cg_level; /* Shared cache level. */ 41 int8_t cg_flags; /* Traversal modifiers. */ 42}; 43 44/* 45 * Defines common resources for CPUs in the group. The highest level 46 * resource should be used when multiple are shared. 47 */ 48#define CG_SHARE_NONE 0 49#define CG_SHARE_L1 1 50#define CG_SHARE_L2 2 51#define CG_SHARE_L3 3 52 53/* 54 * Behavior modifiers for load balancing and affinity. 55 */ 56#define CG_FLAG_HTT 0x01 /* Schedule the alternate core last. */ 57#define CG_FLAG_THREAD 0x02 /* New age htt, less crippled. */ 58 59/* 60 * Convenience routines for building topologies. 61 */ 62struct cpu_group *smp_topo(void); 63struct cpu_group *smp_topo_none(void); 64struct cpu_group *smp_topo_1level(int l1share, int l1count, int l1flags); 65struct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share, 66 int l1count, int l1flags); 67struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu); 68 69extern void (*cpustop_restartfunc)(void); 70extern int smp_active; 71extern int smp_cpus; 72extern volatile cpumask_t started_cpus; 73extern volatile cpumask_t stopped_cpus; 74extern cpumask_t idle_cpus_mask; 75extern cpumask_t hlt_cpus_mask; 76extern cpumask_t logical_cpus_mask; 77#endif /* SMP */ 78 79extern u_int mp_maxid; 80extern int mp_maxcpus; 81extern int mp_ncpus; 82extern volatile int smp_started; 83 84extern cpumask_t all_cpus; 85 86/* 87 * Macro allowing us to determine whether a CPU is absent at any given 88 * time, thus permitting us to configure sparse maps of cpuid-dependent 89 * (per-CPU) structures. 90 */ 91#define CPU_ABSENT(x_cpu) ((all_cpus & (1 << (x_cpu))) == 0) 92 93#ifdef SMP 94/* 95 * Machine dependent functions used to initialize MP support. 96 * 97 * The cpu_mp_probe() should check to see if MP support is present and return 98 * zero if it is not or non-zero if it is. If MP support is present, then 99 * cpu_mp_start() will be called so that MP can be enabled. This function 100 * should do things such as startup secondary processors. It should also 101 * setup mp_ncpus, all_cpus, and smp_cpus. It should also ensure that 102 * smp_active and smp_started are initialized at the appropriate time. 103 * Once cpu_mp_start() returns, machine independent MP startup code will be 104 * executed and a simple message will be output to the console. Finally, 105 * cpu_mp_announce() will be called so that machine dependent messages about 106 * the MP support may be output to the console if desired. 107 * 108 * The cpu_setmaxid() function is called very early during the boot process 109 * so that the MD code may set mp_maxid to provide an upper bound on CPU IDs 110 * that other subsystems may use. If a platform is not able to determine 111 * the exact maximum ID that early, then it may set mp_maxid to MAXCPU - 1. 112 */ 113struct thread; 114 115struct cpu_group *cpu_topo(void); 116void cpu_mp_announce(void); 117int cpu_mp_probe(void); 118void cpu_mp_setmaxid(void); 119void cpu_mp_start(void); 120 121void forward_signal(struct thread *); 122void forward_roundrobin(void); 123int restart_cpus(cpumask_t); 124int stop_cpus(cpumask_t); 125#if defined(__amd64__) 126int suspend_cpus(cpumask_t); 127#endif 128void smp_rendezvous_action(void); 129extern struct mtx smp_ipi_mtx; 130 131#endif /* SMP */ 132void smp_no_rendevous_barrier(void *); 133void smp_rendezvous(void (*)(void *), 134 void (*)(void *), 135 void (*)(void *), 136 void *arg); 137void smp_rendezvous_cpus(cpumask_t, 138 void (*)(void *), 139 void (*)(void *), 140 void (*)(void *), 141 void *arg); 142#endif /* !LOCORE */ 143#endif /* _KERNEL */ 144#endif /* _SYS_SMP_H_ */ 145