diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2018-11-09 15:16:00 +0100 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2018-11-09 15:16:00 +0100 |
commit | 8b797da8ae7a1073d4626f41ac28cf25c1ad8a5c (patch) | |
tree | f2aeef6fd7294f19e558c8d462db303e1752bf7a | |
parent | d4327fbfc7d1ecc962c4450db3e6e3fdbea71717 (diff) | |
download | linux-rt-8b797da8ae7a1073d4626f41ac28cf25c1ad8a5c.tar.gz |
[ANNOUNCE] v4.19.1-rt3v4.19.1-rt3-patches
Dear RT folks!
I'm pleased to announce the v4.19.1-rt3 patch set.
Changes since v4.19.1-rt2:
- A patch to the bcm2835 pinctrl driver to use raw_spinlock_t. Patch
by Lukas Wunner.
- The Atmel TCB timer patch set by Alexandre Belloni has been update
to v7.
- The RCU Kconfig entry has been tweaked and now it is no longer
required to enable RCU_EXPERT in order to enable RCU_BOOST.
Suggested by Paul E. McKenney.
- The crypto caam driver did not compile. Patch by Horia Geantă.
- The kbuild test robot complained about various patches because they
did not compile and so hurt bisectibility. As a result a few patches
and hunks have been moved to avoid that.
Known issues
- A warning triggered in "rcu_note_context_switch" originated from
SyS_timer_gettime(). The issue was always there, it is now
visible. Reported by Grygorii Strashko and Daniel Wagner.
The delta patch against v4.19.1-rt2 is appended below and can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.19/incr/patch-4.19.1-rt2-rt3.patch.xz
You can get this release via the git tree at:
git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.19.1-rt3
The RT patch against v4.19.1 can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patch-4.19.1-rt3.patch.xz
The split quilt queue is available at:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.1-rt3.tar.xz
Sebastian
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
28 files changed, 666 insertions, 372 deletions
diff --git a/patches/0001-ARM-at91-add-TCB-registers-definitions.patch b/patches/0001-ARM-at91-add-TCB-registers-definitions.patch index 2a0bf2141bd6..547035daccad 100644 --- a/patches/0001-ARM-at91-add-TCB-registers-definitions.patch +++ b/patches/0001-ARM-at91-add-TCB-registers-definitions.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:38 +0200 -Subject: [PATCH 1/6] ARM: at91: add TCB registers definitions +Date: Thu, 13 Sep 2018 13:30:18 +0200 +Subject: [PATCH 1/7] ARM: at91: add TCB registers definitions Add registers and bits definitions for the timer counter blocks found on Atmel ARM SoCs. @@ -10,14 +10,14 @@ Tested-by: Andras Szemzo <szemzo.andras@gmail.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/soc/at91/atmel_tcb.h | 216 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 216 insertions(+) + include/soc/at91/atmel_tcb.h | 183 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 183 insertions(+) create mode 100644 include/soc/at91/atmel_tcb.h --- /dev/null +++ b/include/soc/at91/atmel_tcb.h -@@ -0,0 +1,216 @@ -+// SPDX-License-Identifier: GPL-2.0 +@@ -0,0 +1,183 @@ ++//SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2018 Microchip */ + +#ifndef __SOC_ATMEL_TCB_H @@ -185,48 +185,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#define ATMEL_TC_WPMR_WPKEY (0x54494d << 8) +#define ATMEL_TC_WPMR_WPEN BIT(0) + -+static inline struct clk *tcb_clk_get(struct device_node *node, int channel) -+{ -+ struct clk *clk; -+ char clk_name[] = "t0_clk"; -+ -+ clk_name[1] += channel; -+ clk = of_clk_get_by_name(node->parent, clk_name); -+ if (!IS_ERR(clk)) -+ return clk; -+ -+ return of_clk_get_by_name(node->parent, "t0_clk"); -+} -+ -+static inline int tcb_irq_get(struct device_node *node, int channel) -+{ -+ int irq; -+ -+ irq = of_irq_get(node->parent, channel); -+ if (irq > 0) -+ return irq; -+ -+ return of_irq_get(node->parent, 0); -+} -+ +static const u8 atmel_tc_divisors[5] = { 2, 8, 32, 128, 0, }; + -+struct atmel_tcb_info { -+ int bits; -+}; -+ -+static const struct atmel_tcb_info atmel_tcb_infos[] = { -+ { .bits = 16 }, -+ { .bits = 32 }, -+}; -+ +static const struct of_device_id atmel_tcb_dt_ids[] = { + { + .compatible = "atmel,at91rm9200-tcb", -+ .data = &atmel_tcb_infos[0], ++ .data = (void *)16, + }, { + .compatible = "atmel,at91sam9x5-tcb", -+ .data = &atmel_tcb_infos[1], ++ .data = (void *)32, + }, { + /* sentinel */ + } diff --git a/patches/0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch b/patches/0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch index 0062c79059d7..c0d7124dd59f 100644 --- a/patches/0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch +++ b/patches/0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:39 +0200 -Subject: [PATCH 2/6] clocksource/drivers: Add a new driver for the Atmel ARM +Date: Thu, 13 Sep 2018 13:30:19 +0200 +Subject: [PATCH 2/7] clocksource/drivers: Add a new driver for the Atmel ARM TC blocks Add a driver for the Atmel Timer Counter Blocks. This driver provides a @@ -25,8 +25,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/clocksource/Kconfig | 8 drivers/clocksource/Makefile | 3 - drivers/clocksource/timer-atmel-tcb.c | 608 ++++++++++++++++++++++++++++++++++ - 3 files changed, 618 insertions(+), 1 deletion(-) + drivers/clocksource/timer-atmel-tcb.c | 410 ++++++++++++++++++++++++++++++++++ + 3 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 drivers/clocksource/timer-atmel-tcb.c --- a/drivers/clocksource/Kconfig @@ -60,7 +60,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o --- /dev/null +++ b/drivers/clocksource/timer-atmel-tcb.c -@@ -0,0 +1,608 @@ +@@ -0,0 +1,410 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/clk.h> +#include <linux/clockchips.h> @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#include <linux/sched_clock.h> +#include <soc/at91/atmel_tcb.h> + -+static struct atmel_tcb_clksrc { ++struct atmel_tcb_clksrc { + struct clocksource clksrc; + struct clock_event_device clkevt; + struct regmap *regmap; @@ -92,216 +92,22 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + } cache[2]; + u32 bmr_cache; + bool registered; -+} tc = { -+ .clksrc = { -+ .rating = 200, -+ .mask = CLOCKSOURCE_MASK(32), -+ .flags = CLOCK_SOURCE_IS_CONTINUOUS, -+ }, -+ .clkevt = { -+ .features = CLOCK_EVT_FEAT_ONESHOT, -+ /* Should be lower than at91rm9200's system timer */ -+ .rating = 125, -+ }, ++ bool clk_enabled; +}; + -+static struct tc_clkevt_device { -+ struct clock_event_device clkevt; -+ struct regmap *regmap; -+ void __iomem *base; -+ struct clk *slow_clk; -+ struct clk *clk; -+ char name[20]; -+ int channel; -+ int irq; -+ struct { -+ u32 cmr; -+ u32 imr; -+ u32 rc; -+ bool clken; -+ } cache; -+ bool registered; -+} tce = { -+ .clkevt = { -+ .features = CLOCK_EVT_FEAT_PERIODIC | -+ CLOCK_EVT_FEAT_ONESHOT, -+ /* -+ * Should be lower than at91rm9200's system timer -+ * but higher than tc.clkevt.rating -+ */ -+ .rating = 140, -+ }, -+}; -+ -+/* -+ * Clockevent device using its own channel -+ */ -+static int tc_clkevt2_shutdown(struct clock_event_device *d) -+{ -+ writel(0xff, tce.base + ATMEL_TC_IDR(tce.channel)); -+ writel(ATMEL_TC_CCR_CLKDIS, tce.base + ATMEL_TC_CCR(tce.channel)); -+ if (!clockevent_state_detached(d)) -+ clk_disable(tce.clk); -+ -+ return 0; -+} -+ -+/* For now, we always use the 32K clock ... this optimizes for NO_HZ, -+ * because using one of the divided clocks would usually mean the -+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz). -+ * -+ * A divided clock could be good for high resolution timers, since -+ * 30.5 usec resolution can seem "low". -+ */ -+static int tc_clkevt2_set_oneshot(struct clock_event_device *d) -+{ -+ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) -+ tc_clkevt2_shutdown(d); -+ -+ clk_enable(tce.clk); -+ -+ /* slow clock, count up to RC, then irq and stop */ -+ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_CPCSTOP | -+ ATMEL_TC_CMR_WAVE | ATMEL_TC_CMR_WAVESEL_UPRC, -+ tce.base + ATMEL_TC_CMR(tce.channel)); -+ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channel)); -+ -+ return 0; -+} ++static struct atmel_tcb_clksrc tc; + -+static int tc_clkevt2_set_periodic(struct clock_event_device *d) -+{ -+ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) -+ tc_clkevt2_shutdown(d); -+ -+ /* By not making the gentime core emulate periodic mode on top -+ * of oneshot, we get lower overhead and improved accuracy. -+ */ -+ clk_enable(tce.clk); -+ -+ /* slow clock, count up to RC, then irq and restart */ -+ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_WAVE | -+ ATMEL_TC_CMR_WAVESEL_UPRC, -+ tce.base + ATMEL_TC_CMR(tce.channel)); -+ writel((32768 + HZ / 2) / HZ, tce.base + ATMEL_TC_RC(tce.channel)); -+ -+ /* Enable clock and interrupts on RC compare */ -+ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channel)); -+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, -+ tce.base + ATMEL_TC_CCR(tce.channel)); -+ -+ return 0; -+} -+ -+static int tc_clkevt2_next_event(unsigned long delta, -+ struct clock_event_device *d) ++static struct clk *tcb_clk_get(struct device_node *node, int channel) +{ -+ writel(delta, tce.base + ATMEL_TC_RC(tce.channel)); -+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, -+ tce.base + ATMEL_TC_CCR(tce.channel)); -+ -+ return 0; -+} -+ -+static irqreturn_t tc_clkevt2_irq(int irq, void *handle) -+{ -+ unsigned int sr; -+ -+ sr = readl(tce.base + ATMEL_TC_SR(tce.channel)); -+ if (sr & ATMEL_TC_CPCS) { -+ tce.clkevt.event_handler(&tce.clkevt); -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static void tc_clkevt2_suspend(struct clock_event_device *d) -+{ -+ tce.cache.cmr = readl(tce.base + ATMEL_TC_CMR(tce.channel)); -+ tce.cache.imr = readl(tce.base + ATMEL_TC_IMR(tce.channel)); -+ tce.cache.rc = readl(tce.base + ATMEL_TC_RC(tce.channel)); -+ tce.cache.clken = !!(readl(tce.base + ATMEL_TC_SR(tce.channel)) & -+ ATMEL_TC_CLKSTA); -+} -+ -+static void tc_clkevt2_resume(struct clock_event_device *d) -+{ -+ /* Restore registers for the channel, RA and RB are not used */ -+ writel(tce.cache.cmr, tc.base + ATMEL_TC_CMR(tce.channel)); -+ writel(tce.cache.rc, tc.base + ATMEL_TC_RC(tce.channel)); -+ writel(0, tc.base + ATMEL_TC_RA(tce.channel)); -+ writel(0, tc.base + ATMEL_TC_RB(tce.channel)); -+ /* Disable all the interrupts */ -+ writel(0xff, tc.base + ATMEL_TC_IDR(tce.channel)); -+ /* Reenable interrupts that were enabled before suspending */ -+ writel(tce.cache.imr, tc.base + ATMEL_TC_IER(tce.channel)); -+ -+ /* Start the clock if it was used */ -+ if (tce.cache.clken) -+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, -+ tc.base + ATMEL_TC_CCR(tce.channel)); -+} -+ -+static int __init tc_clkevt_register(struct device_node *node, -+ struct regmap *regmap, void __iomem *base, -+ int channel, int irq, int bits) -+{ -+ int ret; -+ -+ tce.regmap = regmap; -+ tce.base = base; -+ tce.channel = channel; -+ tce.irq = irq; -+ -+ tce.slow_clk = of_clk_get_by_name(node->parent, "slow_clk"); -+ if (IS_ERR(tce.slow_clk)) -+ return PTR_ERR(tce.slow_clk); -+ -+ ret = clk_prepare_enable(tce.slow_clk); -+ if (ret) -+ return ret; -+ -+ tce.clk = tcb_clk_get(node, tce.channel); -+ if (IS_ERR(tce.clk)) { -+ ret = PTR_ERR(tce.clk); -+ goto err_slow; -+ } -+ -+ snprintf(tce.name, sizeof(tce.name), "%s:%d", -+ kbasename(node->parent->full_name), channel); -+ tce.clkevt.cpumask = cpumask_of(0); -+ tce.clkevt.name = tce.name; -+ tce.clkevt.set_next_event = tc_clkevt2_next_event, -+ tce.clkevt.set_state_shutdown = tc_clkevt2_shutdown, -+ tce.clkevt.set_state_periodic = tc_clkevt2_set_periodic, -+ tce.clkevt.set_state_oneshot = tc_clkevt2_set_oneshot, -+ tce.clkevt.suspend = tc_clkevt2_suspend, -+ tce.clkevt.resume = tc_clkevt2_resume, -+ -+ /* try to enable clk to avoid future errors in mode change */ -+ ret = clk_prepare_enable(tce.clk); -+ if (ret) -+ goto err_slow; -+ clk_disable(tce.clk); -+ -+ clockevents_config_and_register(&tce.clkevt, 32768, 1, BIT(bits) - 1); -+ -+ ret = request_irq(tce.irq, tc_clkevt2_irq, IRQF_TIMER | IRQF_SHARED, -+ tce.clkevt.name, &tce); -+ if (ret) -+ goto err_clk; -+ -+ tce.registered = true; -+ -+ return 0; ++ struct clk *clk; ++ char clk_name[] = "t0_clk"; + -+err_clk: -+ clk_unprepare(tce.clk); -+err_slow: -+ clk_disable_unprepare(tce.slow_clk); ++ clk_name[1] += channel; ++ clk = of_clk_get_by_name(node->parent, clk_name); ++ if (!IS_ERR(clk)) ++ return clk; + -+ return ret; ++ return of_clk_get_by_name(node->parent, "t0_clk"); +} + +/* @@ -339,7 +145,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +{ + u32 old, next, cur; + -+ + old = readl(tc.base + ATMEL_TC_CV(tc.channels[0])); + next = old + delta; + writel(next, tc.base + ATMEL_TC_RC(tc.channels[0])); @@ -566,6 +371,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + tc.clksrc.name = tc.name; + tc.clksrc.suspend = tc_clksrc_suspend; + tc.clksrc.resume = tc_clksrc_resume; ++ tc.clksrc.rating = 200; ++ tc.clksrc.mask = CLOCKSOURCE_MASK(32); ++ tc.clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; + + err = clocksource_register_hz(&tc.clksrc, divided_rate); + if (err) @@ -581,6 +389,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + tc.clkevt.set_next_event = tcb_clkevt_next_event; + tc.clkevt.set_state_oneshot = tcb_clkevt_oneshot; + tc.clkevt.set_state_shutdown = tcb_clkevt_shutdown; ++ tc.clkevt.features = CLOCK_EVT_FEAT_ONESHOT; ++ tc.clkevt.rating = 125; ++ + clockevents_config_and_register(&tc.clkevt, divided_rate, 1, + BIT(tc.bits) - 1); + @@ -609,13 +420,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +static int __init tcb_clksrc_init(struct device_node *node) +{ + const struct of_device_id *match; -+ const struct atmel_tcb_info *tcb_info; + struct regmap *regmap; + void __iomem *tcb_base; + u32 channel; -+ int bits, irq, err, chan1 = -1; ++ int irq, err, chan1 = -1; ++ unsigned bits; + -+ if (tc.registered && tce.registered) ++ if (tc.registered) + return -ENODEV; + + /* @@ -634,38 +445,29 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + } + + match = of_match_node(atmel_tcb_dt_ids, node->parent); -+ tcb_info = match->data; -+ bits = tcb_info->bits; ++ bits = (uintptr_t)match->data; + + err = of_property_read_u32_index(node, "reg", 0, &channel); + if (err) + return err; + -+ irq = tcb_irq_get(node, channel); -+ if (irq < 0) -+ return irq; -+ -+ if (tc.registered) -+ return tc_clkevt_register(node, regmap, tcb_base, channel, irq, -+ bits); ++ irq = of_irq_get(node->parent, channel); ++ if (irq < 0) { ++ irq = of_irq_get(node->parent, 0); ++ if (irq < 0) ++ return irq; ++ } + + if (bits == 16) { + of_property_read_u32_index(node, "reg", 1, &chan1); + if (chan1 == -1) { -+ if (tce.registered) { -+ pr_err("%s: clocksource needs two channels\n", -+ node->parent->full_name); -+ return -EINVAL; -+ } else { -+ return tc_clkevt_register(node, regmap, -+ tcb_base, channel, -+ irq, bits); -+ } ++ pr_err("%s: clocksource needs two channels\n", ++ node->parent->full_name); ++ return -EINVAL; + } + } + + return tcb_clksrc_register(node, regmap, tcb_base, channel, chan1, irq, + bits); +} -+CLOCKSOURCE_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer", -+ tcb_clksrc_init); ++TIMER_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer", tcb_clksrc_init); diff --git a/patches/0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch b/patches/0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch new file mode 100644 index 000000000000..698988cbd0ba --- /dev/null +++ b/patches/0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch @@ -0,0 +1,264 @@ +From: Alexandre Belloni <alexandre.belloni@bootlin.com> +Date: Thu, 13 Sep 2018 13:30:20 +0200 +Subject: [PATCH 3/7] clocksource/drivers: timer-atmel-tcb: add clockevent + device on separate channel + +Add an other clockevent device that uses a separate TCB channel when +available. + +Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/clocksource/timer-atmel-tcb.c | 217 +++++++++++++++++++++++++++++++++- + 1 file changed, 212 insertions(+), 5 deletions(-) + +--- a/drivers/clocksource/timer-atmel-tcb.c ++++ b/drivers/clocksource/timer-atmel-tcb.c +@@ -32,7 +32,7 @@ struct atmel_tcb_clksrc { + bool clk_enabled; + }; + +-static struct atmel_tcb_clksrc tc; ++static struct atmel_tcb_clksrc tc, tce; + + static struct clk *tcb_clk_get(struct device_node *node, int channel) + { +@@ -48,6 +48,203 @@ static struct clk *tcb_clk_get(struct de + } + + /* ++ * Clockevent device using its own channel ++ */ ++ ++static void tc_clkevt2_clk_disable(struct clock_event_device *d) ++{ ++ clk_disable(tce.clk[0]); ++ tce.clk_enabled = false; ++} ++ ++static void tc_clkevt2_clk_enable(struct clock_event_device *d) ++{ ++ if (tce.clk_enabled) ++ return; ++ clk_enable(tce.clk[0]); ++ tce.clk_enabled = true; ++} ++ ++static int tc_clkevt2_stop(struct clock_event_device *d) ++{ ++ writel(0xff, tce.base + ATMEL_TC_IDR(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKDIS, tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_shutdown(struct clock_event_device *d) ++{ ++ tc_clkevt2_stop(d); ++ if (!clockevent_state_detached(d)) ++ tc_clkevt2_clk_disable(d); ++ ++ return 0; ++} ++ ++/* For now, we always use the 32K clock ... this optimizes for NO_HZ, ++ * because using one of the divided clocks would usually mean the ++ * tick rate can never be less than several dozen Hz (vs 0.5 Hz). ++ * ++ * A divided clock could be good for high resolution timers, since ++ * 30.5 usec resolution can seem "low". ++ */ ++static int tc_clkevt2_set_oneshot(struct clock_event_device *d) ++{ ++ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) ++ tc_clkevt2_stop(d); ++ ++ tc_clkevt2_clk_enable(d); ++ ++ /* slow clock, count up to RC, then irq and stop */ ++ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_CPCSTOP | ++ ATMEL_TC_CMR_WAVE | ATMEL_TC_CMR_WAVESEL_UPRC, ++ tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_set_periodic(struct clock_event_device *d) ++{ ++ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) ++ tc_clkevt2_stop(d); ++ ++ /* By not making the gentime core emulate periodic mode on top ++ * of oneshot, we get lower overhead and improved accuracy. ++ */ ++ tc_clkevt2_clk_enable(d); ++ ++ /* slow clock, count up to RC, then irq and restart */ ++ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_WAVE | ++ ATMEL_TC_CMR_WAVESEL_UPRC, ++ tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel((32768 + HZ / 2) / HZ, tce.base + ATMEL_TC_RC(tce.channels[0])); ++ ++ /* Enable clock and interrupts on RC compare */ ++ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static int tc_clkevt2_next_event(unsigned long delta, ++ struct clock_event_device *d) ++{ ++ writel(delta, tce.base + ATMEL_TC_RC(tce.channels[0])); ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tce.base + ATMEL_TC_CCR(tce.channels[0])); ++ ++ return 0; ++} ++ ++static irqreturn_t tc_clkevt2_irq(int irq, void *handle) ++{ ++ unsigned int sr; ++ ++ sr = readl(tce.base + ATMEL_TC_SR(tce.channels[0])); ++ if (sr & ATMEL_TC_CPCS) { ++ tce.clkevt.event_handler(&tce.clkevt); ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++static void tc_clkevt2_suspend(struct clock_event_device *d) ++{ ++ tce.cache[0].cmr = readl(tce.base + ATMEL_TC_CMR(tce.channels[0])); ++ tce.cache[0].imr = readl(tce.base + ATMEL_TC_IMR(tce.channels[0])); ++ tce.cache[0].rc = readl(tce.base + ATMEL_TC_RC(tce.channels[0])); ++ tce.cache[0].clken = !!(readl(tce.base + ATMEL_TC_SR(tce.channels[0])) & ++ ATMEL_TC_CLKSTA); ++} ++ ++static void tc_clkevt2_resume(struct clock_event_device *d) ++{ ++ /* Restore registers for the channel, RA and RB are not used */ ++ writel(tce.cache[0].cmr, tc.base + ATMEL_TC_CMR(tce.channels[0])); ++ writel(tce.cache[0].rc, tc.base + ATMEL_TC_RC(tce.channels[0])); ++ writel(0, tc.base + ATMEL_TC_RA(tce.channels[0])); ++ writel(0, tc.base + ATMEL_TC_RB(tce.channels[0])); ++ /* Disable all the interrupts */ ++ writel(0xff, tc.base + ATMEL_TC_IDR(tce.channels[0])); ++ /* Reenable interrupts that were enabled before suspending */ ++ writel(tce.cache[0].imr, tc.base + ATMEL_TC_IER(tce.channels[0])); ++ ++ /* Start the clock if it was used */ ++ if (tce.cache[0].clken) ++ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG, ++ tc.base + ATMEL_TC_CCR(tce.channels[0])); ++} ++ ++static int __init tc_clkevt_register(struct device_node *node, ++ struct regmap *regmap, void __iomem *base, ++ int channel, int irq, int bits) ++{ ++ int ret; ++ struct clk *slow_clk; ++ ++ tce.regmap = regmap; ++ tce.base = base; ++ tce.channels[0] = channel; ++ tce.irq = irq; ++ ++ slow_clk = of_clk_get_by_name(node->parent, "slow_clk"); ++ if (IS_ERR(slow_clk)) ++ return PTR_ERR(slow_clk); ++ ++ ret = clk_prepare_enable(slow_clk); ++ if (ret) ++ return ret; ++ ++ tce.clk[0] = tcb_clk_get(node, tce.channels[0]); ++ if (IS_ERR(tce.clk[0])) { ++ ret = PTR_ERR(tce.clk[0]); ++ goto err_slow; ++ } ++ ++ snprintf(tce.name, sizeof(tce.name), "%s:%d", ++ kbasename(node->parent->full_name), channel); ++ tce.clkevt.cpumask = cpumask_of(0); ++ tce.clkevt.name = tce.name; ++ tce.clkevt.set_next_event = tc_clkevt2_next_event, ++ tce.clkevt.set_state_shutdown = tc_clkevt2_shutdown, ++ tce.clkevt.set_state_periodic = tc_clkevt2_set_periodic, ++ tce.clkevt.set_state_oneshot = tc_clkevt2_set_oneshot, ++ tce.clkevt.suspend = tc_clkevt2_suspend, ++ tce.clkevt.resume = tc_clkevt2_resume, ++ tce.clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; ++ tce.clkevt.rating = 140; ++ ++ /* try to enable clk to avoid future errors in mode change */ ++ ret = clk_prepare_enable(tce.clk[0]); ++ if (ret) ++ goto err_slow; ++ clk_disable(tce.clk[0]); ++ ++ clockevents_config_and_register(&tce.clkevt, 32768, 1, ++ CLOCKSOURCE_MASK(bits)); ++ ++ ret = request_irq(tce.irq, tc_clkevt2_irq, IRQF_TIMER | IRQF_SHARED, ++ tce.clkevt.name, &tce); ++ if (ret) ++ goto err_clk; ++ ++ tce.registered = true; ++ ++ return 0; ++ ++err_clk: ++ clk_unprepare(tce.clk[0]); ++err_slow: ++ clk_disable_unprepare(slow_clk); ++ ++ return ret; ++} ++ ++/* + * Clocksource and clockevent using the same channel(s) + */ + static u64 tc_get_cycles(struct clocksource *cs) +@@ -363,7 +560,7 @@ static int __init tcb_clksrc_init(struct + int irq, err, chan1 = -1; + unsigned bits; + +- if (tc.registered) ++ if (tc.registered && tce.registered) + return -ENODEV; + + /* +@@ -395,12 +592,22 @@ static int __init tcb_clksrc_init(struct + return irq; + } + ++ if (tc.registered) ++ return tc_clkevt_register(node, regmap, tcb_base, channel, irq, ++ bits); ++ + if (bits == 16) { + of_property_read_u32_index(node, "reg", 1, &chan1); + if (chan1 == -1) { +- pr_err("%s: clocksource needs two channels\n", +- node->parent->full_name); +- return -EINVAL; ++ if (tce.registered) { ++ pr_err("%s: clocksource needs two channels\n", ++ node->parent->full_name); ++ return -EINVAL; ++ } else { ++ return tc_clkevt_register(node, regmap, ++ tcb_base, channel, ++ irq, bits); ++ } + } + } + diff --git a/patches/0003-clocksource-drivers-atmel-pit-make-option-silent.patch b/patches/0004-clocksource-drivers-atmel-pit-make-option-silent.patch index e627f90709e9..78ad5f0841d1 100644 --- a/patches/0003-clocksource-drivers-atmel-pit-make-option-silent.patch +++ b/patches/0004-clocksource-drivers-atmel-pit-make-option-silent.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:40 +0200 -Subject: [PATCH 3/6] clocksource/drivers: atmel-pit: make option silent +Date: Thu, 13 Sep 2018 13:30:21 +0200 +Subject: [PATCH 4/7] clocksource/drivers: atmel-pit: make option silent To conform with the other option, make the ATMEL_PIT option silent so it can be selected from the platform diff --git a/patches/0004-ARM-at91-Implement-clocksource-selection.patch b/patches/0005-ARM-at91-Implement-clocksource-selection.patch index 8f1f88f5bf48..b044504c9ffb 100644 --- a/patches/0004-ARM-at91-Implement-clocksource-selection.patch +++ b/patches/0005-ARM-at91-Implement-clocksource-selection.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:41 +0200 -Subject: [PATCH 4/6] ARM: at91: Implement clocksource selection +Date: Thu, 13 Sep 2018 13:30:22 +0200 +Subject: [PATCH 5/7] ARM: at91: Implement clocksource selection Allow selecting and unselecting the PIT clocksource driver so it doesn't have to be compile when unused. diff --git a/patches/0005-ARM-configs-at91-use-new-TCB-timer-driver.patch b/patches/0006-ARM-configs-at91-use-new-TCB-timer-driver.patch index a5b12e156930..aaeac81386ad 100644 --- a/patches/0005-ARM-configs-at91-use-new-TCB-timer-driver.patch +++ b/patches/0006-ARM-configs-at91-use-new-TCB-timer-driver.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:42 +0200 -Subject: [PATCH 5/6] ARM: configs: at91: use new TCB timer driver +Date: Thu, 13 Sep 2018 13:30:23 +0200 +Subject: [PATCH 6/7] ARM: configs: at91: use new TCB timer driver Unselecting ATMEL_TCLIB switches the TCB timer driver from tcb_clksrc to timer-atmel-tcb. diff --git a/patches/0006-ARM-configs-at91-unselect-PIT.patch b/patches/0007-ARM-configs-at91-unselect-PIT.patch index d3b805ffd94a..f5694ce09cb6 100644 --- a/patches/0006-ARM-configs-at91-unselect-PIT.patch +++ b/patches/0007-ARM-configs-at91-unselect-PIT.patch @@ -1,6 +1,6 @@ From: Alexandre Belloni <alexandre.belloni@bootlin.com> -Date: Wed, 18 Apr 2018 12:51:43 +0200 -Subject: [PATCH 6/6] ARM: configs: at91: unselect PIT +Date: Thu, 13 Sep 2018 13:30:24 +0200 +Subject: [PATCH 7/7] ARM: configs: at91: unselect PIT The PIT is not required anymore to successfully boot and may actually harm in case preempt-rt is used because the PIT interrupt is shared. diff --git a/patches/cpu-hotplug--Implement-CPU-pinning.patch b/patches/cpu-hotplug--Implement-CPU-pinning.patch index 7d1eee8b2a79..0d86bf078762 100644 --- a/patches/cpu-hotplug--Implement-CPU-pinning.patch +++ b/patches/cpu-hotplug--Implement-CPU-pinning.patch @@ -5,8 +5,8 @@ Date: Wed, 19 Jul 2017 17:31:20 +0200 Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/sched.h | 1 + - kernel/cpu.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 41 insertions(+) + kernel/cpu.c | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 39 insertions(+) --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -32,14 +32,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) static struct lockdep_map cpuhp_state_up_map = STATIC_LOCKDEP_MAP_INIT("cpuhp_state-up", &cpuhp_state_up_map); -@@ -285,7 +290,30 @@ static int cpu_hotplug_disabled; +@@ -285,7 +290,28 @@ static int cpu_hotplug_disabled; */ void pin_current_cpu(void) { + struct rt_rw_lock *cpuhp_pin; + unsigned int cpu; + int ret; - ++ +again: + cpuhp_pin = this_cpu_ptr(&cpuhp_pin_lock); + ret = __read_rt_trylock(cpuhp_pin); @@ -48,13 +48,11 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + return; + } + cpu = smp_processor_id(); -+ preempt_lazy_enable(); + preempt_enable(); + + __read_rt_lock(cpuhp_pin); -+ + + preempt_disable(); -+ preempt_lazy_disable(); + if (cpu != smp_processor_id()) { + __read_rt_unlock(cpuhp_pin); + goto again; @@ -63,7 +61,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /** -@@ -293,6 +321,13 @@ void pin_current_cpu(void) +@@ -293,6 +319,13 @@ void pin_current_cpu(void) */ void unpin_current_cpu(void) { @@ -77,7 +75,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -846,6 +881,7 @@ static int take_cpu_down(void *_param) +@@ -846,6 +879,7 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -85,7 +83,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -858,11 +894,14 @@ static int takedown_cpu(unsigned int cpu +@@ -858,11 +892,14 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -100,7 +98,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -881,6 +920,7 @@ static int takedown_cpu(unsigned int cpu +@@ -881,6 +918,7 @@ static int takedown_cpu(unsigned int cpu wait_for_ap_thread(st, false); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); diff --git a/patches/crypto-caam-qi-simplify-CGR-allocation-freeing.patch b/patches/crypto-caam-qi-simplify-CGR-allocation-freeing.patch new file mode 100644 index 000000000000..bcf3bf8d74df --- /dev/null +++ b/patches/crypto-caam-qi-simplify-CGR-allocation-freeing.patch @@ -0,0 +1,131 @@ +From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com> +Date: Mon, 8 Oct 2018 14:09:37 +0300 +Subject: [PATCH] crypto: caam/qi - simplify CGR allocation, freeing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[Upstream commit 29e83c757006fd751966bdc53392bb22d74179c6] + +CGRs (Congestion Groups) have to be freed by the same CPU that +initialized them. +This is why currently the driver takes special measures; however, using +set_cpus_allowed_ptr() is incorrect - as reported by Sebastian. + +Instead of the generic solution of replacing set_cpus_allowed_ptr() with +work_on_cpu_safe(), we use the qman_delete_cgr_safe() QBMan API instead +of qman_delete_cgr() - which internally takes care of proper CGR +deletion. + +Link: https://lkml.kernel.org/r/20181005125443.dfhd2asqktm22ney@linutronix.de +Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Signed-off-by: Horia Geantă <horia.geanta@nxp.com> +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> +--- + drivers/crypto/caam/qi.c | 43 ++++--------------------------------------- + drivers/crypto/caam/qi.h | 2 +- + 2 files changed, 5 insertions(+), 40 deletions(-) + +--- a/drivers/crypto/caam/qi.c ++++ b/drivers/crypto/caam/qi.c +@@ -84,13 +84,6 @@ static u64 times_congested; + #endif + + /* +- * CPU from where the module initialised. This is required because QMan driver +- * requires CGRs to be removed from same CPU from where they were originally +- * allocated. +- */ +-static int mod_init_cpu; +- +-/* + * This is a a cache of buffers, from which the users of CAAM QI driver + * can allocate short (CAAM_QI_MEMCACHE_SIZE) buffers. It's faster than + * doing malloc on the hotpath. +@@ -492,12 +485,11 @@ void caam_drv_ctx_rel(struct caam_drv_ct + } + EXPORT_SYMBOL(caam_drv_ctx_rel); + +-int caam_qi_shutdown(struct device *qidev) ++void caam_qi_shutdown(struct device *qidev) + { +- int i, ret; ++ int i; + struct caam_qi_priv *priv = dev_get_drvdata(qidev); + const cpumask_t *cpus = qman_affine_cpus(); +- struct cpumask old_cpumask = current->cpus_allowed; + + for_each_cpu(i, cpus) { + struct napi_struct *irqtask; +@@ -510,26 +502,12 @@ int caam_qi_shutdown(struct device *qide + dev_err(qidev, "Rsp FQ kill failed, cpu: %d\n", i); + } + +- /* +- * QMan driver requires CGRs to be deleted from same CPU from where they +- * were instantiated. Hence we get the module removal execute from the +- * same CPU from where it was originally inserted. +- */ +- set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu)); +- +- ret = qman_delete_cgr(&priv->cgr); +- if (ret) +- dev_err(qidev, "Deletion of CGR failed: %d\n", ret); +- else +- qman_release_cgrid(priv->cgr.cgrid); ++ qman_delete_cgr_safe(&priv->cgr); ++ qman_release_cgrid(priv->cgr.cgrid); + + kmem_cache_destroy(qi_cache); + +- /* Now that we're done with the CGRs, restore the cpus allowed mask */ +- set_cpus_allowed_ptr(current, &old_cpumask); +- + platform_device_unregister(priv->qi_pdev); +- return ret; + } + + static void cgr_cb(struct qman_portal *qm, struct qman_cgr *cgr, int congested) +@@ -718,22 +696,11 @@ int caam_qi_init(struct platform_device + struct device *ctrldev = &caam_pdev->dev, *qidev; + struct caam_drv_private *ctrlpriv; + const cpumask_t *cpus = qman_affine_cpus(); +- struct cpumask old_cpumask = current->cpus_allowed; + static struct platform_device_info qi_pdev_info = { + .name = "caam_qi", + .id = PLATFORM_DEVID_NONE + }; + +- /* +- * QMAN requires CGRs to be removed from same CPU+portal from where it +- * was originally allocated. Hence we need to note down the +- * initialisation CPU and use the same CPU for module exit. +- * We select the first CPU to from the list of portal owning CPUs. +- * Then we pin module init to this CPU. +- */ +- mod_init_cpu = cpumask_first(cpus); +- set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu)); +- + qi_pdev_info.parent = ctrldev; + qi_pdev_info.dma_mask = dma_get_mask(ctrldev); + qi_pdev = platform_device_register_full(&qi_pdev_info); +@@ -795,8 +762,6 @@ int caam_qi_init(struct platform_device + return -ENOMEM; + } + +- /* Done with the CGRs; restore the cpus allowed mask */ +- set_cpus_allowed_ptr(current, &old_cpumask); + #ifdef CONFIG_DEBUG_FS + debugfs_create_file("qi_congested", 0444, ctrlpriv->ctl, + ×_congested, &caam_fops_u64_ro); +--- a/drivers/crypto/caam/qi.h ++++ b/drivers/crypto/caam/qi.h +@@ -174,7 +174,7 @@ int caam_drv_ctx_update(struct caam_drv_ + void caam_drv_ctx_rel(struct caam_drv_ctx *drv_ctx); + + int caam_qi_init(struct platform_device *pdev); +-int caam_qi_shutdown(struct device *dev); ++void caam_qi_shutdown(struct device *dev); + + /** + * qi_cache_alloc - Allocate buffers from CAAM-QI cache diff --git a/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch b/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch index 6050bf9b8baa..243ab1d244f2 100644 --- a/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch +++ b/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch @@ -30,7 +30,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct rt_rw_lock *cpuhp_pin; unsigned int cpu; int ret; -@@ -314,6 +315,7 @@ void pin_current_cpu(void) +@@ -312,6 +313,7 @@ void pin_current_cpu(void) goto again; } current->pinned_on_cpu = cpu; @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /** -@@ -321,6 +323,7 @@ void pin_current_cpu(void) +@@ -319,6 +321,7 @@ void pin_current_cpu(void) */ void unpin_current_cpu(void) { @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct rt_rw_lock *cpuhp_pin = this_cpu_ptr(&cpuhp_pin_lock); if (WARN_ON(current->pinned_on_cpu != smp_processor_id())) -@@ -328,6 +331,7 @@ void unpin_current_cpu(void) +@@ -326,6 +329,7 @@ void unpin_current_cpu(void) current->pinned_on_cpu = -1; __read_rt_unlock(cpuhp_pin); @@ -54,7 +54,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -881,7 +885,9 @@ static int take_cpu_down(void *_param) +@@ -879,7 +883,9 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -64,7 +64,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -894,14 +900,18 @@ static int takedown_cpu(unsigned int cpu +@@ -892,14 +898,18 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -920,7 +930,9 @@ static int takedown_cpu(unsigned int cpu +@@ -918,7 +928,9 @@ static int takedown_cpu(unsigned int cpu wait_for_ap_thread(st, false); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); diff --git a/patches/localversion.patch b/patches/localversion.patch index 279489a1d145..e36eb4b6666a 100644 --- a/patches/localversion.patch +++ b/patches/localversion.patch @@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- /dev/null +++ b/localversion-rt @@ -0,0 +1 @@ -+-rt2 ++-rt3 diff --git a/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch b/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch index 7c800eaf3dce..43d695ae42c4 100644 --- a/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch +++ b/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -5926,6 +5926,7 @@ bool napi_schedule_prep(struct napi_stru +@@ -5927,6 +5927,7 @@ bool napi_schedule_prep(struct napi_stru } EXPORT_SYMBOL(napi_schedule_prep); @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * __napi_schedule_irqoff - schedule for receive * @n: entry to schedule -@@ -5937,6 +5938,7 @@ void __napi_schedule_irqoff(struct napi_ +@@ -5938,6 +5939,7 @@ void __napi_schedule_irqoff(struct napi_ ____napi_schedule(this_cpu_ptr(&softnet_data), n); } EXPORT_SYMBOL(__napi_schedule_irqoff); diff --git a/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch b/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch index e093f864732a..124ecdec12e8 100644 --- a/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch +++ b/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch @@ -231,7 +231,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); goto out; -@@ -8359,7 +8364,7 @@ static void netdev_init_one_queue(struct +@@ -8360,7 +8365,7 @@ static void netdev_init_one_queue(struct /* Initialize queue lock */ spin_lock_init(&queue->_xmit_lock); netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); diff --git a/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch b/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch index 19b719721323..e94de9470dc2 100644 --- a/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch +++ b/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch @@ -67,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> void raise_softirq_irqoff(unsigned int nr) --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -6353,7 +6353,7 @@ static __latent_entropy void net_rx_acti +@@ -6354,7 +6354,7 @@ static __latent_entropy void net_rx_acti list_splice_tail(&repoll, &list); list_splice(&list, &sd->poll_list); if (!list_empty(&sd->poll_list)) diff --git a/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch b/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch index 84bfb547d896..29d27889e758 100644 --- a/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch +++ b/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch @@ -23,9 +23,9 @@ Link: http://lkml.kernel.org/r/20111005184518.GA21601@linux.vnet.ibm.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - kernel/rcu/tree.c | 14 +++++++++++++- + kernel/rcu/tree.c | 18 +++++++++++++----- kernel/rcu/tree_plugin.h | 8 +++++++- - 2 files changed, 20 insertions(+), 2 deletions(-) + 2 files changed, 20 insertions(+), 6 deletions(-) --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -50,6 +50,17 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void rcu_bh_qs(void) { RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); +@@ -255,10 +267,6 @@ void rcu_bh_qs(void) + __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); + } + } +-#else +-void rcu_bh_qs(void) +-{ +-} + #endif + + /* --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -29,6 +29,7 @@ diff --git a/patches/pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch b/patches/pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch new file mode 100644 index 000000000000..559af22b2d4c --- /dev/null +++ b/patches/pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch @@ -0,0 +1,96 @@ +From: Lukas Wunner <lukas@wunner.de> +Date: Sat, 27 Oct 2018 10:15:33 +0200 +Subject: [PATCH] pinctrl: bcm2835: Use raw spinlock for RT compatibility + +[Upstream commit 71dfaa749f2f7c1722ebf6716d3f797a04528cba] + +The BCM2835 pinctrl driver acquires a spinlock in its ->irq_enable, +->irq_disable and ->irq_set_type callbacks. Spinlocks become sleeping +locks with CONFIG_PREEMPT_RT_FULL=y, therefore invocation of one of the +callbacks in atomic context may cause a hard lockup if at least two GPIO +pins in the same bank are used as interrupts. The issue doesn't occur +with just a single interrupt pin per bank because the lock is never +contended. I'm experiencing such lockups with GPIO 8 and 28 used as +level-triggered interrupts, i.e. with ->irq_disable being invoked on +reception of every IRQ. + +The critical section protected by the spinlock is very small (one bitop +and one RMW of an MMIO register), hence converting to a raw spinlock +seems a better trade-off than converting the driver to threaded IRQ +handling (which would increase latency to handle an interrupt). + +Cc: Mathias Duckeck <m.duckeck@kunbus.de> +Signed-off-by: Lukas Wunner <lukas@wunner.de> +Acked-by: Julia Cartwright <julia@ni.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -90,7 +90,7 @@ struct bcm2835_pinctrl { + struct gpio_chip gpio_chip; + struct pinctrl_gpio_range gpio_range; + +- spinlock_t irq_lock[BCM2835_NUM_BANKS]; ++ raw_spinlock_t irq_lock[BCM2835_NUM_BANKS]; + }; + + /* pins are just named GPIO0..GPIO53 */ +@@ -461,10 +461,10 @@ static void bcm2835_gpio_irq_enable(stru + unsigned bank = GPIO_REG_OFFSET(gpio); + unsigned long flags; + +- spin_lock_irqsave(&pc->irq_lock[bank], flags); ++ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); + set_bit(offset, &pc->enabled_irq_map[bank]); + bcm2835_gpio_irq_config(pc, gpio, true); +- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); ++ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + } + + static void bcm2835_gpio_irq_disable(struct irq_data *data) +@@ -476,12 +476,12 @@ static void bcm2835_gpio_irq_disable(str + unsigned bank = GPIO_REG_OFFSET(gpio); + unsigned long flags; + +- spin_lock_irqsave(&pc->irq_lock[bank], flags); ++ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); + bcm2835_gpio_irq_config(pc, gpio, false); + /* Clear events that were latched prior to clearing event sources */ + bcm2835_gpio_set_bit(pc, GPEDS0, gpio); + clear_bit(offset, &pc->enabled_irq_map[bank]); +- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); ++ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + } + + static int __bcm2835_gpio_irq_set_type_disabled(struct bcm2835_pinctrl *pc, +@@ -584,7 +584,7 @@ static int bcm2835_gpio_irq_set_type(str + unsigned long flags; + int ret; + +- spin_lock_irqsave(&pc->irq_lock[bank], flags); ++ raw_spin_lock_irqsave(&pc->irq_lock[bank], flags); + + if (test_bit(offset, &pc->enabled_irq_map[bank])) + ret = __bcm2835_gpio_irq_set_type_enabled(pc, gpio, type); +@@ -596,7 +596,7 @@ static int bcm2835_gpio_irq_set_type(str + else + irq_set_handler_locked(data, handle_level_irq); + +- spin_unlock_irqrestore(&pc->irq_lock[bank], flags); ++ raw_spin_unlock_irqrestore(&pc->irq_lock[bank], flags); + + return ret; + } +@@ -1047,7 +1047,7 @@ static int bcm2835_pinctrl_probe(struct + for_each_set_bit(offset, &events, 32) + bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); + +- spin_lock_init(&pc->irq_lock[i]); ++ raw_spin_lock_init(&pc->irq_lock[i]); + } + + err = gpiochip_add_data(&pc->gpio_chip, pc); diff --git a/patches/preempt-lazy-support.patch b/patches/preempt-lazy-support.patch index dff4755ada32..c399b0aa4718 100644 --- a/patches/preempt-lazy-support.patch +++ b/patches/preempt-lazy-support.patch @@ -57,6 +57,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> include/linux/thread_info.h | 12 +++++- include/linux/trace_events.h | 1 kernel/Kconfig.preempt | 6 +++ + kernel/cpu.c | 2 + kernel/sched/core.c | 83 +++++++++++++++++++++++++++++++++++++++++-- kernel/sched/fair.c | 16 ++++---- kernel/sched/features.h | 3 + @@ -64,7 +65,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> kernel/trace/trace.c | 36 ++++++++++-------- kernel/trace/trace.h | 2 + kernel/trace/trace_output.c | 14 ++++++- - 12 files changed, 226 insertions(+), 29 deletions(-) + 13 files changed, 228 insertions(+), 29 deletions(-) --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -231,6 +232,22 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> choice prompt "Preemption Model" default PREEMPT_NONE +--- a/kernel/cpu.c ++++ b/kernel/cpu.c +@@ -303,11 +303,13 @@ void pin_current_cpu(void) + return; + } + cpu = smp_processor_id(); ++ preempt_lazy_enable(); + preempt_enable(); + + __read_rt_lock(cpuhp_pin); + + preempt_disable(); ++ preempt_lazy_disable(); + if (cpu != smp_processor_id()) { + __read_rt_unlock(cpuhp_pin); + goto again; --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -492,6 +492,48 @@ void resched_curr(struct rq *rq) diff --git a/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch b/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch index caeb52ab9c02..962fe570d8b6 100644 --- a/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch +++ b/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch @@ -10,6 +10,7 @@ By default, as a policy decision, disable the expediting of grace periods (after boot) on configurations which enable PREEMPT_RT_FULL. Suggested-by: Luiz Capitulino <lcapitulino@redhat.com> +Acked-by: Paul E. McKenney <paulmck@linux.ibm.com> Signed-off-by: Julia Cartwright <julia@ni.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- diff --git a/patches/rcu-make-RCU_BOOST-default-on-RT.patch b/patches/rcu-make-RCU_BOOST-default-on-RT.patch index bda5c6289f0a..fa1fb18b8b7e 100644 --- a/patches/rcu-make-RCU_BOOST-default-on-RT.patch +++ b/patches/rcu-make-RCU_BOOST-default-on-RT.patch @@ -14,20 +14,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/rcu/Kconfig +++ b/kernel/rcu/Kconfig -@@ -36,7 +36,7 @@ config TINY_RCU +@@ -190,8 +190,8 @@ config RCU_FAST_NO_HZ - config RCU_EXPERT - bool "Make expert-level adjustments to RCU configuration" -- default n -+ default y if PREEMPT_RT_FULL - help - This option needs to be enabled if you wish to make - expert-level adjustments to RCU configuration. By default, -@@ -191,7 +191,7 @@ config RCU_FAST_NO_HZ config RCU_BOOST bool "Enable RCU priority boosting" - depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT +- depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT - default n ++ depends on (RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT) || PREEMPT_RT_FULL + default y if PREEMPT_RT_FULL help This option boosts the priority of preempted RCU readers that diff --git a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch index a07b73e88c2b..cf24cb7360c9 100644 --- a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch +++ b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch @@ -28,10 +28,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> include/linux/rcutree.h | 8 ++++++++ kernel/rcu/rcu.h | 11 +++++++++-- kernel/rcu/rcutorture.c | 7 +++++++ - kernel/rcu/tree.c | 22 ++++++++++++++++++++++ + kernel/rcu/tree.c | 26 ++++++++++++++++++++++++++ kernel/rcu/tree.h | 2 ++ kernel/rcu/update.c | 2 ++ - 7 files changed, 69 insertions(+), 2 deletions(-) + 7 files changed, 73 insertions(+), 2 deletions(-) --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -181,15 +181,19 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void rcu_bh_qs(void) { RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); -@@ -254,6 +255,7 @@ void rcu_bh_qs(void) +@@ -254,6 +255,11 @@ void rcu_bh_qs(void) __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); } } ++#else ++void rcu_bh_qs(void) ++{ ++} +#endif /* * Steal a bit from the bottom of ->dynticks for idle entry/exit -@@ -568,6 +570,7 @@ unsigned long rcu_sched_get_gp_seq(void) +@@ -568,6 +574,7 @@ unsigned long rcu_sched_get_gp_seq(void) } EXPORT_SYMBOL_GPL(rcu_sched_get_gp_seq); @@ -197,7 +201,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Return the number of RCU-bh GPs completed thus far for debug & stats. */ -@@ -576,6 +579,7 @@ unsigned long rcu_bh_get_gp_seq(void) +@@ -576,6 +583,7 @@ unsigned long rcu_bh_get_gp_seq(void) return READ_ONCE(rcu_bh_state.gp_seq); } EXPORT_SYMBOL_GPL(rcu_bh_get_gp_seq); @@ -205,7 +209,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Return the number of RCU expedited batches completed thus far for -@@ -599,6 +603,7 @@ unsigned long rcu_exp_batches_completed_ +@@ -599,6 +607,7 @@ unsigned long rcu_exp_batches_completed_ } EXPORT_SYMBOL_GPL(rcu_exp_batches_completed_sched); @@ -213,7 +217,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Force a quiescent state. */ -@@ -617,6 +622,13 @@ void rcu_bh_force_quiescent_state(void) +@@ -617,6 +626,13 @@ void rcu_bh_force_quiescent_state(void) } EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); @@ -227,7 +231,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Force a quiescent state for RCU-sched. */ -@@ -674,9 +686,11 @@ void rcutorture_get_gp_data(enum rcutort +@@ -674,9 +690,11 @@ void rcutorture_get_gp_data(enum rcutort case RCU_FLAVOR: rsp = rcu_state_p; break; @@ -239,7 +243,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> case RCU_SCHED_FLAVOR: rsp = &rcu_sched_state; break; -@@ -3040,6 +3054,7 @@ void call_rcu_sched(struct rcu_head *hea +@@ -3040,6 +3058,7 @@ void call_rcu_sched(struct rcu_head *hea } EXPORT_SYMBOL_GPL(call_rcu_sched); @@ -247,7 +251,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period. * @head: structure to be used for queueing the RCU updates. -@@ -3067,6 +3082,7 @@ void call_rcu_bh(struct rcu_head *head, +@@ -3067,6 +3086,7 @@ void call_rcu_bh(struct rcu_head *head, __call_rcu(head, func, &rcu_bh_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu_bh); @@ -255,7 +259,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Queue an RCU callback for lazy invocation after a grace period. -@@ -3152,6 +3168,7 @@ void synchronize_sched(void) +@@ -3152,6 +3172,7 @@ void synchronize_sched(void) } EXPORT_SYMBOL_GPL(synchronize_sched); @@ -263,7 +267,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. * -@@ -3178,6 +3195,7 @@ void synchronize_rcu_bh(void) +@@ -3178,6 +3199,7 @@ void synchronize_rcu_bh(void) wait_rcu_gp(call_rcu_bh); } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); @@ -271,7 +275,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * get_state_synchronize_rcu - Snapshot current RCU state -@@ -3485,6 +3503,7 @@ static void _rcu_barrier(struct rcu_stat +@@ -3485,6 +3507,7 @@ static void _rcu_barrier(struct rcu_stat mutex_unlock(&rsp->barrier_mutex); } @@ -279,7 +283,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete. */ -@@ -3493,6 +3512,7 @@ void rcu_barrier_bh(void) +@@ -3493,6 +3516,7 @@ void rcu_barrier_bh(void) _rcu_barrier(&rcu_bh_state); } EXPORT_SYMBOL_GPL(rcu_barrier_bh); @@ -287,7 +291,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks. -@@ -4140,7 +4160,9 @@ void __init rcu_init(void) +@@ -4140,7 +4164,9 @@ void __init rcu_init(void) rcu_bootup_announce(); rcu_init_geometry(); diff --git a/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch b/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch index 13e80368b3a5..7bef860443d8 100644 --- a/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch +++ b/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch @@ -8,8 +8,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/locking/rtmutex.c | 67 ++++++++++++++++++++++------------------ - kernel/locking/rtmutex_common.h | 6 +++ - 2 files changed, 44 insertions(+), 29 deletions(-) + kernel/locking/rtmutex_common.h | 7 ++++ + 2 files changed, 45 insertions(+), 29 deletions(-) --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -113,7 +113,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -159,6 +159,12 @@ extern bool __rt_mutex_futex_unlock(stru +@@ -15,6 +15,7 @@ + + #include <linux/rtmutex.h> + #include <linux/sched/wake_q.h> ++#include <linux/sched/debug.h> + + /* + * This is the control structure for tasks blocked on a rt_mutex, +@@ -159,6 +160,12 @@ extern bool __rt_mutex_futex_unlock(stru struct wake_q_head *wqh); extern void rt_mutex_postunlock(struct wake_q_head *wake_q); diff --git a/patches/rtmutex-add-sleeping-lock-implementation.patch b/patches/rtmutex-add-sleeping-lock-implementation.patch index f6358fa79664..06083df1b175 100644 --- a/patches/rtmutex-add-sleeping-lock-implementation.patch +++ b/patches/rtmutex-add-sleeping-lock-implementation.patch @@ -14,9 +14,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> kernel/fork.c | 1 kernel/futex.c | 11 kernel/locking/rtmutex.c | 436 ++++++++++++++++++++++++++++++++++---- - kernel/locking/rtmutex_common.h | 15 + + kernel/locking/rtmutex_common.h | 14 - kernel/sched/core.c | 28 +- - 11 files changed, 696 insertions(+), 59 deletions(-) + 11 files changed, 695 insertions(+), 59 deletions(-) create mode 100644 include/linux/spinlock_rt.h create mode 100644 include/linux/spinlock_types_rt.h @@ -1076,15 +1076,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -15,6 +15,7 @@ - - #include <linux/rtmutex.h> - #include <linux/sched/wake_q.h> -+#include <linux/sched/debug.h> - - /* - * This is the control structure for tasks blocked on a rt_mutex, -@@ -29,6 +30,7 @@ struct rt_mutex_waiter { +@@ -30,6 +30,7 @@ struct rt_mutex_waiter { struct rb_node pi_tree_entry; struct task_struct *task; struct rt_mutex *lock; @@ -1092,7 +1084,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_DEBUG_RT_MUTEXES unsigned long ip; struct pid *deadlock_task_pid; -@@ -138,7 +140,7 @@ extern void rt_mutex_init_proxy_locked(s +@@ -139,7 +140,7 @@ extern void rt_mutex_init_proxy_locked(s struct task_struct *proxy_owner); extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, struct task_struct *proxy_owner); @@ -1101,7 +1093,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, struct task_struct *task); -@@ -156,9 +158,12 @@ extern int __rt_mutex_futex_trylock(stru +@@ -157,9 +158,12 @@ extern int __rt_mutex_futex_trylock(stru extern void rt_mutex_futex_unlock(struct rt_mutex *lock); extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, @@ -1116,7 +1108,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* RW semaphore special interface */ extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); -@@ -168,6 +173,10 @@ int __sched rt_mutex_slowlock_locked(str +@@ -169,6 +173,10 @@ int __sched rt_mutex_slowlock_locked(str struct hrtimer_sleeper *timeout, enum rtmutex_chainwalk chwalk, struct rt_mutex_waiter *waiter); diff --git a/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch b/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch index 0998821b7248..382dd176710a 100644 --- a/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch +++ b/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch @@ -4,10 +4,10 @@ Subject: rtmutex: add ww_mutex addon for mutex-rt Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/locking/rtmutex.c | 269 ++++++++++++++++++++++++++++++++++++++-- + kernel/locking/rtmutex.c | 271 ++++++++++++++++++++++++++++++++++++++-- kernel/locking/rtmutex_common.h | 2 kernel/locking/rwsem-rt.c | 2 - 3 files changed, 260 insertions(+), 13 deletions(-) + 3 files changed, 261 insertions(+), 14 deletions(-) --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -277,6 +277,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static inline int +@@ -1833,7 +1981,7 @@ rt_mutex_fastunlock(struct rt_mutex *loc + int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) + { + might_sleep(); +- return rt_mutex_fastlock(lock, state, rt_mutex_slowlock); ++ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); + } + + /** @@ -1953,6 +2101,7 @@ rt_mutex_timed_lock(struct rt_mutex *loc mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ret = rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, diff --git a/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch b/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch index 02c9c5394da8..aa364eeb269d 100644 --- a/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch +++ b/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch @@ -22,7 +22,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) { might_sleep(); -+ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); ++ return rt_mutex_fastlock(lock, state, rt_mutex_slowlock); +} + +/** @@ -132,7 +132,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -161,6 +161,9 @@ extern bool __rt_mutex_futex_unlock(stru +@@ -162,6 +162,9 @@ extern bool __rt_mutex_futex_unlock(stru extern void rt_mutex_postunlock(struct wake_q_head *wake_q); /* RW semaphore special interface */ diff --git a/patches/series b/patches/series index e86026944b8e..55976c4bf80c 100644 --- a/patches/series +++ b/patches/series @@ -10,17 +10,20 @@ # POSTED by others ############################################################ # AT91 -# Alexandre Belloni | [PATCH v4 0/6] clocksource: rework Atmel TCB timer driver -# Date: Wed, 18 Apr 2018 12:51:37 +0200 +# Alexandre Belloni | [PATCH v7 0/7] clocksource: rework Atmel TCB timer driver +# Date: Thu, 13 Sep 2018 13:30:18 +0200 0001-ARM-at91-add-TCB-registers-definitions.patch 0002-clocksource-drivers-Add-a-new-driver-for-the-Atmel-A.patch -0003-clocksource-drivers-atmel-pit-make-option-silent.patch -0004-ARM-at91-Implement-clocksource-selection.patch -0005-ARM-configs-at91-use-new-TCB-timer-driver.patch -0006-ARM-configs-at91-unselect-PIT.patch +0003-clocksource-drivers-timer-atmel-tcb-add-clockevent-d.patch +0004-clocksource-drivers-atmel-pit-make-option-silent.patch +0005-ARM-at91-Implement-clocksource-selection.patch +0006-ARM-configs-at91-use-new-TCB-timer-driver.patch +0007-ARM-configs-at91-unselect-PIT.patch irqchip-gic-v3-its-Move-pending-table-allocation-to-.patch kthread-convert-worker-lock-to-raw-spinlock.patch +pinctrl-bcm2835-Use-raw-spinlock-for-RT-compatibilit.patch +crypto-caam-qi-simplify-CGR-allocation-freeing.patch ############################################################ # POSTED @@ -83,7 +86,6 @@ usb-do-not-disable-interrupts-in-giveback.patch # Kconfig on/off rt-preempt-base-config.patch -kconfig-preempt-rt-full.patch cpumask-disable-offstack-on-rt.patch jump-label-rt.patch kconfig-disable-a-few-options-rt.patch @@ -243,6 +245,8 @@ rtmutex-add-rwsem-implementation-based-on-rtmutex.patch rtmutex-add-rwlock-implementation-based-on-rtmutex.patch rtmutex-wire-up-RT-s-locking.patch rtmutex-add-ww_mutex-addon-for-mutex-rt.patch +# Allow to enable RT-FULL after sleeping spinlocks are wired up +kconfig-preempt-rt-full.patch locking-rt-mutex-fix-deadlock-in-device-mapper-block.patch locking-rtmutex-re-init-the-wait_lock-in-rt_mutex_in.patch ptrace-fix-ptrace-vs-tasklist_lock-race.patch diff --git a/patches/skbufhead-raw-lock.patch b/patches/skbufhead-raw-lock.patch index fa90be782684..98d46e41739f 100644 --- a/patches/skbufhead-raw-lock.patch +++ b/patches/skbufhead-raw-lock.patch @@ -90,7 +90,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void flush_all_backlogs(void) -@@ -5827,7 +5830,9 @@ static int process_backlog(struct napi_s +@@ -5828,7 +5831,9 @@ static int process_backlog(struct napi_s while (again) { struct sk_buff *skb; @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rcu_read_lock(); __netif_receive_skb(skb); rcu_read_unlock(); -@@ -5835,9 +5840,9 @@ static int process_backlog(struct napi_s +@@ -5836,9 +5841,9 @@ static int process_backlog(struct napi_s if (++work >= quota) return work; @@ -111,7 +111,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rps_lock(sd); if (skb_queue_empty(&sd->input_pkt_queue)) { /* -@@ -6299,13 +6304,21 @@ static __latent_entropy void net_rx_acti +@@ -6300,13 +6305,21 @@ static __latent_entropy void net_rx_acti unsigned long time_limit = jiffies + usecs_to_jiffies(netdev_budget_usecs); int budget = netdev_budget; @@ -133,7 +133,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> for (;;) { struct napi_struct *n; -@@ -9291,10 +9304,13 @@ static int dev_cpu_dead(unsigned int old +@@ -9292,10 +9305,13 @@ static int dev_cpu_dead(unsigned int old netif_rx_ni(skb); input_queue_head_incr(oldsd); } @@ -148,7 +148,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return 0; } -@@ -9603,8 +9619,9 @@ static int __init net_dev_init(void) +@@ -9604,8 +9620,9 @@ static int __init net_dev_init(void) INIT_WORK(flush, flush_backlog); diff --git a/patches/softirq-preempt-fix-3-re.patch b/patches/softirq-preempt-fix-3-re.patch index 72f8d80b5669..95f8d3edcb46 100644 --- a/patches/softirq-preempt-fix-3-re.patch +++ b/patches/softirq-preempt-fix-3-re.patch @@ -135,7 +135,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); -@@ -5789,12 +5792,14 @@ static void net_rps_action_and_irq_enabl +@@ -5790,12 +5793,14 @@ static void net_rps_action_and_irq_enabl sd->rps_ipi_list = NULL; local_irq_enable(); @@ -150,7 +150,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) -@@ -5872,6 +5877,7 @@ void __napi_schedule(struct napi_struct +@@ -5873,6 +5878,7 @@ void __napi_schedule(struct napi_struct local_irq_save(flags); ____napi_schedule(this_cpu_ptr(&softnet_data), n); local_irq_restore(flags); @@ -158,7 +158,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } EXPORT_SYMBOL(__napi_schedule); -@@ -9273,6 +9279,7 @@ static int dev_cpu_dead(unsigned int old +@@ -9274,6 +9280,7 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); diff --git a/patches/srcu-use-cpu_online-instead-custom-check.patch b/patches/srcu-use-cpu_online-instead-custom-check.patch index 0b7924b7cd08..af2e8c6ae603 100644 --- a/patches/srcu-use-cpu_online-instead-custom-check.patch +++ b/patches/srcu-use-cpu_online-instead-custom-check.patch @@ -11,9 +11,6 @@ on a specific CPU or not. queue_work_on() itself can handle if something is enqueued on an offline CPU but a timer which is enqueued on an offline CPU won't fire until the CPU is back online. -I am not sure if the removal in rcu_init() is okay or not. I assume that -SRCU won't enqueue a work item before SRCU is up and ready. - Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/rcu/srcutree.c | 22 ++++------------------ |