标签:
kernel/smp.c
/* An arch may set nr_cpu_ids earlier if needed, so this would be redundant */
void __init setup_nr_cpu_ids(void)
{
nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1;
}
include/linux/cpumask.h
#if NR_CPUS == 1
#define nr_cpu_ids 1
#else
extern int nr_cpu_ids;
#endif
NR_CPUS不是1,所以编译extern int nr_cpu_ids;,我在源代码中没有找到nr_cpu_ids的定义,资料上说nr_cpu_ids全局变量被声明为__read_mostly属性。
nr_cpu_ids保存的是所有可处于联机状态的CPU总数。
nr_cpu_ids具有当前系统能具备的CPU数的信息,默认值为NR_CPUS值,NR_CPUS是编译时用户可设置的常量值。NR_CPUS并非当前系统内存在的CPU的数值,而是Linux内核能支持的最大CPU数的最大值。
UP(Uni-Processor)中是1,32位SMP中具有2~32的值,64位内核中具有2~64位的值。
kernel/cpu.c
#ifdef CONFIG_INIT_ALL_POSSIBLE
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
= CPU_BITS_ALL;
#else
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
#endif
没有定义CONFIG_INIT_ALL_POSSIBLE,所以编译
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
DECLARE_BITMAP我们在http://blog.csdn.net/yin262/article/details/46774041已经分析过了,这句定义的最终结果是生车功能一个unsigned long 类型的数组,数组名为cpu_possible_bits,用位图来管理cpu个数,每一位对应一个cpu。
关于利用位图来管理cpu变量,还有以下:
include/linux/cpumask.h
/*
* The following particular system cpumasks and operations manage
* possible, present, active and online cpus.
*
* cpu_possible_mask- has bit ‘cpu‘ set iff cpu is populatable
* cpu_present_mask - has bit ‘cpu‘ set iff cpu is populated
* cpu_online_mask - has bit ‘cpu‘ set iff cpu available to scheduler
* cpu_active_mask - has bit ‘cpu‘ set iff cpu available to migration
*
* If !CONFIG_HOTPLUG_CPU, present == possible, and active == online.
*
* The cpu_possible_mask is fixed at boot time, as the set of CPU id‘s
* that it is possible might ever be plugged in at anytime during the
* life of that system boot. The cpu_present_mask is dynamic(*),
* representing which CPUs are currently plugged in. And
* cpu_online_mask is the dynamic subset of cpu_present_mask,
* indicating those CPUs available for scheduling.
*
* If HOTPLUG is enabled, then cpu_possible_mask is forced to have
* all NR_CPUS bits set, otherwise it is just the set of CPUs that
* ACPI reports present at boot.
*
* If HOTPLUG is enabled, then cpu_present_mask varies dynamically,
* depending on what ACPI reports as currently plugged in, otherwise
* cpu_present_mask is just a copy of cpu_possible_mask.
*
* (*) Well, cpu_present_mask is dynamic in the hotplug case. If not
* hotplug, it‘s a copy of cpu_possible_mask, hence fixed at boot.
*
* Subtleties:
* 1) UP arch‘s (NR_CPUS == 1, CONFIG_SMP not defined) hardcode
* assumption that their single CPU is online. The UP
* cpu_{online,possible,present}_masks are placebos. Changing them
* will have no useful affect on the following num_*_cpus()
* and cpu_*() macros in the UP case. This ugliness is a UP
* optimization - don‘t waste any instructions or memory references
* asking if you‘re online or how many CPUs there are if there is
* only one CPU.
*/
extern const struct cpumask *const cpu_possible_mask;
extern const struct cpumask *const cpu_online_mask;
extern const struct cpumask *const cpu_present_mask;
extern const struct cpumask *const cpu_active_mask;
cpu_possible_mask:系统内可安装的最多CPU的位图
cpu_online_mask:系统内安装的CPU中,正在使用的CPU的位图
cpu_present_mask:系统内安装的CPU的位图
cpu_active_mask:处于联机状态且可以动的(migration)的CPU的位图
以上都是结构体指针类型,由相应的bitmap转化而来:
kernel/cpu.c
#ifdef CONFIG_INIT_ALL_POSSIBLE
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly
= CPU_BITS_ALL;
#else
static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
#endif
const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
EXPORT_SYMBOL(cpu_possible_mask);
static DECLARE_BITMAP(cpu_online_bits, CONFIG_NR_CPUS) __read_mostly;
const struct cpumask *const cpu_online_mask = to_cpumask(cpu_online_bits);
EXPORT_SYMBOL(cpu_online_mask);
static DECLARE_BITMAP(cpu_present_bits, CONFIG_NR_CPUS) __read_mostly;
const struct cpumask *const cpu_present_mask = to_cpumask(cpu_present_bits);
EXPORT_SYMBOL(cpu_present_mask);
static DECLARE_BITMAP(cpu_active_bits, CONFIG_NR_CPUS) __read_mostly;
const struct cpumask *const cpu_active_mask = to_cpumask(cpu_active_bits);
EXPORT_SYMBOL(cpu_active_mask);
转换的过程,在之前的文章里也分析了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
start_kernel——setup_nr_cpu_ids
标签:
原文地址:http://blog.csdn.net/yin262/article/details/46778013