- Timestamp:
- Feb 26, 2010 4:35:27 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
r26864 r26866 92 92 93 93 94 static void rtR0MemObjLinuxFreePages(PRTR0MEMOBJLNX pMemLnx); 95 96 94 97 /** 95 98 * Helper that converts from a RTR0PROCESS handle to a linux task. … … 176 179 * @param enmType The object type. 177 180 * @param cb The number of bytes to allocate. 181 * @param uAlignment The alignment of the phyiscal memory. 182 * Only valid if fContiguous == true, ignored otherwise. 178 183 * @param fFlagsLnx The page allocation flags (GPFs). 179 184 * @param fContiguous Whether the allocation must be contiguous. 180 185 */ 181 static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb, unsigned fFlagsLnx, bool fContiguous) 186 static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb, 187 size_t uAlignment, unsigned fFlagsLnx, bool fContiguous) 182 188 { 183 189 size_t iPage; 184 size_t 190 size_t const cPages = cb >> PAGE_SHIFT; 185 191 struct page *paPages; 186 192 … … 202 208 || cb <= PAGE_SIZE * 2) 203 209 { 204 # ifdef VBOX_USE_INSERT_PAGE205 paPages = alloc_pages(fFlagsLnx | __GFP_COMP, rtR0MemObjLinuxOrder(c b >> PAGE_SHIFT));206 # else207 paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(c b >> PAGE_SHIFT));208 # endif210 # ifdef VBOX_USE_INSERT_PAGE 211 paPages = alloc_pages(fFlagsLnx | __GFP_COMP, rtR0MemObjLinuxOrder(cPages)); 212 # else 213 paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages)); 214 # endif 209 215 if (paPages) 210 216 { … … 237 243 #else /* < 2.4.22 */ 238 244 /** @todo figure out why we didn't allocate page-by-page on 2.4.21 and older... */ 239 paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(c b >> PAGE_SHIFT));245 paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages)); 240 246 if (!paPages) 241 247 { … … 260 266 for (iPage = 0; iPage < cPages; iPage++) 261 267 SetPageReserved(pMemLnx->apPages[iPage]); 268 269 /* 270 * Note that the physical address of memory allocated with alloc_pages(flags, order) 271 * is always 2^(PAGE_SHIFT+order)-aligned. 272 */ 273 if ( fContiguous 274 && uAlignment > PAGE_SIZE) 275 { 276 /* 277 * Check for alignment constraints. The physical address of memory allocated with 278 * alloc_pages(flags, order) is always 2^(PAGE_SHIFT+order)-aligned. 279 */ 280 if (RT_UNLIKELY(page_to_phys(pMemLnx->apPages[0]) & ~(uAlignment - 1))) 281 { 282 /* 283 * This should never happen! 284 */ 285 rtR0MemObjLinuxFreePages(pMemLnx); 286 return VERR_NO_MEMORY; 287 } 288 } 262 289 263 290 *ppMemLnx = pMemLnx; … … 503 530 504 531 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22) 505 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, GFP_HIGHUSER, false /* non-contiguous */);532 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, PAGE_SIZE, GFP_HIGHUSER, false /* non-contiguous */); 506 533 #else 507 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, GFP_USER, false /* non-contiguous */);534 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_PAGE, cb, PAGE_SIZE, GFP_USER, false /* non-contiguous */); 508 535 #endif 509 536 if (RT_SUCCESS(rc)) … … 532 559 #if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32) 533 560 /* ZONE_DMA32: 0-4GB */ 534 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, GFP_DMA32, false /* non-contiguous */);561 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_DMA32, false /* non-contiguous */); 535 562 if (RT_FAILURE(rc)) 536 563 #endif 537 564 #ifdef RT_ARCH_AMD64 538 565 /* ZONE_DMA: 0-16MB */ 539 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, GFP_DMA, false /* non-contiguous */);566 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_DMA, false /* non-contiguous */); 540 567 #else 541 568 # ifdef CONFIG_X86_PAE 542 569 # endif 543 570 /* ZONE_NORMAL: 0-896MB */ 544 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, GFP_USER, false /* non-contiguous */);571 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_LOW, cb, PAGE_SIZE, GFP_USER, false /* non-contiguous */); 545 572 #endif 546 573 if (RT_SUCCESS(rc)) … … 568 595 #if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32) 569 596 /* ZONE_DMA32: 0-4GB */ 570 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, GFP_DMA32, true /* contiguous */);597 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA32, true /* contiguous */); 571 598 if (RT_FAILURE(rc)) 572 599 #endif 573 600 #ifdef RT_ARCH_AMD64 574 601 /* ZONE_DMA: 0-16MB */ 575 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, GFP_DMA, true /* contiguous */);602 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_DMA, true /* contiguous */); 576 603 #else 577 604 /* ZONE_NORMAL (32-bit hosts): 0-896MB */ 578 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, GFP_USER, true /* contiguous */);605 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, RTR0MEMOBJTYPE_CONT, cb, PAGE_SIZE, GFP_USER, true /* contiguous */); 579 606 #endif 580 607 if (RT_SUCCESS(rc)) … … 608 635 * @param enmType The object type. 609 636 * @param cb The size of the allocation. 637 * @param uAlignment The alignment of the physical memory. 638 * Only valid for fContiguous == true, ignored otherwise. 610 639 * @param PhysHighest See rtR0MemObjNativeAllocPhys. 611 640 * @param fGfp The Linux GFP flags to use for the allocation. 612 641 */ 613 static int rtR0MemObjLinuxAllocPhysSub2(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb, RTHCPHYS PhysHighest, unsigned fGfp) 642 static int rtR0MemObjLinuxAllocPhysSub2(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, 643 size_t cb, size_t uAlignment, RTHCPHYS PhysHighest, unsigned fGfp) 614 644 { 615 645 PRTR0MEMOBJLNX pMemLnx; 616 646 int rc; 617 647 618 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, enmType, cb, fGfp,648 rc = rtR0MemObjLinuxAllocPages(&pMemLnx, enmType, cb, uAlignment, fGfp, 619 649 enmType == RTR0MEMOBJTYPE_PHYS /* contiguous / non-contiguous */); 620 650 if (RT_FAILURE(rc)) … … 656 686 * @param enmType The object type. 657 687 * @param cb The size of the allocation. 688 * @param uAlignment The alignment of the physical memory. 689 * Only valid for enmType == RTR0MEMOBJTYPE_PHYS, ignored otherwise. 658 690 * @param PhysHighest See rtR0MemObjNativeAllocPhys. 659 691 */ 660 static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb, RTHCPHYS PhysHighest) 692 static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, 693 size_t cb, size_t uAlignment, RTHCPHYS PhysHighest) 661 694 { 662 695 int rc; … … 674 707 if (PhysHighest == NIL_RTHCPHYS) 675 708 /* ZONE_HIGHMEM: the whole physical memory */ 676 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_HIGHUSER);709 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_HIGHUSER); 677 710 else if (PhysHighest <= _1M * 16) 678 711 /* ZONE_DMA: 0-16MB */ 679 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA);712 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA); 680 713 else 681 714 { … … 683 716 if (RT_FAILURE(rc)) 684 717 /* ZONE_HIGHMEM: the whole physical memory */ 685 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_HIGHUSER);718 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_HIGHUSER); 686 719 if (RT_FAILURE(rc)) 687 720 /* ZONE_NORMAL: 0-896MB */ 688 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_USER);721 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_USER); 689 722 #ifdef GFP_DMA32 690 723 if (RT_FAILURE(rc)) 691 724 /* ZONE_DMA32: 0-4GB */ 692 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA32);725 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA32); 693 726 #endif 694 727 if (RT_FAILURE(rc)) 695 728 /* ZONE_DMA: 0-16MB */ 696 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA);729 rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA); 697 730 } 698 731 return rc; … … 702 735 int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment) 703 736 { 704 /* 705 * Contiguous physical memory: Check for the alignment of the physical address. 706 * Use the knowledge that we are using alloc_pages(flags, order) for allocating 707 * contiguous physical memory which is always aligned at 2^(PAGE_SHIFT+order). 708 */ 709 if (uAlignment > cb) 710 return VERR_NOT_SUPPORTED; 711 712 return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest); 737 return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS, cb, uAlignment, PhysHighest); 713 738 } 714 739 … … 716 741 int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest) 717 742 { 718 /* 719 * Non-contiguous memory. 720 */ 721 return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest); 743 return rtR0MemObjLinuxAllocPhysSub(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PAGE_SIZE, PhysHighest); 722 744 } 723 745
Note:
See TracChangeset
for help on using the changeset viewer.