]> git.neil.brown.name Git - history.git/commitdiff
RPC: Make XIDs unique on a per-transport basis rather than globally unique. Gets rid
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 13 Mar 2004 16:38:41 +0000 (11:38 -0500)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Sat, 13 Mar 2004 16:38:41 +0000 (11:38 -0500)
     of an unnecessary global spinlock.

include/linux/sunrpc/xprt.h
net/sunrpc/xprt.c

index 393e6dc6a2689e0373e4a54fd5caee30414ade02..a352a71ecdcb8839ffa469cbc6da55d73ff33e97 100644 (file)
@@ -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)
         */
@@ -154,6 +153,11 @@ struct rpc_xprt {
                                resvport   : 1, /* use a reserved port */
                                stream     : 1; /* TCP */
 
+       /*
+        * XID
+        */
+       __u32                   xid;            /* Next XID value to use */
+
        /*
         * State of TCP reply receive stuff
         */
index efde919a64fc80c454de36a3a4648a4a5cbb956b..3073a4308d1b7a244489d31e0d4fef1416185e78 100644 (file)
@@ -57,6 +57,7 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/file.h>
 #include <linux/workqueue.h>
+#include <linux/random.h>
 
 #include <net/sock.h>
 #include <net/checksum.h>
@@ -1330,22 +1331,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));
 }
 
 /*
@@ -1359,7 +1352,7 @@ xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
        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);
@@ -1478,6 +1471,8 @@ xprt_setup(int proto, struct sockaddr_in *ap, struct rpc_timeout *to)
        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;