From: Trond Myklebust This patch makes the sunrpc XID identifier a per-transport socket variable. Allows us to eliminate the global spinlock Olaf introduced... --- include/linux/sunrpc/xprt.h | 6 +++++- net/sunrpc/xprt.c | 27 +++++++++++---------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff -puN include/linux/sunrpc/xprt.h~nfs-remove-XID-spinlock include/linux/sunrpc/xprt.h --- 25/include/linux/sunrpc/xprt.h~nfs-remove-XID-spinlock 2004-02-28 18:21:15.000000000 -0800 +++ 25-akpm/include/linux/sunrpc/xprt.h 2004-02-28 18:21:15.000000000 -0800 @@ -102,7 +102,6 @@ struct rpc_rqst { struct xdr_buf rq_private_buf; /* The receive buffer * used in the softirq. */ - /* * For authentication (e.g. auth_des) */ @@ -155,6 +154,11 @@ struct rpc_xprt { stream : 1; /* TCP */ /* + * XID + */ + __u32 xid; /* Next XID value to use */ + + /* * State of TCP reply receive stuff */ u32 tcp_recm, /* Fragment header */ diff -puN net/sunrpc/xprt.c~nfs-remove-XID-spinlock net/sunrpc/xprt.c --- 25/net/sunrpc/xprt.c~nfs-remove-XID-spinlock 2004-02-28 18:21:15.000000000 -0800 +++ 25-akpm/net/sunrpc/xprt.c 2004-02-28 18:21:15.000000000 -0800 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -1322,22 +1323,14 @@ do_xprt_reserve(struct rpc_task *task) /* * Allocate a 'unique' XID */ -static u32 -xprt_alloc_xid(void) +static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt) { - static spinlock_t xid_lock = SPIN_LOCK_UNLOCKED; - static int need_init = 1; - static u32 xid; - u32 ret; - - spin_lock(&xid_lock); - if (unlikely(need_init)) { - xid = get_seconds() << 12; - need_init = 0; - } - ret = xid++; - spin_unlock(&xid_lock); - return ret; + return xprt->xid++; +} + +static inline void xprt_init_xid(struct rpc_xprt *xprt) +{ + get_random_bytes(&xprt->xid, sizeof(xprt->xid)); } /* @@ -1351,7 +1344,7 @@ xprt_request_init(struct rpc_task *task, req->rq_timeout = xprt->timeout; req->rq_task = task; req->rq_xprt = xprt; - req->rq_xid = xprt_alloc_xid(); + req->rq_xid = xprt_alloc_xid(xprt); INIT_LIST_HEAD(&req->rq_list); dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, req->rq_xid); @@ -1472,6 +1465,8 @@ xprt_setup(int proto, struct sockaddr_in req->rq_next = NULL; xprt->free = xprt->slot; + xprt_init_xid(xprt); + /* Check whether we want to use a reserved port */ xprt->resvport = capable(CAP_NET_BIND_SERVICE) ? 1 : 0; _