tech-kern archive

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

Am I using bus_dma right?



I've got a driver I'm trying to port from 5.2 to 8.0 for work.  The 8.0
version kinda-sorta works, but I'm having some issues, and I've thrown
debugging around it to the point where I'm coming to suspect that the
problem is somewhere around the driver, and the prime suspect to my
mind is my use of bus_dma calls.  I can give some background, but, in
case anyone just wants to see the calls, I'll show that part first.

This is on amd64.  The driver is not MP_SAFE; it runs giantlocked.  The
read routine looks like

	SAMPLE buffer[N];

	error checking
	while (1)
		if (uio out of space) break;
		n = min(uio space, N);
		o = current offset into ring buffer
		s = splhigh()
		while (fewer than n samples copied)
			DMASYNC_POSTREAD for sample at offset o
			read sample at offset o
			if value is "impossible", break
			set sample at offset o to "impossible" value
			DMASYNC_PREWRITE for sample at offset o
			store sample in buffer[]
		splx(s)
		uiomove from buffer[]
		if we found an "impossible" value, break;

I do not have any PREREAD or POSTWRITE calls anywhere.  So, my first
question: is that a problem?  Do I need them?  If so, when/where?  I'm
fuzzy enough on what they do that I'm not sure.  But I'm reasonably
sure they're not there just for API symmetry. :-)

Obviously, that splhigh() would ideally go away; it is there to ensure
the interrupt handler - which also messes with the buffers, under some
circumstances - doesn't run during that section.  But, because of the
giantlock, I am inclined to doubt that's to blame for the trouble.

buffer[] exists to amortize spl* and uiomove overhead.

I have reason to think that samples are arriving at the card and
getting severely delayed (multiple seconds) before reaching userland.
The driver's read routine is returning zero, meaning that the code
above is seeing the "impossible" value on its first read from the ring
buffer.  Is it plausible that misuse of bus_dma calls could cause that?
The mental model I've found effective for bus_dma is to think of
everything as bounce-buffered, and in that model data not getting
copied out of a bounce buffer could cause what I'm seeing.  But I
thought that's what POSTREAD did, with PREWRITE pushing from my buffer
to the (conceptual) bounce buffer so its getting overwritten can be
reliably detected.

I was careful to make the reads and writes of the samples happen
through pointers-to-volatile.

I can go into more detail if desired, even up to sending the whole
driver (it's for a commercial product, but all the secret sauce is in
userland - I got permission long ago to open-source the kernel stuff).

/~\ 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