Re: Module loading (2.0.24) fails with "Unable to allocate DMA memory"

Gerard Roudier (groudier@club-internet.fr)
Thu, 7 Nov 1996 01:38:29 +0000 (GMT)


On Wed, 6 Nov 1996, Alan Cox wrote:

> > With that priority, it is not possible to wait for swapping, so such
> > allocation may fail. A driver that need memory must be able to try
> > later its memory allocations. If it is not able to do that, it is buggy.
> > That is my opinion.
>
> The bug is in the kernel not the driver. You don't seem to be able to say
> GFP_DMAABLE|GFP_KERNEL to say wait for DMA memory. There are also other
> resource issues involved so its not a trivial fix.

Agreed. However,

I only wrote about GFP_ATOMIC priority which seems to must be used under
interrupt and so does not allow to schedule or to wait for some event.
In that situation, it is not possible to free pages by doing disk ios
(not only under Linux) and the kernel for now trusts some reserved pages.

Perhaps, the following optimistic code (mm/page_alloc.c)

---
	i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+7);
	if (i < 16)
		i = 16;
	min_free_pages = i;
---

should ne changed to something like:

---
	i = (end_mem - PAGE_OFFSET) >> (PAGE_SHIFT+6);
	if (i < 64)
		i = 64;
	min_free_pages = i;

in order to satisfy memory hungry drivers or modules. 256K of contiguous ISAable memory will be reserved at start-up for 16MB main memory and less and __get_free_pages will try to reserve this amount of memory later but not necessarily contiguous and ISAable. (It is what I understood)

At the same time, the following buggy code:

---
	reserved_pages = 5;
	if (priority != GFP_NFS)
		reserved_pages = min_free_pages;
	save_flags(flags);
repeat:
	cli();
	if ((priority==GFP_ATOMIC) || nr_free_pages > reserved_pages) {
		RMQUEUE(order, dma);
		restore_flags(flags);
		return 0;
	}
---

will become more often fortunate for allocation with order > 0 even for not GFP_ATOMIC priorities. Obviously it may still fail in some bad cases.

The above is just a suggestion that might help for the moment.

Saying (GFP_XXX (XXX!=ATOMIC) | GFP_DMAable) and waiting the kernel for satisfying this request is very probably the right solution. I agree. > Alan

Gerard.