From: Viresh Kumar <viresh.kumar(a)linaro.org>
This patch has been added to the 3.12 stable tree. If you have any
objections, please let us know.
===============
commit 84ea7fe37908254c3bd90910921f6e1045c1747a upstream.
switch_hrtimer_base() calls hrtimer_check_target() which ensures that
we do not migrate a timer to a remote cpu if the timer expires before
the current programmed expiry time on that remote cpu.
But __hrtimer_start_range_ns() calls switch_hrtimer_base() before the
new expiry time is set. So the sanity check in hrtimer_check_target()
is operating on stale or even uninitialized data.
Update expiry time before calling switch_hrtimer_base().
[ tglx: Rewrote changelog once again ]
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
Cc: linaro-kernel(a)lists.linaro.org
Cc: linaro-networking(a)linaro.org
Cc: fweisbec(a)gmail.com
Cc: arvind.chauhan(a)arm.com
Link: http://lkml.kernel.org/r/81999e148745fc51bbcd0615823fbab9b2e87e23.139988225…
Signed-off-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Jiri Slaby <jslaby(a)suse.cz>
---
kernel/hrtimer.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6de65d8a70e2..aa149222cd8e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1002,11 +1002,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
/* Remove an active timer from the queue: */
ret = remove_hrtimer(timer, base);
- /* Switch the timer base, if necessary: */
- new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
-
if (mode & HRTIMER_MODE_REL) {
- tim = ktime_add_safe(tim, new_base->get_time());
+ tim = ktime_add_safe(tim, base->get_time());
/*
* CONFIG_TIME_LOW_RES is a temporary way for architectures
* to signal that they simply return xtime in
@@ -1021,6 +1018,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
hrtimer_set_expires_range_ns(timer, tim, delta_ns);
+ /* Switch the timer base, if necessary: */
+ new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
+
timer_stats_hrtimer_set_start_info(timer);
leftmost = enqueue_hrtimer(timer, new_base);
--
1.9.3
Encapsulate the large portion of cpuidle_idle_call inside another
function so when CONFIG_CPU_IDLE=n, the code will be compiled out.
Also that is benefitial for the clarity of the code as it removes
a nested indentation level.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
kernel/sched/idle.c | 161 +++++++++++++++++++++++++++------------------------
1 file changed, 86 insertions(+), 75 deletions(-)
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index b8cd302..f2f4bc9 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -63,6 +63,90 @@ void __weak arch_cpu_idle(void)
local_irq_enable();
}
+#ifdef CONFIG_CPU_IDLE
+static int __cpuidle_idle_call(void)
+{
+ struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
+ struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+ int next_state, entered_state, ret;
+ bool broadcast;
+
+ /*
+ * Check if the cpuidle framework is ready, otherwise fallback
+ * to the default arch specific idle method
+ */
+ ret = cpuidle_enabled(drv, dev);
+ if (ret)
+ return ret;
+
+ /*
+ * Ask the governor to choose an idle state it thinks
+ * it is convenient to go to. There is *always* a
+ * convenient idle state
+ */
+ next_state = cpuidle_select(drv, dev);
+
+ /*
+ * The idle task must be scheduled, it is pointless to
+ * go to idle, just update no idle residency and get
+ * out of this function
+ */
+ if (current_clr_polling_and_test()) {
+ dev->last_residency = 0;
+ entered_state = next_state;
+ local_irq_enable();
+ } else {
+ broadcast = !!(drv->states[next_state].flags &
+ CPUIDLE_FLAG_TIMER_STOP);
+
+ if (broadcast)
+ /*
+ * Tell the time framework to switch to a
+ * broadcast timer because our local timer
+ * will be shutdown. If a local timer is used
+ * from another cpu as a broadcast timer, this
+ * call may fail if it is not available
+ */
+ ret = clockevents_notify(
+ CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
+ &dev->cpu);
+
+ if (!ret) {
+ trace_cpu_idle_rcuidle(next_state, dev->cpu);
+
+ /*
+ * Enter the idle state previously returned by
+ * the governor decision. This function will
+ * block until an interrupt occurs and will
+ * take care of re-enabling the local
+ * interrupts
+ */
+ entered_state = cpuidle_enter(drv, dev, next_state);
+
+ trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
+
+ if (broadcast)
+ clockevents_notify(
+ CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
+ &dev->cpu);
+
+ /*
+ * Give the governor an opportunity to reflect
+ * on the outcome
+ */
+ cpuidle_reflect(dev, entered_state);
+ }
+ }
+
+ return 0;
+}
+#else
+static int inline __cpuidle_idle_call(void)
+{
+ return -ENOSYS;
+}
+#endif
+
/**
* cpuidle_idle_call - the main idle function
*
@@ -70,10 +154,7 @@ void __weak arch_cpu_idle(void)
*/
static void cpuidle_idle_call(void)
{
- struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
- struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
- int next_state, entered_state, ret;
- bool broadcast;
+ int ret;
/*
* Check if the idle task must be rescheduled. If it is the
@@ -100,80 +181,10 @@ static void cpuidle_idle_call(void)
rcu_idle_enter();
/*
- * Check if the cpuidle framework is ready, otherwise fallback
- * to the default arch specific idle method
- */
- ret = cpuidle_enabled(drv, dev);
-
- if (!ret) {
- /*
- * Ask the governor to choose an idle state it thinks
- * it is convenient to go to. There is *always* a
- * convenient idle state
- */
- next_state = cpuidle_select(drv, dev);
-
- /*
- * The idle task must be scheduled, it is pointless to
- * go to idle, just update no idle residency and get
- * out of this function
- */
- if (current_clr_polling_and_test()) {
- dev->last_residency = 0;
- entered_state = next_state;
- local_irq_enable();
- } else {
- broadcast = !!(drv->states[next_state].flags &
- CPUIDLE_FLAG_TIMER_STOP);
-
- if (broadcast)
- /*
- * Tell the time framework to switch
- * to a broadcast timer because our
- * local timer will be shutdown. If a
- * local timer is used from another
- * cpu as a broadcast timer, this call
- * may fail if it is not available
- */
- ret = clockevents_notify(
- CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
- &dev->cpu);
-
- if (!ret) {
- trace_cpu_idle_rcuidle(next_state, dev->cpu);
-
- /*
- * Enter the idle state previously
- * returned by the governor
- * decision. This function will block
- * until an interrupt occurs and will
- * take care of re-enabling the local
- * interrupts
- */
- entered_state = cpuidle_enter(drv, dev,
- next_state);
-
- trace_cpu_idle_rcuidle(PWR_EVENT_EXIT,
- dev->cpu);
-
- if (broadcast)
- clockevents_notify(
- CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
- &dev->cpu);
-
- /*
- * Give the governor an opportunity to reflect on the
- * outcome
- */
- cpuidle_reflect(dev, entered_state);
- }
- }
- }
-
- /*
* We can't use the cpuidle framework, let's use the default
* idle routine
*/
+ ret = __cpuidle_idle_call();
if (ret)
arch_cpu_idle();
--
1.7.9.5
Douglas Anderson, recently pointed out an interesting problem due to which
udelay() was expiring earlier than it should.
While transitioning between frequencies few platforms may temporarily switch to
a stable frequency, waiting for the main PLL to stabilize.
For example: When we transition between very low frequencies on exynos, like
between 200MHz and 300MHz, we may temporarily switch to a PLL running at 800MHz.
No CPUFREQ notification is sent for that. That means there's a period of time
when we're running at 800MHz but loops_per_jiffy is calibrated at between 200MHz
and 300MHz. And so udelay behaves badly.
To get this fixed in a generic way, lets introduce another set of callbacks
get_intermediate() and target_intermediate(), only for drivers with
target_index() and CPUFREQ_ASYNC_NOTIFICATION unset.
get_intermediate() should return a stable intermediate frequency platform wants
to switch to, and target_intermediate() should set CPU to to that frequency,
before jumping to the frequency corresponding to 'index'. Core will take care of
sending notifications and driver doesn't have to handle them in
target_intermediate() or target_index().
This patchset also update Tegra to use this new infrastructure and is already
tested by Stephen.
V4->V5:
- Moved setting old frequency to __target_index() from __target_intermediate()
- Replaced retval with 0 during call to cpufreq_freq_transition_end() for
restoring to restored freq.
- Fix important issues with Tegra driver as reported by Stephen.
- Dropped patch 1, already applied: "cpufreq: handle calls to ->target_index()
in separate routine"
V3->V4:
- Allow get_intermediate() to return zero when we don't need to switch to
intermediate first
- Get rid of 'goto' and create another routine for handling intermediate freqs
- Allow target_index() to fail, its not a crime :)
- Fix tegra driver to return zero from get_intermediate() for few situations
(refer to patch 3/4)
- Fix issues with tegra's patch, like s/rate/rate * 1000
- Overall there are more modifications that what Doug requested as I felt we
need better support from core.
- Looks much better now, thanks Doug :)
V2-V3:
- Fix spelling error: s/Uset/Used
- Update tegra with the changes Stephen suggested
- Include a dependency patch sent separately earlier (3/4)
V1-V2: Almost changed completely, V1 was here: https://lkml.org/lkml/2014/5/15/40
Viresh Kumar (2):
cpufreq: add support for intermediate (stable) frequencies
cpufreq: Tegra: implement intermediate frequency callbacks
Documentation/cpu-freq/cpu-drivers.txt | 29 +++++++++-
drivers/cpufreq/cpufreq.c | 67 ++++++++++++++++++++---
drivers/cpufreq/tegra-cpufreq.c | 97 ++++++++++++++++++++++------------
include/linux/cpufreq.h | 25 +++++++++
4 files changed, 174 insertions(+), 44 deletions(-)
--
2.0.0.rc2
Hi Alexandru,
No, I'm afraid not that stable but this one:
https://git.linaro.org/kernel/linux-linaro-tracking.git
There is a wiki page for that Linaro Kernel tree process:
https://wiki.linaro.org/Platform/DevPlatform/LinuxLinaroKernelTreeProcess
I added Andrey Konovalov to CC list since he currently is the maintainer of
linux-linaro kernel and hopefully can provide you more information.
Thanks.
On 6 June 2014 00:17, Alexandru Rosca <srosca(a)bu.edu> wrote:
> Hi Botao,
>
> Thanks for your help. I am using Ubuntu trusty 14.05. When I type uname -a
> I get Linux linaro 3.15.0-1 arndale. However the latest version on that
> link seems to be 3.1. Should I use the one in linux-linaro-stable.git?
>
> Cheers
>
>
> On Thu, Jun 5, 2014 at 10:11 AM, Botao Sun <botao.sun(a)linaro.org> wrote:
>
>> Hi Alexandru,
>>
>> Here is the Linaro Kernel git repository list:
>>
>> https://git.linaro.org/?a=project_list;pf=kernel
>>
>> And which platform are you working on? Android or ubuntu? I ask because
>> the Kernel version on Android is the old one: 3.9.1
>>
>> FYI.
>>
>>
>>
>> On 5 June 2014 23:56, Alexandru Rosca <srosca(a)bu.edu> wrote:
>>
>>> Hi Botao,
>>>
>>> The instructions online for building and deploying a linux kernel seems
>>> to be for version 3.1. I am using the latest arndale OS from the linaro
>>> releases and would like to know which source code you suggest I compile
>>> with the config file.
>>>
>>> Cheers,
>>> Alex
>>>
>>>
>>> On Thu, Jun 5, 2014 at 9:47 AM, Botao Sun <botao.sun(a)linaro.org> wrote:
>>>
>>>> + Linaro Kernel and Samsung Landing Team
>>>>
>>>> Hi Alexandru,
>>>>
>>>> As I know for the Linux mainline Kernel, we can run make menuconfig
>>>> then search the keyword by typing "/" and USB_SERIAL.
>>>>
>>>> Since we already have Linaro Samsung Arndale Kernel config file, then
>>>> it would be better to use this file and modify USB_SERIAL related items
>>>> later:
>>>>
>>>>
>>>> https://www.kernel.org/doc/index-old.html#Using_an_existing_configuration
>>>>
>>>> FYI.
>>>>
>>>> Thanks.
>>>>
>>>>
>>>> Best Regards
>>>> Botao Sun
>>>>
>>>>
>>>> On 5 June 2014 07:11, Alexandru Rosca <srosca(a)bu.edu> wrote:
>>>>
>>>>> Dear Botao Sun,
>>>>>
>>>>> I have an arndale board for which I would like to communicate with
>>>>> serially via an FTDI and some microcontrollers. It seems that the linaro
>>>>> kernel does not support this. I was thinking of compiling a kernel with the
>>>>> USB SERIAL config option set. Could you advise me on how to do this? Can I
>>>>> just use the config file for the arndale and modify it for compilation?
>>>>>
>>>>> Thank you,
>>>>> Sasha
>>>>>
>>>>
>>>>
>>>
>>
>
When a timer is enqueued or modified on a NO_HZ_FULL target (local or remote),
the target is expected to re-evaluate its timer wheel to decide if tick must be
restarted to handle timer expirations.
If it doesn't re-evaluate timer wheel and restart tick, it wouldn't be able to
call timer's handler on its expiration. It would be delayed until the time tick
is restarted again. Currently the max delay can be 1 second as returned by
scheduler_tick_max_deferment(), but it can increase in future.
To handle this, currently we are calling wake_up_nohz_cpu() from add_timer_on()
but what about timers enqueued/modified with other APIs?
For example, in __mod_timer() we get target cpu (where the timer should
get enqueued) by calling get_nohz_timer_target() and it is free to return a
NO_HZ_FULL cpu as well. So, we *should* re-evaluate timer wheel there as well,
otherwise call to timer's handler might be delayed as explained earlier.
In order to fix this issue we can move wake_up_nohz_cpu(cpu) to
internal_add_timer() so that it is well handled for any add-timer API.
LKML discussion about this: https://lkml.org/lkml/2014/6/4/169
This requires internal_add_timer() to get cpu number from per-cpu object 'base',
as all the callers might not have cpu number to pass to internal_add_timer().
For example, in __mod_timer() we find timer's base from 'timer' pointer and not
from per-cpu arithmetic.
Thus, this patch adds another field 'cpu' in 'struct tvec_base' which will store
cpu number of the cpu it belongs to.
Next patch will then move wake_up_nohz_cpu() to internal_add_timer().
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
kernel/timer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/timer.c b/kernel/timer.c
index 3bb01a3..9e5f4f2 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -82,6 +82,7 @@ struct tvec_base {
unsigned long next_timer;
unsigned long active_timers;
unsigned long all_timers;
+ int cpu;
struct tvec_root tv1;
struct tvec tv2;
struct tvec tv3;
@@ -1568,6 +1569,7 @@ static int init_timers_cpu(int cpu)
}
spin_lock_init(&base->lock);
tvec_base_done[cpu] = 1;
+ base->cpu = cpu;
} else {
base = per_cpu(tvec_bases, cpu);
}
--
2.0.0.rc2
Hi Alexandru,
Here is the Linaro Kernel git repository list:
https://git.linaro.org/?a=project_list;pf=kernel
And which platform are you working on? Android or ubuntu? I ask because the
Kernel version on Android is the old one: 3.9.1
FYI.
On 5 June 2014 23:56, Alexandru Rosca <srosca(a)bu.edu> wrote:
> Hi Botao,
>
> The instructions online for building and deploying a linux kernel seems to
> be for version 3.1. I am using the latest arndale OS from the linaro
> releases and would like to know which source code you suggest I compile
> with the config file.
>
> Cheers,
> Alex
>
>
> On Thu, Jun 5, 2014 at 9:47 AM, Botao Sun <botao.sun(a)linaro.org> wrote:
>
>> + Linaro Kernel and Samsung Landing Team
>>
>> Hi Alexandru,
>>
>> As I know for the Linux mainline Kernel, we can run make menuconfig then
>> search the keyword by typing "/" and USB_SERIAL.
>>
>> Since we already have Linaro Samsung Arndale Kernel config file, then it
>> would be better to use this file and modify USB_SERIAL related items later:
>>
>> https://www.kernel.org/doc/index-old.html#Using_an_existing_configuration
>>
>> FYI.
>>
>> Thanks.
>>
>>
>> Best Regards
>> Botao Sun
>>
>>
>> On 5 June 2014 07:11, Alexandru Rosca <srosca(a)bu.edu> wrote:
>>
>>> Dear Botao Sun,
>>>
>>> I have an arndale board for which I would like to communicate with
>>> serially via an FTDI and some microcontrollers. It seems that the linaro
>>> kernel does not support this. I was thinking of compiling a kernel with the
>>> USB SERIAL config option set. Could you advise me on how to do this? Can I
>>> just use the config file for the arndale and modify it for compilation?
>>>
>>> Thank you,
>>> Sasha
>>>
>>
>>
>
+ Linaro Kernel and Samsung Landing Team
Hi Alexandru,
As I know for the Linux mainline Kernel, we can run make menuconfig then
search the keyword by typing "/" and USB_SERIAL.
Since we already have Linaro Samsung Arndale Kernel config file, then it
would be better to use this file and modify USB_SERIAL related items later:
https://www.kernel.org/doc/index-old.html#Using_an_existing_configuration
FYI.
Thanks.
Best Regards
Botao Sun
On 5 June 2014 07:11, Alexandru Rosca <srosca(a)bu.edu> wrote:
> Dear Botao Sun,
>
> I have an arndale board for which I would like to communicate with
> serially via an FTDI and some microcontrollers. It seems that the linaro
> kernel does not support this. I was thinking of compiling a kernel with the
> USB SERIAL config option set. Could you advise me on how to do this? Can I
> just use the config file for the arndale and modify it for compilation?
>
> Thank you,
> Sasha
>