Esempio n. 1
0
const char* test_page_cache() {
  gc_page_cache cache;
  initialize_page_cache(&cache, 16, 0);
  gc_page pages[32];
  for(int i = 0; i < 32; ++i) {
    pages[i].fill = GC_PAGE_SIZE - 512;
    pages[i].space = 0;
    pages[i].zone = i;
    pages[i].step = 0;
  }

  for(int i = 0; i < 16; ++i) {
    cache_page(&cache, &pages[i]);
  }

  int sum = 0;
  for(int i = 0; i < 16; ++i)
    sum += cache.cache_entries[i]->zone;

  if(sum != 120) return "cache 1 failed";

  for(int i = 16; i < 32; ++i) {
    if(cache_page(&cache, &pages[i])->zone != (i - 16))
      return "cache 2 failed";
  }

  sum = 0;
  for(int i = 0; i < 16; ++i) {
    sum += cache.cache_entries[i]->zone;
  }

  if(sum != 376) return "cache 3 failed";

  gc_page* page = lookup_page(&cache, 200, 19, 0);
  if(page->zone != 19) return "lookup 1 failed";

  if(cache.cache_entries[cache.hint_index]->zone != 19)
    return "lookup 2 failed";

  page = lookup_page(&cache, 200, 5, 0);
  if(page != 0) return "lookup 3 failed";

  page = lookup_page(&cache, 700, 21, 0);
  if(page != 0) return "lookup 4 failed";

  page = lookup_page(&cache, 200, 21, 0);
  if(page->zone != 21) return "lookup 5 failed";
  
  if(cache.cache_entries[cache.hint_index]->zone != 21)
    return "lookup 6 failed";

  finalize_page_cache(&cache);

  return "passed";
}
void free_pointer_table (pmd_t *ptable)
{
	struct ptable_desc *dp;
	unsigned long page = (unsigned long)ptable & PAGE_MASK;
	int index = ((unsigned long)ptable - page)/PTABLE_SIZE;
	unsigned long flags;

	for (dp = ptable_list.next; dp->page && dp->page != page; dp = dp->next)
		;

	if (!dp->page)
		panic ("unable to find desc for ptable %p on list!", ptable);

	if (PD_TABLEFREE (dp, index))
		panic ("table already free!");

	PD_MARKFREE (dp, index);

	if (PD_ALLFREE (dp)) {
		/* all tables in page are free, free page */
		save_flags(flags);
		cli();
		dp->prev->next = dp->next;
		dp->next->prev = dp->prev;
		restore_flags(flags);
		cache_page (dp->page);
		free_page (dp->page);
		kfree (dp);
		return;
	} else {
		/*
		 * move this descriptor the the front of the list, since
		 * it has one or more free tables.
		 */
		save_flags(flags);
		cli();
		dp->prev->next = dp->next;
		dp->next->prev = dp->prev;

		dp->next = ptable_list.next;
		dp->prev = ptable_list.next->prev;
		ptable_list.next->prev = dp;
		ptable_list.next = dp;
		restore_flags(flags);
	}
}
/*
 *  Read from a diskdump-created dumpfile.
 */
int
read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
{
	int ret;
	physaddr_t curpaddr;
	ulong pfn, page_offset;

	pfn = paddr_to_pfn(paddr);

	if (KDUMP_SPLIT()) {
		/* Find proper dd */
		int i;
		unsigned long start_pfn;
		unsigned long end_pfn;

		for (i=0; i<num_dumpfiles; i++) {
			start_pfn = dd_list[i]->sub_header_kdump->start_pfn;
			end_pfn = dd_list[i]->sub_header_kdump->end_pfn;
			if ((pfn >= start_pfn) && (pfn <= end_pfn))	{
				dd = dd_list[i];
				break;
			}
		}

		if (i == num_dumpfiles) {
			if (CRASHDEBUG(8))
				fprintf(fp, "read_diskdump: SEEK_ERROR: "
				    "paddr/pfn %llx/%lx beyond last dumpfile\n",
					(ulonglong)paddr, pfn);
			return SEEK_ERROR;
		}
	}

	curpaddr = paddr & ~((physaddr_t)(dd->block_size-1));
	page_offset = paddr & ((physaddr_t)(dd->block_size-1));

	if ((pfn >= dd->header->max_mapnr) || !page_is_ram(pfn)) {
		if (CRASHDEBUG(8)) {
			fprintf(fp, "read_diskdump: SEEK_ERROR: "
			    "paddr/pfn: %llx/%lx ",
				(ulonglong)paddr, pfn);
			if (pfn >= dd->header->max_mapnr)
				fprintf(fp, "max_mapnr: %x\n",
					dd->header->max_mapnr);
			else
				fprintf(fp, "!page_is_ram\n");
		}

		return SEEK_ERROR;
	}

	if (!page_is_dumpable(pfn)) {
		if ((dd->flags & (ZERO_EXCLUDED|ERROR_EXCLUDED)) ==
		    ERROR_EXCLUDED) {
			if (CRASHDEBUG(8))
				fprintf(fp, "read_diskdump: PAGE_EXCLUDED: "
			    	    "paddr/pfn: %llx/%lx\n",
					(ulonglong)paddr, pfn);
			return PAGE_EXCLUDED;
		}
		if (CRASHDEBUG(8))
			fprintf(fp, "read_diskdump: zero-fill: "
		    	    "paddr/pfn: %llx/%lx\n",
				(ulonglong)paddr, pfn);
		memset(bufptr, 0, cnt);
		return cnt;
	}

	if (!page_is_cached(curpaddr)) {
		if (CRASHDEBUG(8))
			fprintf(fp, "read_diskdump: paddr/pfn: %llx/%lx"
			    " -> cache physical page: %llx\n",
				(ulonglong)paddr, pfn, (ulonglong)curpaddr);

		if ((ret = cache_page(curpaddr)) < 0) {
			if (CRASHDEBUG(8))
				fprintf(fp, "read_diskdump: " 
				    "%s: cannot cache page: %llx\n",
					ret == SEEK_ERROR ?  
					"SEEK_ERROR" : "READ_ERROR",
					(ulonglong)curpaddr);
			return ret;
		}
	} else if (CRASHDEBUG(8))
		fprintf(fp, "read_diskdump: paddr/pfn: %llx/%lx"
		    " -> physical page is cached: %llx\n", 
			(ulonglong)paddr, pfn, (ulonglong)curpaddr);
	
	memcpy(bufptr, dd->curbufptr + page_offset, cnt);
	return cnt;
}