NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/60144: virtio(4) cache coherence issue
> Date: Sat, 11 Apr 2026 02:35:39 +0000
> From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
>
> So that raises the key question:
>
> If we POSTREAD and read _one part_ of the transfer buffer at
> one time, and POSTREAD and read _another part_ of it at
> another time, do we have to do a PREREAD in the interim at (6)
> because between the two reads is essentially a new DMA
> operation?
>
> The question doesn't just apply here -- it also applies to the polling
> scenario (like PR kern/60182: ld@virtio sometimes hangs up):
>
> bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
> trigger_dma();
> for (;;) {
> bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
> if (buf->ready)
> break;
> }
> use(buf->data);
>
> Does this need to be rewritten with another PREREAD for every
> iteration?
>
> bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
> trigger_dma();
> for (;;) {
> bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
> if (buf->ready)
> break;
> bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
> }
> use(buf->data);
Oops -- I forgot add another POSTREAD between testing buf->ready and
using buf->data, in case the device's stores are reordered as observed
by loads in the driver. So the options are:
bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
trigger_dma();
for (;;) {
bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
if (buf->ready)
break;
}
bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
use(buf->data);
versus
bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
trigger_dma();
for (;;) {
bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
ready = buf->ready;
bus_dmamap_sync(buf, BUS_DMASYNC_PREREAD);
if (ready)
break;
}
bus_dmamap_sync(buf, BUS_DMASYNC_POSTREAD);
use(buf->data);
Home |
Main Index |
Thread Index |
Old Index