Skip to content
Snippets Groups Projects
  1. Sep 29, 2022
  2. Jul 15, 2022
  3. Jun 23, 2022
  4. Jun 15, 2022
  5. May 27, 2022
  6. May 06, 2022
  7. Apr 26, 2022
    • John Ogness's avatar
      printk: remove @console_locked · ab406816
      John Ogness authored
      
      The static global variable @console_locked is used to help debug
      VT code to make sure that certain code paths are running with
      the console_lock held. However, this information is also available
      with the static global variable @console_kthreads_blocked (for
      locking via console_lock()), and the static global variable
      @console_kthreads_active (for locking via console_trylock()).
      
      Remove @console_locked and update is_console_locked() to use the
      alternative variables.
      
      Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
      Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
      Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
      Link: https://lore.kernel.org/r/20220421212250.565456-16-john.ogness@linutronix.de
      ab406816
    • John Ogness's avatar
      printk: extend console_lock for per-console locking · 8e274732
      John Ogness authored
      
      Currently threaded console printers synchronize against each
      other using console_lock(). However, different console drivers
      are unrelated and do not require any synchronization between
      each other. Removing the synchronization between the threaded
      console printers will allow each console to print at its own
      speed.
      
      But the threaded consoles printers do still need to synchronize
      against console_lock() callers. Introduce a per-console mutex
      and a new console boolean field @blocked to provide this
      synchronization.
      
      console_lock() is modified so that it must acquire the mutex
      of each console in order to set the @blocked field. Console
      printing threads will acquire their mutex while printing a
      record. If @blocked was set, the thread will go back to sleep
      instead of printing.
      
      The reason for the @blocked boolean field is so that
      console_lock() callers do not need to acquire multiple console
      mutexes simultaneously, which would introduce unnecessary
      complexity due to nested mutex locking. Also, a new field
      was chosen instead of adding a new @flags value so that the
      blocked status could be checked without concern of reading
      inconsistent values due to @flags updates from other contexts.
      
      Threaded console printers also need to synchronize against
      console_trylock() callers. Since console_trylock() may be
      called from any context, the per-console mutex cannot be used
      for this synchronization. (mutex_trylock() cannot be called
      from atomic contexts.) Introduce a global atomic counter to
      identify if any threaded printers are active. The threaded
      printers will also check the atomic counter to identify if the
      console has been locked by another task via console_trylock().
      
      Note that @console_sem is still used to provide synchronization
      between console_lock() and console_trylock() callers.
      
      A locking overview for console_lock(), console_trylock(), and the
      threaded printers is as follows (pseudo code):
      
      console_lock()
      {
              down(&console_sem);
              for_each_console(con) {
                      mutex_lock(&con->lock);
                      con->blocked = true;
                      mutex_unlock(&con->lock);
              }
              /* console_lock acquired */
      }
      
      console_trylock()
      {
              if (down_trylock(&console_sem) == 0) {
                      if (atomic_cmpxchg(&console_kthreads_active, 0, -1) == 0) {
                              /* console_lock acquired */
                      }
              }
      }
      
      threaded_printer()
      {
              mutex_lock(&con->lock);
              if (!con->blocked) {
      		/* console_lock() callers blocked */
      
                      if (atomic_inc_unless_negative(&console_kthreads_active)) {
                              /* console_trylock() callers blocked */
      
                              con->write();
      
                              atomic_dec(&console_lock_count);
                      }
              }
              mutex_unlock(&con->lock);
      }
      
      The console owner and waiter logic now only applies between contexts
      that have taken the console_lock via console_trylock(). Threaded
      printers never take the console_lock, so they do not have a
      console_lock to handover. Tasks that have used console_lock() will
      block the threaded printers using a mutex and if the console_lock
      is handed over to an atomic context, it would be unable to unblock
      the threaded printers. However, the console_trylock() case is
      really the only scenario that is interesting for handovers anyway.
      
      @panic_console_dropped must change to atomic_t since it is no longer
      protected exclusively by the console_lock.
      
      Since threaded printers remain asleep if they see that the console
      is locked, they now must be explicitly woken in __console_unlock().
      This means wake_up_klogd() calls following a console_unlock() are
      no longer necessary and are removed.
      
      Also note that threaded printers no longer need to check
      @console_suspended. The check for the @blocked field implicitly
      covers the suspended console case.
      
      Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
      Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
      Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
      Link: https://lore.kernel.org/r/878rrs6ft7.fsf@jogness.linutronix.de
      8e274732
  8. Apr 22, 2022
  9. Mar 02, 2022
  10. Feb 21, 2022
  11. Feb 15, 2022
  12. Feb 14, 2022
  13. Feb 03, 2022
  14. Jan 26, 2022
  15. Jan 22, 2022
Loading