Date: Thu, 6 Feb 1997 15:23:45 +1030 (CST) From: Michael Smith <msmith@atrad.adelaide.edu.au> To: Shimon@i-Connect.Net (Simon Shapiro) Cc: freebsd-scsi@freebsd.org, freebsd-hackers@freebsd.org Subject: Re: Contigious (spelling?) allocation in kernel Message-ID: <199702060453.PAA00702@genesis.atrad.adelaide.edu.au> In-Reply-To: <XFMail.970205205354.Shimon@i-Connect.Net> from Simon Shapiro at "Feb 5, 97 07:33:54 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
Simon Shapiro stands accused of saying: > I need to allocate a contigious (one piece :-) block of memory for a DMA > scatter/gather list. The HBA knows how to do scatter gather, but wants a > single pointer to a single block of memory that hoslds the entire list. That's a bit icky 8) > The SG structure is very plain, 32bits for length and 32bits for physical > address; 8 bytes. The thing is capable of up to 8192 entries, which give > us a possible list of 64KB per request list. You might want to check on the s/g limit for block I/O for FreeBSD; it's quite possible that something like that is far beyond anything that it's likely to do. In most cases, I/O is likely to be in page-sized (4K) chunks, with a limit of 64K (MAXPHYS). You'd have to ask Bruce or possibly Justin about that; I don't know where to look to confirm such a limit. > As each HBA can have up to 256 concurrent requests, with who knows how > many more in the driver's queue, the list can grow quite impressively. > Since most requests are smaller, it seems very wasteful to allocate all > this memory upfront. So malloc is in order, but what are the options? I'd start with a small pool of permanently-allocated (get them at driver startup time) S/G lists of some empirically determined "adequate" size. Keep enough of these around so that you can cover the maximum number of concurrent outstanding transactions (or possibly just grow your pool as required). Use the BSD queue macros to efficiently manage your buffer lists. If you get a request bigger than will fit in your "normal" S/G block, allocate one temporarily, and throw it away when you're done. As far as actually allocating the suckers goes, contigmalloc() is probably what you're after; call it contigmalloc(size, M_DEVBUF, M_NOWAIT, low, high, align), where low and high are the lowest and highest legal physical addresses, and align is the alignment size for the structure. It sounds like you're talking to a PCI device, so 0, ULONG_MAX and sizeof(u_long) respectively should do the trick. > Simon -- ]] Mike Smith, Software Engineer msmith@gsoft.com.au [[ ]] Genesis Software genesis@gsoft.com.au [[ ]] High-speed data acquisition and (GSM mobile) 0411-222-496 [[ ]] realtime instrument control. (ph) +61-8-8267-3493 [[ ]] Unix hardware collector. "Where are your PEZ?" The Tick [[
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702060453.PAA00702>