NFSv4: Final tweak to sequence id Sacrifice queueing fairness for performance. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4state.c | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) Index: linux-2.6/fs/nfs/nfs4state.c =================================================================== --- linux-2.6.orig/fs/nfs/nfs4state.c +++ linux-2.6/fs/nfs/nfs4state.c @@ -670,15 +670,12 @@ void nfs4_copy_stateid(nfs4_stateid *dst 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 *se { 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_seqi 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; } Index: linux-2.6/fs/nfs/nfs4_fs.h =================================================================== --- linux-2.6.orig/fs/nfs/nfs4_fs.h +++ linux-2.6/fs/nfs/nfs4_fs.h @@ -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)