Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2020 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Christian König
0023  */
0024 
0025 #ifndef _TTM_RESOURCE_H_
0026 #define _TTM_RESOURCE_H_
0027 
0028 #include <linux/types.h>
0029 #include <linux/list.h>
0030 #include <linux/mutex.h>
0031 #include <linux/iosys-map.h>
0032 #include <linux/dma-fence.h>
0033 
0034 #include <drm/drm_print.h>
0035 #include <drm/ttm/ttm_caching.h>
0036 #include <drm/ttm/ttm_kmap_iter.h>
0037 
0038 #define TTM_MAX_BO_PRIORITY 4U
0039 #define TTM_NUM_MEM_TYPES 8
0040 
0041 struct ttm_device;
0042 struct ttm_resource_manager;
0043 struct ttm_resource;
0044 struct ttm_place;
0045 struct ttm_buffer_object;
0046 struct ttm_placement;
0047 struct iosys_map;
0048 struct io_mapping;
0049 struct sg_table;
0050 struct scatterlist;
0051 
0052 struct ttm_resource_manager_func {
0053     /**
0054      * struct ttm_resource_manager_func member alloc
0055      *
0056      * @man: Pointer to a memory type manager.
0057      * @bo: Pointer to the buffer object we're allocating space for.
0058      * @place: Placement details.
0059      * @res: Resulting pointer to the ttm_resource.
0060      *
0061      * This function should allocate space in the memory type managed
0062      * by @man. Placement details if applicable are given by @place. If
0063      * successful, a filled in ttm_resource object should be returned in
0064      * @res. @res::start should be set to a value identifying the beginning
0065      * of the range allocated, and the function should return zero.
0066      * If the manager can't fulfill the request -ENOSPC should be returned.
0067      * If a system error occurred, preventing the request to be fulfilled,
0068      * the function should return a negative error code.
0069      *
0070      * This function may not be called from within atomic context and needs
0071      * to take care of its own locking to protect any data structures
0072      * managing the space.
0073      */
0074     int  (*alloc)(struct ttm_resource_manager *man,
0075               struct ttm_buffer_object *bo,
0076               const struct ttm_place *place,
0077               struct ttm_resource **res);
0078 
0079     /**
0080      * struct ttm_resource_manager_func member free
0081      *
0082      * @man: Pointer to a memory type manager.
0083      * @res: Pointer to a struct ttm_resource to be freed.
0084      *
0085      * This function frees memory type resources previously allocated.
0086      * May not be called from within atomic context.
0087      */
0088     void (*free)(struct ttm_resource_manager *man,
0089              struct ttm_resource *res);
0090 
0091     /**
0092      * struct ttm_resource_manager_func member debug
0093      *
0094      * @man: Pointer to a memory type manager.
0095      * @printer: Prefix to be used in printout to identify the caller.
0096      *
0097      * This function is called to print out the state of the memory
0098      * type manager to aid debugging of out-of-memory conditions.
0099      * It may not be called from within atomic context.
0100      */
0101     void (*debug)(struct ttm_resource_manager *man,
0102               struct drm_printer *printer);
0103 };
0104 
0105 /**
0106  * struct ttm_resource_manager
0107  *
0108  * @use_type: The memory type is enabled.
0109  * @use_tt: If a TT object should be used for the backing store.
0110  * @size: Size of the managed region.
0111  * @bdev: ttm device this manager belongs to
0112  * @func: structure pointer implementing the range manager. See above
0113  * @move_lock: lock for move fence
0114  * @move: The fence of the last pipelined move operation.
0115  * @lru: The lru list for this memory type.
0116  *
0117  * This structure is used to identify and manage memory types for a device.
0118  */
0119 struct ttm_resource_manager {
0120     /*
0121      * No protection. Constant from start.
0122      */
0123     bool use_type;
0124     bool use_tt;
0125     struct ttm_device *bdev;
0126     uint64_t size;
0127     const struct ttm_resource_manager_func *func;
0128     spinlock_t move_lock;
0129 
0130     /*
0131      * Protected by @move_lock.
0132      */
0133     struct dma_fence *move;
0134 
0135     /*
0136      * Protected by the bdev->lru_lock.
0137      */
0138     struct list_head lru[TTM_MAX_BO_PRIORITY];
0139 
0140     /**
0141      * @usage: How much of the resources are used, protected by the
0142      * bdev->lru_lock.
0143      */
0144     uint64_t usage;
0145 };
0146 
0147 /**
0148  * struct ttm_bus_placement
0149  *
0150  * @addr:       mapped virtual address
0151  * @offset:     physical addr
0152  * @is_iomem:       is this io memory ?
0153  * @caching:        See enum ttm_caching
0154  *
0155  * Structure indicating the bus placement of an object.
0156  */
0157 struct ttm_bus_placement {
0158     void            *addr;
0159     phys_addr_t     offset;
0160     bool            is_iomem;
0161     enum ttm_caching    caching;
0162 };
0163 
0164 /**
0165  * struct ttm_resource
0166  *
0167  * @start: Start of the allocation.
0168  * @num_pages: Actual size of resource in pages.
0169  * @mem_type: Resource type of the allocation.
0170  * @placement: Placement flags.
0171  * @bus: Placement on io bus accessible to the CPU
0172  * @bo: weak reference to the BO, protected by ttm_device::lru_lock
0173  *
0174  * Structure indicating the placement and space resources used by a
0175  * buffer object.
0176  */
0177 struct ttm_resource {
0178     unsigned long start;
0179     unsigned long num_pages;
0180     uint32_t mem_type;
0181     uint32_t placement;
0182     struct ttm_bus_placement bus;
0183     struct ttm_buffer_object *bo;
0184 
0185     /**
0186      * @lru: Least recently used list, see &ttm_resource_manager.lru
0187      */
0188     struct list_head lru;
0189 };
0190 
0191 /**
0192  * struct ttm_resource_cursor
0193  *
0194  * @priority: the current priority
0195  *
0196  * Cursor to iterate over the resources in a manager.
0197  */
0198 struct ttm_resource_cursor {
0199     unsigned int priority;
0200 };
0201 
0202 /**
0203  * struct ttm_lru_bulk_move_pos
0204  *
0205  * @first: first res in the bulk move range
0206  * @last: last res in the bulk move range
0207  *
0208  * Range of resources for a lru bulk move.
0209  */
0210 struct ttm_lru_bulk_move_pos {
0211     struct ttm_resource *first;
0212     struct ttm_resource *last;
0213 };
0214 
0215 /**
0216  * struct ttm_lru_bulk_move
0217  *
0218  * @pos: first/last lru entry for resources in the each domain/priority
0219  *
0220  * Container for the current bulk move state. Should be used with
0221  * ttm_lru_bulk_move_init() and ttm_bo_set_bulk_move().
0222  */
0223 struct ttm_lru_bulk_move {
0224     struct ttm_lru_bulk_move_pos pos[TTM_NUM_MEM_TYPES][TTM_MAX_BO_PRIORITY];
0225 };
0226 
0227 /**
0228  * struct ttm_kmap_iter_iomap - Specialization for a struct io_mapping +
0229  * struct sg_table backed struct ttm_resource.
0230  * @base: Embedded struct ttm_kmap_iter providing the usage interface.
0231  * @iomap: struct io_mapping representing the underlying linear io_memory.
0232  * @st: sg_table into @iomap, representing the memory of the struct ttm_resource.
0233  * @start: Offset that needs to be subtracted from @st to make
0234  * sg_dma_address(st->sgl) - @start == 0 for @iomap start.
0235  * @cache: Scatterlist traversal cache for fast lookups.
0236  * @cache.sg: Pointer to the currently cached scatterlist segment.
0237  * @cache.i: First index of @sg. PAGE_SIZE granularity.
0238  * @cache.end: Last index + 1 of @sg. PAGE_SIZE granularity.
0239  * @cache.offs: First offset into @iomap of @sg. PAGE_SIZE granularity.
0240  */
0241 struct ttm_kmap_iter_iomap {
0242     struct ttm_kmap_iter base;
0243     struct io_mapping *iomap;
0244     struct sg_table *st;
0245     resource_size_t start;
0246     struct {
0247         struct scatterlist *sg;
0248         pgoff_t i;
0249         pgoff_t end;
0250         pgoff_t offs;
0251     } cache;
0252 };
0253 
0254 /**
0255  * struct ttm_kmap_iter_linear_io - Iterator specialization for linear io
0256  * @base: The base iterator
0257  * @dmap: Points to the starting address of the region
0258  * @needs_unmap: Whether we need to unmap on fini
0259  */
0260 struct ttm_kmap_iter_linear_io {
0261     struct ttm_kmap_iter base;
0262     struct iosys_map dmap;
0263     bool needs_unmap;
0264 };
0265 
0266 /**
0267  * ttm_resource_manager_set_used
0268  *
0269  * @man: A memory manager object.
0270  * @used: usage state to set.
0271  *
0272  * Set the manager in use flag. If disabled the manager is no longer
0273  * used for object placement.
0274  */
0275 static inline void
0276 ttm_resource_manager_set_used(struct ttm_resource_manager *man, bool used)
0277 {
0278     int i;
0279 
0280     for (i = 0; i < TTM_MAX_BO_PRIORITY; i++)
0281         WARN_ON(!list_empty(&man->lru[i]));
0282     man->use_type = used;
0283 }
0284 
0285 /**
0286  * ttm_resource_manager_used
0287  *
0288  * @man: Manager to get used state for
0289  *
0290  * Get the in use flag for a manager.
0291  * Returns:
0292  * true is used, false if not.
0293  */
0294 static inline bool ttm_resource_manager_used(struct ttm_resource_manager *man)
0295 {
0296     return man->use_type;
0297 }
0298 
0299 /**
0300  * ttm_resource_manager_cleanup
0301  *
0302  * @man: A memory manager object.
0303  *
0304  * Cleanup the move fences from the memory manager object.
0305  */
0306 static inline void
0307 ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
0308 {
0309     dma_fence_put(man->move);
0310     man->move = NULL;
0311 }
0312 
0313 void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk);
0314 void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk);
0315 
0316 void ttm_resource_add_bulk_move(struct ttm_resource *res,
0317                 struct ttm_buffer_object *bo);
0318 void ttm_resource_del_bulk_move(struct ttm_resource *res,
0319                 struct ttm_buffer_object *bo);
0320 void ttm_resource_move_to_lru_tail(struct ttm_resource *res);
0321 
0322 void ttm_resource_init(struct ttm_buffer_object *bo,
0323                        const struct ttm_place *place,
0324                        struct ttm_resource *res);
0325 void ttm_resource_fini(struct ttm_resource_manager *man,
0326                struct ttm_resource *res);
0327 
0328 int ttm_resource_alloc(struct ttm_buffer_object *bo,
0329                const struct ttm_place *place,
0330                struct ttm_resource **res);
0331 void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res);
0332 bool ttm_resource_compat(struct ttm_resource *res,
0333              struct ttm_placement *placement);
0334 void ttm_resource_set_bo(struct ttm_resource *res,
0335              struct ttm_buffer_object *bo);
0336 
0337 void ttm_resource_manager_init(struct ttm_resource_manager *man,
0338                    struct ttm_device *bdev,
0339                    uint64_t size);
0340 
0341 int ttm_resource_manager_evict_all(struct ttm_device *bdev,
0342                    struct ttm_resource_manager *man);
0343 
0344 uint64_t ttm_resource_manager_usage(struct ttm_resource_manager *man);
0345 void ttm_resource_manager_debug(struct ttm_resource_manager *man,
0346                 struct drm_printer *p);
0347 
0348 struct ttm_resource *
0349 ttm_resource_manager_first(struct ttm_resource_manager *man,
0350                struct ttm_resource_cursor *cursor);
0351 struct ttm_resource *
0352 ttm_resource_manager_next(struct ttm_resource_manager *man,
0353               struct ttm_resource_cursor *cursor,
0354               struct ttm_resource *res);
0355 
0356 /**
0357  * ttm_resource_manager_for_each_res - iterate over all resources
0358  * @man: the resource manager
0359  * @cursor: struct ttm_resource_cursor for the current position
0360  * @res: the current resource
0361  *
0362  * Iterate over all the evictable resources in a resource manager.
0363  */
0364 #define ttm_resource_manager_for_each_res(man, cursor, res)     \
0365     for (res = ttm_resource_manager_first(man, cursor); res;    \
0366          res = ttm_resource_manager_next(man, cursor, res))
0367 
0368 struct ttm_kmap_iter *
0369 ttm_kmap_iter_iomap_init(struct ttm_kmap_iter_iomap *iter_io,
0370              struct io_mapping *iomap,
0371              struct sg_table *st,
0372              resource_size_t start);
0373 
0374 struct ttm_kmap_iter_linear_io;
0375 
0376 struct ttm_kmap_iter *
0377 ttm_kmap_iter_linear_io_init(struct ttm_kmap_iter_linear_io *iter_io,
0378                  struct ttm_device *bdev,
0379                  struct ttm_resource *mem);
0380 
0381 void ttm_kmap_iter_linear_io_fini(struct ttm_kmap_iter_linear_io *iter_io,
0382                   struct ttm_device *bdev,
0383                   struct ttm_resource *mem);
0384 
0385 void ttm_resource_manager_create_debugfs(struct ttm_resource_manager *man,
0386                      struct dentry * parent,
0387                      const char *name);
0388 #endif