Skip to content

Commit

Permalink
nfsd: rip out the raparms cache
Browse files Browse the repository at this point in the history
The raparms cache was set up in order to ensure that we carry readahead
information forward from one RPC call to the next. In other words, it
was set up because each RPC call was forced to open a struct file, then
close it, causing the loss of readahead information that is normally
cached in that struct file, and used to keep the page cache filled when
a user calls read() multiple times on the same file descriptor.

Now that we cache the struct file, and reuse it for all the I/O calls
to a given file by a given user, we no longer have to keep a separate
readahead cache.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
  • Loading branch information
Jeff Layton authored and J. Bruce Fields committed Aug 19, 2019
1 parent 6b556ca commit 501cb18
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 167 deletions.
13 changes: 1 addition & 12 deletions fs/nfsd/nfssvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,22 +317,12 @@ static int nfsd_startup_generic(int nrservs)
ret = nfsd_file_cache_init();
if (ret)
goto dec_users;
/*
* Readahead param cache - will no-op if it already exists.
* (Note therefore results will be suboptimal if number of
* threads is modified after nfsd start.)
*/
ret = nfsd_racache_init(2*nrservs);
if (ret)
goto out_file_cache;

ret = nfs4_state_start();
if (ret)
goto out_racache;
goto out_file_cache;
return 0;

out_racache:
nfsd_racache_shutdown();
out_file_cache:
nfsd_file_cache_shutdown();
dec_users:
Expand All @@ -347,7 +337,6 @@ static void nfsd_shutdown_generic(void)

nfs4_state_shutdown();
nfsd_file_cache_shutdown();
nfsd_racache_shutdown();
}

static bool nfsd_needs_lockd(struct nfsd_net *nn)
Expand Down
149 changes: 0 additions & 149 deletions fs/nfsd/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,34 +49,6 @@

#define NFSDDBG_FACILITY NFSDDBG_FILEOP


/*
* This is a cache of readahead params that help us choose the proper
* readahead strategy. Initially, we set all readahead parameters to 0
* and let the VFS handle things.
* If you increase the number of cached files very much, you'll need to
* add a hash table here.
*/
struct raparms {
struct raparms *p_next;
unsigned int p_count;
ino_t p_ino;
dev_t p_dev;
int p_set;
struct file_ra_state p_ra;
unsigned int p_hindex;
};

struct raparm_hbucket {
struct raparms *pb_head;
spinlock_t pb_lock;
} ____cacheline_aligned_in_smp;

#define RAPARM_HASH_BITS 4
#define RAPARM_HASH_SIZE (1<<RAPARM_HASH_BITS)
#define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1)
static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE];

/*
* Called from nfsd_lookup and encode_dirent. Check if we have crossed
* a mount point.
Expand Down Expand Up @@ -822,67 +794,6 @@ nfsd_open_verified(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
return err;
}



struct raparms *
nfsd_init_raparms(struct file *file)
{
struct inode *inode = file_inode(file);
dev_t dev = inode->i_sb->s_dev;
ino_t ino = inode->i_ino;
struct raparms *ra, **rap, **frap = NULL;
int depth = 0;
unsigned int hash;
struct raparm_hbucket *rab;

hash = jhash_2words(dev, ino, 0xfeedbeef) & RAPARM_HASH_MASK;
rab = &raparm_hash[hash];

spin_lock(&rab->pb_lock);
for (rap = &rab->pb_head; (ra = *rap); rap = &ra->p_next) {
if (ra->p_ino == ino && ra->p_dev == dev)
goto found;
depth++;
if (ra->p_count == 0)
frap = rap;
}
depth = nfsdstats.ra_size;
if (!frap) {
spin_unlock(&rab->pb_lock);
return NULL;
}
rap = frap;
ra = *frap;
ra->p_dev = dev;
ra->p_ino = ino;
ra->p_set = 0;
ra->p_hindex = hash;
found:
if (rap != &rab->pb_head) {
*rap = ra->p_next;
ra->p_next = rab->pb_head;
rab->pb_head = ra;
}
ra->p_count++;
nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
spin_unlock(&rab->pb_lock);

if (ra->p_set)
file->f_ra = ra->p_ra;
return ra;
}

void nfsd_put_raparams(struct file *file, struct raparms *ra)
{
struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];

spin_lock(&rab->pb_lock);
ra->p_ra = file->f_ra;
ra->p_set = 1;
ra->p_count--;
spin_unlock(&rab->pb_lock);
}

/*
* Grab and keep cached pages associated with a file in the svc_rqst
* so that they can be passed to the network sendmsg/sendpage routines
Expand Down Expand Up @@ -2094,63 +2005,3 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,

return err? nfserrno(err) : 0;
}

void
nfsd_racache_shutdown(void)
{
struct raparms *raparm, *last_raparm;
unsigned int i;

dprintk("nfsd: freeing readahead buffers.\n");

for (i = 0; i < RAPARM_HASH_SIZE; i++) {
raparm = raparm_hash[i].pb_head;
while(raparm) {
last_raparm = raparm;
raparm = raparm->p_next;
kfree(last_raparm);
}
raparm_hash[i].pb_head = NULL;
}
}
/*
* Initialize readahead param cache
*/
int
nfsd_racache_init(int cache_size)
{
int i;
int j = 0;
int nperbucket;
struct raparms **raparm = NULL;


if (raparm_hash[0].pb_head)
return 0;
nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
nperbucket = max(2, nperbucket);
cache_size = nperbucket * RAPARM_HASH_SIZE;

dprintk("nfsd: allocating %d readahead buffers.\n", cache_size);

for (i = 0; i < RAPARM_HASH_SIZE; i++) {
spin_lock_init(&raparm_hash[i].pb_lock);

raparm = &raparm_hash[i].pb_head;
for (j = 0; j < nperbucket; j++) {
*raparm = kzalloc(sizeof(struct raparms), GFP_KERNEL);
if (!*raparm)
goto out_nomem;
raparm = &(*raparm)->p_next;
}
*raparm = NULL;
}

nfsdstats.ra_size = cache_size;
return 0;

out_nomem:
dprintk("nfsd: kmalloc failed, freeing readahead buffers\n");
nfsd_racache_shutdown();
return -ENOMEM;
}
6 changes: 0 additions & 6 deletions fs/nfsd/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
typedef int (*nfsd_filldir_t)(void *, const char *, int, loff_t, u64, unsigned);

/* nfsd/vfs.c */
int nfsd_racache_init(int);
void nfsd_racache_shutdown(void);
int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
struct svc_export **expp);
__be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *,
Expand Down Expand Up @@ -80,7 +78,6 @@ __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
int, struct file **);
__be32 nfsd_open_verified(struct svc_rqst *, struct svc_fh *, umode_t,
int, struct file **);
struct raparms;
__be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct file *file, loff_t offset,
unsigned long *count);
Expand Down Expand Up @@ -118,9 +115,6 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
struct dentry *, int);

struct raparms *nfsd_init_raparms(struct file *file);
void nfsd_put_raparams(struct file *file, struct raparms *ra);

static inline int fh_want_write(struct svc_fh *fh)
{
int ret;
Expand Down

0 comments on commit 501cb18

Please sign in to comment.