Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1622519 > unrolled thread
| Started by | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| First post | 2017-04-12 22:30 +0200 |
| Last post | 2017-04-13 11:10 +0200 |
| Articles | 20 on this page of 45 — 9 participants |
Back to article view | Back to linux.kernel
[patch 00/13] sched/treewide: Clean up various racy task affinity issues Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
[patch 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic Viresh Kumar <viresh.kumar@linaro.org> - 2017-04-13 05:00 +0200
[patch V2 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 10:20 +0200
[patch V3 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 10:30 +0200
[tip:sched/core] cpufreq/sparc-us2e: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
Re: [patch V2 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic David Miller <davem@davemloft.net> - 2017-04-13 17:00 +0200
[patch 03/13] ia64/salinfo: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
[tip:sched/core] ia64/salinfo: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 04/13] ia64/sn/hwperf: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
[patch V 2 04/13] ia64/sn/hwperf: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 23:00 +0200
[tip:sched/core] ia64/sn/hwperf: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 11/13] cpufreq/sparc-us3: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 11/13] cpufreq/sparc-us3: Replace racy task affinity logic Viresh Kumar <viresh.kumar@linaro.org> - 2017-04-13 04:50 +0200
[tip:sched/core] cpufreq/sparc-us3: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 01/13] ia64/topology: Remove cpus_allowed manipulation Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
[tip:sched/core] ia64/topology: Remove cpus_allowed manipulation tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 07/13] ACPI/processor: Fix error handling in __acpi_processor_start() Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
[tip:sched/core] ACPI/processor: Fix error handling in __acpi_processor_start() tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 08/13] ACPI/processor: Replace racy task affinity logic. Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 08/13] ACPI/processor: Replace racy task affinity logic. Peter Zijlstra <peterz@infradead.org> - 2017-04-13 13:50 +0200
Re: [patch 08/13] ACPI/processor: Replace racy task affinity logic. Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 14:10 +0200
Re: [patch 08/13] ACPI/processor: Replace racy task affinity logic. Peter Zijlstra <peterz@infradead.org> - 2017-04-13 15:00 +0200
[tip:sched/core] ACPI/processor: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 13/13] crypto: n2 - Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 13/13] crypto: n2 - Replace racy task affinity logic Herbert Xu <herbert@gondor.apana.org.au> - 2017-04-13 07:40 +0200
[patch V2 13/13] crypto: n2 - Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 10:30 +0200
Re: [patch V2 13/13] crypto: n2 - Replace racy task affinity logic David Miller <davem@davemloft.net> - 2017-04-13 17:00 +0200
[tip:sched/core] crypto: N2 - Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:40 +0200
[patch 05/13] powerpc/smp: Replace open coded task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 05/13] powerpc/smp: Replace open coded task affinity logic Michael Ellerman <mpe@ellerman.id.au> - 2017-04-13 07:50 +0200
[tip:sched/core] powerpc/smp: Replace open coded task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
[patch 06/13] sparc/sysfs: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 06/13] sparc/sysfs: Replace racy task affinity logic David Miller <davem@davemloft.net> - 2017-04-13 04:00 +0200
[patch V2 06/13] sparc/sysfs: Replace racy task affinity logic Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 10:20 +0200
[tip:sched/core] sparc/sysfs: Replace racy task affinity logic tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:20 +0200
[patch 02/13] workqueue: Provide work_on_cpu_safe() Thomas Gleixner <tglx@linutronix.de> - 2017-04-12 22:30 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-04-13 13:20 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Thomas Gleixner <tglx@linutronix.de> - 2017-04-13 23:30 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Tejun Heo <tj@kernel.org> - 2017-04-14 06:20 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Peter Zijlstra <peterz@infradead.org> - 2017-04-14 11:00 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Thomas Gleixner <tglx@linutronix.de> - 2017-04-14 12:00 +0200
Re: [patch 02/13] workqueue: Provide work_on_cpu_safe() Peter Zijlstra <peterz@infradead.org> - 2017-04-14 12:00 +0200
[tip:sched/core] workqueue: Provide work_on_cpu_safe() tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-04-15 16:30 +0200
Re: [patch 00/13] sched/treewide: Clean up various racy task affinity issues Peter Zijlstra <peterz@infradead.org> - 2017-04-13 11:10 +0200
Page 1 of 3 [1] 2 3 Next page →
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 00/13] sched/treewide: Clean up various racy task affinity issues |
| Message-ID | <tvx3P-QV-3@gated-at.bofh.it> |
While dealing with the fallout of the scheduler cleanups on RT, we found several racy usage sites of the following scheme: cpumask_copy(&save_cpus_allowed, ¤t->cpus_allowed); set_cpus_allowed_ptr(current, cpumask_of(cpu)); do_stuff(); set_cpus_allowed_ptr(current, &save_cpus_allowed); That's racy in two aspects: 1) Nothing prevents the CPU from being unplugged after the temporary affinity setting is in place. This results on code being executed on the wrong CPU(s). 2) Nothing prevents a concurrent affinity setting from user space. That also results in code being executed on the wrong CPU(s) and the restore of the previous affinity setting overwrites the new one. Various variants of cleanups: - Removal, because the calling thread is already guaranteed to run on the correct CPU. - Conversion to smp function calls (simple register read/write) - Conversion to work_on_cpu(). There were even files containing comments to that effect. - The rest needs seperate hotplug protection for work_on_cpu(). To avoid open coding the get_online_cpus(); if (cpu_online(cpu)) ret = do_stuff(); else ret = -ENODEV; put_online_cpus(); scheme this series provides a new helper function work_on_cpu_safe() which implements the above. Aside of fixing these races this allows to restrict the access to current->cpus_allowed with a follow up series. Thanks, tglx --- arch/ia64/kernel/salinfo.c | 31 ++++------- arch/ia64/kernel/topology.c | 6 -- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 16 +++--- arch/powerpc/kernel/smp.c | 26 ++++------ arch/sparc/kernel/sysfs.c | 36 +++---------- drivers/acpi/processor_driver.c | 10 +++ drivers/acpi/processor_throttling.c | 31 +++++------ drivers/cpufreq/ia64-acpi-cpufreq.c | 91 ++++++++++++++--------------------- drivers/cpufreq/sh-cpufreq.c | 45 ++++++++++------- drivers/cpufreq/sparc-us2e-cpufreq.c | 45 ++++++++--------- drivers/cpufreq/sparc-us3-cpufreq.c | 46 ++++++----------- drivers/crypto/n2_core.c | 31 ++++++----- include/linux/workqueue.h | 5 + kernel/workqueue.c | 23 ++++++++ 14 files changed, 209 insertions(+), 233 deletions(-)
[toc] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <tvx3P-QV-13@gated-at.bofh.it> |
| In reply to | #1622519 |
The access to the HBIRD_ESTAR_MODE register in the cpu frequency control
functions must happen on the target CPU. This is achieved by temporarily
setting the affinity of the calling user space thread to the requested CPU
and reset it to the original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by a straight forward smp function call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: linux-pm@vger.kernel.org
---
drivers/cpufreq/sparc-us2e-cpufreq.c | 45 ++++++++++++++++-------------------
1 file changed, 21 insertions(+), 24 deletions(-)
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -118,10 +118,6 @@ static void us2e_transition(unsigned lon
unsigned long clock_tick,
unsigned long old_divisor, unsigned long divisor)
{
- unsigned long flags;
-
- local_irq_save(flags);
-
estar &= ~ESTAR_MODE_DIV_MASK;
/* This is based upon the state transition diagram in the IIe manual. */
@@ -152,8 +148,6 @@ static void us2e_transition(unsigned lon
} else {
BUG();
}
-
- local_irq_restore(flags);
}
static unsigned long index_to_estar_mode(unsigned int index)
@@ -229,48 +223,51 @@ static unsigned long estar_to_divisor(un
return ret;
}
+static void __us2e_freq_get(void *arg)
+{
+ unsigned long *estar = arg;
+
+ *estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+}
+
static unsigned int us2e_freq_get(unsigned int cpu)
{
- cpumask_t cpus_allowed;
unsigned long clock_tick, estar;
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
+ if (smp_call_function_single(cpu, __us2e_freq_get, &estar, 1))
+ return 0;
return clock_tick / estar_to_divisor(estar);
}
-static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+static void __us2e_freq_target(void *arg)
{
- unsigned int cpu = policy->cpu;
+ unsigned int cpu = smp_processor_id();
+ unsigned int *index = arg;
unsigned long new_bits, new_freq;
unsigned long clock_tick, divisor, old_divisor, estar;
- cpumask_t cpus_allowed;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- new_bits = index_to_estar_mode(index);
- divisor = index_to_divisor(index);
+ new_bits = index_to_estar_mode(*index);
+ divisor = index_to_divisor(*index);
new_freq /= divisor;
estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
old_divisor = estar_to_divisor(estar);
- if (old_divisor != divisor)
+ if (old_divisor != divisor) {
us2e_transition(estar, new_bits, clock_tick * 1000,
old_divisor, divisor);
+ }
+}
- set_cpus_allowed_ptr(current, &cpus_allowed);
+static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ unsigned int cpu = policy->cpu;
- return 0;
+ return smp_call_function_single(cpu, __us2e_freq_target, &index, 1))
}
static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
[toc] | [prev] | [next] | [standalone]
| From | Viresh Kumar <viresh.kumar@linaro.org> |
|---|---|
| Date | 2017-04-13 05:00 +0200 |
| Subject | Re: [patch 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <tvD9f-4Zo-7@gated-at.bofh.it> |
| In reply to | #1622521 |
On 12-04-17, 22:07, Thomas Gleixner wrote: > The access to the HBIRD_ESTAR_MODE register in the cpu frequency control > functions must happen on the target CPU. This is achieved by temporarily > setting the affinity of the calling user space thread to the requested CPU > and reset it to the original affinity afterwards. > > That's racy vs. CPU hotplug and concurrent affinity settings for that > thread resulting in code executing on the wrong CPU and overwriting the > new affinity setting. > > Replace it by a straight forward smp function call. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > Cc: "David S. Miller" <davem@davemloft.net> > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> > Cc: Viresh Kumar <viresh.kumar@linaro.org> > Cc: linux-pm@vger.kernel.org > --- > drivers/cpufreq/sparc-us2e-cpufreq.c | 45 ++++++++++++++++------------------- > 1 file changed, 21 insertions(+), 24 deletions(-) Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -- viresh
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-13 10:20 +0200 |
| Subject | [patch V2 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <tvI8W-cb-5@gated-at.bofh.it> |
| In reply to | #1622521 |
spu_queue_register() needs to invoke setup functions on a particular
CPU. This is achieved by temporarily setting the affinity of the
calling user space thread to the requested CPU and reset it to the original
affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-crypto@vger.kernel.org
---
V2: Fixup build-bot complaint
drivers/crypto/n2_core.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
--- a/drivers/crypto/n2_core.c
+++ b/drivers/crypto/n2_core.c
@@ -65,6 +65,11 @@ struct spu_queue {
struct list_head list;
};
+struct spu_qreg {
+ struct spu_queue *queue;
+ unsigned long type;
+};
+
static struct spu_queue **cpu_to_cwq;
static struct spu_queue **cpu_to_mau;
@@ -1631,31 +1636,27 @@ static void queue_cache_destroy(void)
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]);
}
-static int spu_queue_register(struct spu_queue *p, unsigned long q_type)
+static long spu_queue_register_workfn(void *arg)
{
- cpumask_var_t old_allowed;
+ struct spu_qreg *qr = arg;
+ struct spu_queue *p = qr->queue;
+ unsigned long q_type = qr->type;
unsigned long hv_ret;
- if (cpumask_empty(&p->sharing))
- return -EINVAL;
-
- if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL))
- return -ENOMEM;
-
- cpumask_copy(old_allowed, ¤t->cpus_allowed);
-
- set_cpus_allowed_ptr(current, &p->sharing);
-
hv_ret = sun4v_ncs_qconf(q_type, __pa(p->q),
CWQ_NUM_ENTRIES, &p->qhandle);
if (!hv_ret)
sun4v_ncs_sethead_marker(p->qhandle, 0);
- set_cpus_allowed_ptr(current, old_allowed);
+ return hv_ret ? -EINVAL : 0;
+}
- free_cpumask_var(old_allowed);
+static int spu_queue_register(struct spu_queue *p, unsigned long q_type)
+{
+ int cpu = cpumask_any_and(&p->sharing, cpu_online_mask);
+ struct spu_qreg qr = { .queue = p, .type = q_type };
- return (hv_ret ? -EINVAL : 0);
+ return work_on_cpu_safe(cpu, spu_queue_register_workfn, &qr);
}
static int spu_queue_setup(struct spu_queue *p)
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-13 10:30 +0200 |
| Subject | [patch V3 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <tvIiC-gf-5@gated-at.bofh.it> |
| In reply to | #1622805 |
The access to the HBIRD_ESTAR_MODE register in the cpu frequency control
functions must happen on the target CPU. This is achieved by temporarily
setting the affinity of the calling user space thread to the requested CPU
and reset it to the original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by a straight forward smp function call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: linux-pm@vger.kernel.org
---
V3: Include the proper patch
V2: Fix build-bot complaint (-ENOTAWAKEYET / -EWRONGPATCH)
drivers/cpufreq/sparc-us2e-cpufreq.c | 45 ++++++++++++++++-------------------
1 file changed, 21 insertions(+), 24 deletions(-)
Index: b/drivers/cpufreq/sparc-us2e-cpufreq.c
===================================================================
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -118,10 +118,6 @@ static void us2e_transition(unsigned lon
unsigned long clock_tick,
unsigned long old_divisor, unsigned long divisor)
{
- unsigned long flags;
-
- local_irq_save(flags);
-
estar &= ~ESTAR_MODE_DIV_MASK;
/* This is based upon the state transition diagram in the IIe manual. */
@@ -152,8 +148,6 @@ static void us2e_transition(unsigned lon
} else {
BUG();
}
-
- local_irq_restore(flags);
}
static unsigned long index_to_estar_mode(unsigned int index)
@@ -229,48 +223,51 @@ static unsigned long estar_to_divisor(un
return ret;
}
+static void __us2e_freq_get(void *arg)
+{
+ unsigned long *estar = arg;
+
+ *estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+}
+
static unsigned int us2e_freq_get(unsigned int cpu)
{
- cpumask_t cpus_allowed;
unsigned long clock_tick, estar;
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
+ if (smp_call_function_single(cpu, __us2e_freq_get, &estar, 1))
+ return 0;
return clock_tick / estar_to_divisor(estar);
}
-static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+static void __us2e_freq_target(void *arg)
{
- unsigned int cpu = policy->cpu;
+ unsigned int cpu = smp_processor_id();
+ unsigned int *index = arg;
unsigned long new_bits, new_freq;
unsigned long clock_tick, divisor, old_divisor, estar;
- cpumask_t cpus_allowed;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- new_bits = index_to_estar_mode(index);
- divisor = index_to_divisor(index);
+ new_bits = index_to_estar_mode(*index);
+ divisor = index_to_divisor(*index);
new_freq /= divisor;
estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
old_divisor = estar_to_divisor(estar);
- if (old_divisor != divisor)
+ if (old_divisor != divisor) {
us2e_transition(estar, new_bits, clock_tick * 1000,
old_divisor, divisor);
+ }
+}
- set_cpus_allowed_ptr(current, &cpus_allowed);
+static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ unsigned int cpu = policy->cpu;
- return 0;
+ return smp_call_function_single(cpu, __us2e_freq_target, &index, 1);
}
static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <twwS6-7Dd-27@gated-at.bofh.it> |
| In reply to | #1622813 |
Commit-ID: 12699ac53a2e5fbd1fd7c164b11685d55c8aa28b
Gitweb: http://git.kernel.org/tip/12699ac53a2e5fbd1fd7c164b11685d55c8aa28b
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 13 Apr 2017 10:22:43 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 15 Apr 2017 12:20:56 +0200
cpufreq/sparc-us2e: Replace racy task affinity logic
The access to the HBIRD_ESTAR_MODE register in the cpu frequency control
functions must happen on the target CPU. This is achieved by temporarily
setting the affinity of the calling user space thread to the requested CPU
and reset it to the original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by a straight forward smp function call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: linux-pm@vger.kernel.org
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704131020280.2408@nanos
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/cpufreq/sparc-us2e-cpufreq.c | 45 +++++++++++++++++-------------------
1 file changed, 21 insertions(+), 24 deletions(-)
diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c
index 35ddb6d..90f33ef 100644
--- a/drivers/cpufreq/sparc-us2e-cpufreq.c
+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c
@@ -118,10 +118,6 @@ static void us2e_transition(unsigned long estar, unsigned long new_bits,
unsigned long clock_tick,
unsigned long old_divisor, unsigned long divisor)
{
- unsigned long flags;
-
- local_irq_save(flags);
-
estar &= ~ESTAR_MODE_DIV_MASK;
/* This is based upon the state transition diagram in the IIe manual. */
@@ -152,8 +148,6 @@ static void us2e_transition(unsigned long estar, unsigned long new_bits,
} else {
BUG();
}
-
- local_irq_restore(flags);
}
static unsigned long index_to_estar_mode(unsigned int index)
@@ -229,48 +223,51 @@ static unsigned long estar_to_divisor(unsigned long estar)
return ret;
}
+static void __us2e_freq_get(void *arg)
+{
+ unsigned long *estar = arg;
+
+ *estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+}
+
static unsigned int us2e_freq_get(unsigned int cpu)
{
- cpumask_t cpus_allowed;
unsigned long clock_tick, estar;
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
+ if (smp_call_function_single(cpu, __us2e_freq_get, &estar, 1))
+ return 0;
return clock_tick / estar_to_divisor(estar);
}
-static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+static void __us2e_freq_target(void *arg)
{
- unsigned int cpu = policy->cpu;
+ unsigned int cpu = smp_processor_id();
+ unsigned int *index = arg;
unsigned long new_bits, new_freq;
unsigned long clock_tick, divisor, old_divisor, estar;
- cpumask_t cpus_allowed;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
- new_bits = index_to_estar_mode(index);
- divisor = index_to_divisor(index);
+ new_bits = index_to_estar_mode(*index);
+ divisor = index_to_divisor(*index);
new_freq /= divisor;
estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
old_divisor = estar_to_divisor(estar);
- if (old_divisor != divisor)
+ if (old_divisor != divisor) {
us2e_transition(estar, new_bits, clock_tick * 1000,
old_divisor, divisor);
+ }
+}
- set_cpus_allowed_ptr(current, &cpus_allowed);
+static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index)
+{
+ unsigned int cpu = policy->cpu;
- return 0;
+ return smp_call_function_single(cpu, __us2e_freq_target, &index, 1);
}
static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
[toc] | [prev] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2017-04-13 17:00 +0200 |
| Subject | Re: [patch V2 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic |
| Message-ID | <tvOo3-4nr-39@gated-at.bofh.it> |
| In reply to | #1622805 |
From: Thomas Gleixner <tglx@linutronix.de> Date: Thu, 13 Apr 2017 10:19:07 +0200 (CEST) > spu_queue_register() needs to invoke setup functions on a particular > CPU. This is achieved by temporarily setting the affinity of the > calling user space thread to the requested CPU and reset it to the original > affinity afterwards. > > That's racy vs. CPU hotplug and concurrent affinity settings for that > thread resulting in code executing on the wrong CPU and overwriting the > new affinity setting. > > Replace it by using work_on_cpu_safe() which guarantees to run the code on > the requested CPU or to fail in case the CPU is offline. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: David S. Miller <davem@davemloft.net>
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 03/13] ia64/salinfo: Replace racy task affinity logic |
| Message-ID | <tvx3P-QV-23@gated-at.bofh.it> |
| In reply to | #1622519 |
Some of the file operations in /proc/sal require to run code on the
requested cpu. This is achieved by temporarily setting the affinity of the
calling user space thread to the requested CPU and reset it to the original
affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/kernel/salinfo.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -179,14 +179,14 @@ struct salinfo_platform_oemdata_parms {
const u8 *efi_guid;
u8 **oemdata;
u64 *oemdata_size;
- int ret;
};
-static void
+static long
salinfo_platform_oemdata_cpu(void *context)
{
struct salinfo_platform_oemdata_parms *parms = context;
- parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size);
+
+ return salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size);
}
static void
@@ -380,16 +380,7 @@ salinfo_log_release(struct inode *inode,
return 0;
}
-static void
-call_on_cpu(int cpu, void (*fn)(void *), void *arg)
-{
- cpumask_t save_cpus_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
- (*fn)(arg);
- set_cpus_allowed_ptr(current, &save_cpus_allowed);
-}
-
-static void
+static long
salinfo_log_read_cpu(void *context)
{
struct salinfo_data *data = context;
@@ -399,6 +390,7 @@ salinfo_log_read_cpu(void *context)
/* Clear corrected errors as they are read from SAL */
if (rh->severity == sal_log_severity_corrected)
ia64_sal_clear_state_info(data->type);
+ return 0;
}
static void
@@ -430,7 +422,7 @@ salinfo_log_new_read(int cpu, struct sal
spin_unlock_irqrestore(&data_saved_lock, flags);
if (!data->saved_num)
- call_on_cpu(cpu, salinfo_log_read_cpu, data);
+ work_on_cpu_safe(cpu, salinfo_log_read_cpu, data);
if (!data->log_size) {
data->state = STATE_NO_DATA;
cpumask_clear_cpu(cpu, &data->cpu_event);
@@ -459,11 +451,13 @@ salinfo_log_read(struct file *file, char
return simple_read_from_buffer(buffer, count, ppos, buf, bufsize);
}
-static void
+static long
salinfo_log_clear_cpu(void *context)
{
struct salinfo_data *data = context;
+
ia64_sal_clear_state_info(data->type);
+ return 0;
}
static int
@@ -486,7 +480,7 @@ salinfo_log_clear(struct salinfo_data *d
rh = (sal_log_record_header_t *)(data->log_buffer);
/* Corrected errors have already been cleared from SAL */
if (rh->severity != sal_log_severity_corrected)
- call_on_cpu(cpu, salinfo_log_clear_cpu, data);
+ work_on_cpu_safe(cpu, salinfo_log_clear_cpu, data);
/* clearing a record may make a new record visible */
salinfo_log_new_read(cpu, data);
if (data->state == STATE_LOG_RECORD) {
@@ -531,9 +525,8 @@ salinfo_log_write(struct file *file, con
.oemdata = &data->oemdata,
.oemdata_size = &data->oemdata_size
};
- call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms);
- if (parms.ret)
- count = parms.ret;
+ count = work_on_cpu_safe(cpu, salinfo_platform_oemdata_cpu,
+ &parms);
} else
data->oemdata_size = 0;
} else
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] ia64/salinfo: Replace racy task affinity logic |
| Message-ID | <twwS6-7Dd-17@gated-at.bofh.it> |
| In reply to | #1622523 |
Commit-ID: 67cb85fdcee7fbc61c09c00360d1a4ae37641db4
Gitweb: http://git.kernel.org/tip/67cb85fdcee7fbc61c09c00360d1a4ae37641db4
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 12 Apr 2017 22:07:29 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 15 Apr 2017 12:20:53 +0200
ia64/salinfo: Replace racy task affinity logic
Some of the file operations in /proc/sal require to run code on the
requested cpu. This is achieved by temporarily setting the affinity of the
calling user space thread to the requested CPU and reset it to the original
affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/20170412201042.341863457@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/ia64/kernel/salinfo.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index d194d5c..63dc9cd 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -179,14 +179,14 @@ struct salinfo_platform_oemdata_parms {
const u8 *efi_guid;
u8 **oemdata;
u64 *oemdata_size;
- int ret;
};
-static void
+static long
salinfo_platform_oemdata_cpu(void *context)
{
struct salinfo_platform_oemdata_parms *parms = context;
- parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size);
+
+ return salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size);
}
static void
@@ -380,16 +380,7 @@ salinfo_log_release(struct inode *inode, struct file *file)
return 0;
}
-static void
-call_on_cpu(int cpu, void (*fn)(void *), void *arg)
-{
- cpumask_t save_cpus_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
- (*fn)(arg);
- set_cpus_allowed_ptr(current, &save_cpus_allowed);
-}
-
-static void
+static long
salinfo_log_read_cpu(void *context)
{
struct salinfo_data *data = context;
@@ -399,6 +390,7 @@ salinfo_log_read_cpu(void *context)
/* Clear corrected errors as they are read from SAL */
if (rh->severity == sal_log_severity_corrected)
ia64_sal_clear_state_info(data->type);
+ return 0;
}
static void
@@ -430,7 +422,7 @@ retry:
spin_unlock_irqrestore(&data_saved_lock, flags);
if (!data->saved_num)
- call_on_cpu(cpu, salinfo_log_read_cpu, data);
+ work_on_cpu_safe(cpu, salinfo_log_read_cpu, data);
if (!data->log_size) {
data->state = STATE_NO_DATA;
cpumask_clear_cpu(cpu, &data->cpu_event);
@@ -459,11 +451,13 @@ salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *p
return simple_read_from_buffer(buffer, count, ppos, buf, bufsize);
}
-static void
+static long
salinfo_log_clear_cpu(void *context)
{
struct salinfo_data *data = context;
+
ia64_sal_clear_state_info(data->type);
+ return 0;
}
static int
@@ -486,7 +480,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu)
rh = (sal_log_record_header_t *)(data->log_buffer);
/* Corrected errors have already been cleared from SAL */
if (rh->severity != sal_log_severity_corrected)
- call_on_cpu(cpu, salinfo_log_clear_cpu, data);
+ work_on_cpu_safe(cpu, salinfo_log_clear_cpu, data);
/* clearing a record may make a new record visible */
salinfo_log_new_read(cpu, data);
if (data->state == STATE_LOG_RECORD) {
@@ -531,9 +525,8 @@ salinfo_log_write(struct file *file, const char __user *buffer, size_t count, lo
.oemdata = &data->oemdata,
.oemdata_size = &data->oemdata_size
};
- call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms);
- if (parms.ret)
- count = parms.ret;
+ count = work_on_cpu_safe(cpu, salinfo_platform_oemdata_cpu,
+ &parms);
} else
data->oemdata_size = 0;
} else
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 04/13] ia64/sn/hwperf: Replace racy task affinity logic |
| Message-ID | <tvx3Q-QV-33@gated-at.bofh.it> |
| In reply to | #1622519 |
sn_hwperf_op_cpu() which is invoked from an ioctl requires to run code on
the requested cpu. This is achieved by temporarily setting the affinity of
the calling user space thread to the requested CPU and reset it to the
original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/sn/kernel/sn2/sn_hwperf.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -598,6 +598,12 @@ static void sn_hwperf_call_sal(void *inf
op_info->ret = r;
}
+static long sn_hwperf_call_sal_work(void *info)
+{
+ sn_hwperf_call_sal(info);
+ return 0;
+}
+
static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
{
u32 cpu;
@@ -629,13 +635,9 @@ static int sn_hwperf_op_cpu(struct sn_hw
/* use an interprocessor interrupt to call SAL */
smp_call_function_single(cpu, sn_hwperf_call_sal,
op_info, 1);
- }
- else {
- /* migrate the task before calling SAL */
- save_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
- sn_hwperf_call_sal(op_info);
- set_cpus_allowed_ptr(current, &save_allowed);
+ } else {
+ /* Call on the target CPU */
+ work_on_cpu_safe(cpu, sn_hwperf_call_sal, op_info);
}
}
r = op_info->ret;
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 23:00 +0200 |
| Subject | [patch V 2 04/13] ia64/sn/hwperf: Replace racy task affinity logic |
| Message-ID | <tvxwS-15r-25@gated-at.bofh.it> |
| In reply to | #1622524 |
Subject: ia64/sn/hwperf: Replace racy task affinity logic
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 06 Apr 2017 14:56:18 +0200
sn_hwperf_op_cpu() which is invoked from an ioctl requires to run code on
the requested cpu. This is achieved by temporarily setting the affinity of
the calling user space thread to the requested CPU and reset it to the
original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
---
V2: Use the work function for real and remove the unused variable (reported
by kbuild robot)
arch/ia64/sn/kernel/sn2/sn_hwperf.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
Index: b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
===================================================================
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -598,12 +598,17 @@ static void sn_hwperf_call_sal(void *inf
op_info->ret = r;
}
+static long sn_hwperf_call_sal_work(void *info)
+{
+ sn_hwperf_call_sal(info);
+ return 0;
+}
+
static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
{
u32 cpu;
u32 use_ipi;
int r = 0;
- cpumask_t save_allowed;
cpu = (op_info->a->arg & SN_HWPERF_ARG_CPU_MASK) >> 32;
use_ipi = op_info->a->arg & SN_HWPERF_ARG_USE_IPI_MASK;
@@ -629,13 +634,9 @@ static int sn_hwperf_op_cpu(struct sn_hw
/* use an interprocessor interrupt to call SAL */
smp_call_function_single(cpu, sn_hwperf_call_sal,
op_info, 1);
- }
- else {
- /* migrate the task before calling SAL */
- save_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
- sn_hwperf_call_sal(op_info);
- set_cpus_allowed_ptr(current, &save_allowed);
+ } else {
+ /* Call on the target CPU */
+ work_on_cpu_safe(cpu, sn_hwperf_call_sal_work, op_info);
}
}
r = op_info->ret;
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] ia64/sn/hwperf: Replace racy task affinity logic |
| Message-ID | <twwS6-7Dd-25@gated-at.bofh.it> |
| In reply to | #1622552 |
Commit-ID: 9feb42ac88b516e378b9782e82b651ca5bed95c4
Gitweb: http://git.kernel.org/tip/9feb42ac88b516e378b9782e82b651ca5bed95c4
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 6 Apr 2017 14:56:18 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 15 Apr 2017 12:20:53 +0200
ia64/sn/hwperf: Replace racy task affinity logic
sn_hwperf_op_cpu() which is invoked from an ioctl requires to run code on
the requested cpu. This is achieved by temporarily setting the affinity of
the calling user space thread to the requested CPU and reset it to the
original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by using work_on_cpu_safe() which guarantees to run the code on
the requested CPU or to fail in case the CPU is offline.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704122251450.2548@nanos
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/ia64/sn/kernel/sn2/sn_hwperf.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 52704f1..55febd6 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -598,12 +598,17 @@ static void sn_hwperf_call_sal(void *info)
op_info->ret = r;
}
+static long sn_hwperf_call_sal_work(void *info)
+{
+ sn_hwperf_call_sal(info);
+ return 0;
+}
+
static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
{
u32 cpu;
u32 use_ipi;
int r = 0;
- cpumask_t save_allowed;
cpu = (op_info->a->arg & SN_HWPERF_ARG_CPU_MASK) >> 32;
use_ipi = op_info->a->arg & SN_HWPERF_ARG_USE_IPI_MASK;
@@ -629,13 +634,9 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
/* use an interprocessor interrupt to call SAL */
smp_call_function_single(cpu, sn_hwperf_call_sal,
op_info, 1);
- }
- else {
- /* migrate the task before calling SAL */
- save_allowed = current->cpus_allowed;
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
- sn_hwperf_call_sal(op_info);
- set_cpus_allowed_ptr(current, &save_allowed);
+ } else {
+ /* Call on the target CPU */
+ work_on_cpu_safe(cpu, sn_hwperf_call_sal_work, op_info);
}
}
r = op_info->ret;
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 11/13] cpufreq/sparc-us3: Replace racy task affinity logic |
| Message-ID | <tvx3Q-QV-29@gated-at.bofh.it> |
| In reply to | #1622519 |
The access to the safari config register in the CPU frequency functions
must be executed on the target CPU. This is achieved by temporarily setting
the affinity of the calling user space thread to the requested CPU and
reset it to the original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by a straight forward smp function call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-pm@vger.kernel.org
---
drivers/cpufreq/sparc-us3-cpufreq.c | 46 ++++++++++++------------------------
1 file changed, 16 insertions(+), 30 deletions(-)
--- a/drivers/cpufreq/sparc-us3-cpufreq.c
+++ b/drivers/cpufreq/sparc-us3-cpufreq.c
@@ -35,22 +35,28 @@ static struct us3_freq_percpu_info *us3_
#define SAFARI_CFG_DIV_32 0x0000000080000000UL
#define SAFARI_CFG_DIV_MASK 0x00000000C0000000UL
-static unsigned long read_safari_cfg(void)
+static void read_safari_cfg(void *arg)
{
- unsigned long ret;
+ unsigned long ret, *val = arg;
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=&r" (ret)
: "i" (ASI_SAFARI_CONFIG));
- return ret;
+ *val = ret;
}
-static void write_safari_cfg(unsigned long val)
+static void update_safari_cfg(void *arg)
{
+ unsigned long reg, *new_bits = arg;
+
+ read_safari_cfg(®);
+ reg &= ~SAFARI_CFG_DIV_MASK;
+ reg |= *new_bits;
+
__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (val), "i" (ASI_SAFARI_CONFIG)
+ : "r" (reg), "i" (ASI_SAFARI_CONFIG)
: "memory");
}
@@ -78,29 +84,17 @@ static unsigned long get_current_freq(un
static unsigned int us3_freq_get(unsigned int cpu)
{
- cpumask_t cpus_allowed;
unsigned long reg;
- unsigned int ret;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
- reg = read_safari_cfg();
- ret = get_current_freq(cpu, reg);
- set_cpus_allowed_ptr(current, &cpus_allowed);
-
- return ret;
+ if (smp_call_function_single(cpu, read_safari_cfg, ®, 1))
+ return 0;
+ return get_current_freq(cpu, reg);
}
static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index)
{
unsigned int cpu = policy->cpu;
- unsigned long new_bits, new_freq, reg;
- cpumask_t cpus_allowed;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
+ unsigned long new_bits, new_freq;
new_freq = sparc64_get_clock_tick(cpu) / 1000;
switch (index) {
@@ -121,15 +115,7 @@ static int us3_freq_target(struct cpufre
BUG();
}
- reg = read_safari_cfg();
-
- reg &= ~SAFARI_CFG_DIV_MASK;
- reg |= new_bits;
- write_safari_cfg(reg);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
-
- return 0;
+ return smp_call_function_single(cpu, update_safari_cfg, &new_bits, 1);
}
static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
[toc] | [prev] | [next] | [standalone]
| From | Viresh Kumar <viresh.kumar@linaro.org> |
|---|---|
| Date | 2017-04-13 04:50 +0200 |
| Subject | Re: [patch 11/13] cpufreq/sparc-us3: Replace racy task affinity logic |
| Message-ID | <tvCZz-4V5-1@gated-at.bofh.it> |
| In reply to | #1622525 |
On 12-04-17, 22:07, Thomas Gleixner wrote: > The access to the safari config register in the CPU frequency functions > must be executed on the target CPU. This is achieved by temporarily setting > the affinity of the calling user space thread to the requested CPU and > reset it to the original affinity afterwards. > > That's racy vs. CPU hotplug and concurrent affinity settings for that > thread resulting in code executing on the wrong CPU and overwriting the > new affinity setting. > > Replace it by a straight forward smp function call. > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> > Cc: Viresh Kumar <viresh.kumar@linaro.org> > Cc: "David S. Miller" <davem@davemloft.net> > Cc: linux-pm@vger.kernel.org > --- > drivers/cpufreq/sparc-us3-cpufreq.c | 46 ++++++++++++------------------------ > 1 file changed, 16 insertions(+), 30 deletions(-) Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -- viresh
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] cpufreq/sparc-us3: Replace racy task affinity logic |
| Message-ID | <twwS6-7Dd-23@gated-at.bofh.it> |
| In reply to | #1622525 |
Commit-ID: 9fe24c4e92d3963d92d7d383e28ed098bd5689d8
Gitweb: http://git.kernel.org/tip/9fe24c4e92d3963d92d7d383e28ed098bd5689d8
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 12 Apr 2017 22:07:37 +0200
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 15 Apr 2017 12:20:55 +0200
cpufreq/sparc-us3: Replace racy task affinity logic
The access to the safari config register in the CPU frequency functions
must be executed on the target CPU. This is achieved by temporarily setting
the affinity of the calling user space thread to the requested CPU and
reset it to the original affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
Replace it by a straight forward smp function call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Sebastian Siewior <bigeasy@linutronix.de>
Cc: linux-pm@vger.kernel.org
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Len Brown <lenb@kernel.org>
Link: http://lkml.kernel.org/r/20170412201043.047558840@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/cpufreq/sparc-us3-cpufreq.c | 46 +++++++++++++------------------------
1 file changed, 16 insertions(+), 30 deletions(-)
diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c
index a8d86a4..30645b0 100644
--- a/drivers/cpufreq/sparc-us3-cpufreq.c
+++ b/drivers/cpufreq/sparc-us3-cpufreq.c
@@ -35,22 +35,28 @@ static struct us3_freq_percpu_info *us3_freq_table;
#define SAFARI_CFG_DIV_32 0x0000000080000000UL
#define SAFARI_CFG_DIV_MASK 0x00000000C0000000UL
-static unsigned long read_safari_cfg(void)
+static void read_safari_cfg(void *arg)
{
- unsigned long ret;
+ unsigned long ret, *val = arg;
__asm__ __volatile__("ldxa [%%g0] %1, %0"
: "=&r" (ret)
: "i" (ASI_SAFARI_CONFIG));
- return ret;
+ *val = ret;
}
-static void write_safari_cfg(unsigned long val)
+static void update_safari_cfg(void *arg)
{
+ unsigned long reg, *new_bits = arg;
+
+ read_safari_cfg(®);
+ reg &= ~SAFARI_CFG_DIV_MASK;
+ reg |= *new_bits;
+
__asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (val), "i" (ASI_SAFARI_CONFIG)
+ : "r" (reg), "i" (ASI_SAFARI_CONFIG)
: "memory");
}
@@ -78,29 +84,17 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg
static unsigned int us3_freq_get(unsigned int cpu)
{
- cpumask_t cpus_allowed;
unsigned long reg;
- unsigned int ret;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
-
- reg = read_safari_cfg();
- ret = get_current_freq(cpu, reg);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
- return ret;
+ if (smp_call_function_single(cpu, read_safari_cfg, ®, 1))
+ return 0;
+ return get_current_freq(cpu, reg);
}
static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index)
{
unsigned int cpu = policy->cpu;
- unsigned long new_bits, new_freq, reg;
- cpumask_t cpus_allowed;
-
- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed);
- set_cpus_allowed_ptr(current, cpumask_of(cpu));
+ unsigned long new_bits, new_freq;
new_freq = sparc64_get_clock_tick(cpu) / 1000;
switch (index) {
@@ -121,15 +115,7 @@ static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index)
BUG();
}
- reg = read_safari_cfg();
-
- reg &= ~SAFARI_CFG_DIV_MASK;
- reg |= new_bits;
- write_safari_cfg(reg);
-
- set_cpus_allowed_ptr(current, &cpus_allowed);
-
- return 0;
+ return smp_call_function_single(cpu, update_safari_cfg, &new_bits, 1);
}
static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 01/13] ia64/topology: Remove cpus_allowed manipulation |
| Message-ID | <tvx3Q-QV-39@gated-at.bofh.it> |
| In reply to | #1622519 |
The CPU hotplug callback fiddles with the cpus_allowed pointer to pin the calling thread on the plugged CPU. That's already guaranteed by the hotplug core code. Remove it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: linux-ia64@vger.kernel.org --- arch/ia64/kernel/topology.c | 6 ------ 1 file changed, 6 deletions(-) --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -355,18 +355,12 @@ static int cache_add_dev(unsigned int cp unsigned long i, j; struct cache_info *this_object; int retval = 0; - cpumask_t oldmask; if (all_cpu_cache_info[cpu].kobj.parent) return 0; - oldmask = current->cpus_allowed; - retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); - if (unlikely(retval)) - return retval; retval = cpu_cache_sysfs_init(cpu); - set_cpus_allowed_ptr(current, &oldmask); if (unlikely(retval < 0)) return retval;
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] ia64/topology: Remove cpus_allowed manipulation |
| Message-ID | <twwS6-7Dd-15@gated-at.bofh.it> |
| In reply to | #1622526 |
Commit-ID: 048c9b954e20396e0c45ee778466994d1be2e612 Gitweb: http://git.kernel.org/tip/048c9b954e20396e0c45ee778466994d1be2e612 Author: Thomas Gleixner <tglx@linutronix.de> AuthorDate: Wed, 12 Apr 2017 22:07:27 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Sat, 15 Apr 2017 12:20:52 +0200 ia64/topology: Remove cpus_allowed manipulation The CPU hotplug callback fiddles with the cpus_allowed pointer to pin the calling thread on the plugged CPU. That's already guaranteed by the hotplug core code. Remove it. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Tony Luck <tony.luck@intel.com> Cc: linux-ia64@vger.kernel.org Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Lai Jiangshan <jiangshanlai@gmail.com> Cc: Viresh Kumar <viresh.kumar@linaro.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Tejun Heo <tj@kernel.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Len Brown <lenb@kernel.org> Link: http://lkml.kernel.org/r/20170412201042.174518069@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- arch/ia64/kernel/topology.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 1a68f01..d76529c 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -355,18 +355,12 @@ static int cache_add_dev(unsigned int cpu) unsigned long i, j; struct cache_info *this_object; int retval = 0; - cpumask_t oldmask; if (all_cpu_cache_info[cpu].kobj.parent) return 0; - oldmask = current->cpus_allowed; - retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); - if (unlikely(retval)) - return retval; retval = cpu_cache_sysfs_init(cpu); - set_cpus_allowed_ptr(current, &oldmask); if (unlikely(retval < 0)) return retval;
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 07/13] ACPI/processor: Fix error handling in __acpi_processor_start() |
| Message-ID | <tvx3Q-QV-31@gated-at.bofh.it> |
| In reply to | #1622519 |
When acpi_install_notify_handler() fails the cooling device stays registered and the sysfs files created via acpi_pss_perf_init() are leaked and the function returns success. Undo acpi_pss_perf_init() and return a proper error code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: Len Brown <lenb@kernel.org> Cc: linux-acpi@vger.kernel.org --- drivers/acpi/processor_driver.c | 3 +++ 1 file changed, 3 insertions(+) --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -251,6 +251,9 @@ static int __acpi_processor_start(struct if (ACPI_SUCCESS(status)) return 0; + result = -ENODEV; + acpi_pss_perf_exit(pr, device); + err_power_exit: acpi_processor_power_exit(pr); return result;
[toc] | [prev] | [next] | [standalone]
| From | tip-bot for Thomas Gleixner <tipbot@zytor.com> |
|---|---|
| Date | 2017-04-15 16:30 +0200 |
| Subject | [tip:sched/core] ACPI/processor: Fix error handling in __acpi_processor_start() |
| Message-ID | <twwS5-7Dd-9@gated-at.bofh.it> |
| In reply to | #1622528 |
Commit-ID: a5cbdf693a60d5b86d4d21dfedd90f17754eb273 Gitweb: http://git.kernel.org/tip/a5cbdf693a60d5b86d4d21dfedd90f17754eb273 Author: Thomas Gleixner <tglx@linutronix.de> AuthorDate: Wed, 12 Apr 2017 22:07:33 +0200 Committer: Thomas Gleixner <tglx@linutronix.de> CommitDate: Sat, 15 Apr 2017 12:20:54 +0200 ACPI/processor: Fix error handling in __acpi_processor_start() When acpi_install_notify_handler() fails the cooling device stays registered and the sysfs files created via acpi_pss_perf_init() are leaked and the function returns success. Undo acpi_pss_perf_init() and return a proper error code. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Sebastian Siewior <bigeasy@linutronix.de> Cc: Lai Jiangshan <jiangshanlai@gmail.com> Cc: linux-acpi@vger.kernel.org Cc: Viresh Kumar <viresh.kumar@linaro.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Tejun Heo <tj@kernel.org> Cc: "David S. Miller" <davem@davemloft.net> Cc: Len Brown <lenb@kernel.org> Link: http://lkml.kernel.org/r/20170412201042.695499645@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- drivers/acpi/processor_driver.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9d5f0c7..eab8cda 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -251,6 +251,9 @@ static int __acpi_processor_start(struct acpi_device *device) if (ACPI_SUCCESS(status)) return 0; + result = -ENODEV; + acpi_pss_perf_exit(pr, device); + err_power_exit: acpi_processor_power_exit(pr); return result;
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-04-12 22:30 +0200 |
| Subject | [patch 08/13] ACPI/processor: Replace racy task affinity logic. |
| Message-ID | <tvx3Q-QV-27@gated-at.bofh.it> |
| In reply to | #1622519 |
acpi_processor_get_throttling() requires to invoke the getter function on
the target CPU. This is achieved by temporarily setting the affinity of the
calling user space thread to the requested CPU and reset it to the original
affinity afterwards.
That's racy vs. CPU hotplug and concurrent affinity settings for that
thread resulting in code executing on the wrong CPU and overwriting the
new affinity setting.
acpi_processor_get_throttling() is invoked in two ways:
1) The CPU online callback, which is already running on the target CPU and
obviously protected against hotplug and not affected by affinity
settings.
2) The ACPI driver probe function, which is not protected against hotplug
during modprobe.
Switch it over to work_on_cpu() and protect the probe function against CPU
hotplug.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
---
drivers/acpi/processor_driver.c | 7 ++++++-
drivers/acpi/processor_throttling.c | 31 +++++++++++++------------------
2 files changed, 19 insertions(+), 19 deletions(-)
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -262,11 +262,16 @@ static int __acpi_processor_start(struct
static int acpi_processor_start(struct device *dev)
{
struct acpi_device *device = ACPI_COMPANION(dev);
+ int ret;
if (!device)
return -ENODEV;
- return __acpi_processor_start(device);
+ /* Protect against concurrent CPU hotplug operations */
+ get_online_cpus();
+ ret = __acpi_processor_start(device);
+ put_online_cpus();
+ return ret;
}
static int acpi_processor_stop(struct device *dev)
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -901,36 +901,31 @@ static int acpi_processor_get_throttling
return 0;
}
-static int acpi_processor_get_throttling(struct acpi_processor *pr)
+static long __acpi_processor_get_throttling(void *data)
{
- cpumask_var_t saved_mask;
- int ret;
+ struct acpi_processor *pr = data;
+
+ return pr->throttling.acpi_processor_get_throttling(pr);
+}
+static int acpi_processor_get_throttling(struct acpi_processor *pr)
+{
if (!pr)
return -EINVAL;
if (!pr->flags.throttling)
return -ENODEV;
- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
- return -ENOMEM;
-
/*
- * Migrate task to the cpu pointed by pr.
+ * This is either called from the CPU hotplug callback of
+ * processor_driver or via the ACPI probe function. In the latter
+ * case the CPU is not guaranteed to be online. Both call sites are
+ * protected against CPU hotplug.
*/
- cpumask_copy(saved_mask, ¤t->cpus_allowed);
- /* FIXME: use work_on_cpu() */
- if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
- /* Can't migrate to the target pr->id CPU. Exit */
- free_cpumask_var(saved_mask);
+ if (!cpu_online(pr->id))
return -ENODEV;
- }
- ret = pr->throttling.acpi_processor_get_throttling(pr);
- /* restore the previous state */
- set_cpus_allowed_ptr(current, saved_mask);
- free_cpumask_var(saved_mask);
- return ret;
+ return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr);
}
static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | linux.kernel
csiph-web