ref: 2476b4fcea4299d2961a1542f5d73c4657320c2b
parent: fe9a09b8cb56d15c783ca89be5d06a4598f3566d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Oct 3 16:25:58 EDT 2024
kernel: avoid recursive lockloop() prints from screenputs() (thanks noam) We cannot use lock() from screenputs() because lock calls lockloop(), which would try to print() which on very slow output (such as qemu) can cause kernel stack overflow. It got triggered by noam with his rube-goldberg qemu setup: lock 0xffffffff8058bbe0 loop key 0xdeaddead pc 0xffffffff80111114 held by pc 0xffffffff80111114 proc 339 panic: kenter: -40 stack bytes left, up 0xffffffff80bdfd00 ureg 0xffffffff80bddcd8 at pc 0xffffffff80231597 dumpstack ktrace /kernel/path 0xffffffff80117679 0xffffffff80bddae0 <<EOF We might want move this locking logic outside of screenputs() in the future. It is very similar to what iprint() does.
--- a/sys/src/9/bcm/screen.c
+++ b/sys/src/9/bcm/screen.c
@@ -212,8 +212,10 @@
if(!canlock(&screenlock))
return;
}
- else
- lock(&screenlock);
+ else {
+ while(!canlock(&screenlock))
+ ;
+ }
while(n > 0){
i = chartorune(&r, s);
--- a/sys/src/9/imx8/screen.c
+++ b/sys/src/9/imx8/screen.c
@@ -201,8 +201,10 @@
if(!canlock(&screenlock))
return;
}
- else
- lock(&screenlock);
+ else {
+ while(!canlock(&screenlock))
+ ;
+ }
while(n > 0){
i = chartorune(&r, s);
--- a/sys/src/9/kw/cga.c
+++ b/sys/src/9/kw/cga.c
@@ -111,8 +111,10 @@
if(!canlock(&cgascreenlock))
return;
}
- else
- lock(&cgascreenlock);
+ else {
+ while(!canlock(&cgascreenlock))
+ ;
+ }
while(n-- > 0)
cgascreenputc(*s++);
--- a/sys/src/9/omap/screen.c
+++ b/sys/src/9/omap/screen.c
@@ -459,9 +459,10 @@
/* don't deadlock trying to print in interrupt */
if (!canlock(&screenlock))
return; /* discard s */
- } else
- lock(&screenlock);
-
+ } else {
+ while(!canlock(&screenlock))
+ ;
+ }
while (n > 0) {
i = chartorune(&r, s);
if (i == 0) {
--- a/sys/src/9/pc/cga.c
+++ b/sys/src/9/pc/cga.c
@@ -153,8 +153,10 @@
if(!canlock(&cgascreenlock))
return;
}
- else
- lock(&cgascreenlock);
+ else {
+ while(!canlock(&cgascreenlock))
+ ;
+ }
e = s + n;
while(s < e){
--- a/sys/src/9/pc/vga.c
+++ b/sys/src/9/pc/vga.c
@@ -135,8 +135,10 @@
if(!canlock(&vgascreenlock))
return;
}
- else
- lock(&vgascreenlock);
+ else {
+ while(!canlock(&vgascreenlock))
+ ;
+ }
/*
* Be nice to hold this, but not going to deadlock
--
⑨