Subversion Repositories Kolibri OS

Rev

Rev 3262 | Rev 4103 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3262 Rev 4065
Line 31... Line 31...
31
#define _TTM_BO_DRIVER_H_
31
#define _TTM_BO_DRIVER_H_
Line 32... Line 32...
32
 
32
 
33
#include 
33
#include 
34
#include 
34
#include 
-
 
35
#include 
35
#include 
36
#include 
36
#include 
37
#include 
37
#include 
38
#include 
38
//#include 
39
//#include 
39
//#include 
40
//#include 
Line -... Line 41...
-
 
41
#include 
-
 
42
 
40
#include 
43
struct ww_acquire_ctx;
41
 
44
 
42
struct ttm_backend_func {
45
struct ttm_backend_func {
43
	/**
46
	/**
44
	 * struct ttm_backend_func member bind
47
	 * struct ttm_backend_func member bind
Line 776... Line 779...
776
 * ttm_bo_reserve:
779
 * ttm_bo_reserve:
777
 *
780
 *
778
 * @bo: A pointer to a struct ttm_buffer_object.
781
 * @bo: A pointer to a struct ttm_buffer_object.
779
 * @interruptible: Sleep interruptible if waiting.
782
 * @interruptible: Sleep interruptible if waiting.
780
 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
783
 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
781
 * @use_sequence: If @bo is already reserved, Only sleep waiting for
784
 * @use_ticket: If @bo is already reserved, Only sleep waiting for
782
 * it to become unreserved if @sequence < (@bo)->sequence.
785
 * it to become unreserved if @ticket->stamp is older.
783
 *
786
 *
784
 * Locks a buffer object for validation. (Or prevents other processes from
787
 * Locks a buffer object for validation. (Or prevents other processes from
785
 * locking it for validation) and removes it from lru lists, while taking
788
 * locking it for validation) and removes it from lru lists, while taking
786
 * a number of measures to prevent deadlocks.
789
 * a number of measures to prevent deadlocks.
787
 *
790
 *
788
 * Deadlocks may occur when two processes try to reserve multiple buffers in
791
 * Deadlocks may occur when two processes try to reserve multiple buffers in
789
 * different order, either by will or as a result of a buffer being evicted
792
 * different order, either by will or as a result of a buffer being evicted
790
 * to make room for a buffer already reserved. (Buffers are reserved before
793
 * to make room for a buffer already reserved. (Buffers are reserved before
791
 * they are evicted). The following algorithm prevents such deadlocks from
794
 * they are evicted). The following algorithm prevents such deadlocks from
792
 * occurring:
795
 * occurring:
793
 * 1) Buffers are reserved with the lru spinlock held. Upon successful
-
 
794
 * reservation they are removed from the lru list. This stops a reserved buffer
-
 
795
 * from being evicted. However the lru spinlock is released between the time
-
 
796
 * a buffer is selected for eviction and the time it is reserved.
-
 
797
 * Therefore a check is made when a buffer is reserved for eviction, that it
-
 
798
 * is still the first buffer in the lru list, before it is removed from the
-
 
799
 * list. @check_lru == 1 forces this check. If it fails, the function returns
-
 
800
 * -EINVAL, and the caller should then choose a new buffer to evict and repeat
-
 
801
 * the procedure.
-
 
802
 * 2) Processes attempting to reserve multiple buffers other than for eviction,
796
 * Processes attempting to reserve multiple buffers other than for eviction,
803
 * (typically execbuf), should first obtain a unique 32-bit
797
 * (typically execbuf), should first obtain a unique 32-bit
804
 * validation sequence number,
798
 * validation sequence number,
805
 * and call this function with @use_sequence == 1 and @sequence == the unique
799
 * and call this function with @use_ticket == 1 and @ticket->stamp == the unique
806
 * sequence number. If upon call of this function, the buffer object is already
800
 * sequence number. If upon call of this function, the buffer object is already
807
 * reserved, the validation sequence is checked against the validation
801
 * reserved, the validation sequence is checked against the validation
808
 * sequence of the process currently reserving the buffer,
802
 * sequence of the process currently reserving the buffer,
809
 * and if the current validation sequence is greater than that of the process
803
 * and if the current validation sequence is greater than that of the process
810
 * holding the reservation, the function returns -EAGAIN. Otherwise it sleeps
804
 * holding the reservation, the function returns -EAGAIN. Otherwise it sleeps
Line 815... Line 809...
815
 * then rerun the validation with the same validation sequence. This procedure
809
 * then rerun the validation with the same validation sequence. This procedure
816
 * will always guarantee that the process with the lowest validation sequence
810
 * will always guarantee that the process with the lowest validation sequence
817
 * will eventually succeed, preventing both deadlocks and starvation.
811
 * will eventually succeed, preventing both deadlocks and starvation.
818
 *
812
 *
819
 * Returns:
813
 * Returns:
820
 * -EAGAIN: The reservation may cause a deadlock.
814
 * -EDEADLK: The reservation may cause a deadlock.
821
 * Release all buffer reservations, wait for @bo to become unreserved and
815
 * Release all buffer reservations, wait for @bo to become unreserved and
822
 * try again. (only if use_sequence == 1).
816
 * try again. (only if use_sequence == 1).
823
 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
817
 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
824
 * a signal. Release all buffer reservations and return to user-space.
818
 * a signal. Release all buffer reservations and return to user-space.
825
 * -EBUSY: The function needed to sleep, but @no_wait was true
819
 * -EBUSY: The function needed to sleep, but @no_wait was true
826
 * -EDEADLK: Bo already reserved using @sequence. This error code will only
820
 * -EALREADY: Bo already reserved using @ticket. This error code will only
827
 * be returned if @use_sequence is set to true.
821
 * be returned if @use_ticket is set to true.
828
 */
822
 */
829
extern int ttm_bo_reserve(struct ttm_buffer_object *bo,
823
static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
830
			  bool interruptible,
824
			  bool interruptible,
831
			  bool no_wait, bool use_sequence, uint32_t sequence);
825
				 bool no_wait, bool use_ticket,
-
 
826
				 struct ww_acquire_ctx *ticket)
-
 
827
{
-
 
828
	int ret;
-
 
829
 
-
 
830
	WARN_ON(!atomic_read(&bo->kref.refcount));
Line -... Line 831...
-
 
831
 
-
 
832
	ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket,
-
 
833
				    ticket);
-
 
834
	if (likely(ret == 0))
-
 
835
		ttm_bo_del_sub_from_lru(bo);
-
 
836
 
-
 
837
	return ret;
Line 832... Line 838...
832
 
838
}
833
 
