vandys@cisco.com writes:
>No, malloc() generally gives you virtual memory, with the physical
>memory
>behind it faulted in on demand. But that memory can be allocated
>anywhere
>in the full physical range--which can result in buffers in high memory
>which
>the floppy DMA can't touch.
>For quite a long time we had a patch to cap memory at 15 megs or so. I
>fixed up the bounce buffer stuff (with, apparently, some bugs left :->)
>because I got tired of seeing most of my 64 megs in my SMP box sitting
>idle.
>This is probably what will also prod me to finally cook up x86 SMP
>support!
>If you can figure out what's going wrong I'll be happy to try and fix
>it.
Well, I looked at the source again, and here's what seems to be
happening :)
If when fd mallocs the bounce buffer, it happens to be located in <
16M, mach_page_wire will say, okay, that's ISA DMA-able and leave it
alone. You won't have a problem. If for some reason fd gets a page in
high memory, mach_page_wire will have to move it beneath the 16M
boundary.
That much we already knew. The problem is that malloc() is guaranteed
only to give you usable memory; there's no telling whether that memory
will be committed or uncommitted, if the block requested would fit
into a bucket (less than 32k, I think.) In fact, free() never gives
the allocated bucket memory back to the OS until the process exits. It
simply reuses, which is fine for most cases, but this time it causes
trouble. fd requests a 512-byte bounce buffer, which is allocated
using the bucket system. If that memory was already committed (and
used) in physical memory, it will have been already attached to that
process's pview, and mach_page_wire will refuse to move it.
So, you could fix this a couple of ways:
1) Always use mmap() for trying to wire pages for ISA DMA. This
works, because you know mmap() going to give you unused virtual
memory. Also, this particular need is rare enough to justify doing
it differently in this one case.
2) Have page_wire() adopt the policy of "the customer is always
right"; i.e., if the process gives a virtual address that is already in
use, simply detach all of the other outstanding references.
3) Have free() not only deallocate but also decommit the memory
it frees. I don't think there is a syscall that will do this, and it
also
seems expensive and unnecessary for the vast majority of
applications.
Received on Wed May 26 07:03:53 1999
This archive was generated by hypermail 2.1.8 : Thu Sep 22 2005 - 15:12:56 PDT