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.
This commit is contained in:
cinap_lenrek 2024-10-03 20:25:58 +00:00
parent d8973bdc75
commit 4d484968bf
6 changed files with 24 additions and 13 deletions

View file

@ -212,8 +212,10 @@ myscreenputs(char *s, int n)
if(!canlock(&screenlock))
return;
}
else
lock(&screenlock);
else {
while(!canlock(&screenlock))
;
}
while(n > 0){
i = chartorune(&r, s);

View file

@ -201,8 +201,10 @@ myscreenputs(char *s, int n)
if(!canlock(&screenlock))
return;
}
else
lock(&screenlock);
else {
while(!canlock(&screenlock))
;
}
while(n > 0){
i = chartorune(&r, s);

View file

@ -111,8 +111,10 @@ cgascreenputs(char* s, int n)
if(!canlock(&cgascreenlock))
return;
}
else
lock(&cgascreenlock);
else {
while(!canlock(&cgascreenlock))
;
}
while(n-- > 0)
cgascreenputc(*s++);

View file

@ -459,9 +459,10 @@ omapscreenputs(char *s, int n)
/* 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) {

View file

@ -153,8 +153,10 @@ cgascreenputs(char* s, int n)
if(!canlock(&cgascreenlock))
return;
}
else
lock(&cgascreenlock);
else {
while(!canlock(&cgascreenlock))
;
}
e = s + n;
while(s < e){

View file

@ -135,8 +135,10 @@ vgascreenputs(char* s, int n)
if(!canlock(&vgascreenlock))
return;
}
else
lock(&vgascreenlock);
else {
while(!canlock(&vgascreenlock))
;
}
/*
* Be nice to hold this, but not going to deadlock