Subject: Re: Machine-independent bus DMA interface proposal
To: Justin T. Gibbs <gibbs@freefall.freebsd.org>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 09/23/1996 11:10:41
On Sun, 22 Sep 1996 23:08:25 -0700 
 "Justin T. Gibbs" <gibbs@freefall.freebsd.org> wrote:

 > I think we're missing each other here.  Forcing the device driver to do the
 > copy from a bus_dma_segment_t into its own private format doesn't solve the
 > structure alignment problem.  In fact it forces each individual driver to
 > handle it much the same as is done (or not done) now.  The only difference
 > is that instead of handling the mapping (and packing if necessary) inline,
 > you get an intermediate format in there first.  Having a family of
 > functions that can be ported to different architectures and know how to
 > deal with the SG formats completely removes the knowledge of how X arch
 > aligns its data.  My driver passes in a buffer to hold X number of SG
 > segments to one of these routines, and the routine, not my driver, ensures
 > that the packing is confomant with that SG format.

Actually, I think you're completely missing the point of "portable driver".
I think what you're suggesting this this:

	- Define a name for a scatter/gather format used by a bunch
	  of cards, call it "foo".

	- Create a machine-dependent {alpha,i386}/isa/foo_machdep.c.

	- Place the DMA mapping and scatter/gather list packing into
	  a function in foo_machdep.c, call it foo_sg_pack().

I'm sorry, but from a software engineering standpoint, that is simply
_completely_ unacceptable.

In my mind, a portable driver is one that Just Works without any extra
goop when the basic bus functionality is implemented for a given platform.
If you have to create machine-dependent modules for each driver, you're
simply ignoring portability.

I think you're focusing on the ISA/EISA/PCI systems... I'm trying to
create a DMA mapping interface that is immediately scalable to Sun DVMA
(this would have the side-effect of making the SPARC and Sun 3 ports'
DVMA interfaces match, thus making it much easier to share _several_
drivers between those ports), DEC TurboChannel DMA, ISA, EISA, PCI,
and any other wacky thing you might throw at it.

You primary point seems to be that it's wasteful to have a "transient"
copy of the scatter/gather descriptors.  Ignoring the fact that
the bus_dma_segment_t's are potentially much more than scatter/gather
descriptors, let's do a little math:

	In the case of a SCSI driver, the most that will ever be
	transfered in a single transaction is MAXPHYS, which is
	currently 64k (in Real Life Situations, the amount
	actually transfered per-transaction is often much less).
	In a worst case scenario (all pages in the buffer are
	sparse) you need a maximum of:

		(MAXPHYS / NBPG) + 1

	scatter/gather descriptors (+1 for the slop page, in case the
	buffer doesn't start on a page boundary).  On the i386, this
	evaluates to 17.  In the case of each hardware scatter/gather
	descriptor being a 32-bit address and a 32-bit length,
	that comes out to a grand total of 136 bytes.

In my world, adding code complexity (where code complexity is defined
as many machine-dependent modules for each Joe Random Scatter/Gather
Format) is simply not worth optimizing a (corner case) 136-byte copy.

Now, if we take a look are the more real work situations, transferring
a file system block (typically 4k or 8k), on the i386 we're talking
about a max of 2 scatter/gather descriptors, which in the case of
32-bit address/32-bit legth, totals out to 16 bytes.  On some
architectures, 16 bytes is below the optimization threshold for
bcopy().  I.e. you literally gain _nothing_.

 > I haven't been convinced that there is an architectural comprimize.  Right
 > now I'm looking at more code, more memory usage (multiple K), and an extra
 > copy of usually 16 u_int32_t per transaction in an inefficient for
 > loop at the driver level.  If my device doesn't need bouncing, what
 > have I gained?

The architectural compromise is machine-dependent modules for
device-dependent scatter/gather list formats.  Given that you need to
have device-, bus-, and machine-independent DMA mapping anyway, your
suggestion actually adds more code.

The _only_ place where a device's scatter/gather list format should
be dealt with is the in the driver for that device.  Period.

 > I don't see why allowing the user to specify the target SG format and
 > provide a target buffer makes this interface any harder for the programmer
 > to deal with.  You can still put whatever information you need in order
 > to be "sane" in the dma_handle since it is an opaque type.

...uhh, has it occured to you that every time someone invents a new
scatter/gather list format, your interface would require updating?
That is, unless you specify some meta-language used to describe
a format, which is a ball of hair I don't think anyone wants to deal
with.

 > I would guess that there are quite a few more devices that use the
 > 32bit addr, 32bit count format.  They also are not PC scsi cards,
 > they are PCI, EISA, and ISA SCSI cards that can be used on multiple
 > architechtures.  Furthermore, the interface is not device, bus or
 > machine dependant, it is simply SG format dependant.  The SG format
 > dependencies have to be dealt with *somewhere*.  My point is only
 > that by handling them in the interface itself, you gain efficiency
 > and code reuse.

I believe your assertion is false, given that you'd have to mostly
duplicate and then tweak the scatter/gather list packing interface
for each architecture you port it to.

 -- save the ancient forests - http://www.bayarea.net/~thorpej/forest/ -- 
Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffett Field, CA 94035                                Pager: 415.428.6939