Revert "Revert "drm/msm/gem: Prevent blocking within shrinker loop""
This reverts commit eb1f5e4656.
It was perserving the ABI, but that is not needed anymore at this point
in time.
Change-Id: I2f1ddf6bb64c0b7bc4a6b653d60cdd256820080d
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
0e07b5c674
commit
b21e700aa4
3 changed files with 19 additions and 5 deletions
|
|
@ -1351,10 +1351,13 @@ EXPORT_SYMBOL(drm_gem_lru_move_tail);
|
|||
*
|
||||
* @lru: The LRU to scan
|
||||
* @nr_to_scan: The number of pages to try to reclaim
|
||||
* @remaining: The number of pages left to reclaim, should be initialized by caller
|
||||
* @shrink: Callback to try to shrink/reclaim the object.
|
||||
*/
|
||||
unsigned long
|
||||
drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
|
||||
drm_gem_lru_scan(struct drm_gem_lru *lru,
|
||||
unsigned int nr_to_scan,
|
||||
unsigned long *remaining,
|
||||
bool (*shrink)(struct drm_gem_object *obj))
|
||||
{
|
||||
struct drm_gem_lru still_in_lru;
|
||||
|
|
@ -1393,8 +1396,10 @@ drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
|
|||
* hit shrinker in response to trying to get backing pages
|
||||
* for this obj (ie. while it's lock is already held)
|
||||
*/
|
||||
if (!dma_resv_trylock(obj->resv))
|
||||
if (!dma_resv_trylock(obj->resv)) {
|
||||
*remaining += obj->size >> PAGE_SHIFT;
|
||||
goto tail;
|
||||
}
|
||||
|
||||
if (shrink(obj)) {
|
||||
freed += obj->size >> PAGE_SHIFT;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -472,7 +472,9 @@ int drm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
|
|||
void drm_gem_lru_init(struct drm_gem_lru *lru, struct mutex *lock);
|
||||
void drm_gem_lru_remove(struct drm_gem_object *obj);
|
||||
void drm_gem_lru_move_tail(struct drm_gem_lru *lru, struct drm_gem_object *obj);
|
||||
unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru, unsigned nr_to_scan,
|
||||
unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
|
||||
unsigned int nr_to_scan,
|
||||
unsigned long *remaining,
|
||||
bool (*shrink)(struct drm_gem_object *obj));
|
||||
|
||||
#endif /* __DRM_GEM_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue