Commit 8e20fc391711 ("serial_core: Move sysrq functions from header
file") converted the inline sysrq helpers to exported functions which
are now called for every received character and break signal also on
systems without CONFIG_MAGIC_SYSRQ_SERIAL instead of being optimised
away by the compiler.

Inlining these helpers again also avoids the function call overhead when
CONFIG_MAGIC_SYSRQ_SERIAL is enabled.

Fixes: 8e20fc391711 ("serial_core: Move sysrq functions from header file")
Cc: Dmitry Safonov <0x7f454...@gmail.com>
Signed-off-by: Johan Hovold <jo...@kernel.org>
---
 drivers/tty/serial/serial_core.c | 80 +-----------------------------
 include/linux/serial_core.h      | 85 ++++++++++++++++++++++++++++++--
 2 files changed, 84 insertions(+), 81 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index f6cf9cc4ce69..a714402dcf4e 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -41,8 +41,6 @@ static struct lock_class_key port_lock_key;
 
 #define HIGH_BITS_OFFSET       ((sizeof(long)-sizeof(int))*8)
 
-#define SYSRQ_TIMEOUT  (HZ * 5)
-
 static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
                                        struct ktermios *old_termios);
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
@@ -3163,7 +3161,7 @@ static DECLARE_WORK(sysrq_enable_work, uart_sysrq_on);
  *     Returns false if @ch is out of enabling sequence and should be
  *     handled some other way, true if @ch was consumed.
  */
-static bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
+bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch)
 {
        int sysrq_toggle_seq_len = strlen(sysrq_toggle_seq);
 
@@ -3186,83 +3184,9 @@ static bool uart_try_toggle_sysrq(struct uart_port 
*port, unsigned int ch)
        port->sysrq = 0;
        return true;
 }
-#else
-static inline bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int 
ch)
-{
-       return false;
-}
+EXPORT_SYMBOL_GPL(uart_try_toggle_sysrq);
 #endif
 
-int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
-{
-       if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
-               return 0;
-
-       if (!port->has_sysrq || !port->sysrq)
-               return 0;
-
-       if (ch && time_before(jiffies, port->sysrq)) {
-               if (sysrq_mask()) {
-                       handle_sysrq(ch);
-                       port->sysrq = 0;
-                       return 1;
-               }
-               if (uart_try_toggle_sysrq(port, ch))
-                       return 1;
-       }
-       port->sysrq = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_handle_sysrq_char);
-
-int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch)
-{
-       if (!IS_ENABLED(CONFIG_MAGIC_SYSRQ_SERIAL))
-               return 0;
-
-       if (!port->has_sysrq || !port->sysrq)
-               return 0;
-
-       if (ch && time_before(jiffies, port->sysrq)) {
-               if (sysrq_mask()) {
-                       port->sysrq_ch = ch;
-                       port->sysrq = 0;
-                       return 1;
-               }
-               if (uart_try_toggle_sysrq(port, ch))
-                       return 1;
-       }
-       port->sysrq = 0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_prepare_sysrq_char);
-
-/*
- * We do the SysRQ and SAK checking like this...
- */
-int uart_handle_break(struct uart_port *port)
-{
-       struct uart_state *state = port->state;
-
-       if (port->handle_break)
-               port->handle_break(port);
-
-       if (port->has_sysrq && uart_console(port)) {
-               if (!port->sysrq) {
-                       port->sysrq = jiffies + SYSRQ_TIMEOUT;
-                       return 1;
-               }
-               port->sysrq = 0;
-       }
-
-       if (port->flags & UPF_SAK)
-               do_SAK(state->port.tty);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(uart_handle_break);
-
 EXPORT_SYMBOL(uart_write_wakeup);
 EXPORT_SYMBOL(uart_register_driver);
 EXPORT_SYMBOL(uart_unregister_driver);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 858c5dd926ad..a8a213b71553 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -460,8 +460,49 @@ extern void uart_handle_cts_change(struct uart_port *uport,
 extern void uart_insert_char(struct uart_port *port, unsigned int status,
                 unsigned int overrun, unsigned int ch, unsigned int flag);
 
-extern int uart_handle_sysrq_char(struct uart_port *port, unsigned int ch);
-extern int uart_prepare_sysrq_char(struct uart_port *port, unsigned int ch);
+#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
+
+#define SYSRQ_TIMEOUT  (HZ * 5)
+
+bool uart_try_toggle_sysrq(struct uart_port *port, unsigned int ch);
+
+static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int 
ch)
+{
+       if (!port->has_sysrq || !port->sysrq)
+               return 0;
+
+       if (ch && time_before(jiffies, port->sysrq)) {
+               if (sysrq_mask()) {
+                       handle_sysrq(ch);
+                       port->sysrq = 0;
+                       return 1;
+               }
+               if (uart_try_toggle_sysrq(port, ch))
+                       return 1;
+       }
+       port->sysrq = 0;
+
+       return 0;
+}
+
+static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int 
ch)
+{
+       if (!port->has_sysrq || !port->sysrq)
+               return 0;
+
+       if (ch && time_before(jiffies, port->sysrq)) {
+               if (sysrq_mask()) {
+                       port->sysrq_ch = ch;
+                       port->sysrq = 0;
+                       return 1;
+               }
+               if (uart_try_toggle_sysrq(port, ch))
+                       return 1;
+       }
+       port->sysrq = 0;
+
+       return 0;
+}
 
 static inline void uart_unlock_and_check_sysrq(struct uart_port *port, 
unsigned long irqflags)
 {
@@ -480,8 +521,46 @@ static inline void uart_unlock_and_check_sysrq(struct 
uart_port *port, unsigned
        if (sysrq_ch)
                handle_sysrq(sysrq_ch);
 }
+#else  /* CONFIG_MAGIC_SYSRQ_SERIAL */
+static inline int uart_handle_sysrq_char(struct uart_port *port, unsigned int 
ch)
+{
+       return 0;
+}
 
-extern int uart_handle_break(struct uart_port *port);
+static inline int uart_prepare_sysrq_char(struct uart_port *port, unsigned int 
ch)
+{
+       return 0;
+}
+
+static inline void uart_unlock_and_check_sysrq(struct uart_port *port, 
unsigned long irqflags)
+{
+       spin_unlock_irqrestore(&port->lock, irqflags);
+}
+#endif /* CONFIG_MAGIC_SYSRQ_SERIAL */
+
+/*
+ * We do the SysRQ and SAK checking like this...
+ */
+static inline int uart_handle_break(struct uart_port *port)
+{
+       struct uart_state *state = port->state;
+
+       if (port->handle_break)
+               port->handle_break(port);
+
+#ifdef CONFIG_MAGIC_SYSRQ_SERIAL
+       if (port->has_sysrq && uart_console(port)) {
+               if (!port->sysrq) {
+                       port->sysrq = jiffies + SYSRQ_TIMEOUT;
+                       return 1;
+               }
+               port->sysrq = 0;
+       }
+#endif
+       if (port->flags & UPF_SAK)
+               do_SAK(state->port.tty);
+       return 0;
+}
 
 /*
  *     UART_ENABLE_MS - determine if port should enable modem status irqs
-- 
2.26.2

Reply via email to