I think I spoke too soon.. I saw thousands of calls to mmap and assumed it was the thousands of read/writes that I was doing. It's actually for the thousands (8192) of pages that I'm mapping in. Oddly enough though there are only 3272 calls to my mmap routine each time I run the program. I will investigate further.
I did find a bug in mlock() and munlock(). I tried mlock()ing after I mmaped, which I later realized was bogus since the pages are always resident as they exist on the bus. Anyway the kernel faults in vm_page_unwire when I munlock. I will investigate further and post a pr though.
Thanks for your help!
From: Bruce Evans [mailto:[EMAIL PROTECTED]]
Sent: Thursday, January 11, 2001 8:52 PM
To: Jeff Roberson
Cc: '[EMAIL PROTECTED]'
Subject: Re: Broken mmap in current?
On Thu, 11 Jan 2001, Jeff Roberson wrote:
> I have written a character device driver for a proprietary PCI device that
> has a large sum of mapable memory. The character device supports mmap()
> which I use to export the memory into a user process. I have no problems
> accessing the memory on this device, but I notice that my mmap routine is
> called for every access! Is this a problem with current, or a problem with
> my mmap?
Maybe both. The device mmap routine is called mainly by the mmap
syscall for every page to be mmapped. It is also called by
dev_pager_getpages() for some pagefaults, but I think this rarely happens.
> I use bus_alloc_resource and then rman_get_start to get the physical address
> in my attach, and then the mmap just returns atop(physical address). I
> assumed this is correct since I have verified with a logical analyzer that I
> am indeed writing to the memory on the device.
This is correct. I looked at some examples. Many drivers get this
wrong by using i386_btop(), alpha_btop(), etc. (AFAIK, atop() is
for addresses which are what we are converting here, btop() is for
(byte) offsets, and the machine-dependent prefixes are a vestige of
page clustering code that mostly went away 7 years ago.
> Also, I noticed that the
> device's mmap interface does not provide any way to limit the size of the
> block being mapped? Can I specify the length of the region?
The length is implicitly PAGE_SIZE. The device mmap function is called
for each page to be mapped. It must verify that the memory from offset
to (offset + PAGE_SIZE - 1) belongs to the device and can be accessed
with the given protection, and do any device-specific things necessary to
enable this memory. This scheme can't support bank-switched device
memory very well, if at all.
pcvvt_mmap() in the pcvt driver is the simplest example of this.
agp_mmap() is a more up to date example with the same old bug that the
vga drivers used to have (off by 1 (page) error checking the offset).
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message