@@ -724,64 +724,36 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
724
724
return ret ;
725
725
}
726
726
727
- /*
728
- * Repeatedly evict memory from the LRU for @mem_type until we create enough
729
- * space, or we've evicted everything and there isn't enough space.
730
- */
731
- static int ttm_bo_mem_force_space (struct ttm_buffer_object * bo ,
732
- const struct ttm_place * place ,
733
- struct ttm_resource * * mem ,
734
- struct ttm_operation_ctx * ctx )
735
- {
736
- struct ttm_device * bdev = bo -> bdev ;
737
- struct ttm_resource_manager * man ;
738
- struct ww_acquire_ctx * ticket ;
739
- int ret ;
740
-
741
- man = ttm_manager_type (bdev , place -> mem_type );
742
- ticket = dma_resv_locking_ctx (bo -> base .resv );
743
- do {
744
- ret = ttm_resource_alloc (bo , place , mem );
745
- if (likely (!ret ))
746
- break ;
747
- if (unlikely (ret != - ENOSPC ))
748
- return ret ;
749
- ret = ttm_mem_evict_first (bdev , man , place , ctx ,
750
- ticket );
751
- if (unlikely (ret != 0 ))
752
- return ret ;
753
- } while (1 );
754
-
755
- return ttm_bo_add_move_fence (bo , man , * mem , ctx -> no_wait_gpu );
756
- }
757
-
758
727
/**
759
- * ttm_bo_mem_space
728
+ * ttm_bo_alloc_resource - Allocate backing store for a BO
760
729
*
761
- * @bo: Pointer to a struct ttm_buffer_object. the data of which
762
- * we want to allocate space for.
763
- * @placement: Proposed new placement for the buffer object.
764
- * @mem: A struct ttm_resource.
730
+ * @bo: Pointer to a struct ttm_buffer_object of which we want a resource for
731
+ * @placement: Proposed new placement for the buffer object
765
732
* @ctx: if and how to sleep, lock buffers and alloc memory
733
+ * @force_space: If we should evict buffers to force space
734
+ * @res: The resulting struct ttm_resource.
766
735
*
767
- * Allocate memory space for the buffer object pointed to by @bo, using
768
- * the placement flags in @placement, potentially evicting other idle buffer objects.
769
- * This function may sleep while waiting for space to become available.
736
+ * Allocates a resource for the buffer object pointed to by @bo, using the
737
+ * placement flags in @placement, potentially evicting other buffer objects when
738
+ * @force_space is true.
739
+ * This function may sleep while waiting for resources to become available.
770
740
* Returns:
771
- * -EBUSY: No space available (only if no_wait == 1 ).
741
+ * -EBUSY: No space available (only if no_wait == true ).
772
742
* -ENOSPC: Could not allocate space for the buffer object, either due to
773
743
* fragmentation or concurrent allocators.
774
744
* -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
775
745
*/
776
- int ttm_bo_mem_space (struct ttm_buffer_object * bo ,
777
- struct ttm_placement * placement ,
778
- struct ttm_resource * * mem ,
779
- struct ttm_operation_ctx * ctx )
746
+ static int ttm_bo_alloc_resource (struct ttm_buffer_object * bo ,
747
+ struct ttm_placement * placement ,
748
+ struct ttm_operation_ctx * ctx ,
749
+ bool force_space ,
750
+ struct ttm_resource * * res )
780
751
{
781
752
struct ttm_device * bdev = bo -> bdev ;
782
- bool type_found = false ;
753
+ struct ww_acquire_ctx * ticket ;
783
754
int i , ret ;
784
755
756
+ ticket = dma_resv_locking_ctx (bo -> base .resv );
785
757
ret = dma_resv_reserve_fences (bo -> base .resv , 1 );
786
758
if (unlikely (ret ))
787
759
return ret ;
@@ -790,98 +762,73 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
790
762
const struct ttm_place * place = & placement -> placement [i ];
791
763
struct ttm_resource_manager * man ;
792
764
793
- if (place -> flags & TTM_PL_FLAG_FALLBACK )
794
- continue ;
795
-
796
765
man = ttm_manager_type (bdev , place -> mem_type );
797
766
if (!man || !ttm_resource_manager_used (man ))
798
767
continue ;
799
768
800
- type_found = true;
801
- ret = ttm_resource_alloc (bo , place , mem );
802
- if (ret == - ENOSPC )
769
+ if (place -> flags & (force_space ? TTM_PL_FLAG_DESIRED :
770
+ TTM_PL_FLAG_FALLBACK ))
771
+ continue ;
772
+
773
+ do {
774
+ ret = ttm_resource_alloc (bo , place , res );
775
+ if (unlikely (ret && ret != - ENOSPC ))
776
+ return ret ;
777
+ if (likely (!ret ) || !force_space )
778
+ break ;
779
+
780
+ ret = ttm_mem_evict_first (bdev , man , place , ctx ,
781
+ ticket );
782
+ if (unlikely (ret == - EBUSY ))
783
+ break ;
784
+ if (unlikely (ret ))
785
+ return ret ;
786
+ } while (1 );
787
+ if (ret )
803
788
continue ;
804
- if (unlikely (ret ))
805
- goto error ;
806
789
807
- ret = ttm_bo_add_move_fence (bo , man , * mem , ctx -> no_wait_gpu );
790
+ ret = ttm_bo_add_move_fence (bo , man , * res , ctx -> no_wait_gpu );
808
791
if (unlikely (ret )) {
809
- ttm_resource_free (bo , mem );
792
+ ttm_resource_free (bo , res );
810
793
if (ret == - EBUSY )
811
794
continue ;
812
795
813
- goto error ;
796
+ return ret ;
814
797
}
815
798
return 0 ;
816
799
}
817
800
818
- for (i = 0 ; i < placement -> num_placement ; ++ i ) {
819
- const struct ttm_place * place = & placement -> placement [i ];
820
- struct ttm_resource_manager * man ;
821
-
822
- if (place -> flags & TTM_PL_FLAG_DESIRED )
823
- continue ;
824
-
825
- man = ttm_manager_type (bdev , place -> mem_type );
826
- if (!man || !ttm_resource_manager_used (man ))
827
- continue ;
828
-
829
- type_found = true;
830
- ret = ttm_bo_mem_force_space (bo , place , mem , ctx );
831
- if (likely (!ret ))
832
- return 0 ;
833
-
834
- if (ret && ret != - EBUSY )
835
- goto error ;
836
- }
837
-
838
- ret = - ENOSPC ;
839
- if (!type_found ) {
840
- pr_err (TTM_PFX "No compatible memory type found\n" );
841
- ret = - EINVAL ;
842
- }
843
-
844
- error :
845
- return ret ;
801
+ return - ENOSPC ;
846
802
}
847
- EXPORT_SYMBOL (ttm_bo_mem_space );
848
803
849
- static int ttm_bo_move_buffer (struct ttm_buffer_object * bo ,
850
- struct ttm_placement * placement ,
851
- struct ttm_operation_ctx * ctx )
804
+ /*
805
+ * ttm_bo_mem_space - Wrapper around ttm_bo_alloc_resource
806
+ *
807
+ * @bo: Pointer to a struct ttm_buffer_object of which we want a resource for
808
+ * @placement: Proposed new placement for the buffer object
809
+ * @res: The resulting struct ttm_resource.
810
+ * @ctx: if and how to sleep, lock buffers and alloc memory
811
+ *
812
+ * Tries both idle allocation and forcefully eviction of buffers. See
813
+ * ttm_bo_alloc_resource for details.
814
+ */
815
+ int ttm_bo_mem_space (struct ttm_buffer_object * bo ,
816
+ struct ttm_placement * placement ,
817
+ struct ttm_resource * * res ,
818
+ struct ttm_operation_ctx * ctx )
852
819
{
853
- struct ttm_resource * mem ;
854
- struct ttm_place hop ;
820
+ bool force_space = false;
855
821
int ret ;
856
822
857
- dma_resv_assert_held (bo -> base .resv );
823
+ do {
824
+ ret = ttm_bo_alloc_resource (bo , placement , ctx ,
825
+ force_space , res );
826
+ force_space = !force_space ;
827
+ } while (ret == - ENOSPC && force_space );
858
828
859
- /*
860
- * Determine where to move the buffer.
861
- *
862
- * If driver determines move is going to need
863
- * an extra step then it will return -EMULTIHOP
864
- * and the buffer will be moved to the temporary
865
- * stop and the driver will be called to make
866
- * the second hop.
867
- */
868
- ret = ttm_bo_mem_space (bo , placement , & mem , ctx );
869
- if (ret )
870
- return ret ;
871
- bounce :
872
- ret = ttm_bo_handle_move_mem (bo , mem , false, ctx , & hop );
873
- if (ret == - EMULTIHOP ) {
874
- ret = ttm_bo_bounce_temp_buffer (bo , & mem , ctx , & hop );
875
- if (ret )
876
- goto out ;
877
- /* try and move to final place now. */
878
- goto bounce ;
879
- }
880
- out :
881
- if (ret )
882
- ttm_resource_free (bo , & mem );
883
829
return ret ;
884
830
}
831
+ EXPORT_SYMBOL (ttm_bo_mem_space );
885
832
886
833
/**
887
834
* ttm_bo_validate
@@ -902,6 +849,9 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
902
849
struct ttm_placement * placement ,
903
850
struct ttm_operation_ctx * ctx )
904
851
{
852
+ struct ttm_resource * res ;
853
+ struct ttm_place hop ;
854
+ bool force_space ;
905
855
int ret ;
906
856
907
857
dma_resv_assert_held (bo -> base .resv );
@@ -912,20 +862,53 @@ int ttm_bo_validate(struct ttm_buffer_object *bo,
912
862
if (!placement -> num_placement )
913
863
return ttm_bo_pipeline_gutting (bo );
914
864
915
- /* Check whether we need to move buffer. */
916
- if (bo -> resource && ttm_resource_compatible (bo -> resource , placement ))
917
- return 0 ;
865
+ force_space = false;
866
+ do {
867
+ /* Check whether we need to move buffer. */
868
+ if (bo -> resource &&
869
+ ttm_resource_compatible (bo -> resource , placement ,
870
+ force_space ))
871
+ return 0 ;
918
872
919
- /* Moving of pinned BOs is forbidden */
920
- if (bo -> pin_count )
921
- return - EINVAL ;
873
+ /* Moving of pinned BOs is forbidden */
874
+ if (bo -> pin_count )
875
+ return - EINVAL ;
876
+
877
+ /*
878
+ * Determine where to move the buffer.
879
+ *
880
+ * If driver determines move is going to need
881
+ * an extra step then it will return -EMULTIHOP
882
+ * and the buffer will be moved to the temporary
883
+ * stop and the driver will be called to make
884
+ * the second hop.
885
+ */
886
+ ret = ttm_bo_alloc_resource (bo , placement , ctx , force_space ,
887
+ & res );
888
+ force_space = !force_space ;
889
+ if (ret == - ENOSPC )
890
+ continue ;
891
+ if (ret )
892
+ return ret ;
893
+
894
+ bounce :
895
+ ret = ttm_bo_handle_move_mem (bo , res , false, ctx , & hop );
896
+ if (ret == - EMULTIHOP ) {
897
+ ret = ttm_bo_bounce_temp_buffer (bo , & res , ctx , & hop );
898
+ /* try and move to final place now. */
899
+ if (!ret )
900
+ goto bounce ;
901
+ }
902
+ if (ret ) {
903
+ ttm_resource_free (bo , & res );
904
+ return ret ;
905
+ }
906
+
907
+ } while (ret && force_space );
922
908
923
- ret = ttm_bo_move_buffer (bo , placement , ctx );
924
909
/* For backward compatibility with userspace */
925
910
if (ret == - ENOSPC )
926
911
return - ENOMEM ;
927
- if (ret )
928
- return ret ;
929
912
930
913
/*
931
914
* We might need to add a TTM.
0 commit comments