1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
From ebdec06c58c4330925d5603649542827bf7bff25 Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Mon, 30 Nov 2020 01:42:05 +0106
Subject: [PATCH 103/323] printk: change @console_seq to atomic64_t
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.10/older/patches-5.10.204-rt100.tar.xz
In preparation for atomic printing, change @console_seq to atomic
so that it can be accessed without requiring @console_sem.
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/printk/printk.c | 34 +++++++++++++++++++---------------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0ae184675e86..2bc9904fd8ab 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -368,12 +368,13 @@ static u64 syslog_seq;
static size_t syslog_partial;
static bool syslog_time;
-/* All 3 protected by @console_sem. */
-/* the next printk record to write to the console */
-static u64 console_seq;
+/* Both protected by @console_sem. */
static u64 exclusive_console_stop_seq;
static unsigned long console_dropped;
+/* the next printk record to write to the console */
+static atomic64_t console_seq = ATOMIC64_INIT(0);
+
struct latched_seq {
seqcount_latch_t latch;
u64 val[2];
@@ -2273,7 +2274,7 @@ EXPORT_SYMBOL(printk);
#define prb_first_valid_seq(rb) 0
static u64 syslog_seq;
-static u64 console_seq;
+static atomic64_t console_seq = ATOMIC64_INIT(0);
static u64 exclusive_console_stop_seq;
static unsigned long console_dropped;
@@ -2588,6 +2589,7 @@ void console_unlock(void)
bool do_cond_resched, retry;
struct printk_info info;
struct printk_record r;
+ u64 seq;
if (console_suspended) {
up_console_sem();
@@ -2630,12 +2632,14 @@ void console_unlock(void)
size_t len;
skip:
- if (!prb_read_valid(prb, console_seq, &r))
+ seq = atomic64_read(&console_seq);
+ if (!prb_read_valid(prb, seq, &r))
break;
- if (console_seq != r.info->seq) {
- console_dropped += r.info->seq - console_seq;
- console_seq = r.info->seq;
+ if (seq != r.info->seq) {
+ console_dropped += r.info->seq - seq;
+ atomic64_set(&console_seq, r.info->seq);
+ seq = r.info->seq;
}
if (suppress_message_printing(r.info->level)) {
@@ -2644,13 +2648,13 @@ void console_unlock(void)
* directly to the console when we received it, and
* record that has level above the console loglevel.
*/
- console_seq++;
+ atomic64_set(&console_seq, seq + 1);
goto skip;
}
/* Output to all consoles once old messages replayed. */
if (unlikely(exclusive_console &&
- console_seq >= exclusive_console_stop_seq)) {
+ seq >= exclusive_console_stop_seq)) {
exclusive_console = NULL;
}
@@ -2671,7 +2675,7 @@ void console_unlock(void)
len = record_print_text(&r,
console_msg_format & MSG_FORMAT_SYSLOG,
printk_time);
- console_seq++;
+ atomic64_set(&console_seq, seq + 1);
/*
* While actively printing out messages, if another printk()
@@ -2702,7 +2706,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(prb, console_seq, NULL);
+ retry = prb_read_valid(prb, atomic64_read(&console_seq), NULL);
if (retry && console_trylock())
goto again;
}
@@ -2765,7 +2769,7 @@ void console_flush_on_panic(enum con_flush_mode mode)
console_may_schedule = 0;
if (mode == CONSOLE_REPLAY_ALL)
- console_seq = prb_first_valid_seq(prb);
+ atomic64_set(&console_seq, prb_first_valid_seq(prb));
console_unlock();
}
@@ -3002,11 +3006,11 @@ void register_console(struct console *newcon)
* ignores console_lock.
*/
exclusive_console = newcon;
- exclusive_console_stop_seq = console_seq;
+ exclusive_console_stop_seq = atomic64_read(&console_seq);
/* Get a consistent copy of @syslog_seq. */
spin_lock_irqsave(&syslog_lock, flags);
- console_seq = syslog_seq;
+ atomic64_set(&console_seq, syslog_seq);
spin_unlock_irqrestore(&syslog_lock, flags);
}
console_unlock();
--
2.43.0
|