aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch
diff options
context:
space:
mode:
authorIan Pozella <Ian.Pozella@imgtec.com>2017-02-15 09:05:24 +0000
committerFelix Fietkau <nbd@nbd.name>2017-03-22 11:43:22 +0100
commit52c17bff3c861dc28517303e535b880473a54498 (patch)
treeed706b19a6a8f37598f73bba9c5eefb567719482 /target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch
parent370d740647707f9caec915b5c1f5cb1a278b1d3b (diff)
downloadupstream-52c17bff3c861dc28517303e535b880473a54498.tar.gz
upstream-52c17bff3c861dc28517303e535b880473a54498.tar.bz2
upstream-52c17bff3c861dc28517303e535b880473a54498.zip
pistachio: add 4.9 kernel support
This adds kernel support for the Pistachio SoC and the Marduk (Ci40) board which uses it. Much of the code for Pistachio has been upstreamed however some patches are still required to boot from the Marduk board: * spi bug fixes * dma bug fixes * pistachio internal clock tree bug fixes * spi-nand implementation * dts based mtd device naming scheme * dts backports and bug fixes Signed-off-by: Abhijit Mahajani <Abhijit.Mahajani@imgtec.com> Signed-off-by: Francois Berder <francois.berder@imgtec.com> Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
Diffstat (limited to 'target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch')
-rw-r--r--target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch71
1 files changed, 71 insertions, 0 deletions
diff --git a/target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch b/target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch
new file mode 100644
index 0000000000..613584e33c
--- /dev/null
+++ b/target/linux/pistachio/patches-4.9/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch
@@ -0,0 +1,71 @@
+From b46f8c74afdd30cd52bfdcc2231470a0bab04416 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Fri, 22 Apr 2016 18:22:45 +0100
+Subject: clockevents: Retry programming min delta up to 10 times
+
+Under virtualisation it is possible to get unexpected latency during a
+clockevent device's set_next_event() callback which can make it return
+-ETIME even for a delta based on min_delta_ns.
+
+The clockevents_program_min_delta() implementation for
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=n doesn't handle retries when this
+happens, nor does clockevents_program_event() or its callers when force
+is true (for example hrtimer_reprogram()). This can result in hangs
+until the clock event device does a full period.
+
+It isn't appropriate to use MIN_ADJUST in this case as occasional
+hypervisor induced high latency will cause min_delta_ns to quickly
+increase to the maximum.
+Instead, borrow the retry pattern from the MIN_ADJUST case, but without
+making adjustments. We retry up to 10 times before giving up.
+
+(picked https://patchwork.kernel.org/patch/8909491/)
+
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+---
+ kernel/time/clockevents.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
+index 2c5bc77..ddd7e82 100644
+--- a/kernel/time/clockevents.c
++++ b/kernel/time/clockevents.c
+@@ -281,16 +281,28 @@ static int clockevents_program_min_delta(struct clock_event_device *dev)
+ {
+ unsigned long long clc;
+ int64_t delta;
++ int i;
+
+- delta = dev->min_delta_ns;
+- dev->next_event = ktime_add_ns(ktime_get(), delta);
++ for (i = 0;;) {
++ delta = dev->min_delta_ns;
++ dev->next_event = ktime_add_ns(ktime_get(), delta);
+
+- if (clockevent_state_shutdown(dev))
+- return 0;
++ if (clockevent_state_shutdown(dev))
++ return 0;
+
+- dev->retries++;
+- clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
+- return dev->set_next_event((unsigned long) clc, dev);
++ dev->retries++;
++ clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
++ if (dev->set_next_event((unsigned long) clc, dev) == 0)
++ return 0;
++
++ if (++i > 9) {
++ /*
++ * We tried 10 times to program the device with the
++ * given min_delta_ns. Get out of here.
++ */
++ return -ETIME;
++ }
++ }
+ }
+
+ #endif /* CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST */
+--
+2.7.4
+