From patchwork Sun Feb 18 18:57:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 774033 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A85546F09B; Sun, 18 Feb 2024 19:04:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708283075; cv=none; b=ooRR9dVBI0UcwFBp8zIu06DK9/rxerYmFct6AmLUn7jyUakUNgdr7qkCGAvXruL52KFwN0DLJG75dCyunSMNqYOJzTSBNqKvGhzGUUXdA7F2rp/ykjNJx0BPf4un+CWt7y2QXCMAzy1+rWO+AuXWLo6+XmjBqUQ76GvKySzyQog= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708283075; c=relaxed/simple; bh=HasGcnsQPSL+51DxJXDfrG8HXukFZjehWiaU2ph0T/w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=ORgepS+1ySG5mjfXLwPqsP4+P20CTb+DUSFCApEEpIugvnCrltawIBltJR9w9rmcSdgoT2eDZ23cHFunsSosgy4j9FArazqM0fW3uvyMKRFLVtFi9BtHeKzV2AyH0+cRspq6POEtt55K1Ioed6UMqRKiPOa5DGnTGFVpd+Cs+gY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=QbZvSBMy; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1z8+tEXm; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="QbZvSBMy"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1z8+tEXm" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1708282668; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T7h0W3N0f4G0pvkySvFkTqS4E2wnXwr34/jX5hTg2E0=; b=QbZvSBMyDM4LOXmsINAW3w29lQi6+iV6oQkdlkV+GEv4sBYFoXHoVGk4LYf57RGYMZm3Lw Agq6rijvE5UuJlE5kduRrbGQHWNTHZ7CR9JG8p8iIUoQuYgOuogv5b5S2koYAlFnLykNpP BIcvF321vrpUKDgkTI0JnGQe2D69ltp0PKCjHlY/Mio9lGQw5UMcCHy29ZOajsOxjue1cB X4umV+QaQqzODLrSyJc0ZAuZGJSYcA6uKzldZvSMX5nPRvUH8cawUaTYPzzZo2d2OuzuIW R+dkjjwKUNILaScRlyDCvBK91fi0MuotaUffV7vgIsZR6lqLkcsmWhCZvm9PCg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1708282668; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T7h0W3N0f4G0pvkySvFkTqS4E2wnXwr34/jX5hTg2E0=; b=1z8+tEXmXQ18FV+rBWbYgc0kRFK8G2HiNfmJFiIet43GfimLO57gHMXL7MJAJy1NTAVxVb 5IVL+++Q0XAAiiDA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , linux-serial@vger.kernel.org, =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH printk v2 01/26] serial: core: Provide port lock wrappers Date: Sun, 18 Feb 2024 20:03:01 +0106 Message-Id: <20240218185726.1994771-2-john.ogness@linutronix.de> In-Reply-To: <20240218185726.1994771-1-john.ogness@linutronix.de> References: <20240218185726.1994771-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Thomas Gleixner mainline commit: b0af4bcb49464c221ad5f95d40f2b1b252ceedcc When a serial port is used for kernel console output, then all modifications to the UART registers which are done from other contexts, e.g. getty, termios, are interference points for the kernel console. So far this has been ignored and the printk output is based on the principle of hope. The rework of the console infrastructure which aims to support threaded and atomic consoles, requires to mark sections which modify the UART registers as unsafe. This allows the atomic write function to make informed decisions and eventually to restore operational state. It also allows to prevent the regular UART code from modifying UART registers while printk output is in progress. All modifications of UART registers are guarded by the UART port lock, which provides an obvious synchronization point with the console infrastructure. Provide wrapper functions for spin_[un]lock*(port->lock) invocations so that the console mechanics can be applied later on at a single place and does not require to copy the same logic all over the drivers. Signed-off-by: Thomas Gleixner Reviewed-by: Ilpo Järvinen Signed-off-by: John Ogness Link: https://lore.kernel.org/r/20230914183831.587273-2-john.ogness@linutronix.de Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 79 +++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bb6f073bc159..f1d5c0d1568c 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -588,6 +588,85 @@ struct uart_port { void *private_data; /* generic platform data pointer */ }; +/** + * uart_port_lock - Lock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock(struct uart_port *up) +{ + spin_lock(&up->lock); +} + +/** + * uart_port_lock_irq - Lock the UART port and disable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_lock_irq(struct uart_port *up) +{ + spin_lock_irq(&up->lock); +} + +/** + * uart_port_lock_irqsave - Lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + */ +static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) +{ + spin_lock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_trylock - Try to lock the UART port + * @up: Pointer to UART port structure + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock(struct uart_port *up) +{ + return spin_trylock(&up->lock); +} + +/** + * uart_port_trylock_irqsave - Try to lock the UART port, save and disable interrupts + * @up: Pointer to UART port structure + * @flags: Pointer to interrupt flags storage + * + * Returns: True if lock was acquired, false otherwise + */ +static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) +{ + return spin_trylock_irqsave(&up->lock, *flags); +} + +/** + * uart_port_unlock - Unlock the UART port + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock(struct uart_port *up) +{ + spin_unlock(&up->lock); +} + +/** + * uart_port_unlock_irq - Unlock the UART port and re-enable interrupts + * @up: Pointer to UART port structure + */ +static inline void uart_port_unlock_irq(struct uart_port *up) +{ + spin_unlock_irq(&up->lock); +} + +/** + * uart_port_lock_irqrestore - Unlock the UART port, restore interrupts + * @up: Pointer to UART port structure + * @flags: The saved interrupt flags for restore + */ +static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) +{ + spin_unlock_irqrestore(&up->lock, flags); +} + static inline int serial_port_in(struct uart_port *up, int offset) { return up->serial_in(up, offset); From patchwork Sun Feb 18 18:57:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 774032 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A858E6F507; Sun, 18 Feb 2024 19:04:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708283076; cv=none; b=ppMCEYoH98Tb/WHdKsxaa4ATXJb0XjB+OyuMqdyp01u+EigJTtTOqBhAwEjL6uzYiEjF1WlrZYNTBhxWpNZ5EGzzlnMWD2jNpVJ8nyJx0GOIyNW5nnsCMmbtbEKsE9/geATzpf6+2wSNxZSPih7acV6s16pX2MPPuYEuQ3pf2NA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708283076; c=relaxed/simple; bh=keGeNhzs3xp+qeYPU8cNtdBOt0vcNU3zMqIHr/8gsdk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EFNV6inn4TM1o/YYlwAMDMLLhVF2EkQrfd+AWDTiwa7gtIAmMmdnWSaLw7Q4xCTWwO9UsFyLpi4bxBvzQf/PoOSzVxx3sk5wKBsMcSU0QS7htnQuZrI494X/DQh822IoFnt/yNw5zfACaqaYEMypVsiza16W3HiGGCtKZPf7r0U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=hzsRMOH6; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=aTmN1BPg; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="hzsRMOH6"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="aTmN1BPg" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1708282669; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hl9qbklGnpInKmYvJoa6ZS5PHIy9GOhc0q9FzMa8X2Y=; b=hzsRMOH6xeWxc2o2bRi5V62jaRTvfs7zJ+P0LqBDGw2zp7XE/6L+IQGhAIrtviSmkoco4x 9eIgWPX+MYzeEF+BWttPOsMQfQp637cS3Ljr33qbYM0REFlEz+3GqCfKqDIX0XLYBkbH/K l9JX/WpwrANdf0ctJgkvSnfllg0p3BLmu4mhA7pmccbd/V+FqKDyzsgiq1/Ln/fU3EJuwI EO/SzKzaikWR4aiaskFaHBKwzNUgqzm3topJgtTZTG60Axn1vfYluAEdZA5b5ZMkUQnjcI 8tWHpYiq2ITkc4fiGkjXfwa2ndDHUnwfFQKhqfNEU5OYIfM8xQ9K9p3GtVKisQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1708282669; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hl9qbklGnpInKmYvJoa6ZS5PHIy9GOhc0q9FzMa8X2Y=; b=aTmN1BPgkJfjz5ghzY+8zNVy8iT7ckSrrKhBMJR8BN+z8EP3Hh0PLeU0D6cc7pLTCRm959 PY5rzrq5hPOljlDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Randy Dunlap , Greg Kroah-Hartman , Jiri Slaby , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , linux-serial@vger.kernel.org Subject: [PATCH printk v2 03/26] serial: core: fix kernel-doc for uart_port_unlock_irqrestore() Date: Sun, 18 Feb 2024 20:03:03 +0106 Message-Id: <20240218185726.1994771-4-john.ogness@linutronix.de> In-Reply-To: <20240218185726.1994771-1-john.ogness@linutronix.de> References: <20240218185726.1994771-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Randy Dunlap mainline commit: 29bff582b74ed0bdb7e6986482ad9e6799ea4d2f Fix the function name to avoid a kernel-doc warning: include/linux/serial_core.h:666: warning: expecting prototype for uart_port_lock_irqrestore(). Prototype was for uart_port_unlock_irqrestore() instead Fixes: b0af4bcb4946 ("serial: core: Provide port lock wrappers") Signed-off-by: Randy Dunlap Cc: Thomas Gleixner Cc: John Ogness Cc: linux-serial@vger.kernel.org Cc: Greg Kroah-Hartman Cc: Jiri Slaby Reviewed-by: John Ogness Link: https://lore.kernel.org/r/20230927044128.4748-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3091c62ec37b..89f7b6c63598 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -658,7 +658,7 @@ static inline void uart_port_unlock_irq(struct uart_port *up) } /** - * uart_port_lock_irqrestore - Unlock the UART port, restore interrupts + * uart_port_unlock_irqrestore - Unlock the UART port, restore interrupts * @up: Pointer to UART port structure * @flags: The saved interrupt flags for restore */ From patchwork Sun Feb 18 18:57:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Ogness X-Patchwork-Id: 774034 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BEFAD6F09B; Sun, 18 Feb 2024 18:57:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708282674; cv=none; b=AhgcbfS4eg6HlKfcNVIRC6xeRye+lEQZXd646F84cvdUimRUvJvStzmRq0oUyMvDp6MlbubOxn7fdaNlgguVjUjMQYBp7uk+gI2lSHAXc9tLzSa44G+hA5VZAX2upyIqDVWJBiHO+T7d/7zEQpI6ORJPY/zTNmmSqtEnGUGCvBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708282674; c=relaxed/simple; bh=Uh1a7N6liYSzDazmzjchFNl1uPkqsuEMN7I6bWMM5lg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=F8VK+cZaI17xAQQkQ98GiMYBrhgiKM39ALgkY1ZNze7Dlyr2qCWltIHKtAYy8v1sad4izTkuDFauF7DQPvwUD2bV35QWVSQVKFuheOVyozVa0R4Ay1EulMEGreVrdJerJZDb1rZn6v1Ho3bDzvBEeovBI7AxVc8jiz9Ja2EuFEw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=OxRI2d34; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Rsnkb8W7; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="OxRI2d34"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Rsnkb8W7" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1708282671; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xrTMG/IO2xEuBdqD5OxQ1/ULXhRtRhpYhyRMl+KnF7w=; b=OxRI2d34d6eZ84FJ7ek1LsuerkJcVIohMxOCIEONANmxjad1y70ujK/AQkOy/143chnRYk axXq9ozPgZaRTxPS2OU7FU/O2GmA4dQqaDAYVnThA0KVqDRntfohKh/LtQmkD6y6C6/PpO w5Mo7Fvy6+2N6uBZjtL8dfWxrur03oO6Riby83YgQu9pWCnLN3iuAnBMI0QZ8lP6gIHFqN wI3gEXimzNOiRYIOXA7IuqqFHlIQPWrFitlcfb249CDX8ATU6Ne+IliEJ+ba6VDCwX+OcB 8aTaUpAxr18hbUGOGraqr3e+Caqa7suhJtJvrivhatX1a6gL7hZM8e7x1aOLqg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1708282671; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xrTMG/IO2xEuBdqD5OxQ1/ULXhRtRhpYhyRMl+KnF7w=; b=Rsnkb8W7+dOJGMPJ0e2uA0Qw+jE3lvQlvn7hjAPcJzTKGdemWwBwLWErNiRpjvS9iouHHa VyIr8Gp7jlbNNSAg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Andy Shevchenko , Tony Lindgren , Geert Uytterhoeven , Justin Chen , Jiaqing Zhao , linux-serial@vger.kernel.org Subject: [PATCH printk v2 08/26] printk: nbcon: Implement processing in port->lock wrapper Date: Sun, 18 Feb 2024 20:03:08 +0106 Message-Id: <20240218185726.1994771-9-john.ogness@linutronix.de> In-Reply-To: <20240218185726.1994771-1-john.ogness@linutronix.de> References: <20240218185726.1994771-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-serial@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the port->lock wrappers uart_port_lock(), uart_port_unlock() (and their variants) only lock/unlock the spin_lock. If the port is an nbcon console, the wrappers must also acquire/release the console and mark the region as unsafe. This allows general port->lock synchronization to be synchronized with the nbcon console ownership. Add a flag to struct uart_port to track nbcon console ownership. Signed-off-by: John Ogness --- drivers/tty/serial/8250/8250_port.c | 1 + include/linux/printk.h | 13 +++++ include/linux/serial_core.h | 19 ++++++- kernel/printk/nbcon.c | 77 +++++++++++++++++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 141627370aab..16e2705b4867 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -3284,6 +3284,7 @@ void serial8250_init_port(struct uart_8250_port *up) struct uart_port *port = &up->port; spin_lock_init(&port->lock); + port->nbcon_locked_port = false; port->ctrl_id = 0; port->pm = NULL; port->ops = &serial8250_pops; diff --git a/include/linux/printk.h b/include/linux/printk.h index 8d5c5588eec9..ef57a4d93ae2 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -9,6 +9,8 @@ #include #include +struct uart_port; + extern const char linux_banner[]; extern const char linux_proc_banner[]; @@ -195,6 +197,8 @@ void show_regs_print_info(const char *log_lvl); extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; extern asmlinkage void dump_stack(void) __cold; void printk_trigger_flush(void); +extern void uart_nbcon_acquire(struct uart_port *up); +extern void uart_nbcon_release(struct uart_port *up); #else static inline __printf(1, 0) int vprintk(const char *s, va_list args) @@ -274,6 +278,15 @@ static inline void dump_stack(void) static inline void printk_trigger_flush(void) { } + +static inline void uart_nbcon_acquire(struct uart_port *up) +{ +} + +static inline void uart_nbcon_release(struct uart_port *up) +{ +} + #endif bool this_cpu_in_panic(void); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 89f7b6c63598..d4b93d721715 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -488,6 +488,7 @@ struct uart_port { struct uart_icount icount; /* statistics */ struct console *cons; /* struct console, if any */ + bool nbcon_locked_port; /* True, if the port is locked by nbcon */ /* flags must be updated while holding port mutex */ upf_t flags; @@ -595,6 +596,7 @@ struct uart_port { static inline void uart_port_lock(struct uart_port *up) { spin_lock(&up->lock); + uart_nbcon_acquire(up); } /** @@ -604,6 +606,7 @@ static inline void uart_port_lock(struct uart_port *up) static inline void uart_port_lock_irq(struct uart_port *up) { spin_lock_irq(&up->lock); + uart_nbcon_acquire(up); } /** @@ -614,6 +617,7 @@ static inline void uart_port_lock_irq(struct uart_port *up) static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags) { spin_lock_irqsave(&up->lock, *flags); + uart_nbcon_acquire(up); } /** @@ -624,7 +628,11 @@ static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *f */ static inline bool uart_port_trylock(struct uart_port *up) { - return spin_trylock(&up->lock); + if (!spin_trylock(&up->lock)) + return false; + + uart_nbcon_acquire(up); + return true; } /** @@ -636,7 +644,11 @@ static inline bool uart_port_trylock(struct uart_port *up) */ static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags) { - return spin_trylock_irqsave(&up->lock, *flags); + if (!spin_trylock_irqsave(&up->lock, *flags)) + return false; + + uart_nbcon_acquire(up); + return true; } /** @@ -645,6 +657,7 @@ static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long */ static inline void uart_port_unlock(struct uart_port *up) { + uart_nbcon_release(up); spin_unlock(&up->lock); } @@ -654,6 +667,7 @@ static inline void uart_port_unlock(struct uart_port *up) */ static inline void uart_port_unlock_irq(struct uart_port *up) { + uart_nbcon_release(up); spin_unlock_irq(&up->lock); } @@ -664,6 +678,7 @@ static inline void uart_port_unlock_irq(struct uart_port *up) */ static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags) { + uart_nbcon_release(up); spin_unlock_irqrestore(&up->lock, flags); } diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 8ecd76aa22e6..02e8fdc1ea43 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "internal.h" /* * Printk console printing implementation for consoles which does not depend @@ -995,3 +996,79 @@ void nbcon_free(struct console *con) con->pbufs = NULL; } + +static inline bool uart_is_nbcon(struct uart_port *up) +{ + int cookie; + bool ret; + + if (!uart_console(up)) + return false; + + cookie = console_srcu_read_lock(); + ret = (console_srcu_read_flags(up->cons) & CON_NBCON); + console_srcu_read_unlock(cookie); + return ret; +} + +/** + * uart_nbcon_acquire - The second half of the port locking wrapper + * @up: The uart port whose @lock was locked + * + * The uart_port_lock() wrappers will first lock the spin_lock @up->lock. + * Then this function is called to implement nbcon-specific processing. + * + * If @up is an nbcon console, this console will be acquired and marked as + * unsafe. Otherwise this function does nothing. + */ +void uart_nbcon_acquire(struct uart_port *up) +{ + struct console *con = up->cons; + struct nbcon_context ctxt; + + if (!uart_is_nbcon(up)) + return; + + WARN_ON_ONCE(up->nbcon_locked_port); + + do { + do { + memset(&ctxt, 0, sizeof(ctxt)); + ctxt.console = con; + ctxt.prio = NBCON_PRIO_NORMAL; + } while (!nbcon_context_try_acquire(&ctxt)); + + } while (!nbcon_context_enter_unsafe(&ctxt)); + + up->nbcon_locked_port = true; +} +EXPORT_SYMBOL_GPL(uart_nbcon_acquire); + +/** + * uart_nbcon_release - The first half of the port unlocking wrapper + * @up: The uart port whose @lock is about to be unlocked + * + * The uart_port_unlock() wrappers will first call this function to implement + * nbcon-specific processing. Then afterwards the uart_port_unlock() wrappers + * will unlock the spin_lock @up->lock. + * + * If @up is an nbcon console, the console will be marked as safe and + * released. Otherwise this function does nothing. + */ +void uart_nbcon_release(struct uart_port *up) +{ + struct console *con = up->cons; + struct nbcon_context ctxt = { + .console = con, + .prio = NBCON_PRIO_NORMAL, + }; + + if (!up->nbcon_locked_port) + return; + + if (nbcon_context_exit_unsafe(&ctxt)) + nbcon_context_release(&ctxt); + + up->nbcon_locked_port = false; +} +EXPORT_SYMBOL_GPL(uart_nbcon_release);