summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2020-01-10 18:37:01 +0100
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2020-01-10 18:37:01 +0100
commitab7b3b02824b46d2bfaf2e5efcb28f202e96b4ea (patch)
tree613e14c1a20862063bd96268a6a32afa90d6ce00
parentccbbca11ffa55bb3eddfcce42e84e23bda31f5b2 (diff)
downloadlinux-rt-ab7b3b02824b46d2bfaf2e5efcb28f202e96b4ea.tar.gz
[ANNOUNCE] v5.4.10-rt5v5.4.10-rt5-patches
Dear RT folks! I'm pleased to announce the v5.4.10-rt5 patch set. Changes since v5.4.10-rt4: - Dick Hollenbeck reported that the printk rework had a negative impact on the 8250 driver if not used as a console. Patch by John Ogness. Known issues - None The delta patch against v5.4.10-rt4 is appended below and can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.4/incr/patch-5.4.10-rt4-rt5.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 v5.4.10-rt5 The RT patch against v5.4.10 can be found here: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patch-5.4.10-rt5.patch.xz The split quilt queue is available at: https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.4/older/patches-5.4.10-rt5.tar.xz Sebastian Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-rw-r--r--patches/0003-jbd2-Move-dropping-of-jh-reference-out-of-un-re-fili.patch4
-rw-r--r--patches/0006-jbd2-Make-state-lock-a-spinlock.patch4
-rw-r--r--patches/0011-printk_safe-remove-printk-safe-code.patch4
-rw-r--r--patches/fs-buffer-Make-BH_Uptodate_Lock-bit_spin_lock-a-regu.patch2
-rw-r--r--patches/hrtimer-Allow-raw-wakeups-during-boot.patch2
-rw-r--r--patches/hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch2
-rw-r--r--patches/localversion.patch2
-rw-r--r--patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch2
-rw-r--r--patches/net-use-cpu-chill.patch4
-rw-r--r--patches/of-Rework-and-simplify-phandle-cache-to-use-a-fixed-.patch4
-rw-r--r--patches/perf-core-Add-SRCU-annotation-for-pmus-list-walk.patch2
-rw-r--r--patches/rt-introduce-cpu-chill.patch2
-rw-r--r--patches/seqlock-prevent-rt-starvation.patch6
-rw-r--r--patches/serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch102
-rw-r--r--patches/serial-8250-only-atomic-lock-for-console.patch384
-rw-r--r--patches/series2
-rw-r--r--patches/userfaultfd-Use-a-seqlock-instead-of-seqcount.patch2
17 files changed, 509 insertions, 21 deletions
diff --git a/patches/0003-jbd2-Move-dropping-of-jh-reference-out-of-un-re-fili.patch b/patches/0003-jbd2-Move-dropping-of-jh-reference-out-of-un-re-fili.patch
index 82cb224af25f..388bbf4d2953 100644
--- a/patches/0003-jbd2-Move-dropping-of-jh-reference-out-of-un-re-fili.patch
+++ b/patches/0003-jbd2-Move-dropping-of-jh-reference-out-of-un-re-fili.patch
@@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
-@@ -918,6 +918,7 @@ void jbd2_journal_commit_transaction(jou
+@@ -920,6 +920,7 @@ void jbd2_journal_commit_transaction(jou
transaction_t *cp_transaction;
struct buffer_head *bh;
int try_to_free = 0;
@@ -28,7 +28,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
jh = commit_transaction->t_forget;
spin_unlock(&journal->j_list_lock);
-@@ -1022,8 +1023,10 @@ void jbd2_journal_commit_transaction(jou
+@@ -1024,8 +1025,10 @@ void jbd2_journal_commit_transaction(jou
try_to_free = 1;
}
JBUFFER_TRACE(jh, "refile or unfile buffer");
diff --git a/patches/0006-jbd2-Make-state-lock-a-spinlock.patch b/patches/0006-jbd2-Make-state-lock-a-spinlock.patch
index 67433727d495..8664511956ba 100644
--- a/patches/0006-jbd2-Make-state-lock-a-spinlock.patch
+++ b/patches/0006-jbd2-Make-state-lock-a-spinlock.patch
@@ -63,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
}
jbd2_journal_refile_buffer(journal, jh);
}
-@@ -928,7 +928,7 @@ void jbd2_journal_commit_transaction(jou
+@@ -930,7 +930,7 @@ void jbd2_journal_commit_transaction(jou
* done with it.
*/
get_bh(bh);
@@ -72,7 +72,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
J_ASSERT_JH(jh, jh->b_transaction == commit_transaction);
/*
-@@ -1024,7 +1024,7 @@ void jbd2_journal_commit_transaction(jou
+@@ -1026,7 +1026,7 @@ void jbd2_journal_commit_transaction(jou
}
JBUFFER_TRACE(jh, "refile or unfile buffer");
drop_ref = __jbd2_journal_refile_buffer(jh);
diff --git a/patches/0011-printk_safe-remove-printk-safe-code.patch b/patches/0011-printk_safe-remove-printk-safe-code.patch
index 504e3a3a5344..4be8cb82dc6f 100644
--- a/patches/0011-printk_safe-remove-printk-safe-code.patch
+++ b/patches/0011-printk_safe-remove-printk-safe-code.patch
@@ -666,7 +666,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-}
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
-@@ -8908,7 +8908,6 @@ void ftrace_dump(enum ftrace_dump_mode o
+@@ -8916,7 +8916,6 @@ void ftrace_dump(enum ftrace_dump_mode o
tracing_off();
local_irq_save(flags);
@@ -674,7 +674,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
/* Simulate the iterator */
trace_init_global_iter(&iter);
-@@ -8985,7 +8984,6 @@ void ftrace_dump(enum ftrace_dump_mode o
+@@ -8993,7 +8992,6 @@ void ftrace_dump(enum ftrace_dump_mode o
atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
}
atomic_dec(&dump_running);
diff --git a/patches/fs-buffer-Make-BH_Uptodate_Lock-bit_spin_lock-a-regu.patch b/patches/fs-buffer-Make-BH_Uptodate_Lock-bit_spin_lock-a-regu.patch
index e0c9c804a8af..17b26e49f687 100644
--- a/patches/fs-buffer-Make-BH_Uptodate_Lock-bit_spin_lock-a-regu.patch
+++ b/patches/fs-buffer-Make-BH_Uptodate_Lock-bit_spin_lock-a-regu.patch
@@ -102,7 +102,7 @@ after
return;
}
EXPORT_SYMBOL(end_buffer_async_write);
-@@ -3368,6 +3362,7 @@ struct buffer_head *alloc_buffer_head(gf
+@@ -3345,6 +3339,7 @@ struct buffer_head *alloc_buffer_head(gf
struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags);
if (ret) {
INIT_LIST_HEAD(&ret->b_assoc_buffers);
diff --git a/patches/hrtimer-Allow-raw-wakeups-during-boot.patch b/patches/hrtimer-Allow-raw-wakeups-during-boot.patch
index 9d46a70f5c83..8fdb33e2288b 100644
--- a/patches/hrtimer-Allow-raw-wakeups-during-boot.patch
+++ b/patches/hrtimer-Allow-raw-wakeups-during-boot.patch
@@ -22,7 +22,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
-@@ -1816,7 +1816,7 @@ static void __hrtimer_init_sleeper(struc
+@@ -1819,7 +1819,7 @@ static void __hrtimer_init_sleeper(struc
* expiry.
*/
if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
diff --git a/patches/hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch b/patches/hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
index 495dbbf206fe..814f6fb29d7e 100644
--- a/patches/hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
+++ b/patches/hrtimer-move-state-change-before-hrtimer_cancel-in-d.patch
@@ -28,7 +28,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
-@@ -1870,12 +1870,12 @@ static int __sched do_nanosleep(struct h
+@@ -1873,12 +1873,12 @@ static int __sched do_nanosleep(struct h
if (likely(t->task))
freezable_schedule();
diff --git a/patches/localversion.patch b/patches/localversion.patch
index 03a80b8b0e80..72cdd2b3c760 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 @@
-+-rt4
++-rt5
diff --git a/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch b/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch
index ed178d0edbe5..dab6e4456dac 100644
--- a/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch
+++ b/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch
@@ -160,7 +160,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (qdisc->flags & TCQ_F_NOLOCK)
spin_unlock(&qdisc->seqlock);
}
-@@ -535,7 +550,7 @@ static inline spinlock_t *qdisc_root_sle
+@@ -540,7 +555,7 @@ static inline spinlock_t *qdisc_root_sle
return qdisc_lock(root);
}
diff --git a/patches/net-use-cpu-chill.patch b/patches/net-use-cpu-chill.patch
index bfd3a9f3b7d4..b1baf00bdec8 100644
--- a/patches/net-use-cpu-chill.patch
+++ b/patches/net-use-cpu-chill.patch
@@ -22,7 +22,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-@@ -659,7 +660,7 @@ static void prb_retire_rx_blk_timer_expi
+@@ -660,7 +661,7 @@ static void prb_retire_rx_blk_timer_expi
if (BLOCK_NUM_PKTS(pbd)) {
while (atomic_read(&pkc->blk_fill_in_prog)) {
/* Waiting for skb_copy_bits to finish... */
@@ -31,7 +31,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
}
}
-@@ -921,7 +922,7 @@ static void prb_retire_current_block(str
+@@ -922,7 +923,7 @@ static void prb_retire_current_block(str
if (!(status & TP_STATUS_BLK_TMO)) {
while (atomic_read(&pkc->blk_fill_in_prog)) {
/* Waiting for skb_copy_bits to finish... */
diff --git a/patches/of-Rework-and-simplify-phandle-cache-to-use-a-fixed-.patch b/patches/of-Rework-and-simplify-phandle-cache-to-use-a-fixed-.patch
index 8b7d2558fdfe..5e623c4e5a2e 100644
--- a/patches/of-Rework-and-simplify-phandle-cache-to-use-a-fixed-.patch
+++ b/patches/of-Rework-and-simplify-phandle-cache-to-use-a-fixed-.patch
@@ -285,7 +285,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
static inline void of_overlay_mutex_unlock(void) {};
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
-@@ -971,8 +971,6 @@ static int of_overlay_apply(const void *
+@@ -974,8 +974,6 @@ static int of_overlay_apply(const void *
goto err_free_overlay_changeset;
}
@@ -294,7 +294,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
ret = __of_changeset_apply_notify(&ovcs->cset);
if (ret)
pr_err("overlay apply changeset entry notify error %d\n", ret);
-@@ -1215,17 +1213,9 @@ int of_overlay_remove(int *ovcs_id)
+@@ -1218,17 +1216,9 @@ int of_overlay_remove(int *ovcs_id)
list_del(&ovcs->ovcs_list);
diff --git a/patches/perf-core-Add-SRCU-annotation-for-pmus-list-walk.patch b/patches/perf-core-Add-SRCU-annotation-for-pmus-list-walk.patch
index 6729d0d2a4a7..01cb0458a6bd 100644
--- a/patches/perf-core-Add-SRCU-annotation-for-pmus-list-walk.patch
+++ b/patches/perf-core-Add-SRCU-annotation-for-pmus-list-walk.patch
@@ -19,7 +19,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
-@@ -10258,7 +10258,7 @@ static struct pmu *perf_init_event(struc
+@@ -10256,7 +10256,7 @@ static struct pmu *perf_init_event(struc
goto unlock;
}
diff --git a/patches/rt-introduce-cpu-chill.patch b/patches/rt-introduce-cpu-chill.patch
index 3dfb52e49e31..3ce8cf43a213 100644
--- a/patches/rt-introduce-cpu-chill.patch
+++ b/patches/rt-introduce-cpu-chill.patch
@@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
#endif /* defined(_LINUX_DELAY_H) */
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
-@@ -1979,6 +1979,38 @@ SYSCALL_DEFINE2(nanosleep_time32, struct
+@@ -1982,6 +1982,38 @@ SYSCALL_DEFINE2(nanosleep_time32, struct
}
#endif
diff --git a/patches/seqlock-prevent-rt-starvation.patch b/patches/seqlock-prevent-rt-starvation.patch
index 60fda955d42c..32f984ae760b 100644
--- a/patches/seqlock-prevent-rt-starvation.patch
+++ b/patches/seqlock-prevent-rt-starvation.patch
@@ -159,7 +159,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
-@@ -460,7 +460,7 @@ static inline int neigh_hh_bridge(struct
+@@ -459,7 +459,7 @@ static inline int neigh_hh_bridge(struct
}
#endif
@@ -168,7 +168,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
{
unsigned int hh_alen = 0;
unsigned int seq;
-@@ -503,7 +503,7 @@ static inline int neigh_hh_output(const
+@@ -502,7 +502,7 @@ static inline int neigh_hh_output(const
static inline int neigh_output(struct neighbour *n, struct sk_buff *skb,
bool skip_cache)
{
@@ -177,7 +177,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
if ((n->nud_state & NUD_CONNECTED) && hh->hh_len && !skip_cache)
return neigh_hh_output(hh, skb);
-@@ -544,7 +544,7 @@ struct neighbour_cb {
+@@ -543,7 +543,7 @@ struct neighbour_cb {
#define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb)
diff --git a/patches/serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch b/patches/serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch
new file mode 100644
index 000000000000..6db09fe0369c
--- /dev/null
+++ b/patches/serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch
@@ -0,0 +1,102 @@
+From: John Ogness <john.ogness@linutronix.de>
+Date: Fri, 10 Jan 2020 16:45:32 +0106
+Subject: [PATCH] serial: 8250: fsl/ingenic/mtk: fix atomic console
+
+A few 8250 implementations have their own IER access. If the port
+is a console, wrap the accesses with console_atomic_lock.
+
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/tty/serial/8250/8250_fsl.c | 9 +++++++++
+ drivers/tty/serial/8250/8250_ingenic.c | 7 +++++++
+ drivers/tty/serial/8250/8250_mtk.c | 29 +++++++++++++++++++++++++++--
+ 3 files changed, 43 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250_fsl.c
++++ b/drivers/tty/serial/8250/8250_fsl.c
+@@ -57,9 +57,18 @@ int fsl8250_handle_irq(struct uart_port
+
+ /* Stop processing interrupts on input overrun */
+ if ((orig_lsr & UART_LSR_OE) && (up->overrun_backoff_time_ms > 0)) {
++ unsigned int ca_flags;
+ unsigned long delay;
++ bool is_console;
+
++ is_console = uart_console(port);
++
++ if (is_console)
++ console_atomic_lock(&ca_flags);
+ up->ier = port->serial_in(port, UART_IER);
++ if (is_console)
++ console_atomic_unlock(ca_flags);
++
+ if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
+ port->ops->stop_rx(port);
+ } else {
+--- a/drivers/tty/serial/8250/8250_ingenic.c
++++ b/drivers/tty/serial/8250/8250_ingenic.c
+@@ -146,6 +146,8 @@ OF_EARLYCON_DECLARE(x1000_uart, "ingenic
+
+ static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
+ {
++ unsigned int flags;
++ bool is_console;
+ int ier;
+
+ switch (offset) {
+@@ -167,7 +169,12 @@ static void ingenic_uart_serial_out(stru
+ * If we have enabled modem status IRQs we should enable
+ * modem mode.
+ */
++ is_console = uart_console(p);
++ if (is_console)
++ console_atomic_lock(&flags);
+ ier = p->serial_in(p, UART_IER);
++ if (is_console)
++ console_atomic_unlock(flags);
+
+ if (ier & UART_IER_MSI)
+ value |= UART_MCR_MDCE | UART_MCR_FCM;
+--- a/drivers/tty/serial/8250/8250_mtk.c
++++ b/drivers/tty/serial/8250/8250_mtk.c
+@@ -212,12 +212,37 @@ static void mtk8250_shutdown(struct uart
+
+ static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask)
+ {
+- serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask));
++ struct uart_port *port = &up->port;
++ unsigned int flags;
++ unsigned int ier;
++ bool is_console;
++
++ is_console = uart_console(port);
++
++ if (is_console)
++ console_atomic_lock(&flags);
++
++ ier = serial_in(up, UART_IER);
++ serial_out(up, UART_IER, ier & (~mask));
++
++ if (is_console)
++ console_atomic_unlock(flags);
+ }
+
+ static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask)
+ {
+- serial_out(up, UART_IER, serial_in(up, UART_IER) | mask);
++ struct uart_port *port = &up->port;
++ unsigned int flags;
++ unsigned int ier;
++
++ if (uart_console(port))
++ console_atomic_lock(&flags);
++
++ ier = serial_in(up, UART_IER);
++ serial_out(up, UART_IER, ier | mask);
++
++ if (uart_console(port))
++ console_atomic_unlock(flags);
+ }
+
+ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
diff --git a/patches/serial-8250-only-atomic-lock-for-console.patch b/patches/serial-8250-only-atomic-lock-for-console.patch
new file mode 100644
index 000000000000..f149afaa5fbe
--- /dev/null
+++ b/patches/serial-8250-only-atomic-lock-for-console.patch
@@ -0,0 +1,384 @@
+From: John Ogness <john.ogness@linutronix.de>
+Date: Fri, 10 Jan 2020 16:45:31 +0106
+Subject: [PATCH] serial: 8250: only atomic lock for console
+
+The atomic console implementation requires that IER is synchronized
+between atomic and non-atomic usage. However, it was implemented such
+that the console_atomic_lock was performed for all IER access, even
+if that port was not a console.
+
+The implementation also used a usage counter to keep track of IER
+clear/restore windows. However, this is not needed because the
+console_atomic_lock synchronization of IER access with prevent any
+situations where IER is prematurely restored or left cleared.
+
+Move the IER access functions to inline macros. They will only
+console_atomic_lock if the port is a console. Remove the
+restore_ier() function by having clear_ier() return the prior IER
+value so that the caller can restore it using set_ier(). Rename the
+IER access functions to match other 8250 wrapper macros.
+
+Suggested-by: Dick Hollenbeck <dick@softplc.com>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+---
+ drivers/tty/serial/8250/8250.h | 65 +++++++++++++++++++---------
+ drivers/tty/serial/8250/8250_core.c | 6 +-
+ drivers/tty/serial/8250/8250_dma.c | 4 -
+ drivers/tty/serial/8250/8250_port.c | 81 ++++++++----------------------------
+ 4 files changed, 66 insertions(+), 90 deletions(-)
+
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -96,10 +96,6 @@ struct serial8250_config {
+ #define SERIAL8250_SHARE_IRQS 0
+ #endif
+
+-void set_ier(struct uart_8250_port *up, unsigned char ier);
+-void clear_ier(struct uart_8250_port *up);
+-void restore_ier(struct uart_8250_port *up);
+-
+ #define SERIAL8250_PORT_FLAGS(_base, _irq, _flags) \
+ { \
+ .iobase = _base, \
+@@ -134,39 +130,64 @@ static inline void serial_dl_write(struc
+ up->dl_write(up, value);
+ }
+
+-static inline bool serial8250_set_THRI(struct uart_8250_port *up)
++static inline void serial8250_set_IER(struct uart_8250_port *up,
++ unsigned char ier)
+ {
+- if (up->ier & UART_IER_THRI)
+- return false;
+- up->ier |= UART_IER_THRI;
+- serial_out(up, UART_IER, up->ier);
+- return true;
++ struct uart_port *port = &up->port;
++ unsigned int flags;
++ bool is_console;
++
++ is_console = uart_console(port);
++
++ if (is_console)
++ console_atomic_lock(&flags);
++
++ serial_out(up, UART_IER, ier);
++
++ if (is_console)
++ console_atomic_unlock(flags);
+ }
+
+-static inline bool serial8250_set_THRI_sier(struct uart_8250_port *up)
++static inline unsigned char serial8250_clear_IER(struct uart_8250_port *up)
+ {
+- if (up->ier & UART_IER_THRI)
+- return false;
+- up->ier |= UART_IER_THRI;
+- set_ier(up, up->ier);
+- return true;
++ struct uart_port *port = &up->port;
++ unsigned int clearval = 0;
++ unsigned int prior;
++ unsigned int flags;
++ bool is_console;
++
++ is_console = uart_console(port);
++
++ if (up->capabilities & UART_CAP_UUE)
++ clearval = UART_IER_UUE;
++
++ if (is_console)
++ console_atomic_lock(&flags);
++
++ prior = serial_port_in(port, UART_IER);
++ serial_port_out(port, UART_IER, clearval);
++
++ if (is_console)
++ console_atomic_unlock(flags);
++
++ return prior;
+ }
+
+-static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
++static inline bool serial8250_set_THRI(struct uart_8250_port *up)
+ {
+- if (!(up->ier & UART_IER_THRI))
++ if (up->ier & UART_IER_THRI)
+ return false;
+- up->ier &= ~UART_IER_THRI;
+- serial_out(up, UART_IER, up->ier);
++ up->ier |= UART_IER_THRI;
++ serial8250_set_IER(up, up->ier);
+ return true;
+ }
+
+-static inline bool serial8250_clear_THRI_sier(struct uart_8250_port *up)
++static inline bool serial8250_clear_THRI(struct uart_8250_port *up)
+ {
+ if (!(up->ier & UART_IER_THRI))
+ return false;
+ up->ier &= ~UART_IER_THRI;
+- set_ier(up, up->ier);
++ serial8250_set_IER(up, up->ier);
+ return true;
+ }
+
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -266,7 +266,7 @@ static void serial8250_timeout(struct ti
+ static void serial8250_backup_timeout(struct timer_list *t)
+ {
+ struct uart_8250_port *up = from_timer(up, t, timer);
+- unsigned int iir, lsr;
++ unsigned int iir, ier = 0, lsr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+@@ -276,7 +276,7 @@ static void serial8250_backup_timeout(st
+ * based handler.
+ */
+ if (up->port.irq)
+- clear_ier(up);
++ ier = serial8250_clear_IER(up);
+
+ iir = serial_in(up, UART_IIR);
+
+@@ -299,7 +299,7 @@ static void serial8250_backup_timeout(st
+ serial8250_tx_chars(up);
+
+ if (up->port.irq)
+- restore_ier(up);
++ serial8250_set_IER(up, ier);
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+--- a/drivers/tty/serial/8250/8250_dma.c
++++ b/drivers/tty/serial/8250/8250_dma.c
+@@ -35,7 +35,7 @@ static void __dma_tx_complete(void *para
+
+ ret = serial8250_tx_dma(p);
+ if (ret)
+- serial8250_set_THRI_sier(p);
++ serial8250_set_THRI(p);
+
+ spin_unlock_irqrestore(&p->port.lock, flags);
+ }
+@@ -98,7 +98,7 @@ int serial8250_tx_dma(struct uart_8250_p
+ dma_async_issue_pending(dma->txchan);
+ if (dma->tx_err) {
+ dma->tx_err = 0;
+- serial8250_clear_THRI_sier(p);
++ serial8250_clear_THRI(p);
+ }
+ return 0;
+ err:
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -721,7 +721,7 @@ static void serial8250_set_sleep(struct
+ serial_out(p, UART_EFR, UART_EFR_ECB);
+ serial_out(p, UART_LCR, 0);
+ }
+- set_ier(p, sleep ? UART_IERX_SLEEP : 0);
++ serial8250_set_IER(p, sleep ? UART_IERX_SLEEP : 0);
+ if (p->capabilities & UART_CAP_EFR) {
+ serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
+ serial_out(p, UART_EFR, efr);
+@@ -1390,7 +1390,7 @@ static void serial8250_stop_rx(struct ua
+
+ up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
+ up->port.read_status_mask &= ~UART_LSR_DR;
+- set_ier(up, up->ier);
++ serial8250_set_IER(up, up->ier);
+
+ serial8250_rpm_put(up);
+ }
+@@ -1408,7 +1408,7 @@ static void __do_stop_tx_rs485(struct ua
+ serial8250_clear_and_reinit_fifos(p);
+
+ p->ier |= UART_IER_RLSI | UART_IER_RDI;
+- set_ier(p, p->ier);
++ serial8250_set_IER(p, p->ier);
+ }
+ }
+ static enum hrtimer_restart serial8250_em485_handle_stop_tx(struct hrtimer *t)
+@@ -1459,7 +1459,7 @@ static void __stop_tx_rs485(struct uart_
+
+ static inline void __do_stop_tx(struct uart_8250_port *p)
+ {
+- if (serial8250_clear_THRI_sier(p))
++ if (serial8250_clear_THRI(p))
+ serial8250_rpm_put_tx(p);
+ }
+
+@@ -1509,7 +1509,7 @@ static inline void __start_tx(struct uar
+ if (up->dma && !up->dma->tx_dma(up))
+ return;
+
+- if (serial8250_set_THRI_sier(up)) {
++ if (serial8250_set_THRI(up)) {
+ if (up->bugs & UART_BUG_TXEN) {
+ unsigned char lsr;
+
+@@ -1616,7 +1616,7 @@ static void serial8250_disable_ms(struct
+ mctrl_gpio_disable_ms(up->gpios);
+
+ up->ier &= ~UART_IER_MSI;
+- set_ier(up, up->ier);
++ serial8250_set_IER(up, up->ier);
+ }
+
+ static void serial8250_enable_ms(struct uart_port *port)
+@@ -1632,7 +1632,7 @@ static void serial8250_enable_ms(struct
+ up->ier |= UART_IER_MSI;
+
+ serial8250_rpm_get(up);
+- set_ier(up, up->ier);
++ serial8250_set_IER(up, up->ier);
+ serial8250_rpm_put(up);
+ }
+
+@@ -1991,54 +1991,6 @@ static void wait_for_xmitr(struct uart_8
+ }
+ }
+
+-static atomic_t ier_counter = ATOMIC_INIT(0);
+-static atomic_t ier_value = ATOMIC_INIT(0);
+-
+-void set_ier(struct uart_8250_port *up, unsigned char ier)
+-{
+- struct uart_port *port = &up->port;
+- unsigned int flags;
+-
+- console_atomic_lock(&flags);
+- if (atomic_read(&ier_counter) > 0)
+- atomic_set(&ier_value, ier);
+- else
+- serial_port_out(port, UART_IER, ier);
+- console_atomic_unlock(flags);
+-}
+-
+-void clear_ier(struct uart_8250_port *up)
+-{
+- struct uart_port *port = &up->port;
+- unsigned int ier_cleared = 0;
+- unsigned int flags;
+- unsigned int ier;
+-
+- console_atomic_lock(&flags);
+- atomic_inc(&ier_counter);
+- ier = serial_port_in(port, UART_IER);
+- if (up->capabilities & UART_CAP_UUE)
+- ier_cleared = UART_IER_UUE;
+- if (ier != ier_cleared) {
+- serial_port_out(port, UART_IER, ier_cleared);
+- atomic_set(&ier_value, ier);
+- }
+- console_atomic_unlock(flags);
+-}
+-EXPORT_SYMBOL_GPL(clear_ier);
+-
+-void restore_ier(struct uart_8250_port *up)
+-{
+- struct uart_port *port = &up->port;
+- unsigned int flags;
+-
+- console_atomic_lock(&flags);
+- if (atomic_fetch_dec(&ier_counter) == 1)
+- serial_port_out(port, UART_IER, atomic_read(&ier_value));
+- console_atomic_unlock(flags);
+-}
+-EXPORT_SYMBOL_GPL(restore_ier);
+-
+ #ifdef CONFIG_CONSOLE_POLL
+ /*
+ * Console polling routines for writing and reading from the uart while
+@@ -2070,10 +2022,11 @@ static int serial8250_get_poll_char(stru
+ static void serial8250_put_poll_char(struct uart_port *port,
+ unsigned char c)
+ {
++ unsigned int ier;
+ struct uart_8250_port *up = up_to_u8250p(port);
+
+ serial8250_rpm_get(up);
+- clear_ier(up);
++ ier = serial8250_clear_IER(up);
+
+ wait_for_xmitr(up, BOTH_EMPTY);
+ /*
+@@ -2086,7 +2039,7 @@ static void serial8250_put_poll_char(str
+ * and restore the IER
+ */
+ wait_for_xmitr(up, BOTH_EMPTY);
+- restore_ier(up);
++ serial8250_set_IER(up, ier);
+ serial8250_rpm_put(up);
+ }
+
+@@ -2394,7 +2347,7 @@ void serial8250_do_shutdown(struct uart_
+ */
+ spin_lock_irqsave(&port->lock, flags);
+ up->ier = 0;
+- set_ier(up, 0);
++ serial8250_set_IER(up, 0);
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ synchronize_irq(port->irq);
+@@ -2679,7 +2632,7 @@ serial8250_do_set_termios(struct uart_po
+ if (up->capabilities & UART_CAP_RTOIE)
+ up->ier |= UART_IER_RTOIE;
+
+- set_ier(up, up->ier);
++ serial8250_set_IER(up, up->ier);
+
+ if (up->capabilities & UART_CAP_EFR) {
+ unsigned char efr = 0;
+@@ -3189,12 +3142,13 @@ void serial8250_console_write_atomic(str
+ {
+ struct uart_port *port = &up->port;
+ unsigned int flags;
++ unsigned int ier;
+
+ console_atomic_lock(&flags);
+
+ touch_nmi_watchdog();
+
+- clear_ier(up);
++ ier = serial8250_clear_IER(up);
+
+ if (atomic_fetch_inc(&up->console_printing)) {
+ uart_console_write(port, "\n", 1,
+@@ -3204,7 +3158,7 @@ void serial8250_console_write_atomic(str
+ atomic_dec(&up->console_printing);
+
+ wait_for_xmitr(up, BOTH_EMPTY);
+- restore_ier(up);
++ serial8250_set_IER(up, ier);
+
+ console_atomic_unlock(flags);
+ }
+@@ -3220,13 +3174,14 @@ void serial8250_console_write(struct uar
+ {
+ struct uart_port *port = &up->port;
+ unsigned long flags;
++ unsigned int ier;
+
+ touch_nmi_watchdog();
+
+ serial8250_rpm_get(up);
+ spin_lock_irqsave(&port->lock, flags);
+
+- clear_ier(up);
++ ier = serial8250_clear_IER(up);
+
+ /* check scratch reg to see if port powered off during system sleep */
+ if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
+@@ -3243,7 +3198,7 @@ void serial8250_console_write(struct uar
+ * and restore the IER
+ */
+ wait_for_xmitr(up, BOTH_EMPTY);
+- restore_ier(up);
++ serial8250_set_IER(up, ier);
+
+ /*
+ * The receive handling will happen properly because the
diff --git a/patches/series b/patches/series
index 5b7cc4b2a302..892ab591e902 100644
--- a/patches/series
+++ b/patches/series
@@ -82,6 +82,8 @@ printk-kmsg_dump-remove-mutex-usage.patch
printk-devkmsg-read-Return-EPIPE-when-the-first-mess.patch
printk-handle-iterating-while-buffer-changing.patch
printk-hack-out-emergency-loglevel-usage.patch
+serial-8250-only-atomic-lock-for-console.patch
+serial-8250-fsl-ingenic-mtk-fix-atomic-console.patch
############################################################
# POSTED
diff --git a/patches/userfaultfd-Use-a-seqlock-instead-of-seqcount.patch b/patches/userfaultfd-Use-a-seqlock-instead-of-seqcount.patch
index b7f6945d0e7d..4612a45d0e36 100644
--- a/patches/userfaultfd-Use-a-seqlock-instead-of-seqcount.patch
+++ b/patches/userfaultfd-Use-a-seqlock-instead-of-seqcount.patch
@@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
if (need_wakeup)
__wake_userfault(ctx, range);
}
-@@ -1935,7 +1935,7 @@ static void init_once_userfaultfd_ctx(vo
+@@ -1939,7 +1939,7 @@ static void init_once_userfaultfd_ctx(vo
init_waitqueue_head(&ctx->fault_wqh);
init_waitqueue_head(&ctx->event_wqh);
init_waitqueue_head(&ctx->fd_wqh);