Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'rework/atomic-flush-hardlockup' into for-linus

+44 -5
+44 -5
kernel/printk/nbcon.c
··· 118 118 * from scratch. 119 119 */ 120 120 121 + /* Counter of active nbcon emergency contexts. */ 122 + static atomic_t nbcon_cpu_emergency_cnt = ATOMIC_INIT(0); 123 + 121 124 /** 122 125 * nbcon_state_set - Helper function to set the console state 123 126 * @con: Console to update ··· 1166 1163 if (kthread_should_stop()) 1167 1164 return true; 1168 1165 1166 + /* 1167 + * Block the kthread when the system is in an emergency or panic mode. 1168 + * It increases the chance that these contexts would be able to show 1169 + * the messages directly. And it reduces the risk of interrupted writes 1170 + * where the context with a higher priority takes over the nbcon console 1171 + * ownership in the middle of a message. 1172 + */ 1173 + if (unlikely(atomic_read(&nbcon_cpu_emergency_cnt)) || 1174 + unlikely(panic_in_progress())) 1175 + return false; 1176 + 1169 1177 cookie = console_srcu_read_lock(); 1170 1178 1171 1179 flags = console_srcu_read_flags(con); ··· 1227 1213 do { 1228 1214 if (kthread_should_stop()) 1229 1215 return 0; 1216 + 1217 + /* 1218 + * Block the kthread when the system is in an emergency or panic 1219 + * mode. See nbcon_kthread_should_wakeup() for more details. 1220 + */ 1221 + if (unlikely(atomic_read(&nbcon_cpu_emergency_cnt)) || 1222 + unlikely(panic_in_progress())) 1223 + goto wait_for_event; 1230 1224 1231 1225 backlog = false; 1232 1226 ··· 1527 1505 ctxt->prio = nbcon_get_default_prio(); 1528 1506 ctxt->allow_unsafe_takeover = allow_unsafe_takeover; 1529 1507 1530 - if (!nbcon_context_try_acquire(ctxt, false)) 1531 - return -EPERM; 1532 - 1533 1508 while (nbcon_seq_read(con) < stop_seq) { 1509 + if (!nbcon_context_try_acquire(ctxt, false)) 1510 + return -EPERM; 1511 + 1534 1512 /* 1535 1513 * nbcon_emit_next_record() returns false when the console was 1536 1514 * handed over or taken over. In both cases the context is no ··· 1538 1516 */ 1539 1517 if (!nbcon_emit_next_record(&wctxt, true)) 1540 1518 return -EAGAIN; 1519 + 1520 + nbcon_context_release(ctxt); 1541 1521 1542 1522 if (!ctxt->backlog) { 1543 1523 /* Are there reserved but not yet finalized records? */ ··· 1549 1525 } 1550 1526 } 1551 1527 1552 - nbcon_context_release(ctxt); 1553 1528 return err; 1554 1529 } 1555 1530 ··· 1678 1655 1679 1656 preempt_disable(); 1680 1657 1658 + atomic_inc(&nbcon_cpu_emergency_cnt); 1659 + 1681 1660 cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); 1682 1661 (*cpu_emergency_nesting)++; 1683 1662 } ··· 1694 1669 unsigned int *cpu_emergency_nesting; 1695 1670 1696 1671 cpu_emergency_nesting = nbcon_get_cpu_emergency_nesting(); 1697 - 1698 1672 if (!WARN_ON_ONCE(*cpu_emergency_nesting == 0)) 1699 1673 (*cpu_emergency_nesting)--; 1674 + 1675 + /* 1676 + * Wake up kthreads because there might be some pending messages 1677 + * added by other CPUs with normal priority since the last flush 1678 + * in the emergency context. 1679 + */ 1680 + if (!WARN_ON_ONCE(atomic_read(&nbcon_cpu_emergency_cnt) == 0)) { 1681 + if (atomic_dec_return(&nbcon_cpu_emergency_cnt) == 0) { 1682 + struct console_flush_type ft; 1683 + 1684 + printk_get_console_flush_type(&ft); 1685 + if (ft.nbcon_offload) 1686 + nbcon_kthreads_wake(); 1687 + } 1688 + } 1700 1689 1701 1690 preempt_enable(); 1702 1691 }