[Devel] [PATCH RHEL COMMIT] ve/printk: Virtualize console_*

Konstantin Khorenko khorenko at virtuozzo.com
Fri Oct 1 18:23:36 MSK 2021


The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after ark-5.14
------>
commit 037bdf09a9b12a4732c2b6f69d602401c8645b60
Author: Vladimir Davydov <vdavydov.dev at gmail.com>
Date:   Wed Sep 29 21:28:39 2021 +0300

    ve/printk: Virtualize console_*
    
    https://jira.sw.ru/browse/PSBM-17899
    
    Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
    Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
    
    +++
    ve/printk: Fix printk virtualization
    
    ve_printk() corrupts host's dmesg:
            # dmesg|wc -l
            599
            # vzctl create 101
            # vzctl set 101 --netif_add eth0 --save
            # vzctl start 101
            # vzctl exec 101 'tcpdump -w tcpdump.out -U -n -i eth0 esp'
            # dmesg|wc -l
            2
    
    Add missing parts of prinkt virtualization to fix this.
    
    https://jira.sw.ru/browse/PSBM-17899
    https://jira.sw.ru/browse/PSBM-105442
    
    Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
    
    Rebasing to vz9: part of vz8 commit:
     d63aeb311a64 ("ve/printk: printk virtualization")
    
    https://jira.sw.ru/browse/PSBM-133985
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 kernel/printk/printk.c | 45 ++++++++++++++++++++++-----------------------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index a994c2fe19c7..04244a3edeab 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -361,11 +361,6 @@ static DEFINE_RAW_SPINLOCK(syslog_lock);
 
 #ifdef CONFIG_PRINTK
 DECLARE_WAIT_QUEUE_HEAD(log_wait);
-/* All 3 protected by @console_sem. */
-/* the next printk record to write to the console */
-static u64 console_seq;
-static u64 exclusive_console_stop_seq;
-static unsigned long console_dropped;
 
 struct latched_seq {
 	seqcount_latch_t	latch;
@@ -418,6 +413,12 @@ static struct log_state {
 	size_t syslog_partial;
 	bool syslog_time;
 
+	/* All 3 protected by @console_sem. */
+	/* the next printk record to write to the console */
+	u64 console_seq;
+	u64 exclusive_console_stop_seq;
+	unsigned long console_dropped;
+
 	/*
 	 * The next printk record to read after the last 'clear' command. There are
 	 * two copies (updated with seqcount_latch) so that reads can locklessly
@@ -1954,6 +1955,7 @@ static int console_trylock_spinning(void)
 static void call_console_drivers(const char *ext_text, size_t ext_len,
 				 const char *text, size_t len)
 {
+	struct log_state *log = &init_log_state;
 	static char dropped_text[64];
 	size_t dropped_len = 0;
 	struct console *con;
@@ -1963,11 +1965,11 @@ static void call_console_drivers(const char *ext_text, size_t ext_len,
 	if (!console_drivers)
 		return;
 
-	if (console_dropped) {
+	if (log->console_dropped) {
 		dropped_len = snprintf(dropped_text, sizeof(dropped_text),
 				       "** %lu printk messages dropped **\n",
-				       console_dropped);
-		console_dropped = 0;
+				       log->console_dropped);
+		log->console_dropped = 0;
 	}
 
 	for_each_console(con) {
@@ -2302,10 +2304,6 @@ EXPORT_SYMBOL(printk);
 #define prb_read_valid(rb, seq, r)	false
 #define prb_first_valid_seq(rb)		0
 
-static u64 console_seq;
-static u64 exclusive_console_stop_seq;
-static unsigned long console_dropped;
-
 static size_t record_print_text(const struct printk_record *r,
 				bool syslog, bool time)
 {
@@ -2662,12 +2660,12 @@ void console_unlock(void)
 
 		printk_safe_enter_irqsave(flags);
 skip:
-		if (!prb_read_valid(log->prb, console_seq, &r))
+		if (!prb_read_valid(log->prb, log->console_seq, &r))
 			break;
 
-		if (console_seq != r.info->seq) {
-			console_dropped += r.info->seq - console_seq;
-			console_seq = r.info->seq;
+		if (log->console_seq != r.info->seq) {
+			log->console_dropped += r.info->seq - log->console_seq;
+			log->console_seq = r.info->seq;
 		}
 
 		if (suppress_message_printing(r.info->level)) {
@@ -2676,13 +2674,14 @@ void console_unlock(void)
 			 * directly to the console when we received it, and
 			 * record that has level above the console loglevel.
 			 */
-			console_seq++;
+			log->console_seq++;
 			goto skip;
 		}
 
 		/* Output to all consoles once old messages replayed. */
 		if (unlikely(exclusive_console &&
-			     console_seq >= exclusive_console_stop_seq)) {
+			     log->console_seq >=
+				log->exclusive_console_stop_seq)) {
 			exclusive_console = NULL;
 		}
 
@@ -2703,7 +2702,7 @@ void console_unlock(void)
 		len = record_print_text(&r,
 				console_msg_format & MSG_FORMAT_SYSLOG,
 				printk_time);
-		console_seq++;
+		log->console_seq++;
 
 		/*
 		 * While actively printing out messages, if another printk()
@@ -2738,7 +2737,7 @@ void console_unlock(void)
 	 * there's a new owner and the console_unlock() from them will do the
 	 * flush, no worries.
 	 */
-	retry = prb_read_valid(log->prb, console_seq, NULL);
+	retry = prb_read_valid(log->prb, log->console_seq, NULL);
 	printk_safe_exit_irqrestore(flags);
 
 	if (retry && console_trylock())
@@ -2808,7 +2807,7 @@ void console_flush_on_panic(enum con_flush_mode mode)
 		unsigned long flags;
 
 		printk_safe_enter_irqsave(flags);
-		console_seq = prb_first_valid_seq(log->prb);
+		log->console_seq = prb_first_valid_seq(log->prb);
 		printk_safe_exit_irqrestore(flags);
 	}
 	console_unlock();
@@ -3048,11 +3047,11 @@ void register_console(struct console *newcon)
 		 * ignores console_lock.
 		 */
 		exclusive_console = newcon;
-		exclusive_console_stop_seq = console_seq;
+		log->exclusive_console_stop_seq = log->console_seq;
 
 		/* Get a consistent copy of @syslog_seq. */
 		raw_spin_lock_irqsave(&syslog_lock, flags);
-		console_seq = log->syslog_seq;
+		log->console_seq = log->syslog_seq;
 		raw_spin_unlock_irqrestore(&syslog_lock, flags);
 	}
 	console_unlock();


More information about the Devel mailing list