[uClinux-dev] Classzones and stuff in __alloc_pages

Fabrice Gautier Fabrice_Gautier at sdesigns.com
Wed Nov 28 00:08:12 EST 2001


Hi,

Does somebody can enlight me on how __alloc_pages work with the zone stuff ?

My problem seems to be that, while my system still have 132 kb free it it
can't allocate new pages (for init).

I'll try a begining of explanation below, feel free to complete...


So the kernel arrive here in __alloc_pages, in his intent to kmalloc ~24000
bytes. The order paramter passed to __alloc_pages is 3, so it's trying to
allocate a 32kb page (it's my guess that 32kb = PAGE_SIZE *2<< order) 


struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order,
zonelist_t *zonelist)
{

	...

First  we enter a loop where we try to allocate a page in the zone where the
number of free pages is higher than the zone pages_low. 

	for (;;) {
		zone_t *z = *(zone++);
		if (!z)
			break;

		if (zone_free_pages(z, order) > z->pages_low) {
			page = rmqueue(z, order);
			if (page)
				return page;
		}
	}

In my case, the loop fails. So we go on...

	...

	for (;;) {   
		unsigned long min;
		zone_t *z = *(zone++);
		if (!z)
			break;

		min = z->pages_min;
		if (!(gfp_mask & __GFP_WAIT))
			min >>= 2;
		if (zone_free_pages(z, order) > min) {
			page = rmqueue(z, order);
			if (page)
				return page;
		}
	}

In this second loop we try almost the same thing expect we compare to a
value derived from pages_min. This attempt also fail, so we in the low
memory path as a comment in the code says:

	/* here we're in the low on memory slow path */

	if (current->flags & PF_MEMALLOC) {
		...

We dont have this flag, so we go on...

	}   

 rebalance:
	page = balance_classzone(classzone, gfp_mask, order, &freed);   
	if (page)   
		return page;      

I don't know exactly what balance classzone is supposed to do, but anyway it
doesn't find a page.


	zone = zonelist->zones;   
	if (likely(freed)) {   
	 ...

and it liekly(freed) is false too
so we check for a last chance, as per the comment:

	} else {   
		/*       
		 * Check that no other task is been killed meanwhile,      
		 * in such a case we can succeed the allocation.      
		 */      

and this fails also since it's init.

		...
	}   

So finally we got:

	printk(KERN_NOTICE "__alloc_pages: %u-order allocation failed
(gfp=0x%x/%i) from %p\n",   
	       order, gfp_mask, !!(current->flags & PF_MEMALLOC),
__builtin_return_address(0));   
	return NULL;   
}




-- 
Fabrice Gautier
Fabrice_Gautier at sdesigns.com

This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/



More information about the uClinux-dev mailing list