/**************************************************************************1*2* Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL20* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,21* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR22* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE23* USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/26/*27* Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com>28*/2930#ifndef _TTM_BO_API_H_31#define _TTM_BO_API_H_3233#include "drm_hashtab.h"34#include <linux/kref.h>35#include <linux/list.h>36#include <linux/wait.h>37#include <linux/mutex.h>38#include <linux/mm.h>39#include <linux/rbtree.h>40#include <linux/bitmap.h>4142struct ttm_bo_device;4344struct drm_mm_node;454647/**48* struct ttm_placement49*50* @fpfn: first valid page frame number to put the object51* @lpfn: last valid page frame number to put the object52* @num_placement: number of preferred placements53* @placement: preferred placements54* @num_busy_placement: number of preferred placements when need to evict buffer55* @busy_placement: preferred placements when need to evict buffer56*57* Structure indicating the placement you request for an object.58*/59struct ttm_placement {60unsigned fpfn;61unsigned lpfn;62unsigned num_placement;63const uint32_t *placement;64unsigned num_busy_placement;65const uint32_t *busy_placement;66};6768/**69* struct ttm_bus_placement70*71* @addr: mapped virtual address72* @base: bus base address73* @is_iomem: is this io memory ?74* @size: size in byte75* @offset: offset from the base address76* @io_reserved_vm: The VM system has a refcount in @io_reserved_count77* @io_reserved_count: Refcounting the numbers of callers to ttm_mem_io_reserve78*79* Structure indicating the bus placement of an object.80*/81struct ttm_bus_placement {82void *addr;83unsigned long base;84unsigned long size;85unsigned long offset;86bool is_iomem;87bool io_reserved_vm;88uint64_t io_reserved_count;89};909192/**93* struct ttm_mem_reg94*95* @mm_node: Memory manager node.96* @size: Requested size of memory region.97* @num_pages: Actual size of memory region in pages.98* @page_alignment: Page alignment.99* @placement: Placement flags.100* @bus: Placement on io bus accessible to the CPU101*102* Structure indicating the placement and space resources used by a103* buffer object.104*/105106struct ttm_mem_reg {107void *mm_node;108unsigned long start;109unsigned long size;110unsigned long num_pages;111uint32_t page_alignment;112uint32_t mem_type;113uint32_t placement;114struct ttm_bus_placement bus;115};116117/**118* enum ttm_bo_type119*120* @ttm_bo_type_device: These are 'normal' buffers that can121* be mmapped by user space. Each of these bos occupy a slot in the122* device address space, that can be used for normal vm operations.123*124* @ttm_bo_type_user: These are user-space memory areas that are made125* available to the GPU by mapping the buffer pages into the GPU aperture126* space. These buffers cannot be mmaped from the device address space.127*128* @ttm_bo_type_kernel: These buffers are like ttm_bo_type_device buffers,129* but they cannot be accessed from user-space. For kernel-only use.130*/131132enum ttm_bo_type {133ttm_bo_type_device,134ttm_bo_type_user,135ttm_bo_type_kernel136};137138struct ttm_tt;139140/**141* struct ttm_buffer_object142*143* @bdev: Pointer to the buffer object device structure.144* @buffer_start: The virtual user-space start address of ttm_bo_type_user145* buffers.146* @type: The bo type.147* @destroy: Destruction function. If NULL, kfree is used.148* @num_pages: Actual number of pages.149* @addr_space_offset: Address space offset.150* @acc_size: Accounted size for this object.151* @kref: Reference count of this buffer object. When this refcount reaches152* zero, the object is put on the delayed delete list.153* @list_kref: List reference count of this buffer object. This member is154* used to avoid destruction while the buffer object is still on a list.155* Lru lists may keep one refcount, the delayed delete list, and kref != 0156* keeps one refcount. When this refcount reaches zero,157* the object is destroyed.158* @event_queue: Queue for processes waiting on buffer object status change.159* @mem: structure describing current placement.160* @persistent_swap_storage: Usually the swap storage is deleted for buffers161* pinned in physical memory. If this behaviour is not desired, this member162* holds a pointer to a persistent shmem object.163* @ttm: TTM structure holding system pages.164* @evicted: Whether the object was evicted without user-space knowing.165* @cpu_writes: For synchronization. Number of cpu writers.166* @lru: List head for the lru list.167* @ddestroy: List head for the delayed destroy list.168* @swap: List head for swap LRU list.169* @val_seq: Sequence of the validation holding the @reserved lock.170* Used to avoid starvation when many processes compete to validate the171* buffer. This member is protected by the bo_device::lru_lock.172* @seq_valid: The value of @val_seq is valid. This value is protected by173* the bo_device::lru_lock.174* @reserved: Deadlock-free lock used for synchronization state transitions.175* @sync_obj_arg: Opaque argument to synchronization object function.176* @sync_obj: Pointer to a synchronization object.177* @priv_flags: Flags describing buffer object internal state.178* @vm_rb: Rb node for the vm rb tree.179* @vm_node: Address space manager node.180* @offset: The current GPU offset, which can have different meanings181* depending on the memory type. For SYSTEM type memory, it should be 0.182* @cur_placement: Hint of current placement.183*184* Base class for TTM buffer object, that deals with data placement and CPU185* mappings. GPU mappings are really up to the driver, but for simpler GPUs186* the driver can usually use the placement offset @offset directly as the187* GPU virtual address. For drivers implementing multiple188* GPU memory manager contexts, the driver should manage the address space189* in these contexts separately and use these objects to get the correct190* placement and caching for these GPU maps. This makes it possible to use191* these objects for even quite elaborate memory management schemes.192* The destroy member, the API visibility of this object makes it possible193* to derive driver specific types.194*/195196struct ttm_buffer_object {197/**198* Members constant at init.199*/200201struct ttm_bo_global *glob;202struct ttm_bo_device *bdev;203unsigned long buffer_start;204enum ttm_bo_type type;205void (*destroy) (struct ttm_buffer_object *);206unsigned long num_pages;207uint64_t addr_space_offset;208size_t acc_size;209210/**211* Members not needing protection.212*/213214struct kref kref;215struct kref list_kref;216wait_queue_head_t event_queue;217218/**219* Members protected by the bo::reserved lock.220*/221222struct ttm_mem_reg mem;223struct file *persistent_swap_storage;224struct ttm_tt *ttm;225bool evicted;226227/**228* Members protected by the bo::reserved lock only when written to.229*/230231atomic_t cpu_writers;232233/**234* Members protected by the bdev::lru_lock.235*/236237struct list_head lru;238struct list_head ddestroy;239struct list_head swap;240struct list_head io_reserve_lru;241uint32_t val_seq;242bool seq_valid;243244/**245* Members protected by the bdev::lru_lock246* only when written to.247*/248249atomic_t reserved;250251/**252* Members protected by struct buffer_object_device::fence_lock253* In addition, setting sync_obj to anything else254* than NULL requires bo::reserved to be held. This allows for255* checking NULL while reserved but not holding the mentioned lock.256*/257258void *sync_obj_arg;259void *sync_obj;260unsigned long priv_flags;261262/**263* Members protected by the bdev::vm_lock264*/265266struct rb_node vm_rb;267struct drm_mm_node *vm_node;268269270/**271* Special members that are protected by the reserve lock272* and the bo::lock when written to. Can be read with273* either of these locks held.274*/275276unsigned long offset;277uint32_t cur_placement;278};279280/**281* struct ttm_bo_kmap_obj282*283* @virtual: The current kernel virtual address.284* @page: The page when kmap'ing a single page.285* @bo_kmap_type: Type of bo_kmap.286*287* Object describing a kernel mapping. Since a TTM bo may be located288* in various memory types with various caching policies, the289* mapping can either be an ioremap, a vmap, a kmap or part of a290* premapped region.291*/292293#define TTM_BO_MAP_IOMEM_MASK 0x80294struct ttm_bo_kmap_obj {295void *virtual;296struct page *page;297enum {298ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK,299ttm_bo_map_vmap = 2,300ttm_bo_map_kmap = 3,301ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK,302} bo_kmap_type;303struct ttm_buffer_object *bo;304};305306/**307* ttm_bo_reference - reference a struct ttm_buffer_object308*309* @bo: The buffer object.310*311* Returns a refcounted pointer to a buffer object.312*/313314static inline struct ttm_buffer_object *315ttm_bo_reference(struct ttm_buffer_object *bo)316{317kref_get(&bo->kref);318return bo;319}320321/**322* ttm_bo_wait - wait for buffer idle.323*324* @bo: The buffer object.325* @interruptible: Use interruptible wait.326* @no_wait: Return immediately if buffer is busy.327*328* This function must be called with the bo::mutex held, and makes329* sure any previous rendering to the buffer is completed.330* Note: It might be necessary to block validations before the331* wait by reserving the buffer.332* Returns -EBUSY if no_wait is true and the buffer is busy.333* Returns -ERESTARTSYS if interrupted by a signal.334*/335extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,336bool interruptible, bool no_wait);337/**338* ttm_bo_validate339*340* @bo: The buffer object.341* @placement: Proposed placement for the buffer object.342* @interruptible: Sleep interruptible if sleeping.343* @no_wait_reserve: Return immediately if other buffers are busy.344* @no_wait_gpu: Return immediately if the GPU is busy.345*346* Changes placement and caching policy of the buffer object347* according proposed placement.348* Returns349* -EINVAL on invalid proposed placement.350* -ENOMEM on out-of-memory condition.351* -EBUSY if no_wait is true and buffer busy.352* -ERESTARTSYS if interrupted by a signal.353*/354extern int ttm_bo_validate(struct ttm_buffer_object *bo,355struct ttm_placement *placement,356bool interruptible, bool no_wait_reserve,357bool no_wait_gpu);358359/**360* ttm_bo_unref361*362* @bo: The buffer object.363*364* Unreference and clear a pointer to a buffer object.365*/366extern void ttm_bo_unref(struct ttm_buffer_object **bo);367368369/**370* ttm_bo_list_ref_sub371*372* @bo: The buffer object.373* @count: The number of references with which to decrease @bo::list_kref;374* @never_free: The refcount should not reach zero with this operation.375*376* Release @count lru list references to this buffer object.377*/378extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,379bool never_free);380381/**382* ttm_bo_add_to_lru383*384* @bo: The buffer object.385*386* Add this bo to the relevant mem type lru and, if it's backed by387* system pages (ttms) to the swap list.388* This function must be called with struct ttm_bo_global::lru_lock held, and389* is typically called immediately prior to unreserving a bo.390*/391extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);392393/**394* ttm_bo_del_from_lru395*396* @bo: The buffer object.397*398* Remove this bo from all lru lists used to lookup and reserve an object.399* This function must be called with struct ttm_bo_global::lru_lock held,400* and is usually called just immediately after the bo has been reserved to401* avoid recursive reservation from lru lists.402*/403extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo);404405406/**407* ttm_bo_lock_delayed_workqueue408*409* Prevent the delayed workqueue from running.410* Returns411* True if the workqueue was queued at the time412*/413extern int ttm_bo_lock_delayed_workqueue(struct ttm_bo_device *bdev);414415/**416* ttm_bo_unlock_delayed_workqueue417*418* Allows the delayed workqueue to run.419*/420extern void ttm_bo_unlock_delayed_workqueue(struct ttm_bo_device *bdev,421int resched);422423/**424* ttm_bo_synccpu_write_grab425*426* @bo: The buffer object:427* @no_wait: Return immediately if buffer is busy.428*429* Synchronizes a buffer object for CPU RW access. This means430* blocking command submission that affects the buffer and431* waiting for buffer idle. This lock is recursive.432* Returns433* -EBUSY if the buffer is busy and no_wait is true.434* -ERESTARTSYS if interrupted by a signal.435*/436437extern int438ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait);439/**440* ttm_bo_synccpu_write_release:441*442* @bo : The buffer object.443*444* Releases a synccpu lock.445*/446extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo);447448/**449* ttm_bo_init450*451* @bdev: Pointer to a ttm_bo_device struct.452* @bo: Pointer to a ttm_buffer_object to be initialized.453* @size: Requested size of buffer object.454* @type: Requested type of buffer object.455* @flags: Initial placement flags.456* @page_alignment: Data alignment in pages.457* @buffer_start: Virtual address of user space data backing a458* user buffer object.459* @interruptible: If needing to sleep to wait for GPU resources,460* sleep interruptible.461* @persistent_swap_storage: Usually the swap storage is deleted for buffers462* pinned in physical memory. If this behaviour is not desired, this member463* holds a pointer to a persistent shmem object. Typically, this would464* point to the shmem object backing a GEM object if TTM is used to back a465* GEM user interface.466* @acc_size: Accounted size for this object.467* @destroy: Destroy function. Use NULL for kfree().468*469* This function initializes a pre-allocated struct ttm_buffer_object.470* As this object may be part of a larger structure, this function,471* together with the @destroy function,472* enables driver-specific objects derived from a ttm_buffer_object.473* On successful return, the object kref and list_kref are set to 1.474* If a failure occurs, the function will call the @destroy function, or475* kfree() if @destroy is NULL. Thus, after a failure, dereferencing @bo is476* illegal and will likely cause memory corruption.477*478* Returns479* -ENOMEM: Out of memory.480* -EINVAL: Invalid placement flags.481* -ERESTARTSYS: Interrupted by signal while sleeping waiting for resources.482*/483484extern int ttm_bo_init(struct ttm_bo_device *bdev,485struct ttm_buffer_object *bo,486unsigned long size,487enum ttm_bo_type type,488struct ttm_placement *placement,489uint32_t page_alignment,490unsigned long buffer_start,491bool interrubtible,492struct file *persistent_swap_storage,493size_t acc_size,494void (*destroy) (struct ttm_buffer_object *));495/**496* ttm_bo_synccpu_object_init497*498* @bdev: Pointer to a ttm_bo_device struct.499* @bo: Pointer to a ttm_buffer_object to be initialized.500* @size: Requested size of buffer object.501* @type: Requested type of buffer object.502* @flags: Initial placement flags.503* @page_alignment: Data alignment in pages.504* @buffer_start: Virtual address of user space data backing a505* user buffer object.506* @interruptible: If needing to sleep while waiting for GPU resources,507* sleep interruptible.508* @persistent_swap_storage: Usually the swap storage is deleted for buffers509* pinned in physical memory. If this behaviour is not desired, this member510* holds a pointer to a persistent shmem object. Typically, this would511* point to the shmem object backing a GEM object if TTM is used to back a512* GEM user interface.513* @p_bo: On successful completion *p_bo points to the created object.514*515* This function allocates a ttm_buffer_object, and then calls ttm_bo_init516* on that object. The destroy function is set to kfree().517* Returns518* -ENOMEM: Out of memory.519* -EINVAL: Invalid placement flags.520* -ERESTARTSYS: Interrupted by signal while waiting for resources.521*/522523extern int ttm_bo_create(struct ttm_bo_device *bdev,524unsigned long size,525enum ttm_bo_type type,526struct ttm_placement *placement,527uint32_t page_alignment,528unsigned long buffer_start,529bool interruptible,530struct file *persistent_swap_storage,531struct ttm_buffer_object **p_bo);532533/**534* ttm_bo_check_placement535*536* @bo: the buffer object.537* @placement: placements538*539* Performs minimal validity checking on an intended change of540* placement flags.541* Returns542* -EINVAL: Intended change is invalid or not allowed.543*/544extern int ttm_bo_check_placement(struct ttm_buffer_object *bo,545struct ttm_placement *placement);546547/**548* ttm_bo_init_mm549*550* @bdev: Pointer to a ttm_bo_device struct.551* @mem_type: The memory type.552* @p_size: size managed area in pages.553*554* Initialize a manager for a given memory type.555* Note: if part of driver firstopen, it must be protected from a556* potentially racing lastclose.557* Returns:558* -EINVAL: invalid size or memory type.559* -ENOMEM: Not enough memory.560* May also return driver-specified errors.561*/562563extern int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,564unsigned long p_size);565/**566* ttm_bo_clean_mm567*568* @bdev: Pointer to a ttm_bo_device struct.569* @mem_type: The memory type.570*571* Take down a manager for a given memory type after first walking572* the LRU list to evict any buffers left alive.573*574* Normally, this function is part of lastclose() or unload(), and at that575* point there shouldn't be any buffers left created by user-space, since576* there should've been removed by the file descriptor release() method.577* However, before this function is run, make sure to signal all sync objects,578* and verify that the delayed delete queue is empty. The driver must also579* make sure that there are no NO_EVICT buffers present in this memory type580* when the call is made.581*582* If this function is part of a VT switch, the caller must make sure that583* there are no appications currently validating buffers before this584* function is called. The caller can do that by first taking the585* struct ttm_bo_device::ttm_lock in write mode.586*587* Returns:588* -EINVAL: invalid or uninitialized memory type.589* -EBUSY: There are still buffers left in this memory type.590*/591592extern int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type);593594/**595* ttm_bo_evict_mm596*597* @bdev: Pointer to a ttm_bo_device struct.598* @mem_type: The memory type.599*600* Evicts all buffers on the lru list of the memory type.601* This is normally part of a VT switch or an602* out-of-memory-space-due-to-fragmentation handler.603* The caller must make sure that there are no other processes604* currently validating buffers, and can do that by taking the605* struct ttm_bo_device::ttm_lock in write mode.606*607* Returns:608* -EINVAL: Invalid or uninitialized memory type.609* -ERESTARTSYS: The call was interrupted by a signal while waiting to610* evict a buffer.611*/612613extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type);614615/**616* ttm_kmap_obj_virtual617*618* @map: A struct ttm_bo_kmap_obj returned from ttm_bo_kmap.619* @is_iomem: Pointer to an integer that on return indicates 1 if the620* virtual map is io memory, 0 if normal memory.621*622* Returns the virtual address of a buffer object area mapped by ttm_bo_kmap.623* If *is_iomem is 1 on return, the virtual address points to an io memory area,624* that should strictly be accessed by the iowriteXX() and similar functions.625*/626627static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map,628bool *is_iomem)629{630*is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK);631return map->virtual;632}633634/**635* ttm_bo_kmap636*637* @bo: The buffer object.638* @start_page: The first page to map.639* @num_pages: Number of pages to map.640* @map: pointer to a struct ttm_bo_kmap_obj representing the map.641*642* Sets up a kernel virtual mapping, using ioremap, vmap or kmap to the643* data in the buffer object. The ttm_kmap_obj_virtual function can then be644* used to obtain a virtual address to the data.645*646* Returns647* -ENOMEM: Out of memory.648* -EINVAL: Invalid range.649*/650651extern int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page,652unsigned long num_pages, struct ttm_bo_kmap_obj *map);653654/**655* ttm_bo_kunmap656*657* @map: Object describing the map to unmap.658*659* Unmaps a kernel map set up by ttm_bo_kmap.660*/661662extern void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map);663664#if 0665#endif666667/**668* ttm_fbdev_mmap - mmap fbdev memory backed by a ttm buffer object.669*670* @vma: vma as input from the fbdev mmap method.671* @bo: The bo backing the address space. The address space will672* have the same size as the bo, and start at offset 0.673*674* This function is intended to be called by the fbdev mmap method675* if the fbdev address space is to be backed by a bo.676*/677678extern int ttm_fbdev_mmap(struct vm_area_struct *vma,679struct ttm_buffer_object *bo);680681/**682* ttm_bo_mmap - mmap out of the ttm device address space.683*684* @filp: filp as input from the mmap method.685* @vma: vma as input from the mmap method.686* @bdev: Pointer to the ttm_bo_device with the address space manager.687*688* This function is intended to be called by the device mmap method.689* if the device address space is to be backed by the bo manager.690*/691692extern int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,693struct ttm_bo_device *bdev);694695/**696* ttm_bo_io697*698* @bdev: Pointer to the struct ttm_bo_device.699* @filp: Pointer to the struct file attempting to read / write.700* @wbuf: User-space pointer to address of buffer to write. NULL on read.701* @rbuf: User-space pointer to address of buffer to read into.702* Null on write.703* @count: Number of bytes to read / write.704* @f_pos: Pointer to current file position.705* @write: 1 for read, 0 for write.706*707* This function implements read / write into ttm buffer objects, and is708* intended to709* be called from the fops::read and fops::write method.710* Returns:711* See man (2) write, man(2) read. In particular,712* the function may return -ERESTARTSYS if713* interrupted by a signal.714*/715716extern ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,717const char __user *wbuf, char __user *rbuf,718size_t count, loff_t *f_pos, bool write);719720extern void ttm_bo_swapout_all(struct ttm_bo_device *bdev);721722#endif723724725