/* * could be called frequently for query (@nr_to_scan == 0). * we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. */ static int enc_pools_shrink(int nr_to_scan, unsigned int gfp_mask) { if (unlikely(nr_to_scan != 0)) { cfs_spin_lock(&page_pools.epp_lock); nr_to_scan = min(nr_to_scan, (int) page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES); if (nr_to_scan > 0) { enc_pools_release_free_pages(nr_to_scan); CDEBUG(D_SEC, "released %d pages, %ld left\n", nr_to_scan, page_pools.epp_free_pages); page_pools.epp_st_shrinks++; page_pools.epp_last_shrink = cfs_time_current_sec(); } cfs_spin_unlock(&page_pools.epp_lock); } /* * if no pool access for a long time, we consider it's fully idle. * a little race here is fine. */ if (unlikely(cfs_time_current_sec() - page_pools.epp_last_access > CACHE_QUIESCENT_PERIOD)) { cfs_spin_lock(&page_pools.epp_lock); page_pools.epp_idle_idx = IDLE_IDX_MAX; cfs_spin_unlock(&page_pools.epp_lock); } LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); return max((int) page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES, 0) * (IDLE_IDX_MAX - page_pools.epp_idle_idx) / IDLE_IDX_MAX; }
/* * we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. */ static unsigned long enc_pools_shrink_scan(struct shrinker *s, struct shrink_control *sc) { spin_lock(&page_pools.epp_lock); sc->nr_to_scan = min_t(unsigned long, sc->nr_to_scan, page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES); if (sc->nr_to_scan > 0) { enc_pools_release_free_pages(sc->nr_to_scan); CDEBUG(D_SEC, "released %ld pages, %ld left\n", (long)sc->nr_to_scan, page_pools.epp_free_pages); page_pools.epp_st_shrinks++; page_pools.epp_last_shrink = ktime_get_seconds(); } spin_unlock(&page_pools.epp_lock); /* * if no pool access for a long time, we consider it's fully idle. * a little race here is fine. */ if (unlikely(ktime_get_seconds() - page_pools.epp_last_access > CACHE_QUIESCENT_PERIOD)) { spin_lock(&page_pools.epp_lock); page_pools.epp_idle_idx = IDLE_IDX_MAX; spin_unlock(&page_pools.epp_lock); } LASSERT(page_pools.epp_idle_idx <= IDLE_IDX_MAX); return sc->nr_to_scan; }
/* * could be called frequently for query (@nr_to_scan == 0). * we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. */ static int enc_pools_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) { if (unlikely(shrink_param(sc, nr_to_scan) != 0)) { spin_lock(&page_pools.epp_lock); shrink_param(sc, nr_to_scan) = min_t(unsigned long, shrink_param(sc, nr_to_scan), page_pools.epp_free_pages - PTLRPC_MAX_BRW_PAGES); if (shrink_param(sc, nr_to_scan) > 0) { enc_pools_release_free_pages(shrink_param(sc, nr_to_scan)); CDEBUG(D_SEC, "released %ld pages, %ld left\n", (long)shrink_param(sc, nr_to_scan), page_pools.epp_free_pages); page_pools.epp_st_shrinks++; page_pools.epp_last_shrink = cfs_time_current_sec(); } spin_unlock(&page_pools.epp_lock); }