pipe(2): Don't cv_wait_sig in a loop without breaking on signal.
If a signal does arrive, it will turn into a busy wait! Not helpful.
But this wait should be limited to scheduling delays for other
threads anyway, not for general I/O, so there's no need to be
interruptible by a signal.
Prompted by:
PR kern/59056: poll POLLHUP bugs
pipe(2): Restructure select/poll/kqueue records.
1. When a thread is waiting on an endpoint of a pipe, have it wait on
_that endpoint_ (i.e., cv_wait or selrecord), not on the other
endpoint sometimes depending on the direction of the I/O.
2. Make poll(2) on the writer side of a pipe wake with POLLERR when
the reader side is closed, because write would return immediately,
and fail with EPIPE/SIGPIPE. See also:
https://mail-index.NetBSD.org/tech-kern/2026/09/21/msg031255.html
(In contrast, for the other way around, when the writer side of a
pipe is closed, poll(2) on the reader is already defined to wake
with POLLHUP, and while read would return immediately, it will not
_fail_; it will simply report EOF, so there is no justification
for POLLERR in that direction.)
3. For EVFILT_READ, require the reader side of a pipe; likewise, for
[6 lines not shown]
pipe(2): Simplify PIPE_RESTART handling.
Now that it applies to each side independently, we can just make it
final, because new I/O operations are not allowed on an file that has
had its .fo_restart called. Makes reasoning about all this easier.
XXX Consider renaming PIPE_RESTART to PIPE_CLOSING: the .fo_restart
operation means the file is irreversibly destined to be closed soon
and just needs any pending I/O on it to be interrupted and fail
promptly so we can finally close the file.
Preparation for:
PR kern/59056: poll POLLHUP bugs
pipe(2): Make pipe sides a little more symmetric.
1. When reading from or writing to a pipe, busy _this side_ of the
pipe, not the other side.
2. In pipeclose, all operations on _this side_ of the pipe have already
quiesced. But operations on the other side may not have. So wait
for the _other side_ to be unbusied before disconnecting the peer
(changing ppipe->pipe_peer from pipe to NULL).
With (1) and (2) we can prove a simple property that makes reasoning
about this code easier: If a pipe is busy, its peer pointer is stable
even across cv_wait on the pipe lock. Without these changes I'm not
sure I could prove that property (though I haven't exhibited a
reproducer for any issues arising from its failure).
3. Make write wait on wpipe->pipe_wcv, and make read wait on
rpipe->pipe_rcv, consistently, so that any waiters on one side of a
pipe will always be waiting on one of _that side's_ condvars.
[17 lines not shown]
pipe(2): Fix wakeup of pending writers on close of write side.
The job of pipe_restart is to wake any pending I/O operations on the
file when it is about to be closed. New references cannot be taken
for new I/O operations; once all existing references are drained, the
system calls pipe_close.
What pipe_restart did was to wake pipe->pipe_rcv and pipe->pipe_wcv.
But the condvars of _which pipe_?
After renaming the variables to match reality, it becomes clear that
wpipe->pipe_wcv and wpipe->pipe_rcv are never used -- instead,
pipe_read waits for rpipe->pipe_rcv, and pipe_write waits for
rpipe->pipe_wcv. So pipe_restart on the write side of a pipe woke
wpipe->pipe_rcv and wpipe->pipe_wcv, which nothing was waiting for,
and failed to wake rpipe->pipe_rcv or rpipe->pipe_wcv.
(Perhaps we should just have a single struct pipe::pipe_cv member,
and have pipe_read use rpipe->pipe_cv and pipe_write use
[4 lines not shown]
pipe(2): Split new function pipefree out of pipeclose.
Makes it easier to reason about pipeclose this way.
Prompted by:
PR kern/59056: poll POLLHUP bugs
pipe(2): Rename pipe variables to make more sense.
- wpipe for the writer side of a pipe, associated with a file open
for FWRITE.
- rpipe for the writer side of a pipe, associated with a file open
for FREAD.
- pipe for either side of the pipe.
- ppipe for the peer corresponding to pipe.
No functional change intended.
Prompted by trying to wrap my head around this pipe(2) code in order
to address:
PR kern/59056: poll POLLHUP bugs
mips: mask interrupts during context switch to preserve curlwp/sp invariants
Interrupts are masked until MIPS_CURLWP, SP, and this CPU's
ci_curlwp all refer to the new LWP in both cpu_switchto and
softint_fast_dispatch
gcc: backend: Sprinkle -O1 to some files for alpha
With this workaround, more than 270 pkgsrc's successfully build for me.
PR toolchain/60843 GCC/alpha 14 miscompiles GCC backend
heimdal: Apply upstream fix for kill(2) argument order in kdc(8).
commit b22f33250a98efcda3a07fdc36bc2fd386230857
Author: Roland C. Dowdeswell <elric at imrryr.org>
Date: Fri Sep 25 14:45:23 2026 +0100
kdc: correct kill_kids kill(2) arg order
PR bin/60841: kdc(8) sends pids to signals instead of signals to pids
ntp(9): Avoid more left shift of negative UB.
This logic is, presumably, intended to compute integer arithmetic, so
just write it as *16 instead of <<4. If there's an advantage to
using a machine shift instruction to get the same semantics, the
compiler can do that for us.
Also avoid arithmetic overflow. If set a few lines above,
time_monitor can lie anywhere in the interval [-MAXPHASE,MAXPHASE] =
[-500e6,500e6]. Multiplying by sixteen can therefore overflow the
bounds [-2.2e9,2.2e9] of long on LP32 platforms by a factor of four.
But mtemp >= 256 here, so even if time_monitor*16 overflows the
signed 32-bit range, the result (time_monitor*16)/mtemp will not.
Hence: cast to int64_t for the intermediate computation of
time_monitor*16.
This isn't the end of the analysis: time_monitor can also be set in
hardpps(9) to something else whose bounds aren't as clear to me, but
that only applies under `options PPS_SYNC' which is usually not set.
[4 lines not shown]
dtrace: Avoid uninitialized stack garbage.
Found by:
PR kern/60839: use -ftrivial-auto-var-init
This applies the code change of the following FreeBSD commit, but I
didn't understand the comment so I rewrote it:
commit f222a6b88614db13ae83c8110281e690d1381a4c
Author: Bryan Drewery <bdrewery at FreeBSD.org>
Date: Fri Dec 18 09:58:03 2020 -0800
dtrace: Fix /"string" == NULL/ comparisons using an uninitialized value.
A test of this is funcs/tst.strtok.d which has this filter:
BEGIN
/(this->field = strtok(this->str, ",")) == NULL/
[27 lines not shown]
sys: Use ACTIVE_CC to choose -ftrivial-auto-var-init.
I'm a little fuzzy on the finer semantics of ACTIVE_CC vs
HAVE_GCC/HAVE_LLVM from share/mk/bsd.README, but I think this is the
intended way to conditionalize decisions like this.
PR PR kern/60839: use -ftrivial-auto-var-init
sys: Flip on -ftrivial-auto-var-init=pattern for the kernel build.
Note: HAVE_GCC (if defined) is a major version number, but HAVE_LLVM
(if defined) is yes or no, hence the weird conditionals here.
TBD: Would like to make the choice of `pattern' vs `zero' conditional
on `options DEBUG' or something but that's trickier than I want to
figure out right now; let's just get this on at all to start.
TBD: Kernel modules.
PR kern/60839: use -ftrivial-auto-var-init