Skip site navigation (1)Skip section navigation (2)
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..&nbsp; I saw thousands of =
calls to mmap and assumed it was the thousands of read/writes that I =
was doing.&nbsp; It's actually for the thousands (8192) of pages that =
I'm mapping in.&nbsp; Oddly enough though there are only 3272 calls to =
my mmap routine each time I run the program.&nbsp; I will investigate =
further.</FONT></P>

<P><FONT SIZE=3D2>I did find a bug in mlock() and munlock().&nbsp; 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.&nbsp; Anyway =
the kernel faults in vm_page_unwire when I munlock.&nbsp; 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>&gt; I have written a character device driver for a =
proprietary PCI device that</FONT>
<BR><FONT SIZE=3D2>&gt; has a large sum of mapable memory.&nbsp; The =
character device supports mmap()</FONT>
<BR><FONT SIZE=3D2>&gt; which I use to export the memory into a user =
process.&nbsp; I have no problems</FONT>
<BR><FONT SIZE=3D2>&gt; accessing the memory on this device, but I =
notice that my mmap routine is</FONT>
<BR><FONT SIZE=3D2>&gt; called for every access!&nbsp; Is this a =
problem with current, or a problem with</FONT>
<BR><FONT SIZE=3D2>&gt; my mmap?</FONT>
</P>

<P><FONT SIZE=3D2>Maybe both.&nbsp; The device mmap routine is called =
mainly by the mmap</FONT>
<BR><FONT SIZE=3D2>syscall for every page to be mmapped.&nbsp; 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>&gt; I use bus_alloc_resource and then rman_get_start =
to get the physical address</FONT>
<BR><FONT SIZE=3D2>&gt; in my attach, and then the mmap just returns =
atop(physical address).&nbsp; I</FONT>
<BR><FONT SIZE=3D2>&gt; assumed this is correct since I have verified =
with a logical analyzer that I</FONT>
<BR><FONT SIZE=3D2>&gt; am indeed writing to the memory on the =
device.</FONT>
</P>

<P><FONT SIZE=3D2>This is correct.&nbsp; I looked at some =
examples.&nbsp; Many drivers get this</FONT>
<BR><FONT SIZE=3D2>wrong by using i386_btop(), alpha_btop(), etc.&nbsp; =
(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>&gt; Also, I noticed that the</FONT>
<BR><FONT SIZE=3D2>&gt; device's mmap interface does not provide any =
way to limit the size of the</FONT>
<BR><FONT SIZE=3D2>&gt; block being mapped?&nbsp; Can I specify the =
length of the region?</FONT>
</P>

<P><FONT SIZE=3D2>The length is implicitly PAGE_SIZE.&nbsp; The device =
mmap function is called</FONT>
<BR><FONT SIZE=3D2>for each page to be mapped.&nbsp; 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.&nbsp; 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 &quot;unsubscribe freebsd-current&quot; 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>