Date: Fri, 12 Jan 2001 16:29:29 -0800 From: Jeff Roberson <jeff@midstream.com> To: 'Bruce Evans' <bde@zeta.org.au> Cc: "'freebsd-current@freebsd.org'" <freebsd-current@freebsd.org> Subject: RE: Broken mmap in current? Message-ID: <31E4B6337A4FD411BD45000102472E0C05E72A@EMAIL_SERVER>
next in thread | raw e-mail | index | archive | help
This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C07CF7.E8E735A0 Content-Type: text/plain; charset="iso-8859-1" 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! Jeff -----Original Message----- From: Bruce Evans [mailto:bde@zeta.org.au] Sent: Thursday, January 11, 2001 8:52 PM To: Jeff Roberson Cc: 'freebsd-current@freebsd.org' 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). Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message ------_=_NextPart_001_01C07CF7.E8E735A0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = charset=3Diso-8859-1"> <META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version = 5.5.2650.12"> <TITLE>RE: Broken mmap in current?</TITLE> </HEAD> <BODY> <P><FONT SIZE=3D2>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.</FONT></P> <P><FONT SIZE=3D2>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.</FONT></P> <P><FONT SIZE=3D2>Thanks for your help!</FONT> <BR><FONT SIZE=3D2>Jeff</FONT> </P> <P><FONT SIZE=3D2>-----Original Message-----</FONT> <BR><FONT SIZE=3D2>From: Bruce Evans [<A = HREF=3D"mailto:bde@zeta.org.au">mailto:bde@zeta.org.au</A>]</FONT> <BR><FONT SIZE=3D2>Sent: Thursday, January 11, 2001 8:52 PM</FONT> <BR><FONT SIZE=3D2>To: Jeff Roberson</FONT> <BR><FONT SIZE=3D2>Cc: 'freebsd-current@freebsd.org'</FONT> <BR><FONT SIZE=3D2>Subject: Re: Broken mmap in current?</FONT> </P> <BR> <P><FONT SIZE=3D2>On Thu, 11 Jan 2001, Jeff Roberson wrote:</FONT> </P> <P><FONT SIZE=3D2>> I have written a character device driver for a = proprietary PCI device that</FONT> <BR><FONT SIZE=3D2>> has a large sum of mapable memory. The = character device supports mmap()</FONT> <BR><FONT SIZE=3D2>> which I use to export the memory into a user = process. I have no problems</FONT> <BR><FONT SIZE=3D2>> accessing the memory on this device, but I = notice that my mmap routine is</FONT> <BR><FONT SIZE=3D2>> called for every access! Is this a = problem with current, or a problem with</FONT> <BR><FONT SIZE=3D2>> my mmap?</FONT> </P> <P><FONT SIZE=3D2>Maybe both. The device mmap routine is called = mainly by the mmap</FONT> <BR><FONT SIZE=3D2>syscall for every page to be mmapped. It is = also called by</FONT> <BR><FONT SIZE=3D2>dev_pager_getpages() for some pagefaults, but I = think this rarely happens.</FONT> </P> <P><FONT SIZE=3D2>> I use bus_alloc_resource and then rman_get_start = to get the physical address</FONT> <BR><FONT SIZE=3D2>> in my attach, and then the mmap just returns = atop(physical address). I</FONT> <BR><FONT SIZE=3D2>> assumed this is correct since I have verified = with a logical analyzer that I</FONT> <BR><FONT SIZE=3D2>> am indeed writing to the memory on the = device.</FONT> </P> <P><FONT SIZE=3D2>This is correct. I looked at some = examples. Many drivers get this</FONT> <BR><FONT SIZE=3D2>wrong by using i386_btop(), alpha_btop(), etc. = (AFAIK, atop() is</FONT> <BR><FONT SIZE=3D2>for addresses which are what we are converting here, = btop() is for</FONT> <BR><FONT SIZE=3D2>(byte) offsets, and the machine-dependent prefixes = are a vestige of</FONT> <BR><FONT SIZE=3D2>page clustering code that mostly went away 7 years = ago.</FONT> </P> <P><FONT SIZE=3D2>> Also, I noticed that the</FONT> <BR><FONT SIZE=3D2>> device's mmap interface does not provide any = way to limit the size of the</FONT> <BR><FONT SIZE=3D2>> block being mapped? Can I specify the = length of the region?</FONT> </P> <P><FONT SIZE=3D2>The length is implicitly PAGE_SIZE. The device = mmap function is called</FONT> <BR><FONT SIZE=3D2>for each page to be mapped. It must verify = that the memory from offset</FONT> <BR><FONT SIZE=3D2>to (offset + PAGE_SIZE - 1) belongs to the device = and can be accessed</FONT> <BR><FONT SIZE=3D2>with the given protection, and do any = device-specific things necessary to</FONT> <BR><FONT SIZE=3D2>enable this memory. This scheme can't support = bank-switched device</FONT> <BR><FONT SIZE=3D2>memory very well, if at all.</FONT> </P> <P><FONT SIZE=3D2>pcvvt_mmap() in the pcvt driver is the simplest = example of this.</FONT> <BR><FONT SIZE=3D2>agp_mmap() is a more up to date example with the = same old bug that the</FONT> <BR><FONT SIZE=3D2>vga drivers used to have (off by 1 (page) error = checking the offset).</FONT> </P> <P><FONT SIZE=3D2>Bruce</FONT> </P> <BR> <BR> <P><FONT SIZE=3D2>To Unsubscribe: send mail to = majordomo@FreeBSD.org</FONT> <BR><FONT SIZE=3D2>with "unsubscribe freebsd-current" in the = body of the message</FONT> </P> </BODY> </HTML> ------_=_NextPart_001_01C07CF7.E8E735A0-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?31E4B6337A4FD411BD45000102472E0C05E72A>