diff options
Diffstat (limited to 'include/drm/ttm/ttm_bo_driver.h')
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 215 |
1 files changed, 169 insertions, 46 deletions
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index d01b4ddbdc56..1da8af6ac884 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -179,6 +179,90 @@ struct ttm_tt { | |||
179 | #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ | 179 | #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ |
180 | #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ | 180 | #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ |
181 | 181 | ||
182 | struct ttm_mem_type_manager; | ||
183 | |||
184 | struct ttm_mem_type_manager_func { | ||
185 | /** | ||
186 | * struct ttm_mem_type_manager member init | ||
187 | * | ||
188 | * @man: Pointer to a memory type manager. | ||
189 | * @p_size: Implementation dependent, but typically the size of the | ||
190 | * range to be managed in pages. | ||
191 | * | ||
192 | * Called to initialize a private range manager. The function is | ||
193 | * expected to initialize the man::priv member. | ||
194 | * Returns 0 on success, negative error code on failure. | ||
195 | */ | ||
196 | int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); | ||
197 | |||
198 | /** | ||
199 | * struct ttm_mem_type_manager member takedown | ||
200 | * | ||
201 | * @man: Pointer to a memory type manager. | ||
202 | * | ||
203 | * Called to undo the setup done in init. All allocated resources | ||
204 | * should be freed. | ||
205 | */ | ||
206 | int (*takedown)(struct ttm_mem_type_manager *man); | ||
207 | |||
208 | /** | ||
209 | * struct ttm_mem_type_manager member get_node | ||
210 | * | ||
211 | * @man: Pointer to a memory type manager. | ||
212 | * @bo: Pointer to the buffer object we're allocating space for. | ||
213 | * @placement: Placement details. | ||
214 | * @mem: Pointer to a struct ttm_mem_reg to be filled in. | ||
215 | * | ||
216 | * This function should allocate space in the memory type managed | ||
217 | * by @man. Placement details if | ||
218 | * applicable are given by @placement. If successful, | ||
219 | * @mem::mm_node should be set to a non-null value, and | ||
220 | * @mem::start should be set to a value identifying the beginning | ||
221 | * of the range allocated, and the function should return zero. | ||
222 | * If the memory region accomodate the buffer object, @mem::mm_node | ||
223 | * should be set to NULL, and the function should return 0. | ||
224 | * If a system error occured, preventing the request to be fulfilled, | ||
225 | * the function should return a negative error code. | ||
226 | * | ||
227 | * Note that @mem::mm_node will only be dereferenced by | ||
228 | * struct ttm_mem_type_manager functions and optionally by the driver, | ||
229 | * which has knowledge of the underlying type. | ||
230 | * | ||
231 | * This function may not be called from within atomic context, so | ||
232 | * an implementation can and must use either a mutex or a spinlock to | ||
233 | * protect any data structures managing the space. | ||
234 | */ | ||
235 | int (*get_node)(struct ttm_mem_type_manager *man, | ||
236 | struct ttm_buffer_object *bo, | ||
237 | struct ttm_placement *placement, | ||
238 | struct ttm_mem_reg *mem); | ||
239 | |||
240 | /** | ||
241 | * struct ttm_mem_type_manager member put_node | ||
242 | * | ||
243 | * @man: Pointer to a memory type manager. | ||
244 | * @mem: Pointer to a struct ttm_mem_reg to be filled in. | ||
245 | * | ||
246 | * This function frees memory type resources previously allocated | ||
247 | * and that are identified by @mem::mm_node and @mem::start. May not | ||
248 | * be called from within atomic context. | ||
249 | */ | ||
250 | void (*put_node)(struct ttm_mem_type_manager *man, | ||
251 | struct ttm_mem_reg *mem); | ||
252 | |||
253 | /** | ||
254 | * struct ttm_mem_type_manager member debug | ||
255 | * | ||
256 | * @man: Pointer to a memory type manager. | ||
257 | * @prefix: Prefix to be used in printout to identify the caller. | ||
258 | * | ||
259 | * This function is called to print out the state of the memory | ||
260 | * type manager to aid debugging of out-of-memory conditions. | ||
261 | * It may not be called from within atomic context. | ||
262 | */ | ||
263 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); | ||
264 | }; | ||
265 | |||
182 | /** | 266 | /** |
183 | * struct ttm_mem_type_manager | 267 | * struct ttm_mem_type_manager |
184 | * | 268 | * |
@@ -193,29 +277,21 @@ struct ttm_tt { | |||
193 | * as defined in ttm_placement_common.h | 277 | * as defined in ttm_placement_common.h |
194 | * @default_caching: The default caching policy used for a buffer object | 278 | * @default_caching: The default caching policy used for a buffer object |
195 | * placed in this memory type if the user doesn't provide one. | 279 | * placed in this memory type if the user doesn't provide one. |
196 | * @manager: The range manager used for this memory type. FIXME: If the aperture | 280 | * @func: structure pointer implementing the range manager. See above |
197 | * has a page size different from the underlying system, the granularity | 281 | * @priv: Driver private closure for @func. |
198 | * of this manager should take care of this. But the range allocating code | 282 | * @io_reserve_mutex: Mutex optionally protecting shared io_reserve structures |
199 | * in ttm_bo.c needs to be modified for this. | 283 | * @use_io_reserve_lru: Use an lru list to try to unreserve io_mem_regions |
284 | * reserved by the TTM vm system. | ||
285 | * @io_reserve_lru: Optional lru list for unreserving io mem regions. | ||
286 | * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain | ||
287 | * static information. bdev::driver::io_mem_free is never used. | ||
200 | * @lru: The lru list for this memory type. | 288 | * @lru: The lru list for this memory type. |
201 | * | 289 | * |
202 | * This structure is used to identify and manage memory types for a device. | 290 | * This structure is used to identify and manage memory types for a device. |
203 | * It's set up by the ttm_bo_driver::init_mem_type method. | 291 | * It's set up by the ttm_bo_driver::init_mem_type method. |
204 | */ | 292 | */ |
205 | 293 | ||
206 | struct ttm_mem_type_manager; | ||
207 | 294 | ||
208 | struct ttm_mem_type_manager_func { | ||
209 | int (*init)(struct ttm_mem_type_manager *man, unsigned long p_size); | ||
210 | int (*takedown)(struct ttm_mem_type_manager *man); | ||
211 | int (*get_node)(struct ttm_mem_type_manager *man, | ||
212 | struct ttm_buffer_object *bo, | ||
213 | struct ttm_placement *placement, | ||
214 | struct ttm_mem_reg *mem); | ||
215 | void (*put_node)(struct ttm_mem_type_manager *man, | ||
216 | struct ttm_mem_reg *mem); | ||
217 | void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); | ||
218 | }; | ||
219 | 295 | ||
220 | struct ttm_mem_type_manager { | 296 | struct ttm_mem_type_manager { |
221 | struct ttm_bo_device *bdev; | 297 | struct ttm_bo_device *bdev; |
@@ -231,14 +307,22 @@ struct ttm_mem_type_manager { | |||
231 | uint64_t size; | 307 | uint64_t size; |
232 | uint32_t available_caching; | 308 | uint32_t available_caching; |
233 | uint32_t default_caching; | 309 | uint32_t default_caching; |
310 | const struct ttm_mem_type_manager_func *func; | ||
311 | void *priv; | ||
312 | struct mutex io_reserve_mutex; | ||
313 | bool use_io_reserve_lru; | ||
314 | bool io_reserve_fastpath; | ||
234 | 315 | ||
235 | /* | 316 | /* |
236 | * Protected by the bdev->lru_lock. | 317 | * Protected by @io_reserve_mutex: |
237 | * TODO: Consider one lru_lock per ttm_mem_type_manager. | ||
238 | * Plays ill with list removal, though. | ||
239 | */ | 318 | */ |
240 | const struct ttm_mem_type_manager_func *func; | 319 | |
241 | void *priv; | 320 | struct list_head io_reserve_lru; |
321 | |||
322 | /* | ||
323 | * Protected by the global->lru_lock. | ||
324 | */ | ||
325 | |||
242 | struct list_head lru; | 326 | struct list_head lru; |
243 | }; | 327 | }; |
244 | 328 | ||
@@ -441,9 +525,12 @@ struct ttm_bo_global { | |||
441 | * | 525 | * |
442 | * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. | 526 | * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. |
443 | * @man: An array of mem_type_managers. | 527 | * @man: An array of mem_type_managers. |
528 | * @fence_lock: Protects the synchronizing members on *all* bos belonging | ||
529 | * to this device. | ||
444 | * @addr_space_mm: Range manager for the device address space. | 530 | * @addr_space_mm: Range manager for the device address space. |
445 | * lru_lock: Spinlock that protects the buffer+device lru lists and | 531 | * lru_lock: Spinlock that protects the buffer+device lru lists and |
446 | * ddestroy lists. | 532 | * ddestroy lists. |
533 | * @val_seq: Current validation sequence. | ||
447 | * @nice_mode: Try nicely to wait for buffer idle when cleaning a manager. | 534 | * @nice_mode: Try nicely to wait for buffer idle when cleaning a manager. |
448 | * If a GPU lockup has been detected, this is forced to 0. | 535 | * If a GPU lockup has been detected, this is forced to 0. |
449 | * @dev_mapping: A pointer to the struct address_space representing the | 536 | * @dev_mapping: A pointer to the struct address_space representing the |
@@ -462,6 +549,7 @@ struct ttm_bo_device { | |||
462 | struct ttm_bo_driver *driver; | 549 | struct ttm_bo_driver *driver; |
463 | rwlock_t vm_lock; | 550 | rwlock_t vm_lock; |
464 | struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; | 551 | struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; |
552 | spinlock_t fence_lock; | ||
465 | /* | 553 | /* |
466 | * Protected by the vm lock. | 554 | * Protected by the vm lock. |
467 | */ | 555 | */ |
@@ -472,6 +560,7 @@ struct ttm_bo_device { | |||
472 | * Protected by the global:lru lock. | 560 | * Protected by the global:lru lock. |
473 | */ | 561 | */ |
474 | struct list_head ddestroy; | 562 | struct list_head ddestroy; |
563 | uint32_t val_seq; | ||
475 | 564 | ||
476 | /* | 565 | /* |
477 | * Protected by load / firstopen / lastclose /unload sync. | 566 | * Protected by load / firstopen / lastclose /unload sync. |
@@ -684,31 +773,6 @@ extern void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo, | |||
684 | 773 | ||
685 | extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); | 774 | extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); |
686 | 775 | ||
687 | /** | ||
688 | * ttm_bo_pci_offset - Get the PCI offset for the buffer object memory. | ||
689 | * | ||
690 | * @bo Pointer to a struct ttm_buffer_object. | ||
691 | * @bus_base On return the base of the PCI region | ||
692 | * @bus_offset On return the byte offset into the PCI region | ||
693 | * @bus_size On return the byte size of the buffer object or zero if | ||
694 | * the buffer object memory is not accessible through a PCI region. | ||
695 | * | ||
696 | * Returns: | ||
697 | * -EINVAL if the buffer object is currently not mappable. | ||
698 | * 0 otherwise. | ||
699 | */ | ||
700 | |||
701 | extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, | ||
702 | struct ttm_mem_reg *mem, | ||
703 | unsigned long *bus_base, | ||
704 | unsigned long *bus_offset, | ||
705 | unsigned long *bus_size); | ||
706 | |||
707 | extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, | ||
708 | struct ttm_mem_reg *mem); | ||
709 | extern void ttm_mem_io_free(struct ttm_bo_device *bdev, | ||
710 | struct ttm_mem_reg *mem); | ||
711 | |||
712 | extern void ttm_bo_global_release(struct drm_global_reference *ref); | 776 | extern void ttm_bo_global_release(struct drm_global_reference *ref); |
713 | extern int ttm_bo_global_init(struct drm_global_reference *ref); | 777 | extern int ttm_bo_global_init(struct drm_global_reference *ref); |
714 | 778 | ||
@@ -741,6 +805,22 @@ extern int ttm_bo_device_init(struct ttm_bo_device *bdev, | |||
741 | extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); | 805 | extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); |
742 | 806 | ||
743 | /** | 807 | /** |
808 | * ttm_bo_unmap_virtual | ||
809 | * | ||
810 | * @bo: tear down the virtual mappings for this BO | ||
811 | * | ||
812 | * The caller must take ttm_mem_io_lock before calling this function. | ||
813 | */ | ||
814 | extern void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo); | ||
815 | |||
816 | extern int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo); | ||
817 | extern void ttm_mem_io_free_vm(struct ttm_buffer_object *bo); | ||
818 | extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man, | ||
819 | bool interruptible); | ||
820 | extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | ||
821 | |||
822 | |||
823 | /** | ||
744 | * ttm_bo_reserve: | 824 | * ttm_bo_reserve: |
745 | * | 825 | * |
746 | * @bo: A pointer to a struct ttm_buffer_object. | 826 | * @bo: A pointer to a struct ttm_buffer_object. |
@@ -790,11 +870,44 @@ extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); | |||
790 | * try again. (only if use_sequence == 1). | 870 | * try again. (only if use_sequence == 1). |
791 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by | 871 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by |
792 | * a signal. Release all buffer reservations and return to user-space. | 872 | * a signal. Release all buffer reservations and return to user-space. |
873 | * -EBUSY: The function needed to sleep, but @no_wait was true | ||
874 | * -EDEADLK: Bo already reserved using @sequence. This error code will only | ||
875 | * be returned if @use_sequence is set to true. | ||
793 | */ | 876 | */ |
794 | extern int ttm_bo_reserve(struct ttm_buffer_object *bo, | 877 | extern int ttm_bo_reserve(struct ttm_buffer_object *bo, |
795 | bool interruptible, | 878 | bool interruptible, |
796 | bool no_wait, bool use_sequence, uint32_t sequence); | 879 | bool no_wait, bool use_sequence, uint32_t sequence); |
797 | 880 | ||
881 | |||
882 | /** | ||
883 | * ttm_bo_reserve_locked: | ||
884 | * | ||
885 | * @bo: A pointer to a struct ttm_buffer_object. | ||
886 | * @interruptible: Sleep interruptible if waiting. | ||
887 | * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. | ||
888 | * @use_sequence: If @bo is already reserved, Only sleep waiting for | ||
889 | * it to become unreserved if @sequence < (@bo)->sequence. | ||
890 | * | ||
891 | * Must be called with struct ttm_bo_global::lru_lock held, | ||
892 | * and will not remove reserved buffers from the lru lists. | ||
893 | * The function may release the LRU spinlock if it needs to sleep. | ||
894 | * Otherwise identical to ttm_bo_reserve. | ||
895 | * | ||
896 | * Returns: | ||
897 | * -EAGAIN: The reservation may cause a deadlock. | ||
898 | * Release all buffer reservations, wait for @bo to become unreserved and | ||
899 | * try again. (only if use_sequence == 1). | ||
900 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by | ||
901 | * a signal. Release all buffer reservations and return to user-space. | ||
902 | * -EBUSY: The function needed to sleep, but @no_wait was true | ||
903 | * -EDEADLK: Bo already reserved using @sequence. This error code will only | ||
904 | * be returned if @use_sequence is set to true. | ||
905 | */ | ||
906 | extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, | ||
907 | bool interruptible, | ||
908 | bool no_wait, bool use_sequence, | ||
909 | uint32_t sequence); | ||
910 | |||
798 | /** | 911 | /** |
799 | * ttm_bo_unreserve | 912 | * ttm_bo_unreserve |
800 | * | 913 | * |
@@ -805,6 +918,16 @@ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, | |||
805 | extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); | 918 | extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); |
806 | 919 | ||
807 | /** | 920 | /** |
921 | * ttm_bo_unreserve_locked | ||
922 | * | ||
923 | * @bo: A pointer to a struct ttm_buffer_object. | ||
924 | * | ||
925 | * Unreserve a previous reservation of @bo. | ||
926 | * Needs to be called with struct ttm_bo_global::lru_lock held. | ||
927 | */ | ||
928 | extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo); | ||
929 | |||
930 | /** | ||
808 | * ttm_bo_wait_unreserved | 931 | * ttm_bo_wait_unreserved |
809 | * | 932 | * |
810 | * @bo: A pointer to a struct ttm_buffer_object. | 933 | * @bo: A pointer to a struct ttm_buffer_object. |