• T
    printk: do cond_resched() between lines while outputting to consoles · 8d91f8b1
    Tejun Heo 提交于
    @console_may_schedule tracks whether console_sem was acquired through
    lock or trylock.  If the former, we're inside a sleepable context and
    console_conditional_schedule() performs cond_resched().  This allows
    console drivers which use console_lock for synchronization to yield
    while performing time-consuming operations such as scrolling.
    
    However, the actual console outputting is performed while holding
    irq-safe logbuf_lock, so console_unlock() clears @console_may_schedule
    before starting outputting lines.  Also, only a few drivers call
    console_conditional_schedule() to begin with.  This means that when a
    lot of lines need to be output by console_unlock(), for example on a
    console registration, the task doing console_unlock() may not yield for
    a long time on a non-preemptible kernel.
    
    If this happens with a slow console devices, for example a serial
    console, the outputting task may occupy the cpu for a very long time.
    Long enough to trigger softlockup and/or RCU stall warnings, which in
    turn pile more messages, sometimes enough to trigger the next cycle of
    warnings incapacitating the system.
    
    Fix it by making console_unlock() insert cond_resched() between lines if
    @console_may_schedule.
    Signed-off-by: NTejun Heo <tj@kernel.org>
    Reported-by: NCalvin Owens <calvinowens@fb.com>
    Acked-by: NJan Kara <jack@suse.com>
    Cc: Dave Jones <davej@codemonkey.org.uk>
    Cc: Kyle McMartin <kyle@kernel.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    8d91f8b1
printk.c 81.2 KB