tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Access to DMA memory while DMA in progress?



Back 8 days ago, I asked about bus_dmamap_unload() at splhigh().
Thanks to very helpful off-list responses (thank you - you know who you
are!), I think I understand that a little better now.  (Summary: no,
that can't be counted on to work, and it's documented, just not where I
was looking - it's in the splhigh doc, not the bus_dmamap_unload doc.)

Now, I've got another problem.

I would like to read the DMA buffer while DMA is still going on.  That
is, I have a buffer of (say) 64K and the hardware is busily writing
into it; I want to read the buffer and see what the hardware has
written in the memory it has written and what used to be there in the
memory it hasn't.  I'm fine if the CPU's view lags the hardware's view
slightly, but I do care about the CPU's view of the DMA write order
matching the hardware's: that is, if the CPU sees the value written by
a given DMA cycle, then the CPU must also see the values written by all
previous DMA cycles.  (This reading is being carried out from within
the kernel, by driver code.  I might be able to move it to userland,
but it would surprise me if userland could do something the kernel
can't.)

But I'm not sure what sort of sync calls I need to make.  Because of
things like bounce buffers and data caches, I presumably need
bus_dmamap_sync(BUS_DMASYNC_POSTREAD) somewhere in the mix, but it is
not clear to me how/when, nor how fine-grained those calls can be.  Do
I just POSTREAD each byte/word/whatever before I read it?  How
expensive is bus_dmamap_sync - for example, is a 1K sync significantly
cheaper than four 256-byte syncs covering the same memory?  If I'm
reading a bunch of (say) uint32_ts, is it reasonable to POSTREAD each
uint32_t individually?  If I POSTREAD something that DMA hasn't written
yet, will it work to POSTREAD it again (and then read it) after DMA
_has_ written it?  Is BUS_DMA_STREAMING relevant?  I will be
experimenting to see what seems to work, but I'd like to understand
what is promised, not just what happens to work on my development
system.

Of course, there is the risk of reading a partially-written datum.  In
my case (aligned uint32_ts on amd64) I don't think that can happen.

The presence of bus_dmamem_mmap seems to me to imply that it should be
possible to make simple memory accesses Just Work, but it's not clear
to me to what extent bus_dmamem_mmap supports _concurrent_ access by
DMA and userland (for example, does the driver have to
BUS_DMASYNC_POSTREAD after the DMA and before userland access to
mmapped memory, or does the equivalent happen automagically, eg in the
page fault handler, or does bus_dmamem_mmap succeed only on systems
where no such care needs to be taken, or what?).

My impression is that bus_dma is pretty stable, and, thus, version
doesn't matter much.  But, in case it matters, 5.2 on amd64.

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse%rodents-montreal.org@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B


Home | Main Index | Thread Index | Old Index