@@ -489,6 +489,62 @@ int ttm_bo_evict_first(struct ttm_device *bdev, struct ttm_resource_manager *man
489489 return ret ;
490490}
491491
492+ struct ttm_bo_alloc_state {
493+ /** @limit_pool: Which pool limit we should test against */
494+ struct dmem_cgroup_pool_state * limit_pool ;
495+ };
496+
497+ /**
498+ * ttm_bo_alloc_at_place - Attempt allocating a BO's backing store in a place
499+ *
500+ * @bo: The buffer to allocate the backing store of
501+ * @place: The place to attempt allocation in
502+ * @ctx: ttm_operation_ctx associated with this allocation
503+ * @force_space: If we should evict buffers to force space
504+ * @res: On allocation success, the resulting struct ttm_resource.
505+ * @alloc_state: Object holding allocation state such as charged cgroups.
506+ *
507+ * Returns:
508+ * -EBUSY: No space available, but allocation should be retried with ttm_bo_evict_alloc.
509+ * -ENOSPC: No space available, allocation should not be retried.
510+ * -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
511+ *
512+ */
513+ static int ttm_bo_alloc_at_place (struct ttm_buffer_object * bo ,
514+ const struct ttm_place * place ,
515+ struct ttm_operation_ctx * ctx ,
516+ bool force_space ,
517+ struct ttm_resource * * res ,
518+ struct ttm_bo_alloc_state * alloc_state )
519+ {
520+ bool may_evict ;
521+ int ret ;
522+
523+ may_evict = force_space && place -> mem_type != TTM_PL_SYSTEM ;
524+
525+ ret = ttm_resource_alloc (bo , place , res ,
526+ force_space ? & alloc_state -> limit_pool : NULL );
527+
528+ if (ret ) {
529+ /*
530+ * -EAGAIN means the charge failed, which we treat like an
531+ * allocation failure. Therefore, return an error code indicating
532+ * the allocation failed - either -EBUSY if the allocation should
533+ * be retried with eviction, or -ENOSPC if there should be no second
534+ * attempt.
535+ */
536+ if (ret == - EAGAIN )
537+ return may_evict ? - EBUSY : - ENOSPC ;
538+
539+ if (ret == - ENOSPC && may_evict )
540+ return - EBUSY ;
541+
542+ return ret ;
543+ }
544+
545+ return 0 ;
546+ }
547+
492548/**
493549 * struct ttm_bo_evict_walk - Parameters for the evict walk.
494550 */
@@ -504,12 +560,13 @@ struct ttm_bo_evict_walk {
504560 /** @evicted: Number of successful evictions. */
505561 unsigned long evicted ;
506562
507- /** @limit_pool: Which pool limit we should test against */
508- struct dmem_cgroup_pool_state * limit_pool ;
509563 /** @try_low: Whether we should attempt to evict BO's with low watermark threshold */
510564 bool try_low ;
511565 /** @hit_low: If we cannot evict a bo when @try_low is false (first pass) */
512566 bool hit_low ;
567+
568+ /** @alloc_state: State associated with the allocation attempt. */
569+ struct ttm_bo_alloc_state * alloc_state ;
513570};
514571
515572static s64 ttm_bo_evict_cb (struct ttm_lru_walk * walk , struct ttm_buffer_object * bo )
@@ -518,8 +575,9 @@ static s64 ttm_bo_evict_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *
518575 container_of (walk , typeof (* evict_walk ), walk );
519576 s64 lret ;
520577
521- if (!dmem_cgroup_state_evict_valuable (evict_walk -> limit_pool , bo -> resource -> css ,
522- evict_walk -> try_low , & evict_walk -> hit_low ))
578+ if (!dmem_cgroup_state_evict_valuable (evict_walk -> alloc_state -> limit_pool ,
579+ bo -> resource -> css , evict_walk -> try_low ,
580+ & evict_walk -> hit_low ))
523581 return 0 ;
524582
525583 if (bo -> pin_count || !bo -> bdev -> funcs -> eviction_valuable (bo , evict_walk -> place ))
@@ -561,7 +619,7 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
561619 struct ttm_operation_ctx * ctx ,
562620 struct ww_acquire_ctx * ticket ,
563621 struct ttm_resource * * res ,
564- struct dmem_cgroup_pool_state * limit_pool )
622+ struct ttm_bo_alloc_state * state )
565623{
566624 struct ttm_bo_evict_walk evict_walk = {
567625 .walk = {
@@ -574,7 +632,7 @@ static int ttm_bo_evict_alloc(struct ttm_device *bdev,
574632 .place = place ,
575633 .evictor = evictor ,
576634 .res = res ,
577- .limit_pool = limit_pool ,
635+ .alloc_state = state ,
578636 };
579637 s64 lret ;
580638
@@ -725,9 +783,8 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
725783
726784 for (i = 0 ; i < placement -> num_placement ; ++ i ) {
727785 const struct ttm_place * place = & placement -> placement [i ];
728- struct dmem_cgroup_pool_state * limit_pool = NULL ;
786+ struct ttm_bo_alloc_state alloc_state = {} ;
729787 struct ttm_resource_manager * man ;
730- bool may_evict ;
731788
732789 man = ttm_manager_type (bdev , place -> mem_type );
733790 if (!man || !ttm_resource_manager_used (man ))
@@ -737,25 +794,25 @@ static int ttm_bo_alloc_resource(struct ttm_buffer_object *bo,
737794 TTM_PL_FLAG_FALLBACK ))
738795 continue ;
739796
740- may_evict = (force_space && place -> mem_type != TTM_PL_SYSTEM );
741- ret = ttm_resource_alloc (bo , place , res , force_space ? & limit_pool : NULL );
742- if (ret ) {
743- if (ret != - ENOSPC && ret != - EAGAIN ) {
744- dmem_cgroup_pool_state_put (limit_pool );
745- return ret ;
746- }
747- if (!may_evict ) {
748- dmem_cgroup_pool_state_put (limit_pool );
749- continue ;
750- }
797+ ret = ttm_bo_alloc_at_place (bo , place , ctx , force_space ,
798+ res , & alloc_state );
751799
800+ if (ret == - ENOSPC ) {
801+ dmem_cgroup_pool_state_put (alloc_state .limit_pool );
802+ continue ;
803+ } else if (ret == - EBUSY ) {
752804 ret = ttm_bo_evict_alloc (bdev , man , place , bo , ctx ,
753- ticket , res , limit_pool );
754- dmem_cgroup_pool_state_put (limit_pool );
805+ ticket , res , & alloc_state );
806+
807+ dmem_cgroup_pool_state_put (alloc_state .limit_pool );
808+
755809 if (ret == - EBUSY )
756810 continue ;
757- if (ret )
811+ else if (ret )
758812 return ret ;
813+ } else if (ret ) {
814+ dmem_cgroup_pool_state_put (alloc_state .limit_pool );
815+ return ret ;
759816 }
760817
761818 ret = ttm_bo_add_pipelined_eviction_fences (bo , man , ctx -> no_wait_gpu );
0 commit comments