VirtualBox

Changeset 26866 in vbox for trunk/src


Ignore:
Timestamp:
Feb 26, 2010 4:35:27 PM (15 years ago)
Author:
vboxsync
Message:

Runtime/r0drv/memobj-linux: alignment for rtR0MemObjNativeAllocPhys(), 2nd try

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c

    r26864 r26866  
    9292
    9393
     94static void rtR0MemObjLinuxFreePages(PRTR0MEMOBJLNX pMemLnx);
     95
     96
    9497/**
    9598 * Helper that converts from a RTR0PROCESS handle to a linux task.
     
    176179 * @param   enmType     The object type.
    177180 * @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.
    178183 * @param   fFlagsLnx   The page allocation flags (GPFs).
    179184 * @param   fContiguous Whether the allocation must be contiguous.
    180185 */
    181 static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb, unsigned fFlagsLnx, bool fContiguous)
     186static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb,
     187                                     size_t uAlignment, unsigned fFlagsLnx, bool fContiguous)
    182188{
    183189    size_t          iPage;
    184     size_t          cPages = cb >> PAGE_SHIFT;
     190    size_t const    cPages = cb >> PAGE_SHIFT;
    185191    struct page    *paPages;
    186192
     
    202208        ||  cb <= PAGE_SIZE * 2)
    203209    {
    204 #ifdef VBOX_USE_INSERT_PAGE
    205         paPages = alloc_pages(fFlagsLnx |  __GFP_COMP, rtR0MemObjLinuxOrder(cb >> PAGE_SHIFT));
    206 #else
    207         paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cb >> PAGE_SHIFT));
    208 #endif
     210# 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
    209215        if (paPages)
    210216        {
     
    237243#else /* < 2.4.22 */
    238244    /** @todo figure out why we didn't allocate page-by-page on 2.4.21 and older... */
    239     paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cb >> PAGE_SHIFT));
     245    paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages));
    240246    if (!paPages)
    241247    {
     
    260266    for (iPage = 0; iPage < cPages; iPage++)
    261267        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    }
    262289
    263290    *ppMemLnx = pMemLnx;
     
    503530
    504531#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 */);
    506533#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 */);
    508535#endif
    509536    if (RT_SUCCESS(rc))
     
    532559#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
    533560    /* 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 */);
    535562    if (RT_FAILURE(rc))
    536563#endif
    537564#ifdef RT_ARCH_AMD64
    538565        /* 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 */);
    540567#else
    541568# ifdef CONFIG_X86_PAE
    542569# endif
    543570        /* 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 */);
    545572#endif
    546573    if (RT_SUCCESS(rc))
     
    568595#if (defined(RT_ARCH_AMD64) || defined(CONFIG_X86_PAE)) && defined(GFP_DMA32)
    569596    /* 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 */);
    571598    if (RT_FAILURE(rc))
    572599#endif
    573600#ifdef RT_ARCH_AMD64
    574601        /* 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 */);
    576603#else
    577604        /* 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 */);
    579606#endif
    580607    if (RT_SUCCESS(rc))
     
    608635 * @param   enmType     The object type.
    609636 * @param   cb          The size of the allocation.
     637 * @param   uAlignment  The alignment of the physical memory.
     638 *                      Only valid for fContiguous == true, ignored otherwise.
    610639 * @param   PhysHighest See rtR0MemObjNativeAllocPhys.
    611640 * @param   fGfp        The Linux GFP flags to use for the allocation.
    612641 */
    613 static int rtR0MemObjLinuxAllocPhysSub2(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb, RTHCPHYS PhysHighest, unsigned fGfp)
     642static int rtR0MemObjLinuxAllocPhysSub2(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
     643                                        size_t cb, size_t uAlignment, RTHCPHYS PhysHighest, unsigned fGfp)
    614644{
    615645    PRTR0MEMOBJLNX pMemLnx;
    616646    int rc;
    617647
    618     rc = rtR0MemObjLinuxAllocPages(&pMemLnx, enmType, cb, fGfp,
     648    rc = rtR0MemObjLinuxAllocPages(&pMemLnx, enmType, cb, uAlignment, fGfp,
    619649                                   enmType == RTR0MEMOBJTYPE_PHYS /* contiguous / non-contiguous */);
    620650    if (RT_FAILURE(rc))
     
    656686 * @param   enmType     The object type.
    657687 * @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.
    658690 * @param   PhysHighest See rtR0MemObjNativeAllocPhys.
    659691 */
    660 static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType, size_t cb, RTHCPHYS PhysHighest)
     692static int rtR0MemObjLinuxAllocPhysSub(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJTYPE enmType,
     693                                       size_t cb, size_t uAlignment, RTHCPHYS PhysHighest)
    661694{
    662695    int rc;
     
    674707    if (PhysHighest == NIL_RTHCPHYS)
    675708        /* 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);
    677710    else if (PhysHighest <= _1M * 16)
    678711        /* ZONE_DMA: 0-16MB */
    679         rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA);
     712        rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA);
    680713    else
    681714    {
     
    683716        if (RT_FAILURE(rc))
    684717            /* 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);
    686719        if (RT_FAILURE(rc))
    687720            /* ZONE_NORMAL: 0-896MB */
    688             rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_USER);
     721            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_USER);
    689722#ifdef GFP_DMA32
    690723        if (RT_FAILURE(rc))
    691724            /* ZONE_DMA32: 0-4GB */
    692             rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA32);
     725            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA32);
    693726#endif
    694727        if (RT_FAILURE(rc))
    695728            /* ZONE_DMA: 0-16MB */
    696             rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, PhysHighest, GFP_DMA);
     729            rc = rtR0MemObjLinuxAllocPhysSub2(ppMem, enmType, cb, uAlignment, PhysHighest, GFP_DMA);
    697730    }
    698731    return rc;
     
    702735int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
    703736{
    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);
    713738}
    714739
     
    716741int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
    717742{
    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);
    722744}
    723745
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette