diff options
author | Maarten Lankhorst <m.b.lankhorst@gmail.com> | 2013-06-27 07:48:24 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-06-27 22:04:09 -0400 |
commit | 3482032457f50cae196f6397ebec7f5f2ad3cf7d (patch) | |
tree | 7f41fe11224f91d1fb1b90edb0ccec56970cc921 /include/drm/ttm | |
parent | c43f9b16991950c00621641ef2c5cd4a3af2a052 (diff) |
drm/ttm: inline ttm_bo_reserve and related calls
Makes lockdep a lot more useful.
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include/drm/ttm')
-rw-r--r-- | include/drm/ttm/ttm_bo_driver.h | 175 |
1 files changed, 105 insertions, 70 deletions
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index ec18c5f3e6e9..984fc2d571a1 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h | |||
@@ -33,6 +33,7 @@ | |||
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> |
38 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
@@ -772,6 +773,55 @@ extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man, | |||
772 | bool interruptible); | 773 | bool interruptible); |
773 | extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | 774 | extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); |
774 | 775 | ||
776 | extern void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo); | ||
777 | extern 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 | */ | ||
801 | static 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 | } | ||
775 | 825 | ||
776 | /** | 826 | /** |
777 | * ttm_bo_reserve: | 827 | * ttm_bo_reserve: |
@@ -780,7 +830,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | |||
780 | * @interruptible: Sleep interruptible if waiting. | 830 | * @interruptible: Sleep interruptible if waiting. |
781 | * @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. |
782 | * @use_ticket: If @bo is already reserved, Only sleep waiting for | 832 | * @use_ticket: If @bo is already reserved, Only sleep waiting for |
783 | * it to become unreserved if @sequence < (@bo)->sequence. | 833 | * it to become unreserved if @ticket->stamp is older. |
784 | * | 834 | * |
785 | * Locks a buffer object for validation. (Or prevents other processes from | 835 | * Locks a buffer object for validation. (Or prevents other processes from |
786 | * 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 |
@@ -794,7 +844,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | |||
794 | * Processes attempting to reserve multiple buffers other than for eviction, | 844 | * Processes attempting to reserve multiple buffers other than for eviction, |
795 | * (typically execbuf), should first obtain a unique 32-bit | 845 | * (typically execbuf), should first obtain a unique 32-bit |
796 | * validation sequence number, | 846 | * validation sequence number, |
797 | * 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 |
798 | * 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 |
799 | * reserved, the validation sequence is checked against the validation | 849 | * reserved, the validation sequence is checked against the validation |
800 | * sequence of the process currently reserving the buffer, | 850 | * sequence of the process currently reserving the buffer, |
@@ -809,37 +859,31 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); | |||
809 | * will eventually succeed, preventing both deadlocks and starvation. | 859 | * will eventually succeed, preventing both deadlocks and starvation. |
810 | * | 860 | * |
811 | * Returns: | 861 | * Returns: |
812 | * -EAGAIN: The reservation may cause a deadlock. | 862 | * -EDEADLK: The reservation may cause a deadlock. |
813 | * Release all buffer reservations, wait for @bo to become unreserved and | 863 | * Release all buffer reservations, wait for @bo to become unreserved and |
814 | * try again. (only if use_sequence == 1). | 864 | * try again. (only if use_sequence == 1). |
815 | * -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 |
816 | * a signal. Release all buffer reservations and return to user-space. | 866 | * a signal. Release all buffer reservations and return to user-space. |
817 | * -EBUSY: The function needed to sleep, but @no_wait was true | 867 | * -EBUSY: The function needed to sleep, but @no_wait was true |
818 | * -EDEADLK: Bo already reserved using @sequence. This error code will only | 868 | * -EALREADY: Bo already reserved using @ticket. This error code will only |
819 | * be returned if @use_sequence is set to true. | 869 | * be returned if @use_ticket is set to true. |
820 | */ | 870 | */ |
821 | extern int ttm_bo_reserve(struct ttm_buffer_object *bo, | 871 | static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, |
822 | bool interruptible, | 872 | bool interruptible, |
823 | bool no_wait, bool use_ticket, | 873 | bool no_wait, bool use_ticket, |
824 | struct ww_acquire_ctx *ticket); | 874 | struct ww_acquire_ctx *ticket) |
875 | { | ||
876 | int ret; | ||
825 | 877 | ||
826 | /** | 878 | WARN_ON(!atomic_read(&bo->kref.refcount)); |
827 | * ttm_bo_reserve_slowpath_nolru: | 879 | |
828 | * @bo: A pointer to a struct ttm_buffer_object. | 880 | ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket, |
829 | * @interruptible: Sleep interruptible if waiting. | 881 | ticket); |
830 | * @sequence: Set (@bo)->sequence to this value after lock | 882 | if (likely(ret == 0)) |
831 | * | 883 | ttm_bo_del_sub_from_lru(bo); |
832 | * This is called after ttm_bo_reserve returns -EAGAIN and we backed off | ||
833 | * from all our other reservations. Because there are no other reservations | ||
834 | * held by us, this function cannot deadlock any more. | ||
835 | * | ||
836 | * Will not remove reserved buffers from the lru lists. | ||
837 | * Otherwise identical to ttm_bo_reserve_slowpath. | ||
838 | */ | ||
839 | extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo, | ||
840 | bool interruptible, | ||
841 | struct ww_acquire_ctx *ticket); | ||
842 | 884 | ||
885 | return ret; | ||
886 | } | ||
843 | 887 | ||
844 | /** | 888 | /** |
845 | * ttm_bo_reserve_slowpath: | 889 | * ttm_bo_reserve_slowpath: |
@@ -851,45 +895,27 @@ extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo, | |||
851 | * from all our other reservations. Because there are no other reservations | 895 | * from all our other reservations. Because there are no other reservations |
852 | * held by us, this function cannot deadlock any more. | 896 | * held by us, this function cannot deadlock any more. |
853 | */ | 897 | */ |
854 | extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, | 898 | static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, |
855 | bool interruptible, | 899 | bool interruptible, |
856 | struct ww_acquire_ctx *ticket); | 900 | struct ww_acquire_ctx *ticket) |
901 | { | ||
902 | int ret = 0; | ||
857 | 903 | ||
858 | /** | 904 | WARN_ON(!atomic_read(&bo->kref.refcount)); |
859 | * ttm_bo_reserve_nolru: | ||
860 | * | ||
861 | * @bo: A pointer to a struct ttm_buffer_object. | ||
862 | * @interruptible: Sleep interruptible if waiting. | ||
863 | * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. | ||
864 | * @use_sequence: If @bo is already reserved, Only sleep waiting for | ||
865 | * it to become unreserved if @sequence < (@bo)->sequence. | ||
866 | * | ||
867 | * Will not remove reserved buffers from the lru lists. | ||
868 | * Otherwise identical to ttm_bo_reserve. | ||
869 | * | ||
870 | * Returns: | ||
871 | * -EAGAIN: The reservation may cause a deadlock. | ||
872 | * Release all buffer reservations, wait for @bo to become unreserved and | ||
873 | * try again. (only if use_sequence == 1). | ||
874 | * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by | ||
875 | * a signal. Release all buffer reservations and return to user-space. | ||
876 | * -EBUSY: The function needed to sleep, but @no_wait was true | ||
877 | * -EDEADLK: Bo already reserved using @sequence. This error code will only | ||
878 | * be returned if @use_sequence is set to true. | ||
879 | */ | ||
880 | extern int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo, | ||
881 | bool interruptible, | ||
882 | bool no_wait, bool use_ticket, | ||
883 | struct ww_acquire_ctx *ticket); | ||
884 | 905 | ||
885 | /** | 906 | if (interruptible) |
886 | * ttm_bo_unreserve | 907 | ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock, |
887 | * | 908 | ticket); |
888 | * @bo: A pointer to a struct ttm_buffer_object. | 909 | else |
889 | * | 910 | ww_mutex_lock_slow(&bo->resv->lock, ticket); |
890 | * Unreserve a previous reservation of @bo. | 911 | |
891 | */ | 912 | if (likely(ret == 0)) |
892 | extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); | 913 | ttm_bo_del_sub_from_lru(bo); |
914 | else if (ret == -EINTR) | ||
915 | ret = -ERESTARTSYS; | ||
916 | |||
917 | return ret; | ||
918 | } | ||
893 | 919 | ||
894 | /** | 920 | /** |
895 | * ttm_bo_unreserve_ticket | 921 | * ttm_bo_unreserve_ticket |
@@ -898,19 +924,28 @@ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); | |||
898 | * | 924 | * |
899 | * Unreserve a previous reservation of @bo made with @ticket. | 925 | * Unreserve a previous reservation of @bo made with @ticket. |
900 | */ | 926 | */ |
901 | extern void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo, | 927 | static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo, |
902 | struct ww_acquire_ctx *ticket); | 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 | } | ||
903 | 937 | ||
904 | /** | 938 | /** |
905 | * ttm_bo_unreserve_locked | 939 | * ttm_bo_unreserve |
940 | * | ||
906 | * @bo: A pointer to a struct ttm_buffer_object. | 941 | * @bo: A pointer to a struct ttm_buffer_object. |
907 | * @ticket: ww_acquire_ctx used for reserving, or NULL | ||
908 | * | 942 | * |
909 | * Unreserve a previous reservation of @bo made with @ticket. | 943 | * Unreserve a previous reservation of @bo. |
910 | * Needs to be called with struct ttm_bo_global::lru_lock held. | ||
911 | */ | 944 | */ |
912 | extern void ttm_bo_unreserve_ticket_locked(struct ttm_buffer_object *bo, | 945 | static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo) |
913 | struct ww_acquire_ctx *ticket); | 946 | { |
947 | ttm_bo_unreserve_ticket(bo, NULL); | ||
948 | } | ||
914 | 949 | ||
915 | /* | 950 | /* |
916 | * ttm_bo_util.c | 951 | * ttm_bo_util.c |