mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
Linux 3.12 compat: shrinker semantics
The new shrinker API as of Linux 3.12 modifies "struct shrinker" by replacing the @shrink callback with the pair of @count_objects and @scan_objects. It also requires the return value of @count_objects to return the number of objects actually freed whereas the previous @shrink callback returned the number of remaining freeable objects. This patch adds support for the new @scan_objects return value semantics. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tim Chase <tim@chase2k.com> Closes #2837
This commit is contained in:
parent
9635861742
commit
ed6e9cc235
@ -2604,27 +2604,39 @@ arc_evictable_memory(void) {
|
|||||||
return (ghost_clean + MAX((int64_t)arc_size - (int64_t)arc_c_min, 0));
|
return (ghost_clean + MAX((int64_t)arc_size - (int64_t)arc_c_min, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/*
|
||||||
|
* If sc->nr_to_scan is zero, the caller is requesting a query of the
|
||||||
|
* number of objects which can potentially be freed. If it is nonzero,
|
||||||
|
* the request is to free that many objects.
|
||||||
|
*
|
||||||
|
* Linux kernels >= 3.12 have the count_objects and scan_objects callbacks
|
||||||
|
* in struct shrinker and also require the shrinker to return the number
|
||||||
|
* of objects freed.
|
||||||
|
*
|
||||||
|
* Older kernels require the shrinker to return the number of freeable
|
||||||
|
* objects following the freeing of nr_to_free.
|
||||||
|
*/
|
||||||
|
static spl_shrinker_t
|
||||||
__arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc)
|
__arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc)
|
||||||
{
|
{
|
||||||
uint64_t pages;
|
int64_t pages;
|
||||||
|
|
||||||
/* The arc is considered warm once reclaim has occurred */
|
/* The arc is considered warm once reclaim has occurred */
|
||||||
if (unlikely(arc_warm == B_FALSE))
|
if (unlikely(arc_warm == B_FALSE))
|
||||||
arc_warm = B_TRUE;
|
arc_warm = B_TRUE;
|
||||||
|
|
||||||
/* Return the potential number of reclaimable pages */
|
/* Return the potential number of reclaimable pages */
|
||||||
pages = btop(arc_evictable_memory());
|
pages = btop((int64_t)arc_evictable_memory());
|
||||||
if (sc->nr_to_scan == 0)
|
if (sc->nr_to_scan == 0)
|
||||||
return (pages);
|
return (pages);
|
||||||
|
|
||||||
/* Not allowed to perform filesystem reclaim */
|
/* Not allowed to perform filesystem reclaim */
|
||||||
if (!(sc->gfp_mask & __GFP_FS))
|
if (!(sc->gfp_mask & __GFP_FS))
|
||||||
return (-1);
|
return (SHRINK_STOP);
|
||||||
|
|
||||||
/* Reclaim in progress */
|
/* Reclaim in progress */
|
||||||
if (mutex_tryenter(&arc_reclaim_thr_lock) == 0)
|
if (mutex_tryenter(&arc_reclaim_thr_lock) == 0)
|
||||||
return (-1);
|
return (SHRINK_STOP);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evict the requested number of pages by shrinking arc_c the
|
* Evict the requested number of pages by shrinking arc_c the
|
||||||
@ -2633,10 +2645,15 @@ __arc_shrinker_func(struct shrinker *shrink, struct shrink_control *sc)
|
|||||||
*/
|
*/
|
||||||
if (pages > 0) {
|
if (pages > 0) {
|
||||||
arc_kmem_reap_now(ARC_RECLAIM_AGGR, ptob(sc->nr_to_scan));
|
arc_kmem_reap_now(ARC_RECLAIM_AGGR, ptob(sc->nr_to_scan));
|
||||||
|
|
||||||
|
#ifdef HAVE_SPLIT_SHRINKER_CALLBACK
|
||||||
|
pages = MAX(pages - btop(arc_evictable_memory()), 0);
|
||||||
|
#else
|
||||||
pages = btop(arc_evictable_memory());
|
pages = btop(arc_evictable_memory());
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
arc_kmem_reap_now(ARC_RECLAIM_CONS, ptob(sc->nr_to_scan));
|
arc_kmem_reap_now(ARC_RECLAIM_CONS, ptob(sc->nr_to_scan));
|
||||||
pages = -1;
|
pages = SHRINK_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user