aboutsummaryrefslogtreecommitdiffstats
path: root/include/drm/ttm/ttm_bo_driver.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm/ttm/ttm_bo_driver.h')
-rw-r--r--include/drm/ttm/ttm_bo_driver.h179
1 files changed, 114 insertions, 65 deletions
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 9c8dca79808e..8639c85d61c4 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -33,11 +33,14 @@
33#include <ttm/ttm_bo_api.h> 33#include <ttm/ttm_bo_api.h>
34#include <ttm/ttm_memory.h> 34#include <ttm/ttm_memory.h>
35#include <ttm/ttm_module.h> 35#include <ttm/ttm_module.h>
36#include <ttm/ttm_placement.h>
36#include <drm/drm_mm.h> 37#include <drm/drm_mm.h>
37#include <drm/drm_global.h> 38#include <drm/drm_global.h>
39#include <drm/drm_vma_manager.h>
38#include <linux/workqueue.h> 40#include <linux/workqueue.h>
39#include <linux/fs.h> 41#include <linux/fs.h>
40#include <linux/spinlock.h> 42#include <linux/spinlock.h>
43#include <linux/reservation.h>
41 44
42struct ttm_backend_func { 45struct ttm_backend_func {
43 /** 46 /**
@@ -517,7 +520,7 @@ struct ttm_bo_global {
517 * @man: An array of mem_type_managers. 520 * @man: An array of mem_type_managers.
518 * @fence_lock: Protects the synchronizing members on *all* bos belonging 521 * @fence_lock: Protects the synchronizing members on *all* bos belonging
519 * to this device. 522 * to this device.
520 * @addr_space_mm: Range manager for the device address space. 523 * @vma_manager: Address space manager
521 * lru_lock: Spinlock that protects the buffer+device lru lists and 524 * lru_lock: Spinlock that protects the buffer+device lru lists and
522 * ddestroy lists. 525 * ddestroy lists.
523 * @val_seq: Current validation sequence. 526 * @val_seq: Current validation sequence.
@@ -535,14 +538,13 @@ struct ttm_bo_device {
535 struct list_head device_list; 538 struct list_head device_list;
536 struct ttm_bo_global *glob; 539 struct ttm_bo_global *glob;
537 struct ttm_bo_driver *driver; 540 struct ttm_bo_driver *driver;
538 rwlock_t vm_lock;
539 struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; 541 struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
540 spinlock_t fence_lock; 542 spinlock_t fence_lock;
543
541 /* 544 /*
542 * Protected by the vm lock. 545 * Protected by internal locks.
543 */ 546 */
544 struct rb_root addr_space_rb; 547 struct drm_vma_offset_manager vma_manager;
545 struct drm_mm addr_space_mm;
546 548
547 /* 549 /*
548 * Protected by the global:lru lock. 550 * Protected by the global:lru lock.
@@ -771,6 +773,55 @@ extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man,
771 bool interruptible); 773 bool interruptible);
772extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); 774extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
773 775
776extern void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo);
777extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);
778
779/**
780 * ttm_bo_reserve_nolru:
781 *
782 * @bo: A pointer to a struct ttm_buffer_object.
783 * @interruptible: Sleep interruptible if waiting.
784 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
785 * @use_ticket: If @bo is already reserved, Only sleep waiting for
786 * it to become unreserved if @ticket->stamp is older.
787 *
788 * Will not remove reserved buffers from the lru lists.
789 * Otherwise identical to ttm_bo_reserve.
790 *
791 * Returns:
792 * -EDEADLK: The reservation may cause a deadlock.
793 * Release all buffer reservations, wait for @bo to become unreserved and
794 * try again. (only if use_sequence == 1).
795 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
796 * a signal. Release all buffer reservations and return to user-space.
797 * -EBUSY: The function needed to sleep, but @no_wait was true
798 * -EALREADY: Bo already reserved using @ticket. This error code will only
799 * be returned if @use_ticket is set to true.
800 */
801static inline int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
802 bool interruptible,
803 bool no_wait, bool use_ticket,
804 struct ww_acquire_ctx *ticket)
805{
806 int ret = 0;
807
808 if (no_wait) {
809 bool success;
810 if (WARN_ON(ticket))
811 return -EBUSY;
812
813 success = ww_mutex_trylock(&bo->resv->lock);
814 return success ? 0 : -EBUSY;
815 }
816
817 if (interruptible)
818 ret = ww_mutex_lock_interruptible(&bo->resv->lock, ticket);
819 else
820 ret = ww_mutex_lock(&bo->resv->lock, ticket);
821 if (ret == -EINTR)
822 return -ERESTARTSYS;
823 return ret;
824}
774 825
775/** 826/**
776 * ttm_bo_reserve: 827 * ttm_bo_reserve:
@@ -778,8 +829,8 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
778 * @bo: A pointer to a struct ttm_buffer_object. 829 * @bo: A pointer to a struct ttm_buffer_object.
779 * @interruptible: Sleep interruptible if waiting. 830 * @interruptible: Sleep interruptible if waiting.
780 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. 831 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
781 * @use_sequence: If @bo is already reserved, Only sleep waiting for 832 * @use_ticket: If @bo is already reserved, Only sleep waiting for
782 * it to become unreserved if @sequence < (@bo)->sequence. 833 * it to become unreserved if @ticket->stamp is older.
783 * 834 *
784 * Locks a buffer object for validation. (Or prevents other processes from 835 * Locks a buffer object for validation. (Or prevents other processes from
785 * locking it for validation) and removes it from lru lists, while taking 836 * locking it for validation) and removes it from lru lists, while taking
@@ -793,7 +844,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
793 * Processes attempting to reserve multiple buffers other than for eviction, 844 * Processes attempting to reserve multiple buffers other than for eviction,
794 * (typically execbuf), should first obtain a unique 32-bit 845 * (typically execbuf), should first obtain a unique 32-bit
795 * validation sequence number, 846 * validation sequence number,
796 * and call this function with @use_sequence == 1 and @sequence == the unique 847 * and call this function with @use_ticket == 1 and @ticket->stamp == the unique
797 * sequence number. If upon call of this function, the buffer object is already 848 * sequence number. If upon call of this function, the buffer object is already
798 * reserved, the validation sequence is checked against the validation 849 * reserved, the validation sequence is checked against the validation
799 * sequence of the process currently reserving the buffer, 850 * sequence of the process currently reserving the buffer,
@@ -808,36 +859,31 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
808 * will eventually succeed, preventing both deadlocks and starvation. 859 * will eventually succeed, preventing both deadlocks and starvation.
809 * 860 *
810 * Returns: 861 * Returns:
811 * -EAGAIN: The reservation may cause a deadlock. 862 * -EDEADLK: The reservation may cause a deadlock.
812 * Release all buffer reservations, wait for @bo to become unreserved and 863 * Release all buffer reservations, wait for @bo to become unreserved and
813 * try again. (only if use_sequence == 1). 864 * try again. (only if use_sequence == 1).
814 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by 865 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
815 * a signal. Release all buffer reservations and return to user-space. 866 * a signal. Release all buffer reservations and return to user-space.
816 * -EBUSY: The function needed to sleep, but @no_wait was true 867 * -EBUSY: The function needed to sleep, but @no_wait was true
817 * -EDEADLK: Bo already reserved using @sequence. This error code will only 868 * -EALREADY: Bo already reserved using @ticket. This error code will only
818 * be returned if @use_sequence is set to true. 869 * be returned if @use_ticket is set to true.
819 */ 870 */
820extern int ttm_bo_reserve(struct ttm_buffer_object *bo, 871static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
821 bool interruptible, 872 bool interruptible,
822 bool no_wait, bool use_sequence, uint32_t sequence); 873 bool no_wait, bool use_ticket,
874 struct ww_acquire_ctx *ticket)
875{
876 int ret;
823 877
824/** 878 WARN_ON(!atomic_read(&bo->kref.refcount));
825 * ttm_bo_reserve_slowpath_nolru:
826 * @bo: A pointer to a struct ttm_buffer_object.
827 * @interruptible: Sleep interruptible if waiting.
828 * @sequence: Set (@bo)->sequence to this value after lock
829 *
830 * This is called after ttm_bo_reserve returns -EAGAIN and we backed off
831 * from all our other reservations. Because there are no other reservations
832 * held by us, this function cannot deadlock any more.
833 *
834 * Will not remove reserved buffers from the lru lists.
835 * Otherwise identical to ttm_bo_reserve_slowpath.
836 */
837extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
838 bool interruptible,
839 uint32_t sequence);
840 879
880 ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket,
881 ticket);
882 if (likely(ret == 0))
883 ttm_bo_del_sub_from_lru(bo);
884
885 return ret;
886}
841 887
842/** 888/**
843 * ttm_bo_reserve_slowpath: 889 * ttm_bo_reserve_slowpath:
@@ -849,54 +895,57 @@ extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
849 * from all our other reservations. Because there are no other reservations 895 * from all our other reservations. Because there are no other reservations
850 * held by us, this function cannot deadlock any more. 896 * held by us, this function cannot deadlock any more.
851 */ 897 */
852extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, 898static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
853 bool interruptible, uint32_t sequence); 899 bool interruptible,
900 struct ww_acquire_ctx *ticket)
901{
902 int ret = 0;
854 903
855/** 904 WARN_ON(!atomic_read(&bo->kref.refcount));
856 * ttm_bo_reserve_nolru: 905
857 * 906 if (interruptible)
858 * @bo: A pointer to a struct ttm_buffer_object. 907 ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
859 * @interruptible: Sleep interruptible if waiting. 908 ticket);
860 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. 909 else
861 * @use_sequence: If @bo is already reserved, Only sleep waiting for 910 ww_mutex_lock_slow(&bo->resv->lock, ticket);
862 * it to become unreserved if @sequence < (@bo)->sequence. 911
863 * 912 if (likely(ret == 0))
864 * Will not remove reserved buffers from the lru lists. 913 ttm_bo_del_sub_from_lru(bo);
865 * Otherwise identical to ttm_bo_reserve. 914 else if (ret == -EINTR)
866 * 915 ret = -ERESTARTSYS;
867 * Returns: 916
868 * -EAGAIN: The reservation may cause a deadlock. 917 return ret;
869 * Release all buffer reservations, wait for @bo to become unreserved and 918}
870 * try again. (only if use_sequence == 1).
871 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
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.
876 */
877extern int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
878 bool interruptible,
879 bool no_wait, bool use_sequence,
880 uint32_t sequence);
881 919
882/** 920/**
883 * ttm_bo_unreserve 921 * ttm_bo_unreserve_ticket
884 *
885 * @bo: A pointer to a struct ttm_buffer_object. 922 * @bo: A pointer to a struct ttm_buffer_object.
923 * @ticket: ww_acquire_ctx used for reserving
886 * 924 *
887 * Unreserve a previous reservation of @bo. 925 * Unreserve a previous reservation of @bo made with @ticket.
888 */ 926 */
889extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); 927static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
928 struct ww_acquire_ctx *t)
929{
930 if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
931 spin_lock(&bo->glob->lru_lock);
932 ttm_bo_add_to_lru(bo);
933 spin_unlock(&bo->glob->lru_lock);
934 }
935 ww_mutex_unlock(&bo->resv->lock);
936}
890 937
891/** 938/**
892 * ttm_bo_unreserve_locked 939 * ttm_bo_unreserve
893 * 940 *
894 * @bo: A pointer to a struct ttm_buffer_object. 941 * @bo: A pointer to a struct ttm_buffer_object.
895 * 942 *
896 * Unreserve a previous reservation of @bo. 943 * Unreserve a previous reservation of @bo.
897 * Needs to be called with struct ttm_bo_global::lru_lock held.
898 */ 944 */
899extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo); 945static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo)
946{
947 ttm_bo_unreserve_ticket(bo, NULL);
948}
900 949
901/* 950/*
902 * ttm_bo_util.c 951 * ttm_bo_util.c