vbox的更動 41652 路徑 trunk/src/VBox/Runtime/r0drv
- 時間撮記:
- 2012-6-11 下午02:13:01 (12 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
r41629 r41652 68 68 * allocation. */ 69 69 bool fLargePage; 70 /** Whether we have individual pages or a kernel-mapped virtual memory block in 71 * an RTR0MEMOBJTYPE_PHYS_NC allocation. */ 72 bool fIndivPages; 70 73 } RTR0MEMOBJSOL, *PRTR0MEMOBJSOL; 71 74 … … 154 157 { 155 158 /* 156 * Lock this page into memory "long term" to prevent paging out of this page. 159 * Lock this page into memory "long term" to prevent paging out of this page 160 * when we drop the page lock temporarily (during free). 157 161 */ 158 162 page_pp_lock(pPage, 0 /* COW */, 1 /* Kernel */); … … 169 173 * Allocates physical, non-contiguous memory of pages. 170 174 * 171 * @param uPhysHi The upper physical address limit (inclusive).172 175 * @param puPhys Where to store the physical address of first page. Optional, 173 176 * can be NULL. … … 176 179 * @return Array of allocated pages, NULL on failure. 177 180 */ 178 static page_t **rtR0MemObjSolPagesAlloc(uint64_t uPhysHi, uint64_t*puPhys, size_t cb)181 static page_t **rtR0MemObjSolPagesAlloc(uint64_t *puPhys, size_t cb) 179 182 { 180 183 /* … … 191 194 * Non-pageable memory reservation request for _4K pages, don't sleep. 192 195 */ 193 pgcnt_t cPages = (cb + PAGE_SIZE - 1) >> PAGE_SHIFT;196 size_t cPages = (cb + PAGE_SIZE - 1) >> PAGE_SHIFT; 194 197 int rc = page_resv(cPages, KM_NOSLEEP); 195 198 if (rc) … … 203 206 * we don't yet have the 'virtAddr' to which this memory may be mapped. 204 207 */ 205 caddr_t virtAddr = NULL;208 caddr_t virtAddr = 0; 206 209 for (size_t i = 0; i < cPages; i++, virtAddr += PAGE_SIZE) 207 210 { 208 uint32_t cTries = 3; 209 page_t *pPage = NULL; 210 while (cTries > 0) 211 { 212 /* 213 * Get a page from the free list locked exclusively. The page will be named (hashed in) 214 * and we rely on it during free. Downgrade the page to a shared lock to prevent the page 215 * from being relocated. 216 */ 217 pPage = rtR0MemObjSolPageAlloc(virtAddr, PAGE_SIZE); 218 if (!pPage) 219 break; 220 221 /* 222 * Check if the physical address backing the page is within the requested range if any. 223 * If it isn't, discard the page and try again. 224 */ 225 /** @todo Remove this constraint here, force all high-limit applicable cases 226 * through rtR0SolMemAlloc() */ 227 if (uPhysHi != NIL_RTHCPHYS) 228 { 229 uint64_t uPhys = rtR0MemObjSolPagePhys(pPage); 230 if (uPhys > uPhysHi) 231 { 232 page_destroy(pPage, 0 /* move it to the free list */); 233 pPage = NULL; 234 --cTries; 235 continue; 236 } 237 } 238 239 ppPages[i] = pPage; 240 break; 241 } 242 211 /* 212 * Get a page from the free list locked exclusively. The page will be named (hashed in) 213 * and we rely on it during free. Downgrade the page to a shared lock to prevent the page 214 * from being relocated. 215 */ 216 page_t *pPage = rtR0MemObjSolPageAlloc(virtAddr, PAGE_SIZE); 243 217 if (RT_UNLIKELY(!pPage)) 244 218 { … … 252 226 return NULL; 253 227 } 228 229 ppPages[i] = pPage; 254 230 } 255 231 … … 595 571 596 572 case RTR0MEMOBJTYPE_PHYS_NC: 597 rtR0MemObjSolPagesFree(pMemSolaris->pvHandle, pMemSolaris->Core.cb); 573 if (pMemSolaris->fIndivPages) 574 rtR0MemObjSolPagesFree(pMemSolaris->pvHandle, pMemSolaris->Core.cb); 575 else 576 rtR0SolMemFree(pMemSolaris->Core.pv, pMemSolaris->Core.cb); 598 577 break; 599 578 … … 688 667 return VERR_NO_MEMORY; 689 668 690 uint64_t PhysAddr = UINT64_MAX; 691 void *pvPages = rtR0MemObjSolPagesAlloc((uint64_t)PhysHighest, &PhysAddr, cb); 692 if (!pvPages) 693 { 694 LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0MemObjSolPagesAlloc failed for cb=%u.\n", cb)); 695 rtR0MemObjDelete(&pMemSolaris->Core); 696 return VERR_NO_MEMORY; 697 } 698 pMemSolaris->Core.pv = NULL; 699 pMemSolaris->pvHandle = pvPages; 700 701 Assert(PhysAddr != UINT64_MAX); 702 Assert(!(PhysAddr & PAGE_OFFSET_MASK)); 703 *ppMem = &pMemSolaris->Core; 704 return VINF_SUCCESS; 669 if (PhysHighest == NIL_RTHCPHYS) 670 { 671 uint64_t PhysAddr = UINT64_MAX; 672 void *pvPages = rtR0MemObjSolPagesAlloc(&PhysAddr, cb); 673 if (!pvPages) 674 { 675 LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0MemObjSolPagesAlloc failed for cb=%u.\n", cb)); 676 rtR0MemObjDelete(&pMemSolaris->Core); 677 return VERR_NO_MEMORY; 678 } 679 Assert(PhysAddr != UINT64_MAX); 680 Assert(!(PhysAddr & PAGE_OFFSET_MASK)); 681 682 pMemSolaris->Core.pv = NULL; 683 pMemSolaris->pvHandle = pvPages; 684 pMemSolaris->fIndivPages = true; 685 *ppMem = &pMemSolaris->Core; 686 return VINF_SUCCESS; 687 } 688 else 689 { 690 /* 691 * If we must satisfy an upper limit constraint, it isn't feasible to grab individual pages. 692 * We fall back to using contig_alloc(). 693 */ 694 uint64_t PhysAddr = UINT64_MAX; 695 void *pvMem = rtR0SolMemAlloc(PhysHighest, &PhysAddr, cb, PAGE_SIZE, false /* fContig */); 696 if (!pvMem) 697 { 698 LogRel(("rtR0MemObjNativeAllocPhysNC: rtR0SolMemAlloc failed for cb=%u PhysHighest=%RHp.\n", cb, PhysHighest)); 699 rtR0MemObjDelete(&pMemSolaris->Core); 700 return VERR_NO_MEMORY; 701 } 702 Assert(PhysAddr != UINT64_MAX); 703 Assert(!(PhysAddr & PAGE_OFFSET_MASK)); 704 705 pMemSolaris->Core.pv = pvMem; 706 pMemSolaris->pvHandle = NULL; 707 pMemSolaris->fIndivPages = false; 708 *ppMem = &pMemSolaris->Core; 709 return VINF_SUCCESS; 710 } 705 711 706 712 #else /* 32 bit: */ … … 1001 1007 * Prepare the pages for mapping according to type. 1002 1008 */ 1003 if (pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC) 1009 if ( pMemToMapSolaris->Core.enmType == RTR0MEMOBJTYPE_PHYS_NC 1010 && pMemToMapSolaris->fIndivPages) 1004 1011 { 1005 1012 page_t **ppPages = pMemToMapSolaris->pvHandle; 1013 AssertPtr(ppPages); 1006 1014 for (size_t iPage = 0; iPage < cPages; iPage++) 1007 1015 paPhysAddrs[iPage] = rtR0MemObjSolPagePhys(ppPages[iPage]); … … 1086 1094 { 1087 1095 case RTR0MEMOBJTYPE_PHYS_NC: 1088 if (pMemSolaris->Core.u.Phys.fAllocated) 1096 if ( pMemSolaris->Core.u.Phys.fAllocated 1097 || !pMemSolaris->fIndivPages) 1089 1098 { 1090 1099 uint8_t *pb = (uint8_t *)pMemSolaris->Core.pv + ((size_t)iPage << PAGE_SHIFT);
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器