diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_shrinker.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem_shrinker.c | 11 | 
1 files changed, 9 insertions, 2 deletions
| diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c index 051bdbc093cf..f38296ad8743 100644 --- a/drivers/gpu/drm/msm/msm_gem_shrinker.c +++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c @@ -107,6 +107,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)  		bool (*shrink)(struct drm_gem_object *obj);  		bool cond;  		unsigned long freed; +		unsigned long remaining;  	} stages[] = {  		/* Stages of progressively more aggressive/expensive reclaim: */  		{ &priv->lru.dontneed, purge,        true }, @@ -116,14 +117,18 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)  	};  	long nr = sc->nr_to_scan;  	unsigned long freed = 0; +	unsigned long remaining = 0;  	for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {  		if (!stages[i].cond)  			continue;  		stages[i].freed = -			drm_gem_lru_scan(stages[i].lru, nr, stages[i].shrink); +			drm_gem_lru_scan(stages[i].lru, nr, +					&stages[i].remaining, +					 stages[i].shrink);  		nr -= stages[i].freed;  		freed += stages[i].freed; +		remaining += stages[i].remaining;  	}  	if (freed) { @@ -132,7 +137,7 @@ msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)  				     stages[3].freed);  	} -	return (freed > 0) ? freed : SHRINK_STOP; +	return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP;  }  #ifdef CONFIG_DEBUG_FS @@ -182,10 +187,12 @@ msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr)  		NULL,  	};  	unsigned idx, unmapped = 0; +	unsigned long remaining = 0;  	for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {  		unmapped += drm_gem_lru_scan(lrus[idx],  					     vmap_shrink_limit - unmapped, +					     &remaining,  					     vmap_shrink);  	} |