Freeing mmapped memory
John Baldwin
jhb at freebsd.org
Tue Feb 7 07:15:56 PST 2006
On Monday 06 February 2006 19:55, John-Mark Gurney wrote:
> Raaf wrote this message on Tue, Feb 07, 2006 at 01:42 +0100:
> > John-Mark Gurney wrote:
> > > Raaf wrote this message on Mon, Feb 06, 2006 at 22:54 +0100:
> > >> Hi, i am working on a usb driver that allocates some memory when
> > >> the device is opened using malloc.
> > >>
> > >> Now i want user processes to be able to access this memory using
> > >> mmap and i want to free this memory when it is no longer needed.
> > >>
> > >> The problem is that there seems to be no way of knowing for my
> > >> driver at what time the memory is no longer mapped in a process
> > >> address space so that i can safely free this memory.
> > >
> > > why not at close time? I would imagine that the device won't be closed
> > > until all the mmap's that are backed by the device are unmapped.. it
> > > shouldn't be hard to test... the mapping should hold a reference to
> > > the device until it's munmapped..
> >
> > The problem is that it is perfectly legal to access the mapped memory
> > after a close, consider following code:
> >
> > fd = open()
> > mem = mmap()
> > close(fd)
> > process_data(mem)
> >
> > Unfortunately the mapping doesn't seem to hold a reference to the
> > related fileobject, so the close in above code actually ends up
> > in the close function of my driver but the mapping is still there.
>
> and you've tested that the mmap function still gets called after the
> close function of your device driver is? If this is the case, we need
> to fix FreeBSD.. the mmap should increase the ref count on the device,
> and the close shouldn't initiate the close until the mapping goes away..
>
> fd = open() # ref cnt = 1
> mem = mmap() # ref cnt++
> close(fd) # ref cnt--
> process_data(mem) # valid ref cnt > 0
> munmap(mem) # ref cnt-- and close sine ref cnt == 0
No, it doesn't work quite like that since the device_pager is system-wide and
not per-process. That is, you can't have d_mmap() return different mappings
for different processes, the mapping is global and shared, at least not w/o
jumping through a lot of hoops. It might be nice to support different
mappings for different proccesses. OS X does it nicely via
IOUserClient::clientMemoryForType(), but our device_pager stuff would need a
redesign to handle that sort of thing.
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-hackers
mailing list