} 
static struct page *kimage_alloc_page(struct kimage *image, unsigned int gfp_mask, unsigned long destination){	/*	 * Here we implement safeguards to ensure that a source page	 * is not copied to its destination page before the data on	 * the destination page is no longer useful.	 *	 * To do this we maintain the invariant that a source page is	 * either its own destination page, or it is not a	 * destination page at all.	 *	 * That is slightly stronger than required, but the proof	 * that no problems will not occur is trivial, and the	 * implementation is simply to verify.	 *	 * When allocating all pages normally this algorithm will run	 * in O(N) time, but in the worst case it will run in O(N^2)	 * time.   If the runtime is a problem the data structures can	 * be fixed.	 */	struct page *page;	unsigned long addr;	/*	 * Walk through the list of destination pages, and see if I	 * have a match.	 */	list_for_each_entry(page, &image->dest_pages, lru) {		addr = page_to_pfn(page) << PAGE_SHIFT;		if (addr == destination) {			list_del(&page->lru);			return page;		}	}	page = NULL;	while (1) {		kimage_entry_t *old;		/* Allocate a page, if we run out of memory give up */		page = kimage_alloc_pages(gfp_mask, 0);		if (!page) {			return 0;		}		/* If the page cannot be used file it away */		if (page_to_pfn(page) > (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {			list_add(&page->lru, &image->unuseable_pages);			continue;		}		addr = page_to_pfn(page) << PAGE_SHIFT;		/* If it is the destination page we want use it */		if (addr == destination)			break;		/* If the page is not a destination page use it */		if (!kimage_is_destination_range(image, addr, addr + PAGE_SIZE))			break;		/*		 * I know that the page is someones destination page.		 * See if there is already a source page for this		 * destination page.  And if so swap the source pages.		 */		old = kimage_dst_used(image, addr);		if (old) {			/* If so move it */			unsigned long old_addr;			struct page *old_page;			old_addr = *old & PAGE_MASK;			old_page = pfn_to_page(old_addr >> PAGE_SHIFT);			copy_highpage(page, old_page);			*old = addr | (*old & ~PAGE_MASK);			/* The old page I have found cannot be a			 * destination page, so return it.			 */			addr = old_addr;			page = old_page;			break;		}		else {			/* Place the page on the destination list I			 * will use it later.			 */			list_add(&page->lru, &image->dest_pages);		}	}	return page;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/72414d3f1d22fc3e311b162fca95c430048d38ce/kexec.c/clean/kernel/kexec.c