This introduces another routine cpufreq_notify_post_transition() which can be
used to send POSTCHANGE notification for new freq with or without both
{PRE|POST}CHANGE notifications for last freq in case of failures. This is useful
at multiple places, specially for sending transition failure notifications.
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
Hi Rafael,
Please see if you want to take it for 3.13 or 14, as this fixes bugs which are
partly introduced in 3.13..
drivers/cpufreq/cpufreq.c | 14 ++++++++++++++
include/linux/cpufreq.h | 2 ++
2 files changed, 16 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 606224a..a862aa9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -324,6 +324,20 @@ void cpufreq_notify_transition(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
+/* Do post notifications when there are chances that transition has failed */
+void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+ struct cpufreq_freqs *freqs, int transition_failed)
+{
+ cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
+ if (!transition_failed)
+ return;
+
+ swap(freqs->old, freqs->new);
+ cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
+}
+EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition);
+
/*********************************************************************
* SYSFS INTERFACE *
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ee5fe9d..57e48db 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -314,6 +314,8 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
void cpufreq_notify_transition(struct cpufreq_policy *policy,
struct cpufreq_freqs *freqs, unsigned int state);
+void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
+ struct cpufreq_freqs *freqs, int transition_failed);
#else /* CONFIG_CPU_FREQ */
static inline int cpufreq_register_notifier(struct notifier_block *nb,
--
1.7.12.rc2.18.g61b472e
From: Arnaldo Carvalho de Melo <acme(a)ghostprotocols.net>
Hi Ingo,
Ingo, this is the 3rd try, this time removing the last two patches in
the series, from Jean, till we get the problems I found and the one reported by
Jiri sorted out.
Jiri told me the problem exhibits when one doesn't have libunwind devel
files installed.
At some point we're considering using things like the 'mock' tool to
do the tools/perf/tests/ builds tests with all possible development packages
combos to detect these kinds of problems earlier.
Please consider applying,
Best Regards,
- Arnaldo
The following changes since commit 65661f96d3b32f4b28fef26d21be81d7e173b965:
perf/x86: Add RAPL hrtimer support (2013-11-27 15:31:23 +0100)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux tags/perf-core-for-mingo
for you to fetch changes up to 26286141a43251bed548349efbf60b61f1c433e8:
perf tools: Fix tags/TAGS targets rebuilding (2013-11-27 16:47:14 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
. Make per-cpu mmaps the default in 'perf record', from Adrian Hunter.
. Default -t/--thread 'perf record' option to no inheritance,
from Adrian Hunter.
. Make 'perf top -g' refer to callchains, for consistency with other tools,
from David Ahern.
. Skip ignored symbols while printing callchain, from David Ahern.
. Print callchains and symbols if they exist in 'perf script',
from David Ahern.
. Remove thread summary coloring in 'perf trace', from Pekka Enberg.
. zsh completion support, from Ramkumar Ramachandra.
. 'perf timechart' improvements, including backtrace support,
from Stanislav Fomichev.
. Fix using kcore files stored in the buildid cache when doing report/annotate
in non-live sessions, from Adrian Hunter
. Minor 'timechart' cleanups.
. Fix tags/TAGS targets rebuilding, from Jiri Olsa.
. Add options to show comm, fork, exit and mmap PERF_RECORD_ events in
'perf script', from Namhyung Kim.
Signed-off-by: Arnaldo Carvalho de Melo <acme(a)redhat.com>
----------------------------------------------------------------
Adrian Hunter (5):
perf record: Make per-cpu mmaps the default.
perf tools: Allow '--inherit' as the negation of '--no-inherit'
perf tools: Add option macro OPT_BOOLEAN_SET
perf record: Default -t option to no inheritance
perf symbols: Fix not finding kcore in buildid cache
Arnaldo Carvalho de Melo (2):
perf timechart: Remove some needless struct forward declarations
perf timechart: Remove misplaced __maybe_unused
David Ahern (6):
perf top: Make -g refer to callchains
perf evsel: Skip ignored symbols while printing callchain
perf symbols: Move idle syms check from top to generic function
perf thread: Move comm_list check into function
perf tools: Export setup_list
perf script: Print callchains and symbols if they exist
Jiri Olsa (1):
perf tools: Fix tags/TAGS targets rebuilding
Namhyung Kim (3):
perf script: Move evname print code to process_event()
perf script: Print comm, fork and exit events also
perf script: Print mmap[2] events also
Pekka Enberg (1):
perf trace: Remove thread summary coloring
Ramkumar Ramachandra (5):
perf completion: Introduce a layer of indirection
perf completion: Factor out compgen stuff
perf completion: Factor out call to __ltrim_colon_completions
perf completion: Introduce zsh support
perf completion: Rename file to reflect zsh support
Stanislav Fomichev (8):
perf timechart: Always try to print at least 15 tasks
perf timechart: Add option to limit number of tasks
perf timechart: Use proc_num to implement --power-only
perf timechart: Add support for displaying only tasks related data
perf timechart: Group figures and add title with details
perf timechart: Add support for -P and -T in timechart recording
perf timechart: Add backtrace support
perf timechart: dynamically determine event fields offset
Steven Rostedt (1):
tools lib traceevent: Use helper trace-seq in print functions like kernel does
tools/lib/traceevent/event-parse.c | 7 +-
tools/perf/Documentation/perf-record.txt | 12 +-
tools/perf/Documentation/perf-script.txt | 6 +
tools/perf/Documentation/perf-timechart.txt | 26 +-
tools/perf/Documentation/perf-top.txt | 5 +-
tools/perf/Makefile | 7 +-
tools/perf/Makefile.perf | 4 +-
tools/perf/builtin-record.c | 13 +-
tools/perf/builtin-script.c | 209 ++++++++++-
tools/perf/builtin-timechart.c | 418 ++++++++++++++-------
tools/perf/builtin-top.c | 29 +-
tools/perf/builtin-trace.c | 13 +-
tools/perf/{bash_completion => perf-completion.sh} | 100 ++++-
tools/perf/perf.h | 1 +
tools/perf/tests/attr/test-record-no-inherit | 2 +-
tools/perf/util/event.c | 3 +-
tools/perf/util/evlist.c | 6 +-
tools/perf/util/evsel.c | 5 +-
tools/perf/util/parse-options.c | 21 ++
tools/perf/util/parse-options.h | 8 +
tools/perf/util/session.c | 10 +-
tools/perf/util/svghelper.c | 77 +++-
tools/perf/util/svghelper.h | 11 +-
tools/perf/util/symbol.c | 41 +-
tools/perf/util/symbol.h | 4 +
tools/perf/util/target.c | 11 +-
tools/perf/util/target.h | 4 +-
tools/perf/util/thread.h | 12 +
28 files changed, 831 insertions(+), 234 deletions(-)
rename tools/perf/{bash_completion => perf-completion.sh} (65%)
From: Lorenzo Pieralisi <lorenzo.pieralisi(a)arm.com>
Commit 422a83fb1f9e84ead72b8ea15e21da6b8f20e57d upstream
On the TC2 testchip, when all CPUs in a cluster enter standbywfi
and commit a power down request, the power controller will wait
for standbywfil2 coming from L2 cache controller to shut the
cluster down.
By the time all CPUs in a cluster commit a power down request
and enter wfi, the power controller cannot backtrack, or put it
another way, a CPU must not be allowed to complete execution
independently of the power controller, the only way for it to
resume properly must be upon wake-up IRQ pending and subsequent
reset triggered from the power controller.
Current MCPM back-end for TC2 disables the GIC CPU IF only when
power down is committed through the tc2_pm_suspend() method, that
makes sense since a suspended CPU is still online and can receive
interrupts whereas a hotplugged CPU, since it is offline,
migrated all IRQs and shutdown the per-CPU peripherals, hence
their PPIs.
The flaw with this reasoning is the following. If all CPUs in
a clusters are entering a power down state either through CPU
idle or CPU hotplug, when the last man successfully completes
the MCPM power down sequence (and executes wfi), power controller
waits for L2 wfi signal to quiesce the cluster and shut it down.
If, when all CPUs are sitting in wfi, an online CPU hotplugs back
in one of the CPUs in the cluster being shutdown, that CPU
receives an IPI that causes wfi to complete (since tc2_pm_down()
method does not disable the GIC CPU IF in that case - CPU being
hotplugged out, not idle) and the power controller will never see
the stanbywfil2 signal coming from L2 that is required for
shutdown to happen and the system deadlocks.
Further to this issue, kexec hotplugs secondary CPUs out during
kernel reload/restart.
Because kexec may (deliberately) trash the old kernel text, it is
not OK for CPUs to follow the MCPM soft reboot path, since
instructions after the WFI may have been replaced by kexec.
If tc2_pm_down() does not disable the GIC cpu interface, there is a
race between CPU powerdown in the old kernel and the IPI from the
new kernel that triggers secondary boot, particularly if the
powerdown is slow (due to L2 cache cleaning for example). If the
new kernel wins the race, the affected CPU(s) will not really be
reset and may execute garbage after the WFI.
The only solution to this problem consists in disabling the GIC
CPU IF on a CPU committed to power down regardless of the power
down entry method (CPU hotplug or CPU idle). This way, CPU wake-up
is under power controller control, which prevents unexpected wfi
exit caused by a pending IRQ.
This patch moves the GIC CPU IF disable call in the TC2 MCPM
implementation from the tc2_pm_suspend() method to the
tc2_pm_down() method to fix the mentioned race condition(s).
Reviewed-by: Dave Martin <Dave.Martin(a)arm.com>
Tested-by: Dave Martin <Dave.Martin(a)arm.com> (for kexec)
Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha(a)arm.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi(a)arm.com>
Acked-by: Nicolas Pitre <nico(a)linaro.org>
Signed-off-by: Olof Johansson <olof(a)lixom.net>
Signed-off-by: Jon Medhurst <tixy(a)linaro.org>
---
Hi Mark. This patch is backport of a bug fix from 13.12 which fixes a
very difficult to hit race condition which is even more difficult to
debug. Please consider this for inclusion into LSK. As the code it fixes
isn't in 13.10 it can't go via the LSK tree.
Thanks, Tixy
arch/arm/mach-vexpress/tc2_pm.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c
index 9c742ed..2b519ee 100644
--- a/arch/arm/mach-vexpress/tc2_pm.c
+++ b/arch/arm/mach-vexpress/tc2_pm.c
@@ -122,7 +122,15 @@ static void tc2_pm_down(u64 residency)
} else
BUG();
- gic_cpu_if_down();
+ /*
+ * If the CPU is committed to power down, make sure
+ * the power controller will be in charge of waking it
+ * up upon IRQ, ie IRQ lines are cut from GIC CPU IF
+ * to the CPU by disabling the GIC CPU IF to prevent wfi
+ * from completing execution behind power controller back
+ */
+ if (!skip_wfi)
+ gic_cpu_if_down();
if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) {
arch_spin_unlock(&tc2_pm_lock);
--
1.7.10.4
Sometimes boot loaders set CPU frequency to a value outside of frequency table
present with cpufreq core. In such cases CPU might be unstable if it has to run
on that frequency for long duration of time and so its better to set it to a
frequency which is specified in freq-table. This also makes cpufreq stats
inconsistent as cpufreq-stats would fail to register because current frequency
of CPU isn't found in freq-table.
Because we don't want this change to effect boot process badly, we go for the
next freq which is >= policy->cur ('cur' must be set by now, otherwise we will
end up setting freq to lowest of the table as 'cur' is initialized to zero).
In case current frequency doesn't match any frequency from freq-table, we throw
warnings to user, so that user can get this fixed in their bootloaders or
freq-tables.
On some systems we can't really say what frequency we're running at the moment
and so for these we have added another flag: CPUFREQ_SKIP_INITIAL_FREQ_CHECK.
Reported-by: Carlos Hernandez <ceh(a)ti.com>
Reported-and-tested-by: Nishanth Menon <nm(a)ti.com>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
V2->V3:
- Minor cleanups suggested by Rafael
- New patch: 2/2 (cpufreq: Mark x86 drivers with CPUFREQ_SKIP_INITIAL_FREQ_CHECK
flag)
- Rebased on PM/bleeding-edge
drivers/cpufreq/cpufreq.c | 40 ++++++++++++++++++++++++++++++++++++++++
drivers/cpufreq/freq_table.c | 22 ++++++++++++++++++++++
include/linux/cpufreq.h | 11 +++++++++++
3 files changed, 73 insertions(+)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 606224a..f13320a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1042,6 +1042,46 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
}
}
+ /*
+ * Sometimes boot loaders set CPU frequency to a value outside of
+ * frequency table present with cpufreq core. In such cases CPU might be
+ * unstable if it has to run on that frequency for long duration of time
+ * and so its better to set it to a frequency which is specified in
+ * freq-table. This also makes cpufreq stats inconsistent as
+ * cpufreq-stats would fail to register because current frequency of CPU
+ * isn't found in freq-table.
+ *
+ * Because we don't want this change to effect boot process badly, we go
+ * for the next freq which is >= policy->cur ('cur' must be set by now,
+ * otherwise we will end up setting freq to lowest of the table as 'cur'
+ * is initialized to zero).
+ *
+ * We are passing target-freq as "policy->cur - 1" otherwise
+ * __cpufreq_driver_target() would simply fail, as policy->cur will be
+ * equal to target-freq.
+ */
+ if (!(cpufreq_driver->flags & CPUFREQ_SKIP_INITIAL_FREQ_CHECK)
+ && has_target()) {
+ /* Are we running at unknown frequency ? */
+ ret = cpufreq_frequency_table_get_index(policy, policy->cur);
+ if (ret == -EINVAL) {
+ /* Warn user and fix it */
+ pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n",
+ __func__, policy->cpu, policy->cur);
+ ret = __cpufreq_driver_target(policy, policy->cur - 1,
+ CPUFREQ_RELATION_L);
+
+ /*
+ * Reaching here after boot in a few seconds may not
+ * mean that system will remain stable at "unknown"
+ * frequency for longer duration. Hence, a BUG_ON().
+ */
+ BUG_ON(ret);
+ pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n",
+ __func__, policy->cpu, policy->cur);
+ }
+ }
+
/* related cpus should atleast have policy->cpus */
cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 3458d27..a8ac042 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -178,7 +178,29 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
+int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
+ unsigned int freq)
+{
+ struct cpufreq_frequency_table *table;
+ int i;
+
+ table = cpufreq_frequency_get_table(policy->cpu);
+ if (unlikely(!table)) {
+ pr_debug("%s: Unable to find frequency table\n", __func__);
+ return -ENOENT;
+ }
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ if (table[i].frequency == freq)
+ return i;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index);
+
static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table);
+
/**
* show_available_freqs - show available frequencies for the specified CPU
*/
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index ee5fe9d..03174ab 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -252,6 +252,15 @@ struct cpufreq_driver {
*/
#define CPUFREQ_ASYNC_NOTIFICATION (1 << 4)
+/*
+ * Set by drivers which don't want cpufreq core to check if CPU is running at a
+ * frequency present in freq-table exposed by the driver. For other drivers if
+ * CPU is found running at an out of table freq, we will try to set it to a freq
+ * from the table. And if that fails, we will stop further boot process by
+ * issuing a BUG_ON().
+ */
+#define CPUFREQ_SKIP_INITIAL_FREQ_CHECK (1 << 5)
+
int cpufreq_register_driver(struct cpufreq_driver *driver_data);
int cpufreq_unregister_driver(struct cpufreq_driver *driver_data);
@@ -447,6 +456,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation,
unsigned int *index);
+int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
+ unsigned int freq);
void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy);
ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf);
--
1.7.12.rc2.18.g61b472e
From: Mark Brown <broonie(a)linaro.org>
Simple code reorganisation so we can change the logic for deciding what
full constraints are more easily.
Signed-off-by: Mark Brown <broonie(a)linaro.org>
---
drivers/regulator/core.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 3fe13130baec..02fdf925bb56 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -119,6 +119,11 @@ static const char *rdev_get_name(struct regulator_dev *rdev)
return "";
}
+static bool have_full_constraints(void)
+{
+ return has_full_constraints;
+}
+
/**
* of_get_regulator - get a regulator device node based on supply name
* @dev: Device pointer for the consumer (of regulator) device
@@ -1340,7 +1345,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
* Assume that a regulator is physically present and enabled
* even if it isn't hooked up and just provide a dummy.
*/
- if (has_full_constraints && allow_dummy) {
+ if (have_full_constraints() && allow_dummy) {
pr_warn("%s supply %s not found, using dummy regulator\n",
devname, id);
@@ -3627,7 +3632,7 @@ int regulator_suspend_finish(void)
if (error)
ret = error;
} else {
- if (!has_full_constraints)
+ if (!have_full_constraints())
goto unlock;
if (!ops->disable)
goto unlock;
@@ -3825,7 +3830,7 @@ static int __init regulator_init_complete(void)
if (!enabled)
goto unlock;
- if (has_full_constraints) {
+ if (have_full_constraints()) {
/* We log since this may kill the system if it
* goes wrong. */
rdev_info(rdev, "disabling\n");
--
1.8.4.4