06 Dec, 2011

4 commits

  • Move dma data to a superset ttm_dma_tt structure which herit
    from ttm_tt. This allow driver that don't use dma functionalities
    to not have to waste memory for it.

    V2 Rebase on top of no memory account changes (where/when is my
    delorean when i need it ?)
    V3 Make sure page list is initialized empty
    V4 typo/syntax fixes

    Signed-off-by: Jerome Glisse
    Reviewed-by: Thomas Hellstrom

    Jerome Glisse
     
  • In TTM world the pages for the graphic drivers are kept in three different
    pools: write combined, uncached, and cached (write-back). When the pages
    are used by the graphic driver the graphic adapter via its built in MMU
    (or AGP) programs these pages in. The programming requires the virtual address
    (from the graphic adapter perspective) and the physical address (either System RAM
    or the memory on the card) which is obtained using the pci_map_* calls (which does the
    virtual to physical - or bus address translation). During the graphic application's
    "life" those pages can be shuffled around, swapped out to disk, moved from the
    VRAM to System RAM or vice-versa. This all works with the existing TTM pool code
    - except when we want to use the software IOTLB (SWIOTLB) code to "map" the physical
    addresses to the graphic adapter MMU. We end up programming the bounce buffer's
    physical address instead of the TTM pool memory's and get a non-worky driver.
    There are two solutions:
    1) using the DMA API to allocate pages that are screened by the DMA API, or
    2) using the pci_sync_* calls to copy the pages from the bounce-buffer and back.

    This patch fixes the issue by allocating pages using the DMA API. The second
    is a viable option - but it has performance drawbacks and potential correctness
    issues - think of the write cache page being bounced (SWIOTLB->TTM), the
    WC is set on the TTM page and the copy from SWIOTLB not making it to the TTM
    page until the page has been recycled in the pool (and used by another application).

    The bounce buffer does not get activated often - only in cases where we have
    a 32-bit capable card and we want to use a page that is allocated above the
    4GB limit. The bounce buffer offers the solution of copying the contents
    of that 4GB page to an location below 4GB and then back when the operation has been
    completed (or vice-versa). This is done by using the 'pci_sync_*' calls.
    Note: If you look carefully enough in the existing TTM page pool code you will
    notice the GFP_DMA32 flag is used - which should guarantee that the provided page
    is under 4GB. It certainly is the case, except this gets ignored in two cases:
    - If user specifies 'swiotlb=force' which bounces _every_ page.
    - If user is using a Xen's PV Linux guest (which uses the SWIOTLB and the
    underlaying PFN's aren't necessarily under 4GB).

    To not have this extra copying done the other option is to allocate the pages
    using the DMA API so that there is not need to map the page and perform the
    expensive 'pci_sync_*' calls.

    This DMA API capable TTM pool requires for this the 'struct device' to
    properly call the DMA API. It also has to track the virtual and bus address of
    the page being handed out in case it ends up being swapped out or de-allocated -
    to make sure it is de-allocated using the proper's 'struct device'.

    Implementation wise the code keeps two lists: one that is attached to the
    'struct device' (via the dev->dma_pools list) and a global one to be used when
    the 'struct device' is unavailable (think shrinker code). The global list can
    iterate over all of the 'struct device' and its associated dma_pool. The list
    in dev->dma_pools can only iterate the device's dma_pool.
    /[struct device_pool]\
    /---------------------------------------------------| dev |
    / +-------| dma_pool |
    /-----+------\ / \--------------------/
    |struct device| /-->[struct dma_pool for WC]</ /[struct device_pool]\
    | dma_pools +----+ /-| dev |
    | ... | \--->[struct dma_pool for uncached]
    [v1: Using swiotlb_nr_tbl instead of swiotlb_enabled]
    [v2: Major overhaul - added 'inuse_list' to seperate used from inuse and reorder
    the order of lists to get better performance.]
    [v3: Added comments/and some logic based on review, Added Jerome tag]
    [v4: rebase on top of ttm_tt & ttm_backend merge]
    [v5: rebase on top of ttm memory accounting overhaul]
    [v6: New rebase on top of more memory accouting changes]
    [v7: well rebase on top of no memory accounting changes]
    [v8: make sure pages list is initialized empty]
    [v9: calll ttm_mem_global_free_page in unpopulate for accurate accountg]
    Signed-off-by: Konrad Rzeszutek Wilk
    Reviewed-by: Jerome Glisse
    Acked-by: Thomas Hellstrom

    Konrad Rzeszutek Wilk
     
  • Move the page allocation and freeing to driver callback and
    provide ttm code helper function for those.

    Most intrusive change, is the fact that we now only fully
    populate an object this simplify some of code designed around
    the page fault design.

    V2 Rebase on top of memory accounting overhaul
    V3 New rebase on top of more memory accouting changes
    V4 Rebase on top of no memory account changes (where/when is my
    delorean when i need it ?)

    Signed-off-by: Jerome Glisse
    Reviewed-by: Konrad Rzeszutek Wilk
    Reviewed-by: Thomas Hellstrom

    Jerome Glisse
     
  • Use the ttm_tt pages array for pages allocations, move the list
    unwinding into the page allocation functions.

    Signed-off-by: Jerome Glisse

    Jerome Glisse
     

