aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-02-04 08:18:06 -0500
committerJ. Bruce Fields <bfields@redhat.com>2013-02-04 17:19:13 -0500
commitb4e7f2c9450968303d24b48fec9da8abebcc0036 (patch)
treec3fd66317bf1df16cfd939bcf30e643d2146239f /fs
parentaca8a23de60c705e2458b2c6731ad59aa0717f83 (diff)
nfsd: register a shrinker for DRC cache entries
Since we dynamically allocate them now, allow the system to call us up to release them if it gets low on memory. Since these entries aren't replaceable, only free ones that are expired or that are over the cap. The the seeks value is set to '1' however to indicate that freeing the these entries is low-cost. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfscache.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c
index d7b088bee684..d16a5d6435f2 100644
--- a/fs/nfsd/nfscache.c
+++ b/fs/nfsd/nfscache.c
@@ -37,6 +37,13 @@ static inline u32 request_hash(u32 xid)
37 37
38static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec); 38static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
39static void cache_cleaner_func(struct work_struct *unused); 39static void cache_cleaner_func(struct work_struct *unused);
40static int nfsd_reply_cache_shrink(struct shrinker *shrink,
41 struct shrink_control *sc);
42
43struct shrinker nfsd_reply_cache_shrinker = {
44 .shrink = nfsd_reply_cache_shrink,
45 .seeks = 1,
46};
40 47
41/* 48/*
42 * locking for the reply cache: 49 * locking for the reply cache:
@@ -110,6 +117,7 @@ nfsd_reply_cache_free(struct svc_cacherep *rp)
110 117
111int nfsd_reply_cache_init(void) 118int nfsd_reply_cache_init(void)
112{ 119{
120 register_shrinker(&nfsd_reply_cache_shrinker);
113 drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep), 121 drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
114 0, 0, NULL); 122 0, 0, NULL);
115 if (!drc_slab) 123 if (!drc_slab)
@@ -133,6 +141,7 @@ void nfsd_reply_cache_shutdown(void)
133{ 141{
134 struct svc_cacherep *rp; 142 struct svc_cacherep *rp;
135 143
144 unregister_shrinker(&nfsd_reply_cache_shrinker);
136 cancel_delayed_work_sync(&cache_cleaner); 145 cancel_delayed_work_sync(&cache_cleaner);
137 146
138 while (!list_empty(&lru_head)) { 147 while (!list_empty(&lru_head)) {
@@ -214,6 +223,20 @@ cache_cleaner_func(struct work_struct *unused)
214 spin_unlock(&cache_lock); 223 spin_unlock(&cache_lock);
215} 224}
216 225
226static int
227nfsd_reply_cache_shrink(struct shrinker *shrink, struct shrink_control *sc)
228{
229 unsigned int num;
230
231 spin_lock(&cache_lock);
232 if (sc->nr_to_scan)
233 prune_cache_entries();
234 num = num_drc_entries;
235 spin_unlock(&cache_lock);
236
237 return num;
238}
239
217/* 240/*
218 * Search the request hash for an entry that matches the given rqstp. 241 * Search the request hash for an entry that matches the given rqstp.
219 * Must be called with cache_lock held. Returns the found entry or 242 * Must be called with cache_lock held. Returns the found entry or