]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
nfsd: Only set PF_LESS_THROTTLE when really needed.
authorNeilBrown <neilb@suse.de>
Mon, 12 May 2014 01:22:47 +0000 (11:22 +1000)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 22 May 2014 19:59:19 +0000 (15:59 -0400)
PF_LESS_THROTTLE has a very specific use case: to avoid deadlocks
and live-locks while writing to the page cache in a loop-back
NFS mount situation.

It therefore makes sense to *only* set PF_LESS_THROTTLE in this
situation.
We now know when a request came from the local-host so it could be a
loop-back mount.  We already know when we are handling write requests,
and when we are doing anything else.

So combine those two to allow nfsd to still be throttled (like any
other process) in every situation except when it is known to be
problematic.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfssvc.c
fs/nfsd/vfs.c

index 9a4a5f9e7468748f7195ac92f86d7317c83e0822..1879e43f2868c7ffbf21405f41412d2f540f19f7 100644 (file)
@@ -591,12 +591,6 @@ nfsd(void *vrqstp)
        nfsdstats.th_cnt++;
        mutex_unlock(&nfsd_mutex);
 
-       /*
-        * We want less throttling in balance_dirty_pages() so that nfs to
-        * localhost doesn't cause nfsd to lock up due to all the client's
-        * dirty pages.
-        */
-       current->flags |= PF_LESS_THROTTLE;
        set_freezable();
 
        /*
index 6aaa3057683a2271aff077c709e46dee5b0f65a3..3aa38523b6d786dee03b80e4f88a63dad7a857fd 100644 (file)
@@ -908,6 +908,16 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     stable = *stablep;
        int                     use_wgather;
        loff_t                  pos = offset;
+       unsigned int            pflags = current->flags;
+
+       if (rqstp->rq_local)
+               /*
+                * We want less throttling in balance_dirty_pages()
+                * and shrink_inactive_list() so that nfs to
+                * localhost doesn't cause nfsd to lock up due to all
+                * the client's dirty pages or its congested queue.
+                */
+               current->flags |= PF_LESS_THROTTLE;
 
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
@@ -941,6 +951,8 @@ out_nfserr:
                err = 0;
        else
                err = nfserrno(host_err);
+       if (rqstp->rq_local)
+               tsk_restore_flags(current, pflags, PF_LESS_THROTTLE);
        return err;
 }