Skip to content

Commit 848a9c1

Browse files
jognesspmladek
authored andcommitted
printk: relieve console_lock of list synchronization duties
The console_list_lock provides synchronization for console list and console->flags updates. All call sites that were using the console_lock for this synchronization have either switched to use the console_list_lock or the SRCU list iterator. Remove console_lock usage for console list updates and console->flags updates. Signed-off-by: John Ogness <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e2b3965 commit 848a9c1

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

kernel/printk/printk.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ EXPORT_SYMBOL(oops_in_progress);
8686
static DEFINE_MUTEX(console_mutex);
8787

8888
/*
89-
* console_sem protects console_list and console->flags updates, and also
90-
* provides serialization for access to the entire console driver system.
89+
* console_sem protects updates to console->seq and console_suspended,
90+
* and also provides serialization for console printing.
9191
*/
9292
static DEFINE_SEMAPHORE(console_sem);
9393
HLIST_HEAD(console_list);
@@ -2640,10 +2640,10 @@ static int console_cpu_notify(unsigned int cpu)
26402640
}
26412641

26422642
/**
2643-
* console_lock - lock the console system for exclusive use.
2643+
* console_lock - block the console subsystem from printing
26442644
*
2645-
* Acquires a lock which guarantees that the caller has
2646-
* exclusive access to the console system and console_list.
2645+
* Acquires a lock which guarantees that no consoles will
2646+
* be in or enter their write() callback.
26472647
*
26482648
* Can sleep, returns nothing.
26492649
*/
@@ -2660,10 +2660,10 @@ void console_lock(void)
26602660
EXPORT_SYMBOL(console_lock);
26612661

26622662
/**
2663-
* console_trylock - try to lock the console system for exclusive use.
2663+
* console_trylock - try to block the console subsystem from printing
26642664
*
2665-
* Try to acquire a lock which guarantees that the caller has exclusive
2666-
* access to the console system and console_list.
2665+
* Try to acquire a lock which guarantees that no consoles will
2666+
* be in or enter their write() callback.
26672667
*
26682668
* returns 1 on success, and 0 on failure to acquire the lock.
26692669
*/
@@ -2920,10 +2920,10 @@ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *handove
29202920
}
29212921

29222922
/**
2923-
* console_unlock - unlock the console system
2923+
* console_unlock - unblock the console subsystem from printing
29242924
*
2925-
* Releases the console_lock which the caller holds on the console system
2926-
* and the console driver list.
2925+
* Releases the console_lock which the caller holds to block printing of
2926+
* the console subsystem.
29272927
*
29282928
* While the console_lock was held, console output may have been buffered
29292929
* by printk(). If this is the case, console_unlock(); emits
@@ -3110,9 +3110,7 @@ void console_stop(struct console *console)
31103110
{
31113111
__pr_flush(console, 1000, true);
31123112
console_list_lock();
3113-
console_lock();
31143113
console_srcu_write_flags(console, console->flags & ~CON_ENABLED);
3115-
console_unlock();
31163114
console_list_unlock();
31173115

31183116
/*
@@ -3128,9 +3126,7 @@ EXPORT_SYMBOL(console_stop);
31283126
void console_start(struct console *console)
31293127
{
31303128
console_list_lock();
3131-
console_lock();
31323129
console_srcu_write_flags(console, console->flags | CON_ENABLED);
3133-
console_unlock();
31343130
console_list_unlock();
31353131
__pr_flush(console, 1000, true);
31363132
}
@@ -3247,6 +3243,12 @@ static void console_init_seq(struct console *newcon, bool bootcon_registered)
32473243
* the furthest behind.
32483244
*/
32493245
if (bootcon_registered && !keep_bootcon) {
3246+
/*
3247+
* Hold the console_lock to stop console printing and
3248+
* guarantee safe access to console->seq.
3249+
*/
3250+
console_lock();
3251+
32503252
/*
32513253
* Flush all consoles and set the console to start at
32523254
* the next unprinted sequence number.
@@ -3273,6 +3275,8 @@ static void console_init_seq(struct console *newcon, bool bootcon_registered)
32733275
}
32743276
}
32753277
}
3278+
3279+
console_unlock();
32763280
}
32773281
}
32783282
}
@@ -3371,7 +3375,6 @@ void register_console(struct console *newcon)
33713375
}
33723376

33733377
newcon->dropped = 0;
3374-
console_lock();
33753378
console_init_seq(newcon, bootcon_registered);
33763379

33773380
/*
@@ -3391,7 +3394,6 @@ void register_console(struct console *newcon)
33913394
} else {
33923395
hlist_add_behind_rcu(&newcon->node, console_list.first);
33933396
}
3394-
console_unlock();
33953397

33963398
/*
33973399
* No need to synchronize SRCU here! The caller does not rely
@@ -3439,15 +3441,11 @@ static int unregister_console_locked(struct console *console)
34393441
if (res > 0)
34403442
return 0;
34413443

3442-
console_lock();
3443-
34443444
/* Disable it unconditionally */
34453445
console_srcu_write_flags(console, console->flags & ~CON_ENABLED);
34463446

3447-
if (!console_is_registered_locked(console)) {
3448-
console_unlock();
3447+
if (!console_is_registered_locked(console))
34493448
return -ENODEV;
3450-
}
34513449

34523450
hlist_del_init_rcu(&console->node);
34533451

@@ -3463,8 +3461,6 @@ static int unregister_console_locked(struct console *console)
34633461
if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
34643462
console_srcu_write_flags(console_first(), console_first()->flags | CON_CONSDEV);
34653463

3466-
console_unlock();
3467-
34683464
/*
34693465
* Ensure that all SRCU list walks have completed. All contexts
34703466
* must not be able to see this console in the list so that any

0 commit comments

Comments
 (0)