[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJOA=zNyssmgoHXbX6maR=EM4T8A79YU-iwgy8oW2xMoVrQvZA@mail.gmail.com>
Date: Thu, 11 Aug 2011 11:39:03 -0700
From: "Turquette, Mike" <mturquette@...com>
To: Mike Turquette <mturquette@...com>, linux-kernel@...r.kernel.org,
linux-pm@...ts.linux-foundation.org, gregkh@...e.de,
linaro-dev@...ts.linaro.org, patches@...aro.org
Subject: Re: [PATCH v2 1/2] cpumask: introduce cpumask for hotpluggable CPUs
On Wed, Aug 10, 2011 at 11:06 PM, Amit Kucheria
<amit.kucheria@...aro.org> wrote:
> See comments inline.
>
> On 11 Aug 10, Mike Turquette wrote:
>> On some platforms it is possible to have some CPUs which support CPU
>> hotplug and some which do not. Currently the prescence of an 'online'
>> sysfs entry in userspace is adequate for applications to know that a CPU
>> supports hotplug, but there is no convenient way to make the same
>> determination in the kernel.
>>
>> To better model this relationship this patch introduces a new cpumask to
>> track CPUs that support CPU hotplug operations.
>>
>> This new cpumask is populated at boot-time and remains static for the
>> life of the machine. Bits set in the mask indicate a CPU which supports
>> hotplug, but make no guarantees about whether that CPU is currently
>> online or not. Likewise a cleared bit in the mask indicates either a
>> CPU which cannot hotplug or a lack of a populated CPU.
>>
>> The purpose of this new cpumask is to aid kernel code which uses CPU to
>> take CPUs online and offline. Possible uses are as a thermal event
>> mitigation technique or as a power capping mechanism.
>>
>> Signed-off-by: Mike Turquette <mturquette@...com>
>> ---
>> Change log:
>> v2: fixed missing parentheses in cpumask_test_cpu and improved grammar
>> in comments
>>
>> include/linux/cpumask.h | 27 ++++++++++++++++++++++-----
>> kernel/cpu.c | 18 ++++++++++++++++++
>> 2 files changed, 40 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
>> index b24ac56..52e64a7 100644
>> --- a/include/linux/cpumask.h
>> +++ b/include/linux/cpumask.h
>> @@ -39,10 +39,11 @@ extern int nr_cpu_ids;
>> * 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
>> + * cpu_possible_mask - has bit 'cpu' set iff cpu is populatable
>> + * cpu_hotpluggable_mask - has bit 'cpu' set iff cpu is hotpluggable
>> + * 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.
>> *
>> @@ -51,7 +52,11 @@ extern int nr_cpu_ids;
>> * 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.
>> + * indicating those CPUs available for scheduling. The
>> + * cpu_hotpluggable_mask is also fixed at boot time as the set of CPU
>> + * id's which are possible AND can hotplug. Cleared bits in this mask
>> + * mean that either the CPU is not possible, or it is possible but does
>> + * not support CPU hotplug operations.
>> *
>> * 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
>> @@ -61,6 +66,9 @@ extern int nr_cpu_ids;
>> * depending on what ACPI reports as currently plugged in, otherwise
>> * cpu_present_mask is just a copy of cpu_possible_mask.
>> *
>> + * If HOTPLUG is not enabled then cpu_hotpluggable_mask is the empty
>> + * set.
>> + *
>> * (*) 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.
>> *
>> @@ -76,6 +84,7 @@ extern int nr_cpu_ids;
>> */
>>
>> extern const struct cpumask *const cpu_possible_mask;
>> +extern const struct cpumask *const cpu_hotpluggable_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;
>> @@ -85,19 +94,23 @@ extern const struct cpumask *const cpu_active_mask;
>> #define num_possible_cpus() cpumask_weight(cpu_possible_mask)
>> #define num_present_cpus() cpumask_weight(cpu_present_mask)
>> #define num_active_cpus() cpumask_weight(cpu_active_mask)
>> +#define num_hotpluggable_cpus() cpumask_weight(cpu_hotpluggable_mask)
>> #define cpu_online(cpu) cpumask_test_cpu((cpu), cpu_online_mask)
>> #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask)
>> #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask)
>> #define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask)
>> +#define cpu_hotpluggable(cpu) cpumask_test_cpu((cpu, cpu_hotpluggable_mask))
>
> The bracket should be around cpu, like this (cpu) so that there are no
> side-effects when passing anything to the macro. See the other #defines above.
Wow, not sure how that happened... will send in V3...
>> #else
>> #define num_online_cpus() 1U
>> #define num_possible_cpus() 1U
>> #define num_present_cpus() 1U
>> #define num_active_cpus() 1U
>> +#define num_hotpluggable_cpus() 0
>> #define cpu_online(cpu) ((cpu) == 0)
>> #define cpu_possible(cpu) ((cpu) == 0)
>> #define cpu_present(cpu) ((cpu) == 0)
>> #define cpu_active(cpu) ((cpu) == 0)
>> +#define cpu_hotpluggable(cpu) 0
>> #endif
>>
>> /* verify cpu argument to cpumask_* operators */
>> @@ -678,16 +691,20 @@ extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS);
>> #define cpu_none_mask to_cpumask(cpu_bit_bitmap[0])
>>
>> #define for_each_possible_cpu(cpu) for_each_cpu((cpu), cpu_possible_mask)
>> +#define for_each_hotpluggable_cpu(cpu) \
>> + for_each_cpu((cpu), cpu_hotpluggable_mask)
>> #define for_each_online_cpu(cpu) for_each_cpu((cpu), cpu_online_mask)
>> #define for_each_present_cpu(cpu) for_each_cpu((cpu), cpu_present_mask)
>>
>> /* Wrappers for arch boot code to manipulate normally-constant masks */
>> void set_cpu_possible(unsigned int cpu, bool possible);
>> +void set_cpu_hotpluggable(unsigned int cpu, bool hotpluggable);
>> void set_cpu_present(unsigned int cpu, bool present);
>> void set_cpu_online(unsigned int cpu, bool online);
>> void set_cpu_active(unsigned int cpu, bool active);
>> void init_cpu_present(const struct cpumask *src);
>> void init_cpu_possible(const struct cpumask *src);
>> +void init_cpu_hotpluggable(const struct cpumask *src);
>> void init_cpu_online(const struct cpumask *src);
>>
>> /**
>> diff --git a/kernel/cpu.c b/kernel/cpu.c
>> index 12b7458..8c397c9 100644
>> --- a/kernel/cpu.c
>> +++ b/kernel/cpu.c
>> @@ -536,6 +536,11 @@ static DECLARE_BITMAP(cpu_possible_bits, CONFIG_NR_CPUS) __read_mostly;
>> const struct cpumask *const cpu_possible_mask = to_cpumask(cpu_possible_bits);
>> EXPORT_SYMBOL(cpu_possible_mask);
>>
>> +static DECLARE_BITMAP(cpu_hotpluggable_bits, CONFIG_NR_CPUS) __read_mostly;
>> +const struct cpumask *const cpu_hotpluggable_mask =
>> + to_cpumask(cpu_hotpluggable_bits);
>> +EXPORT_SYMBOL(cpu_hotpluggable_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);
>> @@ -556,6 +561,14 @@ void set_cpu_possible(unsigned int cpu, bool possible)
>> cpumask_clear_cpu(cpu, to_cpumask(cpu_possible_bits));
>> }
>>
>> +void set_cpu_hotpluggable(unsigned int cpu, bool hotpluggable)
>> +{
>> + if (hotpluggable)
>> + cpumask_set_cpu(cpu, to_cpumask(cpu_hotpluggable_bits));
>> + else
>> + cpumask_clear_cpu(cpu, to_cpumask(cpu_hotpluggable_bits));
>> +}
>> +
>> void set_cpu_present(unsigned int cpu, bool present)
>> {
>> if (present)
>> @@ -590,6 +603,11 @@ void init_cpu_possible(const struct cpumask *src)
>> cpumask_copy(to_cpumask(cpu_possible_bits), src);
>> }
>>
>> +void init_cpu_hotpluggable(const struct cpumask *src)
>> +{
>> + cpumask_copy(to_cpumask(cpu_hotpluggable_bits), src);
>> +}
>> +
>
> Just to be clear I understand this code, init_cpu_hotpluggable will be called
> in arch code, right? e.g. arch/arm/kernel/smp.c or do you intend for it to be
> called in platform-specific code?
It could be called in either, though I assume arch code is a better
place to call this.
This call is made redundant by patch 2 which populates the
hotpluggable bits in register_cpu, but some platforms might still need
it so it is included for completeness sake. x86 and ARM will not call
this, for example. In fact I could not find any users of the
init_cpu_xxx cpumask helpers on any architectures.
Thanks,
Mike
>> void init_cpu_online(const struct cpumask *src)
>> {
>> cpumask_copy(to_cpumask(cpu_online_bits), src);
>> --
>> 1.7.4.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists