• Thomas Gleixner's avatar
    printk: nbcon: Add acquire/release logic · 3a5bb251
    Thomas Gleixner authored
    Add per console acquire/release functionality.
    
    The state of the console is maintained in the "nbcon_state" atomic
    variable.
    
    The console is locked when:
    
      - The 'prio' field contains the priority of the context that owns the
        console. Only higher priority contexts are allowed to take over the
        lock. A value of 0 (NBCON_PRIO_NONE) means the console is not locked.
    
      - The 'cpu' field denotes on which CPU the console is locked. It is used
        to prevent busy waiting on the same CPU. Also it informs the lock owner
        that it has lost the lock in a more complex scenario when the lock was
        taken over by a higher priority context, released, and taken on another
        CPU with the same priority as the interrupted owner.
    
    The acquire mechanism uses a few more fields:
    
      - The 'req_prio' field is used by the handover approach to make the
        current owner aware that there is a context with a higher priority
        waiting for the friendly handover.
    
      - The 'unsafe' field allows to take over the console in a safe way in the
        middle of emitting a message. The field is set only when accessing some
        shared resources or when the console device is manipulated. It can be
        cleared, for example, after emitting one character when the console
        device is in a consistent state.
    
      - The 'unsafe_takeover' field is set when a hostile takeover took the
        console in an unsafe state. The console will stay in the unsafe state
        until re-initialized.
    
    The acquire mechanism uses three approaches:
    
      1) Direct acquire when the console is not owned or is owned by a lower
         priority context and is in a safe state.
    
      2) Friendly handover mechanism uses a request/grant handshake. It is used
         when the current owner has lower priority and the console is in an
         unsafe state.
    
         The requesting context:
    
           a) Sets its priority into the 'req_prio' field.
    
           b) Waits (with a timeout) for the owning context to unlock the
              console.
    
           c) Takes the lock and clears the 'req_prio' field.
    
         The owning context:
    
           a) Observes the 'req_prio' field set on exit from the unsafe
              console state.
    
           b) Gives up console ownership by clearing the 'prio' field.
    
      3) Unsafe hostile takeover allows to take over the lock even when the
         console is an unsafe state. It is used only in panic() by the final
         attempt to flush consoles in a try and hope mode.
    
         Note that separate record buffers are used in panic(). As a result,
         the messages can be read and formatted without any risk even after
         using the hostile takeover in unsafe state.
    
    The release function simply clears the 'prio' field.
    
    All operations on @console::nbcon_state are atomic cmpxchg based to
    handle concurrency.
    
    The acquire/release functions implement only minimal policies:
    
      - Preference for higher priority contexts.
      - Protection of the panic CPU.
    
    All other policy decisions must be made at the call sites:
    
      - What is marked as an unsafe section.
      - Whether to spin-wait if there is already an owner and the console is
        in an unsafe state.
      - Whether to attempt an unsafe hostile takeover.
    
    The design allows to implement the well known:
    
        acquire()
        output_one_printk_record()
        release()
    
    The output of one printk record might be interrupted with a higher priority
    context. The new owner is supposed to reprint the entire interrupted record
    from scratch.
    Co-developed-by: default avatarJohn Ogness <john.ogness@linutronix.de>
    Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
    Signed-off-by: default avatarThomas Gleixner (Intel) <tglx@linutronix.de>
    Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
    Link: https://lore.kernel.org/r/20230916192007.608398-3-john.ogness@linutronix.de
    3a5bb251
nbcon.c 16.7 KB