Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* Copyright (c) 2025 Valve Corporation */
#ifndef _TTM_ALLOCATION_H_
#define _TTM_ALLOCATION_H_
#define TTM_ALLOCATION_POOL_BENEFICIAL_ORDER(n) ((n) & 0xff) /* Max order which caller can benefit from */
#define TTM_ALLOCATION_POOL_USE_DMA_ALLOC BIT(8) /* Use coherent DMA allocations. */
#define TTM_ALLOCATION_POOL_USE_DMA32 BIT(9) /* Use GFP_DMA32 allocations. */
#define TTM_ALLOCATION_PROPAGATE_ENOSPC BIT(10) /* Do not convert ENOSPC from resource managers to ENOMEM. */
#endif
+72
View File
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2024 Intel Corporation
*/
#ifndef _TTM_BACKUP_H_
#define _TTM_BACKUP_H_
#include <linux/mm_types.h>
#include <linux/shmem_fs.h>
/**
* ttm_backup_handle_to_page_ptr() - Convert handle to struct page pointer
* @handle: The handle to convert.
*
* Converts an opaque handle received from a ttm_backup_backup_*()
* function to an (invalid) struct page pointer suitable for a struct page array.
*
* Return: An (invalid) struct page pointer.
*/
static inline struct page *
ttm_backup_handle_to_page_ptr(unsigned long handle)
{
return (struct page *)(handle << 1 | 1);
}
/**
* ttm_backup_page_ptr_is_handle() - Whether a struct page pointer is a handle
* @page: The struct page pointer to check.
*
* Return: true if the struct page pointer is a handld returned from
* ttm_backup_handle_to_page_ptr(). False otherwise.
*/
static inline bool ttm_backup_page_ptr_is_handle(const struct page *page)
{
return (unsigned long)page & 1;
}
/**
* ttm_backup_page_ptr_to_handle() - Convert a struct page pointer to a handle
* @page: The struct page pointer to convert
*
* Return: The handle that was previously used in
* ttm_backup_handle_to_page_ptr() to obtain a struct page pointer, suitable
* for use as argument in the struct ttm_backup_drop() or
* ttm_backup_copy_page() functions.
*/
static inline unsigned long
ttm_backup_page_ptr_to_handle(const struct page *page)
{
WARN_ON(!ttm_backup_page_ptr_is_handle(page));
return (unsigned long)page >> 1;
}
void ttm_backup_drop(struct file *backup, pgoff_t handle);
int ttm_backup_copy_page(struct file *backup, struct page *dst,
pgoff_t handle, bool intr, gfp_t additional_gfp);
s64
ttm_backup_backup_folio(struct file *backup, struct folio *folio,
unsigned int order, bool writeback, pgoff_t idx,
gfp_t folio_gfp, gfp_t alloc_gfp,
pgoff_t *nr_pages_backed);
void ttm_backup_fini(struct file *backup);
u64 ttm_backup_bytes_avail(void);
struct file *ttm_backup_shmem_create(loff_t size);
#endif
+556
View File
@@ -0,0 +1,556 @@
/**************************************************************************
*
* Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
#ifndef _TTM_BO_API_H_
#define _TTM_BO_API_H_
#include <drm/drm_gem.h>
#include <linux/kref.h>
#include <linux/list.h>
#include "ttm_device.h"
/* Default number of pre-faulted pages in the TTM fault handler */
#define TTM_BO_VM_NUM_PREFAULT 16
struct iosys_map;
struct ttm_global;
struct ttm_device;
struct ttm_placement;
struct ttm_place;
struct ttm_resource;
struct ttm_resource_manager;
struct ttm_tt;
/**
* enum ttm_bo_type
*
* @ttm_bo_type_device: These are 'normal' buffers that can
* be mmapped by user space. Each of these bos occupy a slot in the
* device address space, that can be used for normal vm operations.
*
* @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers,
* but they cannot be accessed from user-space. For kernel-only use.
*
* @ttm_bo_type_sg: Buffer made from dmabuf sg table shared with another
* driver.
*/
enum ttm_bo_type {
ttm_bo_type_device,
ttm_bo_type_kernel,
ttm_bo_type_sg
};
/**
* struct ttm_buffer_object
*
* @base: drm_gem_object superclass data.
* @bdev: Pointer to the buffer object device structure.
* @type: The bo type.
* @page_alignment: Page alignment.
* @destroy: Destruction function. If NULL, kfree is used.
* @kref: Reference count of this buffer object. When this refcount reaches
* zero, the object is destroyed or put on the delayed delete list.
* @resource: structure describing current placement.
* @ttm: TTM structure holding system pages.
* @deleted: True if the object is only a zombie and already deleted.
* @bulk_move: The bulk move object.
* @priority: Priority for LRU, BOs with lower priority are evicted first.
* @pin_count: Pin count.
*
* Base class for TTM buffer object, that deals with data placement and CPU
* mappings. GPU mappings are really up to the driver, but for simpler GPUs
* the driver can usually use the placement offset @offset directly as the
* GPU virtual address. For drivers implementing multiple
* GPU memory manager contexts, the driver should manage the address space
* in these contexts separately and use these objects to get the correct
* placement and caching for these GPU maps. This makes it possible to use
* these objects for even quite elaborate memory management schemes.
* The destroy member, the API visibility of this object makes it possible
* to derive driver specific types.
*/
struct ttm_buffer_object {
struct drm_gem_object base;
/*
* Members constant at init.
*/
struct ttm_device *bdev;
enum ttm_bo_type type;
uint32_t page_alignment;
void (*destroy) (struct ttm_buffer_object *);
/*
* Members not needing protection.
*/
struct kref kref;
/*
* Members protected by the bo::resv::reserved lock.
*/
struct ttm_resource *resource;
struct ttm_tt *ttm;
bool deleted;
struct ttm_lru_bulk_move *bulk_move;
unsigned priority;
unsigned pin_count;
/**
* @delayed_delete: Work item used when we can't delete the BO
* immediately
*/
struct work_struct delayed_delete;
/**
* @sg: external source of pages and DMA addresses, protected by the
* reservation lock.
*/
struct sg_table *sg;
};
#define TTM_BO_MAP_IOMEM_MASK 0x80
/**
* struct ttm_bo_kmap_obj
*
* @virtual: The current kernel virtual address.
* @page: The page when kmap'ing a single page.
* @bo_kmap_type: Type of bo_kmap.
* @bo: The TTM BO.
*
* Object describing a kernel mapping. Since a TTM bo may be located
* in various memory types with various caching policies, the
* mapping can either be an ioremap, a vmap, a kmap or part of a
* premapped region.
*/
struct ttm_bo_kmap_obj {
void *virtual;
struct page *page;
enum {
ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK,
ttm_bo_map_vmap = 2,
ttm_bo_map_kmap = 3,
ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK,
} bo_kmap_type;
struct ttm_buffer_object *bo;
};
/**
* struct ttm_operation_ctx
*
* Context for TTM operations like changing buffer placement or general memory
* allocation.
*/
struct ttm_operation_ctx {
/** @interruptible: Sleep interruptible if sleeping. */
bool interruptible;
/** @no_wait_gpu: Return immediately if the GPU is busy. */
bool no_wait_gpu;
/**
* @gfp_retry_mayfail: Use __GFP_RETRY_MAYFAIL | __GFP_NOWARN
* when allocation pages. This is to avoid invoking the OOM
* killer when populating a buffer object, in order to
* forward the error for it to be dealt with.
*/
bool gfp_retry_mayfail;
/**
* @allow_res_evict: Allow eviction of reserved BOs. Can be used
* when multiple BOs share the same reservation object @resv.
*/
bool allow_res_evict;
/**
* @resv: Reservation object to be used together with
* @allow_res_evict.
*/
struct dma_resv *resv;
/**
* @bytes_moved: Statistics on how many bytes have been moved.
*/
uint64_t bytes_moved;
};
struct ttm_lru_walk;
/** struct ttm_lru_walk_ops - Operations for a LRU walk. */
struct ttm_lru_walk_ops {
/**
* process_bo - Process this bo.
* @walk: struct ttm_lru_walk describing the walk.
* @bo: A locked and referenced buffer object.
*
* Return: Negative error code on error, User-defined positive value
* (typically, but not always, size of the processed bo) on success.
* On success, the returned values are summed by the walk and the
* walk exits when its target is met.
* 0 also indicates success, -EBUSY means this bo was skipped.
*/
s64 (*process_bo)(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo);
};
/**
* struct ttm_lru_walk_arg - Common part for the variants of BO LRU walk.
*/
struct ttm_lru_walk_arg {
/** @ctx: Pointer to the struct ttm_operation_ctx. */
struct ttm_operation_ctx *ctx;
/** @ticket: The struct ww_acquire_ctx if any. */
struct ww_acquire_ctx *ticket;
/** @trylock_only: Only use trylock for locking. */
bool trylock_only;
};
/**
* struct ttm_lru_walk - Structure describing a LRU walk.
*/
struct ttm_lru_walk {
/** @ops: Pointer to the ops structure. */
const struct ttm_lru_walk_ops *ops;
/** @arg: Common bo LRU walk arguments. */
struct ttm_lru_walk_arg arg;
};
s64 ttm_lru_walk_for_evict(struct ttm_lru_walk *walk, struct ttm_device *bdev,
struct ttm_resource_manager *man, s64 target);
/**
* struct ttm_bo_shrink_flags - flags to govern the bo shrinking behaviour
* @purge: Purge the content rather than backing it up.
* @writeback: Attempt to immediately write content to swap space.
* @allow_move: Allow moving to system before shrinking. This is typically
* not desired for zombie- or ghost objects (with zombie object meaning
* objects with a zero gem object refcount)
*/
struct ttm_bo_shrink_flags {
u32 purge : 1;
u32 writeback : 1;
u32 allow_move : 1;
};
long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
const struct ttm_bo_shrink_flags flags);
bool ttm_bo_shrink_suitable(struct ttm_buffer_object *bo, struct ttm_operation_ctx *ctx);
bool ttm_bo_shrink_avoid_wait(void);
/**
* ttm_bo_reserve:
*
* @bo: A pointer to a struct ttm_buffer_object.
* @interruptible: Sleep interruptible if waiting.
* @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
* @ticket: ticket used to acquire the ww_mutex.
*
* Locks a buffer object for validation. (Or prevents other processes from
* locking it for validation), while taking a number of measures to prevent
* deadlocks.
*
* Returns:
* -EDEADLK: The reservation may cause a deadlock.
* Release all buffer reservations, wait for @bo to become unreserved and
* try again.
* -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space.
* -EBUSY: The function needed to sleep, but @no_wait was true
* -EALREADY: Bo already reserved using @ticket. This error code will only
* be returned if @use_ticket is set to true.
*/
static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
bool interruptible, bool no_wait,
struct ww_acquire_ctx *ticket)
{
int ret = 0;
if (no_wait) {
bool success;
if (WARN_ON(ticket))
return -EBUSY;
success = dma_resv_trylock(bo->base.resv);
return success ? 0 : -EBUSY;
}
if (interruptible)
ret = dma_resv_lock_interruptible(bo->base.resv, ticket);
else
ret = dma_resv_lock(bo->base.resv, ticket);
if (ret == -EINTR)
return -ERESTARTSYS;
return ret;
}
/**
* ttm_bo_reserve_slowpath:
* @bo: A pointer to a struct ttm_buffer_object.
* @interruptible: Sleep interruptible if waiting.
* @ticket: Ticket used to acquire the ww_mutex.
*
* This is called after ttm_bo_reserve returns -EAGAIN and we backed off
* from all our other reservations. Because there are no other reservations
* held by us, this function cannot deadlock any more.
*/
static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
bool interruptible,
struct ww_acquire_ctx *ticket)
{
if (interruptible) {
int ret = dma_resv_lock_slow_interruptible(bo->base.resv,
ticket);
if (ret == -EINTR)
ret = -ERESTARTSYS;
return ret;
}
dma_resv_lock_slow(bo->base.resv, ticket);
return 0;
}
void ttm_bo_move_to_lru_tail(struct ttm_buffer_object *bo);
static inline void
ttm_bo_move_to_lru_tail_unlocked(struct ttm_buffer_object *bo)
{
spin_lock(&bo->bdev->lru_lock);
ttm_bo_move_to_lru_tail(bo);
spin_unlock(&bo->bdev->lru_lock);
}
static inline void ttm_bo_assign_mem(struct ttm_buffer_object *bo,
struct ttm_resource *new_mem)
{
WARN_ON(bo->resource);
bo->resource = new_mem;
}
/**
* ttm_bo_move_null - assign memory for a buffer object.
* @bo: The bo to assign the memory to
* @new_mem: The memory to be assigned.
*
* Assign the memory from new_mem to the memory of the buffer object bo.
*/
static inline void ttm_bo_move_null(struct ttm_buffer_object *bo,
struct ttm_resource *new_mem)
{
ttm_resource_free(bo, &bo->resource);
ttm_bo_assign_mem(bo, new_mem);
}
/**
* ttm_bo_unreserve
*
* @bo: A pointer to a struct ttm_buffer_object.
*
* Unreserve a previous reservation of @bo.
*/
static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo)
{
ttm_bo_move_to_lru_tail_unlocked(bo);
dma_resv_unlock(bo->base.resv);
}
/**
* ttm_kmap_obj_virtual
*
* @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap.
* @is_iomem: Pointer to an integer that on return indicates 1 if the
* virtual map is io memory, 0 if normal memory.
*
* Returns the virtual address of a buffer object area mapped by ttm_bo_kmap.
* If *is_iomem is 1 on return, the virtual address points to an io memory area,
* that should strictly be accessed by the iowriteXX() and similar functions.
*/
static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map,
bool *is_iomem)
{
*is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK);
return map->virtual;
}
int ttm_bo_wait_ctx(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx);
int ttm_bo_validate(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
struct ttm_operation_ctx *ctx);
void ttm_bo_fini(struct ttm_buffer_object *bo);
void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo,
struct ttm_lru_bulk_move *bulk);
bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
const struct ttm_place *place);
int ttm_bo_init_reserved(struct ttm_device *bdev, struct ttm_buffer_object *bo,
enum ttm_bo_type type, struct ttm_placement *placement,
uint32_t alignment, struct ttm_operation_ctx *ctx,
struct sg_table *sg, struct dma_resv *resv,
void (*destroy)(struct ttm_buffer_object *));
int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo,
enum ttm_bo_type type, struct ttm_placement *placement,
uint32_t alignment, bool interruptible,
struct sg_table *sg, struct dma_resv *resv,
void (*destroy)(struct ttm_buffer_object *));
int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page,
unsigned long num_pages, struct ttm_bo_kmap_obj *map);
void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);
void *ttm_bo_kmap_try_from_panic(struct ttm_buffer_object *bo, unsigned long page);
int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map);
void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map);
int ttm_bo_mmap_obj(struct vm_area_struct *vma, struct ttm_buffer_object *bo);
s64 ttm_bo_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
struct ttm_resource_manager *man, gfp_t gfp_flags,
s64 target);
void ttm_bo_pin(struct ttm_buffer_object *bo);
void ttm_bo_unpin(struct ttm_buffer_object *bo);
int ttm_bo_evict_first(struct ttm_device *bdev,
struct ttm_resource_manager *man,
struct ttm_operation_ctx *ctx);
int ttm_bo_access(struct ttm_buffer_object *bo, unsigned long offset,
void *buf, int len, int write);
vm_fault_t ttm_bo_vm_reserve(struct ttm_buffer_object *bo,
struct vm_fault *vmf);
vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
pgprot_t prot,
pgoff_t num_prefault);
vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf);
void ttm_bo_vm_open(struct vm_area_struct *vma);
void ttm_bo_vm_close(struct vm_area_struct *vma);
int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr,
void *buf, int len, int write);
vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot);
int ttm_bo_mem_space(struct ttm_buffer_object *bo,
struct ttm_placement *placement,
struct ttm_resource **mem,
struct ttm_operation_ctx *ctx);
void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo);
/*
* ttm_bo_util.c
*/
int ttm_mem_io_reserve(struct ttm_device *bdev,
struct ttm_resource *mem);
void ttm_mem_io_free(struct ttm_device *bdev,
struct ttm_resource *mem);
void ttm_move_memcpy(bool clear, u32 num_pages,
struct ttm_kmap_iter *dst_iter,
struct ttm_kmap_iter *src_iter);
int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx,
struct ttm_resource *new_mem);
int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
struct dma_fence *fence, bool evict,
bool pipeline,
struct ttm_resource *new_mem);
void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo,
struct ttm_resource *new_mem);
int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo);
pgprot_t ttm_io_prot(struct ttm_buffer_object *bo, struct ttm_resource *res,
pgprot_t tmp);
void ttm_bo_tt_destroy(struct ttm_buffer_object *bo);
int ttm_bo_populate(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx);
int ttm_bo_setup_export(struct ttm_buffer_object *bo,
struct ttm_operation_ctx *ctx);
/* Driver LRU walk helpers initially targeted for shrinking. */
/**
* struct ttm_bo_lru_cursor - Iterator cursor for TTM LRU list looping
*/
struct ttm_bo_lru_cursor {
/** @res_curs: Embedded struct ttm_resource_cursor. */
struct ttm_resource_cursor res_curs;
/**
* @bo: Buffer object pointer if a buffer object is refcounted,
* NULL otherwise.
*/
struct ttm_buffer_object *bo;
/**
* @needs_unlock: Valid iff @bo != NULL. The bo resv needs
* unlock before the next iteration or after loop exit.
*/
bool needs_unlock;
/** @arg: Pointer to common BO LRU walk arguments. */
struct ttm_lru_walk_arg *arg;
};
void ttm_bo_lru_cursor_fini(struct ttm_bo_lru_cursor *curs);
struct ttm_bo_lru_cursor *
ttm_bo_lru_cursor_init(struct ttm_bo_lru_cursor *curs,
struct ttm_resource_manager *man,
struct ttm_lru_walk_arg *arg);
struct ttm_buffer_object *ttm_bo_lru_cursor_first(struct ttm_bo_lru_cursor *curs);
struct ttm_buffer_object *ttm_bo_lru_cursor_next(struct ttm_bo_lru_cursor *curs);
/*
* Defines needed to use autocleanup (linux/cleanup.h) with struct ttm_bo_lru_cursor.
*/
DEFINE_CLASS(ttm_bo_lru_cursor, struct ttm_bo_lru_cursor *,
if (_T) {ttm_bo_lru_cursor_fini(_T); },
ttm_bo_lru_cursor_init(curs, man, arg),
struct ttm_bo_lru_cursor *curs, struct ttm_resource_manager *man,
struct ttm_lru_walk_arg *arg);
static inline void *
class_ttm_bo_lru_cursor_lock_ptr(class_ttm_bo_lru_cursor_t *_T)
{ return *_T; }
#define class_ttm_bo_lru_cursor_is_conditional false
/**
* ttm_bo_lru_for_each_reserved_guarded() - Iterate over buffer objects owning
* resources on LRU lists.
* @_cursor: struct ttm_bo_lru_cursor to use for the iteration.
* @_man: The resource manager whose LRU lists to iterate over.
* @_arg: The struct ttm_lru_walk_arg to govern the LRU walk.
* @_bo: The struct ttm_buffer_object pointer pointing to the buffer object
* for the current iteration.
*
* Iterate over all resources of @_man and for each resource, attempt to
* reference and lock (using the locking mode detailed in @_ctx) the buffer
* object it points to. If successful, assign @_bo to the address of the
* buffer object and update @_cursor. The iteration is guarded in the
* sense that @_cursor will be initialized before looping start and cleaned
* up at looping termination, even if terminated prematurely by, for
* example a return or break statement. Exiting the loop will also unlock
* (if needed) and unreference @_bo.
*
* Return: If locking of a bo returns an error, then iteration is terminated
* and @_bo is set to a corresponding error pointer. It's illegal to
* dereference @_bo after loop exit.
*/
#define ttm_bo_lru_for_each_reserved_guarded(_cursor, _man, _arg, _bo) \
scoped_guard(ttm_bo_lru_cursor, _cursor, _man, _arg) \
for ((_bo) = ttm_bo_lru_cursor_first(_cursor); \
!IS_ERR_OR_NULL(_bo); \
(_bo) = ttm_bo_lru_cursor_next(_cursor))
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright 2020 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Christian König
*/
#ifndef _TTM_CACHING_H_
#define _TTM_CACHING_H_
#include <linux/pgtable.h>
#define TTM_NUM_CACHING_TYPES 3
/**
* enum ttm_caching - CPU caching and BUS snooping behavior.
*/
enum ttm_caching {
/**
* @ttm_uncached: Most defensive option for device mappings,
* don't even allow write combining.
*/
ttm_uncached,
/**
* @ttm_write_combined: Don't cache read accesses, but allow at least
* writes to be combined.
*/
ttm_write_combined,
/**
* @ttm_cached: Fully cached like normal system memory, requires that
* devices snoop the CPU cache on accesses.
*/
ttm_cached
};
pgprot_t ttm_prot_from_caching(enum ttm_caching caching, pgprot_t tmp);
#endif
+305
View File
@@ -0,0 +1,305 @@
/*
* Copyright 2020 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Christian König
*/
#ifndef _TTM_DEVICE_H_
#define _TTM_DEVICE_H_
#include <linux/types.h>
#include <linux/workqueue.h>
#include <drm/ttm/ttm_allocation.h>
#include <drm/ttm/ttm_resource.h>
#include <drm/ttm/ttm_pool.h>
struct ttm_device;
struct ttm_placement;
struct ttm_buffer_object;
struct ttm_operation_ctx;
/**
* struct ttm_global - Buffer object driver global data.
*/
extern struct ttm_global {
/**
* @dummy_read_page: Pointer to a dummy page used for mapping requests
* of unpopulated pages. Constant after init.
*/
struct page *dummy_read_page;
/**
* @device_list: List of buffer object devices. Protected by
* ttm_global_mutex.
*/
struct list_head device_list;
/**
* @bo_count: Number of buffer objects allocated by devices.
*/
atomic_t bo_count;
} ttm_glob;
struct ttm_device_funcs {
/**
* ttm_tt_create
*
* @bo: The buffer object to create the ttm for.
* @page_flags: Page flags as identified by TTM_TT_FLAG_XX flags.
*
* Create a struct ttm_tt to back data with system memory pages.
* No pages are actually allocated.
* Returns:
* NULL: Out of memory.
*/
struct ttm_tt *(*ttm_tt_create)(struct ttm_buffer_object *bo,
uint32_t page_flags);
/**
* ttm_tt_populate
*
* @ttm: The struct ttm_tt to contain the backing pages.
*
* Allocate all backing pages
* Returns:
* -ENOMEM: Out of memory.
*/
int (*ttm_tt_populate)(struct ttm_device *bdev,
struct ttm_tt *ttm,
struct ttm_operation_ctx *ctx);
/**
* ttm_tt_unpopulate
*
* @ttm: The struct ttm_tt to contain the backing pages.
*
* Free all backing page
*/
void (*ttm_tt_unpopulate)(struct ttm_device *bdev,
struct ttm_tt *ttm);
/**
* ttm_tt_destroy
*
* @bdev: Pointer to a ttm device
* @ttm: Pointer to a struct ttm_tt.
*
* Destroy the backend. This will be call back from ttm_tt_destroy so
* don't call ttm_tt_destroy from the callback or infinite loop.
*/
void (*ttm_tt_destroy)(struct ttm_device *bdev, struct ttm_tt *ttm);
/**
* struct ttm_bo_driver member eviction_valuable
*
* @bo: the buffer object to be evicted
* @place: placement we need room for
*
* Check with the driver if it is valuable to evict a BO to make room
* for a certain placement.
*/
bool (*eviction_valuable)(struct ttm_buffer_object *bo,
const struct ttm_place *place);
/**
* struct ttm_bo_driver member evict_flags:
*
* @bo: the buffer object to be evicted
*
* Return the bo flags for a buffer which is not mapped to the hardware.
* These will be placed in proposed_flags so that when the move is
* finished, they'll end up in bo->mem.flags
* This should not cause multihop evictions, and the core will warn
* if one is proposed.
*/
void (*evict_flags)(struct ttm_buffer_object *bo,
struct ttm_placement *placement);
/**
* struct ttm_bo_driver member move:
*
* @bo: the buffer to move
* @evict: whether this motion is evicting the buffer from
* the graphics address space
* @ctx: context for this move with parameters
* @new_mem: the new memory region receiving the buffer
* @hop: placement for driver directed intermediate hop
*
* Move a buffer between two memory regions.
* Returns errno -EMULTIHOP if driver requests a hop
*/
int (*move)(struct ttm_buffer_object *bo, bool evict,
struct ttm_operation_ctx *ctx,
struct ttm_resource *new_mem,
struct ttm_place *hop);
/**
* Hook to notify driver about a resource delete.
*/
void (*delete_mem_notify)(struct ttm_buffer_object *bo);
/**
* notify the driver that we're about to swap out this bo
*/
void (*swap_notify)(struct ttm_buffer_object *bo);
/**
* Driver callback on when mapping io memory (for bo_move_memcpy
* for instance). TTM will take care to call io_mem_free whenever
* the mapping is not use anymore. io_mem_reserve & io_mem_free
* are balanced.
*/
int (*io_mem_reserve)(struct ttm_device *bdev,
struct ttm_resource *mem);
void (*io_mem_free)(struct ttm_device *bdev,
struct ttm_resource *mem);
/**
* Return the pfn for a given page_offset inside the BO.
*
* @bo: the BO to look up the pfn for
* @page_offset: the offset to look up
*/
unsigned long (*io_mem_pfn)(struct ttm_buffer_object *bo,
unsigned long page_offset);
/**
* Read/write memory buffers for ptrace access
*
* @bo: the BO to access
* @offset: the offset from the start of the BO
* @buf: pointer to source/destination buffer
* @len: number of bytes to copy
* @write: whether to read (0) from or write (non-0) to BO
*
* If successful, this function should return the number of
* bytes copied, -EIO otherwise. If the number of bytes
* returned is < len, the function may be called again with
* the remainder of the buffer to copy.
*/
int (*access_memory)(struct ttm_buffer_object *bo, unsigned long offset,
void *buf, int len, int write);
/**
* Notify the driver that we're about to release a BO
*
* @bo: BO that is about to be released
*
* Gives the driver a chance to do any cleanup, including
* adding fences that may force a delayed delete
*/
void (*release_notify)(struct ttm_buffer_object *bo);
};
/**
* struct ttm_device - Buffer object driver device-specific data.
*/
struct ttm_device {
/**
* @device_list: Our entry in the global device list.
* Constant after bo device init
*/
struct list_head device_list;
/**
* @alloc_flags: TTM_ALLOCATION_* flags.
*/
unsigned int alloc_flags;
/**
* @funcs: Function table for the device.
* Constant after bo device init
*/
const struct ttm_device_funcs *funcs;
/**
* @sysman: Resource manager for the system domain.
* Access via ttm_manager_type.
*/
struct ttm_resource_manager sysman;
/**
* @man_drv: An array of resource_managers, one per resource type.
*/
struct ttm_resource_manager *man_drv[TTM_NUM_MEM_TYPES];
/**
* @vma_manager: Address space manager for finding BOs to mmap.
*/
struct drm_vma_offset_manager *vma_manager;
/**
* @pool: page pool for the device.
*/
struct ttm_pool pool;
/**
* @lru_lock: Protection for the per manager LRU and ddestroy lists.
*/
spinlock_t lru_lock;
/**
* @unevictable: Buffer objects which are pinned or swapped and as such
* not on an LRU list.
*/
struct list_head unevictable;
/**
* @dev_mapping: A pointer to the struct address_space for invalidating
* CPU mappings on buffer move. Protected by load/unload sync.
*/
struct address_space *dev_mapping;
/**
* @wq: Work queue structure for the delayed delete workqueue.
*/
struct workqueue_struct *wq;
};
int ttm_global_swapout(struct ttm_operation_ctx *ctx, gfp_t gfp_flags);
int ttm_device_swapout(struct ttm_device *bdev, struct ttm_operation_ctx *ctx,
gfp_t gfp_flags);
int ttm_device_prepare_hibernation(struct ttm_device *bdev);
static inline struct ttm_resource_manager *
ttm_manager_type(struct ttm_device *bdev, int mem_type)
{
BUILD_BUG_ON(__builtin_constant_p(mem_type)
&& mem_type >= TTM_NUM_MEM_TYPES);
return bdev->man_drv[mem_type];
}
static inline void ttm_set_driver_manager(struct ttm_device *bdev, int type,
struct ttm_resource_manager *manager)
{
BUILD_BUG_ON(__builtin_constant_p(type) && type >= TTM_NUM_MEM_TYPES);
bdev->man_drv[type] = manager;
}
int ttm_device_init(struct ttm_device *bdev, const struct ttm_device_funcs *funcs,
struct device *dev, struct address_space *mapping,
struct drm_vma_offset_manager *vma_manager,
unsigned int alloc_flags);
void ttm_device_fini(struct ttm_device *bdev);
void ttm_device_clear_dma_mappings(struct ttm_device *bdev);
#endif
@@ -0,0 +1,119 @@
/**************************************************************************
*
* Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
#ifndef _TTM_EXECBUF_UTIL_H_
#define _TTM_EXECBUF_UTIL_H_
#include <linux/list.h>
struct ww_acquire_ctx;
struct dma_fence;
struct ttm_buffer_object;
/**
* struct ttm_validate_buffer
*
* @head: list head for thread-private list.
* @bo: refcounted buffer object pointer.
* @num_shared: How many shared fences we want to add.
*/
struct ttm_validate_buffer {
struct list_head head;
struct ttm_buffer_object *bo;
unsigned int num_shared;
};
/**
* ttm_eu_backoff_reservation
*
* @ticket: ww_acquire_ctx from reserve call
* @list: thread private list of ttm_validate_buffer structs.
*
* Undoes all buffer validation reservations for bos pointed to by
* the list entries.
*/
void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
struct list_head *list);
/**
* ttm_eu_reserve_buffers
*
* @ticket: [out] ww_acquire_ctx filled in by call, or NULL if only
* non-blocking reserves should be tried.
* @list: thread private list of ttm_validate_buffer structs.
* @intr: should the wait be interruptible
* @dups: [out] optional list of duplicates.
*
* Tries to reserve bos pointed to by the list entries for validation.
* If the function returns 0, all buffers are marked as "unfenced",
* taken off the lru lists and are not synced for write CPU usage.
*
* If the function detects a deadlock due to multiple threads trying to
* reserve the same buffers in reverse order, all threads except one will
* back off and retry. This function may sleep while waiting for
* CPU write reservations to be cleared, and for other threads to
* unreserve their buffers.
*
* If intr is set to true, this function may return -ERESTARTSYS if the
* calling process receives a signal while waiting. In that case, no
* buffers on the list will be reserved upon return.
*
* If dups is non NULL all buffers already reserved by the current thread
* (e.g. duplicates) are added to this list, otherwise -EALREADY is returned
* on the first already reserved buffer and all buffers from the list are
* unreserved again.
*
* Buffers reserved by this function should be unreserved by
* a call to either ttm_eu_backoff_reservation() or
* ttm_eu_fence_buffer_objects() when command submission is complete or
* has failed.
*/
int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
struct list_head *list, bool intr,
struct list_head *dups);
/**
* ttm_eu_fence_buffer_objects
*
* @ticket: ww_acquire_ctx from reserve call
* @list: thread private list of ttm_validate_buffer structs.
* @fence: The new exclusive fence for the buffers.
*
* This function should be called when command submission is complete, and
* it will add a new sync object to bos pointed to by entries on @list.
* It also unreserves all buffers, putting them on lru lists.
*
*/
void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
struct list_head *list,
struct dma_fence *fence);
#endif
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2021 Intel Corporation
*/
#ifndef __TTM_KMAP_ITER_H__
#define __TTM_KMAP_ITER_H__
#include <linux/types.h>
struct ttm_kmap_iter;
struct iosys_map;
/**
* struct ttm_kmap_iter_ops - Ops structure for a struct
* ttm_kmap_iter.
* @maps_tt: Whether the iterator maps TT memory directly, as opposed
* mapping a TT through an aperture. Both these modes have
* struct ttm_resource_manager::use_tt set, but the latter typically
* returns is_iomem == true from ttm_mem_io_reserve.
*/
struct ttm_kmap_iter_ops {
/**
* @map_local: Map a PAGE_SIZE part of the resource using
* kmap_local semantics.
* @res_iter: Pointer to the struct ttm_kmap_iter representing
* the resource.
* @dmap: The struct iosys_map holding the virtual address after
* the operation.
* @i: The location within the resource to map. PAGE_SIZE granularity.
*/
void (*map_local)(struct ttm_kmap_iter *res_iter,
struct iosys_map *dmap, pgoff_t i);
/**
* @unmap_local: Unmap a PAGE_SIZE part of the resource previously
* mapped using kmap_local.
* @res_iter: Pointer to the struct ttm_kmap_iter representing
* the resource.
* @dmap: The struct iosys_map holding the virtual address after
* the operation.
*/
void (*unmap_local)(struct ttm_kmap_iter *res_iter,
struct iosys_map *dmap);
bool maps_tt;
};
/**
* struct ttm_kmap_iter - Iterator for kmap_local type operations on a
* resource.
* @ops: Pointer to the operations struct.
*
* This struct is intended to be embedded in a resource-specific specialization
* implementing operations for the resource.
*
* Nothing stops us from extending the operations to vmap, vmap_pfn etc,
* replacing some or parts of the ttm_bo_util. cpu-map functionality.
*/
struct ttm_kmap_iter {
const struct ttm_kmap_iter_ops *ops;
};
#endif /* __TTM_KMAP_ITER_H__ */
+103
View File
@@ -0,0 +1,103 @@
/**************************************************************************
*
* Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
#ifndef _TTM_PLACEMENT_H_
#define _TTM_PLACEMENT_H_
#include <linux/types.h>
/*
* Memory regions for data placement.
*
* Buffers placed in TTM_PL_SYSTEM are considered under TTMs control and can
* be swapped out whenever TTMs thinks it is a good idea.
* In cases where drivers would like to use TTM_PL_SYSTEM as a valid
* placement they need to be able to handle the issues that arise due to the
* above manually.
*
* For BO's which reside in system memory but for which the accelerator
* requires direct access (i.e. their usage needs to be synchronized
* between the CPU and accelerator via fences) a new, driver private
* placement that can handle such scenarios is a good idea.
*/
#define TTM_PL_SYSTEM 0
#define TTM_PL_TT 1
#define TTM_PL_VRAM 2
#define TTM_PL_PRIV 3
/*
* TTM_PL_FLAG_TOPDOWN requests to be placed from the
* top of the memory area, instead of the bottom.
*/
#define TTM_PL_FLAG_CONTIGUOUS (1 << 0)
#define TTM_PL_FLAG_TOPDOWN (1 << 1)
/* For multihop handling */
#define TTM_PL_FLAG_TEMPORARY (1 << 2)
/* Placement is never used during eviction */
#define TTM_PL_FLAG_DESIRED (1 << 3)
/* Placement is only used during eviction */
#define TTM_PL_FLAG_FALLBACK (1 << 4)
/**
* struct ttm_place
*
* @fpfn: first valid page frame number to put the object
* @lpfn: last valid page frame number to put the object
* @mem_type: One of TTM_PL_* where the resource should be allocated from.
* @flags: memory domain and caching flags for the object
*
* Structure indicating a possible place to put an object.
*/
struct ttm_place {
uint64_t fpfn;
uint64_t lpfn;
uint32_t mem_type;
uint32_t flags;
};
/**
* struct ttm_placement
*
* @num_placement: number of preferred placements
* @placement: preferred placements
*
* Structure indicating the placement you request for an object.
*/
struct ttm_placement {
unsigned num_placement;
const struct ttm_place *placement;
};
#endif
+100
View File
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
* Copyright 2020 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Christian König
*/
#ifndef _TTM_PAGE_POOL_H_
#define _TTM_PAGE_POOL_H_
#include <linux/mmzone.h>
#include <linux/llist.h>
#include <linux/spinlock.h>
#include <linux/list_lru.h>
#include <drm/ttm/ttm_caching.h>
struct device;
struct seq_file;
struct ttm_backup_flags;
struct ttm_operation_ctx;
struct ttm_pool;
struct ttm_tt;
/**
* struct ttm_pool_type - Pool for a certain memory type
*
* @pool: the pool we belong to, might be NULL for the global ones
* @order: the allocation order our pages have
* @caching: the caching type our pages have
* @shrinker_list: our place on the global shrinker list
* @pages: the lru_list of pages in the pool
*/
struct ttm_pool_type {
struct ttm_pool *pool;
unsigned int order;
enum ttm_caching caching;
struct list_head shrinker_list;
struct list_lru pages;
};
/**
* struct ttm_pool - Pool for all caching and orders
*
* @dev: the device we allocate pages for
* @nid: which numa node to use
* @alloc_flags: TTM_ALLOCATION_POOL_* flags
* @caching: pools for each caching/order
*/
struct ttm_pool {
struct device *dev;
int nid;
unsigned int alloc_flags;
struct {
struct ttm_pool_type orders[NR_PAGE_ORDERS];
} caching[TTM_NUM_CACHING_TYPES];
};
int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
struct ttm_operation_ctx *ctx);
void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt);
void ttm_pool_init(struct ttm_pool *pool, struct device *dev,
int nid, unsigned int alloc_flags);
void ttm_pool_fini(struct ttm_pool *pool);
int ttm_pool_debugfs(struct ttm_pool *pool, struct seq_file *m);
void ttm_pool_drop_backed_up(struct ttm_tt *tt);
long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *ttm,
const struct ttm_backup_flags *flags);
int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx);
int ttm_pool_mgr_init(unsigned long num_pages);
void ttm_pool_mgr_fini(void);
#endif
@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
#ifndef _TTM_RANGE_MANAGER_H_
#define _TTM_RANGE_MANAGER_H_
#include <drm/ttm/ttm_resource.h>
#include <drm/ttm/ttm_device.h>
#include <drm/drm_mm.h>
/**
* struct ttm_range_mgr_node
*
* @base: base clase we extend
* @mm_nodes: MM nodes, usually 1
*
* Extending the ttm_resource object to manage an address space allocation with
* one or more drm_mm_nodes.
*/
struct ttm_range_mgr_node {
struct ttm_resource base;
struct drm_mm_node mm_nodes[];
};
/**
* to_ttm_range_mgr_node
*
* @res: the resource to upcast
*
* Upcast the ttm_resource object into a ttm_range_mgr_node object.
*/
static inline struct ttm_range_mgr_node *
to_ttm_range_mgr_node(struct ttm_resource *res)
{
return container_of(res, struct ttm_range_mgr_node, base);
}
int ttm_range_man_init_nocheck(struct ttm_device *bdev,
unsigned type, bool use_tt,
unsigned long p_size);
int ttm_range_man_fini_nocheck(struct ttm_device *bdev,
unsigned type);
static __always_inline int ttm_range_man_init(struct ttm_device *bdev,
unsigned int type, bool use_tt,
unsigned long p_size)
{
BUILD_BUG_ON(__builtin_constant_p(type) && type >= TTM_NUM_MEM_TYPES);
return ttm_range_man_init_nocheck(bdev, type, use_tt, p_size);
}
static __always_inline int ttm_range_man_fini(struct ttm_device *bdev,
unsigned int type)
{
BUILD_BUG_ON(__builtin_constant_p(type) && type >= TTM_NUM_MEM_TYPES);
return ttm_range_man_fini_nocheck(bdev, type);
}
#endif
+526
View File
@@ -0,0 +1,526 @@
/*
* Copyright 2020 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Christian König
*/
#ifndef _TTM_RESOURCE_H_
#define _TTM_RESOURCE_H_
#include <linux/types.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/iosys-map.h>
#include <linux/dma-fence.h>
#include <drm/ttm/ttm_caching.h>
#include <drm/ttm/ttm_kmap_iter.h>
#define TTM_MAX_BO_PRIORITY 4U
#define TTM_NUM_MEM_TYPES 9
struct dentry;
struct dmem_cgroup_device;
struct drm_printer;
struct ttm_device;
struct ttm_resource_manager;
struct ttm_resource;
struct ttm_place;
struct ttm_buffer_object;
struct ttm_placement;
struct iosys_map;
struct io_mapping;
struct sg_table;
struct scatterlist;
/**
* define TTM_NUM_MOVE_FENCES - How many entities can be used for evictions
*
* Pipelined evictions can be spread on multiple entities. This
* is the max number of entities that can be used by the driver
* for that purpose.
*/
#define TTM_NUM_MOVE_FENCES 8
/**
* enum ttm_lru_item_type - enumerate ttm_lru_item subclasses
*/
enum ttm_lru_item_type {
/** @TTM_LRU_RESOURCE: The resource subclass */
TTM_LRU_RESOURCE,
/** @TTM_LRU_HITCH: The iterator hitch subclass */
TTM_LRU_HITCH
};
/**
* struct ttm_lru_item - The TTM lru list node base class
* @link: The list link
* @type: The subclass type
*/
struct ttm_lru_item {
struct list_head link;
enum ttm_lru_item_type type;
};
/**
* ttm_lru_item_init() - initialize a struct ttm_lru_item
* @item: The item to initialize
* @type: The subclass type
*/
static inline void ttm_lru_item_init(struct ttm_lru_item *item,
enum ttm_lru_item_type type)
{
item->type = type;
INIT_LIST_HEAD(&item->link);
}
static inline bool ttm_lru_item_is_res(const struct ttm_lru_item *item)
{
return item->type == TTM_LRU_RESOURCE;
}
struct ttm_resource_manager_func {
/**
* struct ttm_resource_manager_func member alloc
*
* @man: Pointer to a memory type manager.
* @bo: Pointer to the buffer object we're allocating space for.
* @place: Placement details.
* @res: Resulting pointer to the ttm_resource.
*
* This function should allocate space in the memory type managed
* by @man. Placement details if applicable are given by @place. If
* successful, a filled in ttm_resource object should be returned in
* @res. @res::start should be set to a value identifying the beginning
* of the range allocated, and the function should return zero.
* If the manager can't fulfill the request -ENOSPC should be returned.
* If a system error occurred, preventing the request to be fulfilled,
* the function should return a negative error code.
*
* This function may not be called from within atomic context and needs
* to take care of its own locking to protect any data structures
* managing the space.
*/
int (*alloc)(struct ttm_resource_manager *man,
struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res);
/**
* struct ttm_resource_manager_func member free
*
* @man: Pointer to a memory type manager.
* @res: Pointer to a struct ttm_resource to be freed.
*
* This function frees memory type resources previously allocated.
* May not be called from within atomic context.
*/
void (*free)(struct ttm_resource_manager *man,
struct ttm_resource *res);
/**
* struct ttm_resource_manager_func member intersects
*
* @man: Pointer to a memory type manager.
* @res: Pointer to a struct ttm_resource to be checked.
* @place: Placement to check against.
* @size: Size of the check.
*
* Test if @res intersects with @place + @size. Used to judge if
* evictions are valueable or not.
*/
bool (*intersects)(struct ttm_resource_manager *man,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size);
/**
* struct ttm_resource_manager_func member compatible
*
* @man: Pointer to a memory type manager.
* @res: Pointer to a struct ttm_resource to be checked.
* @place: Placement to check against.
* @size: Size of the check.
*
* Test if @res compatible with @place + @size. Used to check of
* the need to move the backing store or not.
*/
bool (*compatible)(struct ttm_resource_manager *man,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size);
/**
* struct ttm_resource_manager_func member debug
*
* @man: Pointer to a memory type manager.
* @printer: Prefix to be used in printout to identify the caller.
*
* This function is called to print out the state of the memory
* type manager to aid debugging of out-of-memory conditions.
* It may not be called from within atomic context.
*/
void (*debug)(struct ttm_resource_manager *man,
struct drm_printer *printer);
};
/**
* struct ttm_resource_manager
*
* @use_type: The memory type is enabled.
* @use_tt: If a TT object should be used for the backing store.
* @size: Size of the managed region.
* @bdev: ttm device this manager belongs to
* @func: structure pointer implementing the range manager. See above
* @eviction_lock: lock for eviction fences
* @eviction_fences: The fences of the last pipelined move operation.
* @lru: The lru list for this memory type.
*
* This structure is used to identify and manage memory types for a device.
*/
struct ttm_resource_manager {
/*
* No protection. Constant from start.
*/
bool use_type;
bool use_tt;
struct ttm_device *bdev;
uint64_t size;
const struct ttm_resource_manager_func *func;
/* This is very similar to a dma_resv object, but locking rules make
* it difficult to use one in this context.
*/
spinlock_t eviction_lock;
struct dma_fence *eviction_fences[TTM_NUM_MOVE_FENCES];
/*
* Protected by the bdev->lru_lock.
*/
struct list_head lru[TTM_MAX_BO_PRIORITY];
/**
* @usage: How much of the resources are used, protected by the
* bdev->lru_lock.
*/
uint64_t usage;
/**
* @cg: &dmem_cgroup_region used for memory accounting, if not NULL.
*/
struct dmem_cgroup_region *cg;
};
/**
* struct ttm_bus_placement
*
* @addr: mapped virtual address
* @offset: physical addr
* @is_iomem: is this io memory ?
* @caching: See enum ttm_caching
*
* Structure indicating the bus placement of an object.
*/
struct ttm_bus_placement {
void *addr;
phys_addr_t offset;
bool is_iomem;
enum ttm_caching caching;
};
/**
* struct ttm_resource
*
* @start: Start of the allocation.
* @size: Actual size of resource in bytes.
* @mem_type: Resource type of the allocation.
* @placement: Placement flags.
* @bus: Placement on io bus accessible to the CPU
* @bo: weak reference to the BO, protected by ttm_device::lru_lock
* @css: cgroup state this resource is charged to
*
* Structure indicating the placement and space resources used by a
* buffer object.
*/
struct ttm_resource {
unsigned long start;
size_t size;
uint32_t mem_type;
uint32_t placement;
struct ttm_bus_placement bus;
struct ttm_buffer_object *bo;
struct dmem_cgroup_pool_state *css;
/**
* @lru: Least recently used list, see &ttm_resource_manager.lru
*/
struct ttm_lru_item lru;
};
/**
* ttm_lru_item_to_res() - Downcast a struct ttm_lru_item to a struct ttm_resource
* @item: The struct ttm_lru_item to downcast
*
* Return: Pointer to the embedding struct ttm_resource
*/
static inline struct ttm_resource *
ttm_lru_item_to_res(struct ttm_lru_item *item)
{
return container_of(item, struct ttm_resource, lru);
}
/**
* struct ttm_lru_bulk_move_pos
*
* @first: first res in the bulk move range
* @last: last res in the bulk move range
*
* Range of resources for a lru bulk move.
*/
struct ttm_lru_bulk_move_pos {
struct ttm_resource *first;
struct ttm_resource *last;
};
/**
* struct ttm_lru_bulk_move
* @pos: first/last lru entry for resources in the each domain/priority
* @cursor_list: The list of cursors currently traversing any of
* the sublists of @pos. Protected by the ttm device's lru_lock.
*
* Container for the current bulk move state. Should be used with
* ttm_lru_bulk_move_init() and ttm_bo_set_bulk_move().
* All BOs in a bulk_move structure need to share the same reservation object to
* ensure that the bulk as a whole is locked for eviction even if only one BO of
* the bulk is evicted.
*/
struct ttm_lru_bulk_move {
struct ttm_lru_bulk_move_pos pos[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY];
struct list_head cursor_list;
};
/**
* struct ttm_resource_cursor
* @man: The resource manager currently being iterated over
* @hitch: A hitch list node inserted before the next resource
* to iterate over.
* @bulk_link: A list link for the list of cursors traversing the
* bulk sublist of @bulk. Protected by the ttm device's lru_lock.
* @bulk: Pointer to struct ttm_lru_bulk_move whose subrange @hitch is
* inserted to. NULL if none. Never dereference this pointer since
* the struct ttm_lru_bulk_move object pointed to might have been
* freed. The pointer is only for comparison.
* @mem_type: The memory type of the LRU list being traversed.
* This field is valid iff @bulk != NULL.
* @priority: the current priority
*
* Cursor to iterate over the resources in a manager.
*/
struct ttm_resource_cursor {
struct ttm_resource_manager *man;
struct ttm_lru_item hitch;
struct list_head bulk_link;
struct ttm_lru_bulk_move *bulk;
unsigned int mem_type;
unsigned int priority;
};
void ttm_resource_cursor_init(struct ttm_resource_cursor *cursor,
struct ttm_resource_manager *man);
void ttm_resource_cursor_fini(struct ttm_resource_cursor *cursor);
/**
* struct ttm_kmap_iter_iomap - Specialization for a struct io_mapping +
* struct sg_table backed struct ttm_resource.
* @base: Embedded struct ttm_kmap_iter providing the usage interface.
* @iomap: struct io_mapping representing the underlying linear io_memory.
* @st: sg_table into @iomap, representing the memory of the struct ttm_resource.
* @start: Offset that needs to be subtracted from @st to make
* sg_dma_address(st->sgl) - @start == 0 for @iomap start.
* @cache: Scatterlist traversal cache for fast lookups.
* @cache.sg: Pointer to the currently cached scatterlist segment.
* @cache.i: First index of @sg. PAGE_SIZE granularity.
* @cache.end: Last index + 1 of @sg. PAGE_SIZE granularity.
* @cache.offs: First offset into @iomap of @sg. PAGE_SIZE granularity.
*/
struct ttm_kmap_iter_iomap {
struct ttm_kmap_iter base;
struct io_mapping *iomap;
struct sg_table *st;
resource_size_t start;
struct {
struct scatterlist *sg;
pgoff_t i;
pgoff_t end;
pgoff_t offs;
} cache;
};
/**
* struct ttm_kmap_iter_linear_io - Iterator specialization for linear io
* @base: The base iterator
* @dmap: Points to the starting address of the region
* @needs_unmap: Whether we need to unmap on fini
*/
struct ttm_kmap_iter_linear_io {
struct ttm_kmap_iter base;
struct iosys_map dmap;
bool needs_unmap;
};
/**
* ttm_resource_manager_set_used
*
* @man: A memory manager object.
* @used: usage state to set.
*
* Set the manager in use flag. If disabled the manager is no longer
* used for object placement.
*/
static inline void
ttm_resource_manager_set_used(struct ttm_resource_manager *man, bool used)
{
int i;
for (i = 0; i < TTM_MAX_BO_PRIORITY; i++)
WARN_ON(!list_empty(&man->lru[i]));
man->use_type = used;
}
/**
* ttm_resource_manager_used
*
* @man: Manager to get used state for
*
* Get the in use flag for a manager.
* Returns:
* true is used, false if not.
*/
static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man)
{
return man->use_type;
}
/**
* ttm_resource_manager_cleanup
*
* @man: A memory manager object.
*
* Cleanup the move fences from the memory manager object.
*/
static inline void
ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
{
int i;
for (i = 0; i < TTM_NUM_MOVE_FENCES; i++) {
dma_fence_put(man->eviction_fences[i]);
man->eviction_fences[i] = NULL;
}
}
void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk);
void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk);
void ttm_lru_bulk_move_fini(struct ttm_device *bdev,
struct ttm_lru_bulk_move *bulk);
void ttm_resource_add_bulk_move(struct ttm_resource *res,
struct ttm_buffer_object *bo);
void ttm_resource_del_bulk_move(struct ttm_resource *res,
struct ttm_buffer_object *bo);
void ttm_resource_del_bulk_move_unevictable(struct ttm_resource *res,
struct ttm_buffer_object *bo);
void ttm_resource_move_to_lru_tail(struct ttm_resource *res);
void ttm_resource_init(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource *res);
void ttm_resource_fini(struct ttm_resource_manager *man,
struct ttm_resource *res);
int ttm_resource_alloc(struct ttm_buffer_object *bo,
const struct ttm_place *place,
struct ttm_resource **res,
struct dmem_cgroup_pool_state **ret_limit_pool);
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
bool ttm_resource_intersects(struct ttm_device *bdev,
struct ttm_resource *res,
const struct ttm_place *place,
size_t size);
bool ttm_resource_compatible(struct ttm_resource *res,
struct ttm_placement *placement,
bool evicting);
void ttm_resource_set_bo(struct ttm_resource *res,
struct ttm_buffer_object *bo);
void ttm_resource_manager_init(struct ttm_resource_manager *man,
struct ttm_device *bdev,
uint64_t size);
int ttm_resource_manager_evict_all(struct ttm_device *bdev,
struct ttm_resource_manager *man);
uint64_t ttm_resource_manager_usage(struct ttm_resource_manager *man);
void ttm_resource_manager_debug(struct ttm_resource_manager *man,
struct drm_printer *p);
struct ttm_resource *
ttm_resource_manager_first(struct ttm_resource_cursor *cursor);
struct ttm_resource *
ttm_resource_manager_next(struct ttm_resource_cursor *cursor);
struct ttm_resource *
ttm_lru_first_res_or_null(struct list_head *head);
/**
* ttm_resource_manager_for_each_res - iterate over all resources
* @cursor: struct ttm_resource_cursor for the current position
* @res: the current resource
*
* Iterate over all the evictable resources in a resource manager.
*/
#define ttm_resource_manager_for_each_res(cursor, res) \
for (res = ttm_resource_manager_first(cursor); res; \
res = ttm_resource_manager_next(cursor))
struct ttm_kmap_iter *
ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
struct io_mapping *iomap,
struct sg_table *st,
resource_size_t start);
struct ttm_kmap_iter_linear_io;
struct ttm_kmap_iter *
ttm_kmap_iter_linear_io_init(struct ttm_kmap_iter_linear_io *iter_io,
struct ttm_device *bdev,
struct ttm_resource *mem);
void ttm_kmap_iter_linear_io_fini(struct ttm_kmap_iter_linear_io *iter_io,
struct ttm_device *bdev,
struct ttm_resource *mem);
void ttm_resource_manager_create_debugfs(struct ttm_resource_manager *man,
struct dentry * parent,
const char *name);
#endif
+327
View File
@@ -0,0 +1,327 @@
/**************************************************************************
*
* Copyright (c) 2006-2009 Vmware, Inc., Palo Alto, CA., USA
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef _TTM_TT_H_
#define _TTM_TT_H_
#include <linux/pagemap.h>
#include <linux/types.h>
#include <drm/ttm/ttm_caching.h>
#include <drm/ttm/ttm_kmap_iter.h>
struct ttm_backup;
struct ttm_device;
struct ttm_tt;
struct ttm_resource;
struct ttm_buffer_object;
struct ttm_operation_ctx;
struct ttm_pool_tt_restore;
/**
* struct ttm_tt - This is a structure holding the pages, caching- and aperture
* binding status for a buffer object that isn't backed by fixed (VRAM / AGP)
* memory.
*/
struct ttm_tt {
/** @pages: Array of pages backing the data. */
struct page **pages;
/**
* @page_flags: The page flags.
*
* Supported values:
*
* TTM_TT_FLAG_SWAPPED: Set by TTM when the pages have been unpopulated
* and swapped out by TTM. Calling ttm_tt_populate() will then swap the
* pages back in, and unset the flag. Drivers should in general never
* need to touch this.
*
* TTM_TT_FLAG_ZERO_ALLOC: Set if the pages will be zeroed on
* allocation.
*
* TTM_TT_FLAG_EXTERNAL: Set if the underlying pages were allocated
* externally, like with dma-buf or userptr. This effectively disables
* TTM swapping out such pages. Also important is to prevent TTM from
* ever directly mapping these pages.
*
* Note that enum ttm_bo_type.ttm_bo_type_sg objects will always enable
* this flag.
*
* TTM_TT_FLAG_EXTERNAL_MAPPABLE: Same behaviour as
* TTM_TT_FLAG_EXTERNAL, but with the reduced restriction that it is
* still valid to use TTM to map the pages directly. This is useful when
* implementing a ttm_tt backend which still allocates driver owned
* pages underneath(say with shmem).
*
* Note that since this also implies TTM_TT_FLAG_EXTERNAL, the usage
* here should always be:
*
* page_flags = TTM_TT_FLAG_EXTERNAL |
* TTM_TT_FLAG_EXTERNAL_MAPPABLE;
*
* TTM_TT_FLAG_DECRYPTED: The mapped ttm pages should be marked as
* not encrypted. The framework will try to match what the dma layer
* is doing, but note that it is a little fragile because ttm page
* fault handling abuses the DMA api a bit and dma_map_attrs can't be
* used to assure pgprot always matches.
*
* TTM_TT_FLAG_BACKED_UP: TTM internal only. This is set if the
* struct ttm_tt has been (possibly partially) backed up.
*
* TTM_TT_FLAG_PRIV_POPULATED: TTM internal only. DO NOT USE. This is
* set by TTM after ttm_tt_populate() has successfully returned, and is
* then unset when TTM calls ttm_tt_unpopulate().
*
*/
#define TTM_TT_FLAG_SWAPPED BIT(0)
#define TTM_TT_FLAG_ZERO_ALLOC BIT(1)
#define TTM_TT_FLAG_EXTERNAL BIT(2)
#define TTM_TT_FLAG_EXTERNAL_MAPPABLE BIT(3)
#define TTM_TT_FLAG_DECRYPTED BIT(4)
#define TTM_TT_FLAG_BACKED_UP BIT(5)
#define TTM_TT_FLAG_PRIV_POPULATED BIT(6)
uint32_t page_flags;
/** @num_pages: Number of pages in the page array. */
uint32_t num_pages;
/** @sg: for SG objects via dma-buf. */
struct sg_table *sg;
/** @dma_address: The DMA (bus) addresses of the pages. */
dma_addr_t *dma_address;
/** @swap_storage: Pointer to shmem struct file for swap storage. */
struct file *swap_storage;
/**
* @backup: Pointer to backup struct for backed up tts.
* Could be unified with @swap_storage. Meanwhile, the driver's
* ttm_tt_create() callback is responsible for assigning
* this field.
*/
struct file *backup;
/**
* @caching: The current caching state of the pages, see enum
* ttm_caching.
*/
enum ttm_caching caching;
/** @restore: Partial restoration from backup state. TTM private */
struct ttm_pool_tt_restore *restore;
};
/**
* struct ttm_kmap_iter_tt - Specialization of a mappig iterator for a tt.
* @base: Embedded struct ttm_kmap_iter providing the usage interface
* @tt: Cached struct ttm_tt.
* @prot: Cached page protection for mapping.
*/
struct ttm_kmap_iter_tt {
struct ttm_kmap_iter base;
struct ttm_tt *tt;
pgprot_t prot;
};
static inline bool ttm_tt_is_populated(struct ttm_tt *tt)
{
return tt->page_flags & TTM_TT_FLAG_PRIV_POPULATED;
}
/**
* ttm_tt_is_swapped() - Whether the ttm_tt is swapped out or backed up
* @tt: The struct ttm_tt.
*
* Return: true if swapped or backed up, false otherwise.
*/
static inline bool ttm_tt_is_swapped(const struct ttm_tt *tt)
{
return tt->page_flags & (TTM_TT_FLAG_SWAPPED | TTM_TT_FLAG_BACKED_UP);
}
/**
* ttm_tt_is_backed_up() - Whether the ttm_tt backed up
* @tt: The struct ttm_tt.
*
* Return: true if swapped or backed up, false otherwise.
*/
static inline bool ttm_tt_is_backed_up(const struct ttm_tt *tt)
{
return tt->page_flags & TTM_TT_FLAG_BACKED_UP;
}
/**
* ttm_tt_clear_backed_up() - Clear the ttm_tt backed-up status
* @tt: The struct ttm_tt.
*
* Drivers can use this functionto clear the backed-up status,
* for example before destroying or re-validating a purged tt.
*/
static inline void ttm_tt_clear_backed_up(struct ttm_tt *tt)
{
tt->page_flags &= ~TTM_TT_FLAG_BACKED_UP;
}
/**
* ttm_tt_create
*
* @bo: pointer to a struct ttm_buffer_object
* @zero_alloc: true if allocated pages needs to be zeroed
*
* Make sure we have a TTM structure allocated for the given BO.
* No pages are actually allocated.
*/
int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc);
/**
* ttm_tt_init
*
* @ttm: The struct ttm_tt.
* @bo: The buffer object we create the ttm for.
* @page_flags: Page flags as identified by TTM_TT_FLAG_XX flags.
* @caching: the desired caching state of the pages
* @extra_pages: Extra pages needed for the driver.
*
* Create a struct ttm_tt to back data with system memory pages.
* No pages are actually allocated.
* Returns:
* NULL: Out of memory.
*/
int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
uint32_t page_flags, enum ttm_caching caching,
unsigned long extra_pages);
int ttm_sg_tt_init(struct ttm_tt *ttm_dma, struct ttm_buffer_object *bo,
uint32_t page_flags, enum ttm_caching caching);
/**
* ttm_tt_fini
*
* @ttm: the ttm_tt structure.
*
* Free memory of ttm_tt structure
*/
void ttm_tt_fini(struct ttm_tt *ttm);
/**
* ttm_tt_destroy:
*
* @bdev: the ttm_device this object belongs to
* @ttm: The struct ttm_tt.
*
* Unbind, unpopulate and destroy common struct ttm_tt.
*/
void ttm_tt_destroy(struct ttm_device *bdev, struct ttm_tt *ttm);
/**
* ttm_tt_swapin:
*
* @ttm: The struct ttm_tt.
*
* Swap in a previously swap out ttm_tt.
*/
int ttm_tt_swapin(struct ttm_tt *ttm);
int ttm_tt_swapout(struct ttm_device *bdev, struct ttm_tt *ttm,
gfp_t gfp_flags);
/**
* ttm_tt_populate - allocate pages for a ttm
*
* @bdev: the ttm_device this object belongs to
* @ttm: Pointer to the ttm_tt structure
* @ctx: operation context for populating the tt object.
*
* Calls the driver method to allocate pages for a ttm
*/
int ttm_tt_populate(struct ttm_device *bdev, struct ttm_tt *ttm,
struct ttm_operation_ctx *ctx);
/**
* ttm_tt_unpopulate - free pages from a ttm
*
* @bdev: the ttm_device this object belongs to
* @ttm: Pointer to the ttm_tt structure
*
* Calls the driver method to free all pages from a ttm
*/
void ttm_tt_unpopulate(struct ttm_device *bdev, struct ttm_tt *ttm);
/**
* ttm_tt_mark_for_clear - Mark pages for clearing on populate.
*
* @ttm: Pointer to the ttm_tt structure
*
* Marks pages for clearing so that the next time the page vector is
* populated, the pages will be cleared.
*/
static inline void ttm_tt_mark_for_clear(struct ttm_tt *ttm)
{
ttm->page_flags |= TTM_TT_FLAG_ZERO_ALLOC;
}
void ttm_tt_mgr_init(unsigned long num_pages, unsigned long num_dma32_pages);
struct ttm_kmap_iter *ttm_kmap_iter_tt_init(struct ttm_kmap_iter_tt *iter_tt,
struct ttm_tt *tt);
unsigned long ttm_tt_pages_limit(void);
/**
* struct ttm_backup_flags - Flags to govern backup behaviour.
* @purge: Free pages without backing up. Bypass pools.
* @writeback: Attempt to copy contents directly to swap space, even
* if that means blocking on writes to external memory.
*/
struct ttm_backup_flags {
u32 purge : 1;
u32 writeback : 1;
};
long ttm_tt_backup(struct ttm_device *bdev, struct ttm_tt *tt,
const struct ttm_backup_flags flags);
int ttm_tt_restore(struct ttm_device *bdev, struct ttm_tt *tt,
const struct ttm_operation_ctx *ctx);
int ttm_tt_setup_backup(struct ttm_tt *tt);
#if IS_ENABLED(CONFIG_AGP)
#include <linux/agp_backend.h>
/**
* ttm_agp_tt_create
*
* @bo: Buffer object we allocate the ttm for.
* @bridge: The agp bridge this device is sitting on.
* @page_flags: Page flags as identified by TTM_TT_FLAG_XX flags.
*
*
* Create a TTM backend that uses the indicated AGP bridge as an aperture
* for TT memory. This function uses the linux agpgart interface to
* bind and unbind memory backing a ttm_tt.
*/
struct ttm_tt *ttm_agp_tt_create(struct ttm_buffer_object *bo,
struct agp_bridge_data *bridge,
uint32_t page_flags);
int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_resource *bo_mem);
void ttm_agp_unbind(struct ttm_tt *ttm);
void ttm_agp_destroy(struct ttm_tt *ttm);
bool ttm_agp_is_bound(struct ttm_tt *ttm);
#endif
#endif