Commit 734f5929 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] PATCH 4/16: NFSD: BKL Removal: Locking in nfssvc.c

Tidy up locking in nfssvc - preparing for BKL removal

- nfsd_busy becomes atomic_t
- nfsd_call_lock created to protect timing of calls and stats gathering
- lock_kernel around thread creation and destruction.  It is
  sufficiently uncommon that it doesn't really need a lock of it's
  own.  It is currently under the BKL because all of the nfsservctl
  syscall is, but that is about to be removed so we preserve BKL here.
parent f90efd5a
...@@ -54,8 +54,9 @@ extern struct svc_program nfsd_program; ...@@ -54,8 +54,9 @@ extern struct svc_program nfsd_program;
static void nfsd(struct svc_rqst *rqstp); static void nfsd(struct svc_rqst *rqstp);
struct timeval nfssvc_boot; struct timeval nfssvc_boot;
static struct svc_serv *nfsd_serv; static struct svc_serv *nfsd_serv;
static int nfsd_busy; static atomic_t nfsd_busy;
static unsigned long nfsd_last_call; static unsigned long nfsd_last_call;
static spinlock_t nfsd_call_lock = SPIN_LOCK_UNLOCKED;
struct nfsd_list { struct nfsd_list {
struct list_head list; struct list_head list;
...@@ -74,7 +75,8 @@ nfsd_svc(unsigned short port, int nrservs) ...@@ -74,7 +75,8 @@ nfsd_svc(unsigned short port, int nrservs)
int error; int error;
int none_left; int none_left;
struct list_head *victim; struct list_head *victim;
lock_kernel();
dprintk("nfsd: creating service\n"); dprintk("nfsd: creating service\n");
error = -EINVAL; error = -EINVAL;
if (nrservs <= 0) if (nrservs <= 0)
...@@ -87,6 +89,7 @@ nfsd_svc(unsigned short port, int nrservs) ...@@ -87,6 +89,7 @@ nfsd_svc(unsigned short port, int nrservs)
if (error<0) if (error<0)
goto out; goto out;
if (!nfsd_serv) { if (!nfsd_serv) {
atomic_set(&nfsd_busy, 0);
nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE); nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE);
if (nfsd_serv == NULL) if (nfsd_serv == NULL)
goto out; goto out;
...@@ -125,6 +128,7 @@ nfsd_svc(unsigned short port, int nrservs) ...@@ -125,6 +128,7 @@ nfsd_svc(unsigned short port, int nrservs)
nfsd_racache_shutdown(); nfsd_racache_shutdown();
} }
out: out:
unlock_kernel();
return error; return error;
} }
...@@ -135,6 +139,7 @@ update_thread_usage(int busy_threads) ...@@ -135,6 +139,7 @@ update_thread_usage(int busy_threads)
unsigned long diff; unsigned long diff;
int decile; int decile;
spin_lock(&nfsd_call_lock);
prev_call = nfsd_last_call; prev_call = nfsd_last_call;
nfsd_last_call = jiffies; nfsd_last_call = jiffies;
decile = busy_threads*10/nfsdstats.th_cnt; decile = busy_threads*10/nfsdstats.th_cnt;
...@@ -145,6 +150,7 @@ update_thread_usage(int busy_threads) ...@@ -145,6 +150,7 @@ update_thread_usage(int busy_threads)
if (decile == 10) if (decile == 10)
nfsdstats.th_fullcnt++; nfsdstats.th_fullcnt++;
} }
spin_unlock(&nfsd_call_lock);
} }
/* /*
...@@ -192,8 +198,8 @@ nfsd(struct svc_rqst *rqstp) ...@@ -192,8 +198,8 @@ nfsd(struct svc_rqst *rqstp)
; ;
if (err < 0) if (err < 0)
break; break;
update_thread_usage(nfsd_busy); update_thread_usage(atomic_read(&nfsd_busy));
nfsd_busy++; atomic_inc(&nfsd_busy);
/* Lock the export hash tables for reading. */ /* Lock the export hash tables for reading. */
exp_readlock(); exp_readlock();
...@@ -212,8 +218,8 @@ nfsd(struct svc_rqst *rqstp) ...@@ -212,8 +218,8 @@ nfsd(struct svc_rqst *rqstp)
/* Unlock export hash tables */ /* Unlock export hash tables */
exp_readunlock(); exp_readunlock();
update_thread_usage(nfsd_busy); update_thread_usage(atomic_read(&nfsd_busy));
nfsd_busy--; atomic_dec(&nfsd_busy);
} }
if (err != -EINTR) { if (err != -EINTR) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment