[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: memory leak in DMA buffers allocation?

From: olafBuddenhagen
Subject: Re: memory leak in DMA buffers allocation?
Date: Fri, 12 Feb 2010 20:29:12 +0100
User-agent: Mutt/1.5.19 (2009-01-05)


On Sun, Feb 07, 2010 at 10:08:27PM +0800, Da Zheng wrote:

> I wrote a RPC in GNUMach to allocate contiguous physical memory for
> DMA buffers. The code is shown as below. I have been using this
> function for quite a long time, but it seems it can cause some kind of
> memory leak. If I run the pcnet32 driver, which uses this function to
> allocate DMA buffers, for many times, the system seems to run out of
> memory. I checked the code, but didn't find the place which could
> cause memory leak. After a process is terminated, the memory and
> relevant objects allocated by vm_dma_buff_alloc should be freed
> automatically. I don't have much experience of Mach development. Maybe
> that's why I fail to find the problem.

I can't really tell what is happening there, without digging much deeper
into the code -- which I have no time for presently.

Also, I'm not sure it's even worthwhile, considering that it's just a
temporary solution anyways: I think when you implement it "properly" --
seperating the physical page allocation from the virtual mapping (and
using the standard mechanism for the latter) -- it should become much
clearer... And there is a good chance that the bug will just go away in
the process :-)

Seems strange though that you didn't see the problem with your original
pcnet32 port; only with the DDE-based one...

> antrik said this implementation isn't consistent with Mach's memory
> management and I should make it work like device_map, so there will be
> a pager in the kernel. I basically agree with that. What should the
> interface be? any suggestions?

It should be something along these lines I think:

   kern_return_t mach_get_dma_pages (
      host_priv_t host_priv,
      vm_size_t size,
      mach_port_t *pager,
      vm_offset_t *phys_addr,
      mach_dma_flags_t flags

The last parameter would contain various options, like restricting to
first 32 MiB of RAM (for ISA DMA) or first 4 GiB (for many other
devices). Not sure whether we actually need any other options --
otherwise, perhaps this should get a more specific name.

"pager" returns a memory object, which can then be used in a vm_map()
call. "phys_addr" returns the physical address of the allocated region,
used to program the DMA hardware.

BTW, I'm not sure about handling scatter-gather DMA. This still needs
the physical addresses to be stable during the transfer, and available
to the driver; but the region needn't be contiguous... So I guess we
could just use "normal" memory (ideally passed directly from/to the
clients); wire it; and use some other special function to obtain the
physical addresses of each page.

> +             kfree (pages, npages * sizeof (vm_page_t));
> +             vm_pages_release (npages, pages, TRUE);

This looks wrong -- freeing the "pages" array before using it to free
the actual pages... But I doubt it is related to the problem you are
experiencing, considering that this is just an error path.

(Also, I don't think the extra vm_pages_release() function is really
useful, considering that it's just a very simple loop, and used only in
a single place... But here I am nitpicking again :-) )


reply via email to

[Prev in Thread] Current Thread [Next in Thread]