CPU MASK
CPU MASK
CPU MASKとはCPUの状態を表すビットマップ配列です。
以下の4種類あり、それぞれが0または1の値を取る。
cpu_possible_mask : NR_CPUSの値と同じになる。
cpu_present_mask : 現在、どのCPUが接続されているかを示す。
cpu_online_mask : cpu_present のサブセットで、スケジューラからアクセス可能なCPUを示す。
cpu_active_mask : このマスクのいくつかのビットは、タスクが特定のプロセッサに移動した可能性があることをLinuxカーネルに伝えます。
#以下グローバル変数としてアクセスできます。
extern struct cpumask __cpu_possible_mask;
extern struct cpumask __cpu_online_mask;
extern struct cpumask __cpu_present_mask;
extern struct cpumask __cpu_active_mask;
cpu_online_maskで説明します。
CPUを管理する配列です。ここでいうCPUとは物理CPUではなく、論理CPUです。
CPU数が8個の場合、1が2進数で8個並びます。
cpu_mask_online->bits[0] = 2進数で11111111の値になります。
72個の場合、1が2進数で72個並びます。
cpu_online_mask->bits[0]はunsigned long型(64bit)なので、
cpu_online_mask->bits[0]は1が64個並びます。
cpu_online_mask->bits[1]にあふれた1が8個並びます。
CPUの最大数はNR_CPUS = CONFIG_NR_CPUS = 8192なので1が8192個並ぶ可能性があります。
定義の計算式が以下です。
unsigend long cpu_online_mask->bits[NR_CPU * / sizeof(long)]
unsigned long cpu_online_mask->bits[8192 * /8]
unsigned long cpu_online_mask->bits[182]となります。
実際に設定するところを見ていきます。
2段階で設定しています。
boot_cpu_initで初期化されます。
//Activate the first processor.
void __init boot_cpu_init(void)
{
int cpu = smp_processor_id();
/* Mark the boot cpu "present", "online" etc for SMP and UP case */
set_cpu_online(cpu, true);
set_cpu_active(cpu, true);
set_cpu_present(cpu, true);
set_cpu_possible(cpu, true);
#ifdef CONFIG_SMP
__boot_cpu_id = cpu;
#endif
}
4つのCPU MAPですが、先にpossibleとpresentが決まります。
presentの値を受けてonlineが設定されます。
setup_arch
acpi_boot_init
acpi_process_madt
acpi_parse_madt_lapic_entries
acpi_table_parse_entries_array
acpi_parse_entries_array
acpi_parse_lapic
acpi_register_lapic
generic_processor_info
generic_processor_info {
set_cpu_possible(cpu, true);
physid_set(apicid, phys_cpu_present_map);
set_cpu_present(cpu, true);
num_processors++;
}
/online
Active the first processerとあるように最初の設定です。
smp_processor_id()は起動時0を返すので、cpu = 0です。
set_cpu_online(0, true)を実行します。
この結果, cpu_online_mask->bits[0]は1になります。
1番目以降はstart_secondaryが呼び出している。
smp_init()
bringup_nonboot_cpus()
cpu_up()
_cpu_up()
cpuhp_up_callbacks()
cpuhp_invoke_callback_range()
cpuhp_invoke_callback()
cpuhp_hp_states[CPUHP_BRINGUP_CPU]
bringup_cpu()
__cpu_up()
native_cpu_up()
do_boot_cpu()
start_secondary()
set_cpu_online()
set_cpu_online(1, true)
set_cpu_online(2, true)
set_cpu_online(3, true)
...
set_cpu_online(71, true)
以降、論理CPUの数だけset_cpu_onlineを設定しています。
Discussion