Skip to content

Commit

Permalink
Return number of object freed in the generic shrinker
Browse files Browse the repository at this point in the history
According to the comments in the kernel's shrinker.h file, the
scan_objects callback should return the number of objects actually
freed.  Previously, the shrinker returned the number of objects
which were _attempted_ to be freed.  It also didn't cap the freeing
at nr_to_scan.  If the value returned is too high, callers may retry
shrinking indefinitely.
  • Loading branch information
dweeezil committed Oct 2, 2014
1 parent e302072 commit efbda78
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions module/spl/spl-kmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ MODULE_PARM_DESC(spl_kmem_cache_expire, "By age (0x1) or low memory (0x2)");
* setting this value to KMC_RECLAIM_ONCE limits how aggressively the cache
* is reclaimed. This may increase the likelihood of out of memory events.
*/
unsigned int spl_kmem_cache_reclaim = 0;
unsigned int spl_kmem_cache_reclaim = 0 /* KMC_RECLAIM_ONCE */;
module_param(spl_kmem_cache_reclaim, uint, 0644);
MODULE_PARM_DESC(spl_kmem_cache_reclaim, "Single reclaim pass (0x1)");

Expand Down Expand Up @@ -2249,21 +2249,22 @@ __spl_kmem_cache_generic_shrinker(struct shrinker *shrink,
struct shrink_control *sc)
{
spl_kmem_cache_t *skc;
uint64_t oldalloc;
int alloc = 0;

down_read(&spl_kmem_cache_sem);
list_for_each_entry(skc, &spl_kmem_cache_list, skc_list) {
if (sc->nr_to_scan)
if (sc->nr_to_scan) {
oldalloc = skc->skc_obj_alloc;
spl_kmem_cache_reap_now(skc,
MAX(sc->nr_to_scan >> fls64(skc->skc_slab_objs), 1));

/*
* Presume everything alloc'ed is reclaimable, this ensures
* we are called again with nr_to_scan > 0 so can try and
* reclaim. The exact number is not important either so
* we forgo taking this already highly contented lock.
*/
alloc += skc->skc_obj_alloc;
if (oldalloc > skc->skc_obj_alloc)
alloc += oldalloc - skc->skc_obj_alloc;
} else {
alloc += skc->skc_obj_alloc;
}
if (alloc >= sc->nr_to_scan)
break;
}
up_read(&spl_kmem_cache_sem);

Expand All @@ -2273,7 +2274,7 @@ __spl_kmem_cache_generic_shrinker(struct shrinker *shrink,
* shrink_slabs() is repeatedly invoked by many cores causing the
* system to thrash.
*/
if ((spl_kmem_cache_reclaim & KMC_RECLAIM_ONCE) && sc->nr_to_scan)
if ((spl_kmem_cache_reclaim & KMC_RECLAIM_ONCE))
return (-1);

return MAX((alloc * sysctl_vfs_cache_pressure) / 100, 0);
Expand Down

0 comments on commit efbda78

Please sign in to comment.