839
 
834
/**
-
 
835
 * ttm_bo_reserve_locked:
840
/**
836
 *
841
 * ttm_bo_reserve_slowpath:
837
 * @bo: A pointer to a struct ttm_buffer_object.
-
 
838
 * @interruptible: Sleep interruptible if waiting.
842
 * @bo: A pointer to a struct ttm_buffer_object.
839
 * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
-
 
840
 * @use_sequence: If @bo is already reserved, Only sleep waiting for
-
 
841
 * it to become unreserved if @sequence < (@bo)->sequence.
-
 
842
 *
-
 
843
 * Must be called with struct ttm_bo_global::lru_lock held,
-
 
844
 * and will not remove reserved buffers from the lru lists.
-
 
845
 * The function may release the LRU spinlock if it needs to sleep.
843
 * @interruptible: Sleep interruptible if waiting.
846
 * Otherwise identical to ttm_bo_reserve.
-
 
847
 *
844
 * @sequence: Set (@bo)->sequence to this value after lock
848
 * Returns:
845
 *
849
 * -EAGAIN: The reservation may cause a deadlock.
-
 
850
 * Release all buffer reservations, wait for @bo to become unreserved and
-
 
851
 * try again. (only if use_sequence == 1).
-
 
852
 * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
-
 
853
 * a signal. Release all buffer reservations and return to user-space.
-
 
854
 * -EBUSY: The function needed to sleep, but @no_wait was true
846
 * This is called after ttm_bo_reserve returns -EAGAIN and we backed off
855
 * -EDEADLK: Bo already reserved using @sequence. This error code will only
847
 * from all our other reservations. Because there are no other reservations
856
 * be returned if @use_sequence is set to true.
848
 * held by us, this function cannot deadlock any more.
857
 */
