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; }