ref: 06221c080dad6650b1e1af88857951775803bf32
parent: 6c9c2beb6e54a2ced1466615452e338d9bb7d48d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Mar 16 13:07:03 EDT 2024
qio: fix queue bloat blocking condition for qwrite() The code in qwrite() that enters a non-interruptable blocking loop is there because normally flow control is done after Block's have been queued. A process can skip that flow-control by receiving a note duing qflow(). If that happens in a loop it can bloat the queue without limit. So if normal flow control fails to maintain the limit, we want to block before allocating and queuing the blocks as a last resort. The condition however should be q->len >= q->limit, not q->len/2 >= q->limit.
--- a/sys/src/9/port/qio.c
+++ b/sys/src/9/port/qio.c
@@ -1165,7 +1165,7 @@
print("qwrite hi %#p\n", getcallerpc(&q));
/* stop queue bloat before allocating blocks */
- if(q->len/2 >= q->limit && q->noblock == 0 && q->bypass == nil){
+ if(q->len >= q->limit && q->noblock == 0 && q->bypass == nil){
while(waserror()){
if(up->procctl == Proc_exitme || up->procctl == Proc_exitbig)
error(Egreg);
@@ -1222,10 +1222,7 @@
ilock(q);
- /* we use an artificially high limit for kernel prints since anything
- * over the limit gets dropped
- */
- if((q->state & Qclosed) != 0 || q->len/2 >= q->limit){
+ if((q->state & Qclosed) != 0 || q->len >= q->limit){
iunlock(q);
freeb(b);
break;