21 Jun, 2011

1 commit


23 Feb, 2011

2 commits


28 Jan, 2011

1 commit


07 Jul, 2010

1 commit

  • Repeated ttm_page_alloc_init/fini fails noisily because the pool
    manager kobj isn't zeroed out between uses (we could do just that but
    statically allocated kobjects are generally considered a bad thing).
    Move it to kzalloc'ed memory.

    Note that this patch drops the refcounting behavior of the pool
    allocator init/fini functions: it would have led to a race condition
    in its current form, and anyway it was never exploited.

    This fixes a regression with reloading kms modules at runtime, since
    page allocator was introduced.

    Signed-off-by: Francisco Jerez
    Signed-off-by: Dave Airlie

    Francisco Jerez
     

06 Apr, 2010

3 commits

  • Sysfs interface allows user to configure pool allocator functionality and
    change limits for the size of pool.

    Signed-off-by: Pauli Nieminen
    Signed-off-by: Dave Airlie

    Pauli Nieminen
     
  • ttm_page_alloc_debugfs can be registered to output the state
    of pools.

    Debugfs file will output number of pages freed from the pool,
    number of pages in pool now and the lowes number of pages in
    pool since previous shrink.

    Signed-off-by: Pauli Nieminen
    Signed-off-by: Dave Airlie

    Pauli Nieminen
     
  • On AGP system we might allocate/free routinely uncached or wc memory,
    changing page from cached (wb) to uc or wc is very expensive and involves
    a lot of flushing. To improve performance this allocator use a pool
    of uc,wc pages.

    Pools are protected with spinlocks to allow multiple threads to allocate pages
    simultanously. Expensive operations are done outside of spinlock to maximize
    concurrency.

    Pools are linked lists of pages that were recently freed. mm shrink callback
    allows kernel to claim back pages when they are required for something else.

    Fixes:
    * set_pages_array_wb handles highmem pages so we don't have to remove them
    from pool.
    * Add count parameter to ttm_put_pages to avoid looping in free code.
    * Change looping from _safe to normal in pool fill error path.
    * Initialize sum variable and make the loop prettier in get_num_unused_pages.

    * Moved pages_freed reseting inside the loop in ttm_page_pool_free.
    * Add warning comment about spinlock context in ttm_page_pool_free.

    Based on Jerome Glisse's and Dave Airlie's pool allocator.

    Signed-off-by: Jerome Glisse
    Signed-off-by: Dave Airlie
    Signed-off-by: Pauli Nieminen
    Reviewed-by: Jerome Glisse
    Signed-off-by: Dave Airlie

    Pauli Nieminen