NFSv4: Final tweak to sequence id
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 20 Oct 2005 21:22:41 +0000 (14:22 -0700)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 20 Oct 2005 21:22:41 +0000 (14:22 -0700)
 Sacrifice queueing fairness for performance.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/nfs4_fs.h
fs/nfs/nfs4state.c

index 45bff1d1a513c1521bf2843a98d7af5c0bc437df..5c0dd26d09855860c1cebfb4c4c5f3cc2d6d3191 100644 (file)
@@ -110,8 +110,8 @@ struct nfs_seqid_counter {
 };
 
 struct nfs_seqid {
-       struct list_head list;
        struct nfs_seqid_counter *sequence;
+       struct list_head list;
 };
 
 static inline void nfs_confirm_seqid(struct nfs_seqid_counter *seqid, int status)
index da0861db57fbc7fa7d040b876e98174ace13db7a..c59ef90e956b7840bf93a34abdfdd53550834e6a 100644 (file)
@@ -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;
 }