For devices on a bus with no direct _PRT, use the raw intr pin with the
parent bridge's slot number to derive a pin number that can be used to
lookup the pin -> irq mapping in the parent bus's _PRT.
cgdconfig: getfsspecname failed: no match for `wd0e'
as the virtual machine has root on dk0, dk0 at wd0 and trying to
open wd0e fails.
This tests runs without a rump kernel and therefore should not
even try to open configured devices on the host. Replace the
disks "wd0e" and "ld1e" with non-existant disks "dska" and "dskb".
When the linux,pci-probe-only flag is set, we still need to process the
ranges property to determine whether or not to set PCI_FLAGS_IO_OKAY and
PCI_FLAGS_MEM_OKAY flags on the bus.
- Allocate the usrbuf from kmem(9) instead of uvm(9). The usrbuf has used
uvm(9), in case mmap(2) might be issued later. However, despite the most
apps don't use mmap(2), allocating (and reallocating) uvm(9) every time
would be expensive. In addition, uvm(9) for recording usrbuf was totally
pointless now.
- For playback, the usrbuf memory will be allocated in pages. Because the
usrbuf for playback is mostly near 64KB for backward compatibility.
This will reduce reallocation especially from the initial ulaw to the most
commonly used format like slinear16/2ch/48kHz.
- When mmap(2) is called, it will replace the playback usrbuf from kmem(9) to
uvm(9).
- Prohibit changing playback format once mmap(2) is called.
It follows netbsd-7.
- For recording, the usrbuf memory will be allocated in the requested size
every time as before. Because the usrbuf for recording is only one block
and is enough small to the page in the most case.
Inspired by PR kern/56947.
- If there's a prior concurrent close, it must have interrupted this
open.
- If there's a new concurrent close, it must wait until this open has
released device_lock before it can revoke.
There's no important state that needs to be recorded, or resources
that need to be relinquished, so detach-on-shutdown isn't necessary.
At the moment, detach-on-shutdown is actually harmful here: if
shutdown is triggered by a sysmon power switch event, then
config_detach will be called from the sysmon taskqueue, but
thinkpad_detach has to wait for ACPI notifiers to finish running
which means waiting for the sysmon taskqueue -> deadlock or crash.
We should maybe arrange to do config_detach from a thread other than
the sysmon taskqueue thread to avoid this class of problems -- but
for now, thinkpad(4) has no reason to detach on shutdown anyway, so
let's take the easy path.
Note: There are many drivers that set DVF_DETACH_SHUTDOWN which
probably shouldn't; the flag means the kernel _will_ detach on
shutdown, not that it _may_. Even those that do need to record state
or relinquish resources might be better served by pmf shutdown hooks
which can skip freeing software resources for faster shutdown.
Modules that have not been audited for autounload safety don't
recognize the command MODULE_CMD_AUTOUNLOAD and return ENOTTY. These
modules are not safe to autounload, so don't autounload them. Since
unload is risky business (if not careful, can lead to use-after-free,
kernel memory corruption, &c.), it needs to be opt-in by default, not
opt-out.
Modules that have been audited can return 0 or EBUSY to explicitly
allow or deny autounload. Users who want to live on the edge to try
to exercise module autounload even for unaudited modules -- and are
willing to accept the consequences, and maybe contribute to auditing!
-- can set the new sysctl knob kern.module.autounload_unsafe=1.
Discussed on tech-kern:
https://mail-index.netbsd.org/tech-kern/2022/08/08/msg028282.html
And expand the comment on the lfence for POSTREAD before bouncing.
Net change:
op before bounce after bounce
old new
PREREAD nop lfence sfence
PREWRITE nop mfence sfence
PREREAD|PREWRITE nop mfence sfence
POSTREAD lfence lfence nop[*]
POSTWRITE nop mfence nop
POSTREAD|POSTWRITE lfence mfence nop[*]
The case of PREREAD is as follows:
1. loads and stores before DMA buffer may be allocated for the purpose
2. bus_dmamap_sync(BUS_DMASYNC_PREREAD)
3. store to register or DMA descriptor to trigger DMA
The register or DMA descriptor may be in any type of memory (or I/O).
lfence at (2) is _not enough_ to ensure stores at (1) have completed
before the store in (3) in case the register or DMA descriptor lives
in wc/wc+ memory, or the store to it is non-temporal: in that case,
it may executed early before all the stores in (1) have completed.
On the other hand, lfence at (2) is _not needed_ to ensure loads in
(1) have completed before the store in (3), because x86 never
reorders load;store to store;load. So we may need to enforce
store/store ordering, but not any other ordering, hence sfence.
The case of PREWRITE is as follows:
1. stores to DMA buffer (and loads from it, before allocated)
2. bus_dmamap_sync(BUS_DMASYNC_PREWRITE)
3. store to register or DMA descriptor to trigger DMA
Ensuring prior loads have completed is not necessary because x86
never reorders load;store to store;load (and in any case, the device
isn't changing the DMA buffer, so it's safe to read over and over
again). But we must ensure the stores in (1) have completed before
the store in (3). So we need sfence, in case either the DMA buffer
or the register or the DMA descriptor is in wc/wc+ memory or either
store is non-temporal. But we don't need mfence.
The case of POSTREAD is as follows:
1. load from register or DMA descriptor notifying DMA completion
2. bus_dmamap_sync(BUS_DMASYNC_POSTREAD)
(a) lfence [*]
(b) if bouncing, memcpy(userbuf, bouncebuf, ...)
(c) ???
3. loads from DMA buffer to use data, and stores to reuse buffer
This certainly needs an lfence to prevent the loads at (3) from being
executed early -- but bus_dmamap_sync already issues lfence in that
case at 2(a), before it conditionally loads from the bounce buffer
into the user's buffer. So we don't need any _additional_ fence
_after_ bouncing at 2(c).
The case of POSTWRITE is as follows:
1. load from register or DMA descriptor notifying DMA completion
2. bus_dmamap_sync(BUS_DMASYNC_POSTWRITE)
3. loads and stores to reuse buffer
Stores at (3) will never be executed early because x86 never reorders
load;store to store;load for any memory types. Loads at (3) are
harmless because the device isn't changing the buffer -- it's
supposed to be fixed from the time of PREWRITE to the time of
POSTWRITE as far as the CPU can witness.
Proposed on port-amd64 last month:
https://mail-index.netbsd.org/port-amd64/2022/07/16/msg003593.html
Reference:
AMD64 Architecture Programmer's Manual, Volume 2: System Programming,
24593--Rev. 3.38--November 2021, Sec. 7.4.2 Memory Barrier Interaction
with Memory Types, Table 7-3, p. 196.
https://www.amd.com/system/files/TechDocs/24593.pdf
As proposed on tech-kern:
https://mail-index.netbsd.org/tech-kern/2022/07/16/msg028249.html
tl;dr:
- bus_space_barrier is needed only with prefetchable/cacheable.
- BUS_SPACE_BARRIER_READ is like membar_acquire.
- BUS_SPACE_BARRIER_WRITE is like membar_release.
- READ|WRITE is like membar_sync.
In usbnet.c rev. 1.16, usbnet_newbuf was first passed a buffer length
to verify it fits within MCLBYTES. It also changed m_adj to go
before, not after, setting m_len and m_pkthdr.len -- which had the
effect of making the m_adj a no-op, because after MGETHDR the mbuf
has zero length and m_adj stops at the length of the mbuf, so nothing
was aligned as intended.
To make this aligned as intended, we require the buffer length to be
_below_ MCLBYTES, by ETHER_ALIGN, so there's room for the ethernet
header in a maximum-length payload. Once we do that, it is safe to
initialize m_len = m_pkthdr.len = ETHER_ALIGN + buflen, which is
below the actual size of the mbuf (MHLEN or MCLBYTES, depending), and
_then_ do m_adj to align the pointer.
viocon* at virtio?
/dev/ttyVI??
Tested under qemu with:
qemu-system-aarch64 ... \
-device virtio-serial \
-chardev socket,path=/tmp/ttyVI00,server=on,wait=off,id=ttyVI00 \
-device virtconsole,chardev=ttyVI00,name=org.NetBSD.dev.ttyVI00 \
...
I updated MAKEDEV.conf to create /dev/ttyVI?? on all ports where it
looks likely to work based on:
(a) having pci or a non-pci virtio attachment,
(b) `qemu-system-$ARCH -M ?' mentioned something resembling the port,
and
(c) `qemu-system-$ARCH -device virtio-serial' launched without
complaining about the virtio-serial device.
(Criterion (c) excluded sparc and sparc64.)
- Where we had #ifndef WM_MPSAFE splnet(), we also had WM_CORE_LOCK,
which implies splnet, so just remove the conditional splnet.
- Make the core lock unconditional and remove macro indirections.
- Pass CALLOUT_MPSAFE, SOFTINT_MPSAFE, and WQ_MPSAFE directly without
macro indirections.
The return value must be used, because some of the acquire/release
pairs hold a mutex from acquire to release, and failing to call
release, or calling release twice, leads to an inconsistent state.
Don't touch if_flags without IFNET_LOCK:
- If only core lock is held, use sc_if_flags.
- If only txq lock is held, use txq_stopping.
=> Verified all paths guarantee !txq_stopping, so assert.
- Make sure sc_if_flags is updated on stop.
- Make wm_init fail once we enter wm_detach.
- Sprinkle assertions.
Author: Taylor R Campbell <riastradh@NetBSD.org>