summary refs log tree commit diff
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-20 14:22:41 -0700
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-20 14:22:41 -0700
commit4e51336a00bdcb42960acca52c23e90e9f4e6959 (patch)
tree87d619bcd796a0c272abe2499bcc56bc3eda30b4 /fs/nfs/nfs4state.c
parenta0857d03b21fa54653c9d2fe7a315381176015b4 (diff)
downloadlinux-4e51336a00bdcb42960acca52c23e90e9f4e6959.tar.gz
NFSv4: Final tweak to sequence id
 Sacrifice queueing fairness for performance.

 Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index da0861db57fb..c59ef90e956b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -670,15 +670,12 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
 
 struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
 {
-	struct rpc_sequence *sequence = counter->sequence;
 	struct nfs_seqid *new;
 
 	new = kmalloc(sizeof(*new), GFP_KERNEL);
 	if (new != NULL) {
 		new->sequence = counter;
-		spin_lock(&sequence->lock);
-		list_add_tail(&new->list, &sequence->list);
-		spin_unlock(&sequence->lock);
+		INIT_LIST_HEAD(&new->list);
 	}
 	return new;
 }
@@ -687,10 +684,12 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
 {
 	struct rpc_sequence *sequence = seqid->sequence->sequence;
 
-	spin_lock(&sequence->lock);
-	list_del(&seqid->list);
-	rpc_wake_up(&sequence->wait);
-	spin_unlock(&sequence->lock);
+	if (!list_empty(&seqid->list)) {
+		spin_lock(&sequence->lock);
+		list_del(&seqid->list);
+		spin_unlock(&sequence->lock);
+	}
+	rpc_wake_up_next(&sequence->wait);
 	kfree(seqid);
 }
 
@@ -746,12 +745,16 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
 	struct rpc_sequence *sequence = seqid->sequence->sequence;
 	int status = 0;
 
+	if (sequence->list.next == &seqid->list)
+		goto out;
 	spin_lock(&sequence->lock);
-	if (sequence->list.next != &seqid->list) {
+	if (!list_empty(&sequence->list)) {
 		rpc_sleep_on(&sequence->wait, task, NULL, NULL);
 		status = -EAGAIN;
-	}
+	} else
+		list_add(&seqid->list, &sequence->list);
 	spin_unlock(&sequence->lock);
+out:
 	return status;
 }