849
 */
858
extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
850
static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
-
 
851
				 bool interruptible,
859
				 bool interruptible,
852
					  struct ww_acquire_ctx *ticket)
Line -... Line 853...
-
 
853
{
860
				 bool no_wait, bool use_sequence,
854
	int ret = 0;
861
				 uint32_t sequence);
855
 
-
 
856
	WARN_ON(!atomic_read(&bo->kref.refcount));
-
 
857
 
862
 
858
	if (interruptible)
863
/**
859
		ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
864
 * ttm_bo_unreserve
860
						       ticket);
-
 
861
	else
-
 
862
		ww_mutex_lock_slow(&bo->resv->lock, ticket);
865
 *
863
 
-
 
864
	if (likely(ret == 0))
866
 * @bo: A pointer to a struct ttm_buffer_object.
865
		ttm_bo_del_sub_from_lru(bo);
867
 *
866
	else if (ret == -EINTR)
-
 
867
		ret = -ERESTARTSYS;
Line 868... Line 868...
868
 * Unreserve a previous reservation of @bo.
868
 
869
 */
869
	return ret;
870
extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
-
 
871
 
870
}
-
 
871
 
872
/**
872
/**
873
 * ttm_bo_unreserve_locked
873
 * ttm_bo_unreserve_ticket
874
 *
-
 
875
 * @bo: A pointer to a struct ttm_buffer_object.
874
 * @bo: A pointer to a struct ttm_buffer_object.
876
 *
875
 * @ticket: ww_acquire_ctx used for reserving
-
 
876
 *
-
 
877
 * Unreserve a previous reservation of @bo made with @ticket.
-
 
878
 */
-
 
879
static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
-
 
880
					   struct ww_acquire_ctx *t)
-
 
881
{
-
 
882
	if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
-
 
883
		spin_lock(&bo->glob->lru_lock);
-
 
884
		ttm_bo_add_to_lru(bo);
Line 877... Line 885...
877
 * Unreserve a previous reservation of @bo.
885
		spin_unlock(&bo->glob->lru_lock);
878
 * Needs to be called with struct ttm_bo_global::lru_lock held.
886
	}
879
 */
887
	ww_mutex_unlock(&bo->resv->lock);
880
extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo);
888
}
881
 
889
 
882
/**
-
 
883
 * ttm_bo_wait_unreserved
-
 
884
 *
890
/**
885
 * @bo: A pointer to a struct ttm_buffer_object.
891
 * ttm_bo_unreserve
886
 *
892
 *
-
 
893
 * @bo: A pointer to a struct ttm_buffer_object.
887
 * Wait for a struct ttm_buffer_object to become unreserved.
894
 *
-
 
895
 * Unreserve a previous reservation of @bo.
Line 888... Line 896...
888
 * This is typically used in the execbuf code to relax cpu-usage when
896
 */
889
 * a potential deadlock condition backoff.
897
static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo)
890
 */
898
{
Line -... Line 899...
-
 
899
	ttm_bo_unreserve_ticket(bo, NULL);
-
 
900
}
-
 
901
 
-
 
902
/*
891
extern int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo,
903
 * ttm_bo_util.c
892
				  bool interruptible);
904
 */
893
 
905
 
894
/*
906
int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
895
 * ttm_bo_util.c
907
		       struct ttm_mem_reg *mem);