Author: bonefish Date: 2010-06-10 19:30:49 +0200 (Thu, 10 Jun 2010) New Revision: 37086 Changeset: http://dev.haiku-os.org/changeset/37086/haiku Modified: haiku/trunk/headers/private/kernel/vm/vm_page.h haiku/trunk/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp haiku/trunk/src/system/kernel/vm/vm.cpp haiku/trunk/src/system/kernel/vm/vm_page.cpp Log: vm_page_allocate_page_run(): Added parameter "limit", specifying the upper physical address limit for the page run to allocate. Modified: haiku/trunk/headers/private/kernel/vm/vm_page.h =================================================================== --- haiku/trunk/headers/private/kernel/vm/vm_page.h 2010-06-10 13:25:36 UTC (rev 37085) +++ haiku/trunk/headers/private/kernel/vm/vm_page.h 2010-06-10 17:30:49 UTC (rev 37086) @@ -61,7 +61,7 @@ struct vm_page *vm_page_allocate_page(vm_page_reservation* reservation, uint32 flags); struct vm_page *vm_page_allocate_page_run(uint32 flags, phys_addr_t base, - page_num_t length, int priority); + phys_addr_t limit, page_num_t length, int priority); struct vm_page *vm_page_at_index(int32 index); struct vm_page *vm_lookup_page(page_num_t pageNumber); bool vm_page_is_dummy(struct vm_page *page); Modified: haiku/trunk/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp 2010-06-10 13:25:36 UTC (rev 37085) +++ haiku/trunk/src/add-ons/kernel/bus_managers/agp_gart/agp_gart.cpp 2010-06-10 17:30:49 UTC (rev 37086) @@ -540,7 +540,7 @@ if ((flags & B_APERTURE_NEED_PHYSICAL) != 0) { memory->page = vm_page_allocate_page_run( - PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR, 0, count, + PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR, 0, 0, count, VM_PRIORITY_SYSTEM); if (memory->page == NULL) return B_NO_MEMORY; Modified: haiku/trunk/src/system/kernel/vm/vm.cpp =================================================================== --- haiku/trunk/src/system/kernel/vm/vm.cpp 2010-06-10 13:25:36 UTC (rev 37085) +++ haiku/trunk/src/system/kernel/vm/vm.cpp 2010-06-10 17:30:49 UTC (rev 37086) @@ -1181,7 +1181,7 @@ // we try to allocate the page run here upfront as this may easily // fail for obvious reasons page = vm_page_allocate_page_run(PAGE_STATE_WIRED | pageAllocFlags, - physicalAddress, size / B_PAGE_SIZE, priority); + physicalAddress, 0, size / B_PAGE_SIZE, priority); if (page == NULL) { status = B_NO_MEMORY; goto err0; Modified: haiku/trunk/src/system/kernel/vm/vm_page.cpp =================================================================== --- haiku/trunk/src/system/kernel/vm/vm_page.cpp 2010-06-10 13:25:36 UTC (rev 37085) +++ haiku/trunk/src/system/kernel/vm/vm_page.cpp 2010-06-10 17:30:49 UTC (rev 37086) @@ -3319,11 +3319,30 @@ } -vm_page * -vm_page_allocate_page_run(uint32 flags, phys_addr_t base, page_num_t length, - int priority) +/*! Allocate a physically contiguous range of pages. + + \param flags Page allocation flags. Encodes the state the function shall + set the allocated pages to, whether the pages shall be marked busy + (VM_PAGE_ALLOC_BUSY), and whether the pages shall be cleared + (VM_PAGE_ALLOC_CLEAR). + \param base The first acceptable physical address where the page run may + start. + \param limit The last acceptable physical address where the page run may + end (i.e. it must hold runStartAddress + runSize <= limit). If \c 0, + the limit is ignored. + \param length The number of contiguous pages to allocate. + \param priority The page reservation priority (as passed to + vm_page_reserve_pages()). + \return The first page of the allocated page run on success; \c NULL + when the allocation failed. +*/ +vm_page* +vm_page_allocate_page_run(uint32 flags, phys_addr_t base, phys_addr_t limit, + page_num_t length, int priority) { - page_num_t start = base >> PAGE_SHIFT; + page_num_t start = base / B_PAGE_SIZE; + page_num_t end = std::min(limit > 0 ? limit / B_PAGE_SIZE : sNumPages, + sNumPages); vm_page_reservation reservation; vm_page_reserve_pages(&reservation, length, priority); @@ -3338,8 +3357,7 @@ int useCached = freePages > 0 && (page_num_t)freePages > 2 * length ? 0 : 1; for (;;) { - bool foundRun = true; - if (start + length > sNumPages) { + if (start + length > end) { if (useCached == 0) { // The first iteration with free pages only was unsuccessful. // Try again also considering cached pages. @@ -3356,6 +3374,7 @@ return NULL; } + bool foundRun = true; page_num_t i; for (i = 0; i < length; i++) { uint32 pageState = sPages[start + i].State();