]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Clean up and fix SMP issue w.r.t. XID allocation
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Thu, 13 Feb 2003 10:26:22 +0000 (02:26 -0800)
committerTrond Myklebust <trond.myklebust@fys.uio.no>
Thu, 13 Feb 2003 10:26:22 +0000 (02:26 -0800)
This problem was identified by Olaf Kirch:

In xprt_request_init(), the XID allocation needs to be protected by a
global spinlock.

net/sunrpc/xprt.c

index 5ff838e376c2df0750ffff1c00b3af053bf63758..b201141153394694938189f08f54e7b6eff17bd8 100644 (file)
@@ -1272,6 +1272,27 @@ do_xprt_reserve(struct rpc_task *task)
        rpc_sleep_on(&xprt->backlog, task, NULL, NULL);
 }
 
+/*
+ * Allocate a 'unique' XID
+ */
+static u32
+xprt_alloc_xid(void)
+{
+       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;
+}
+
 /*
  * Initialize RPC request
  */
@@ -1279,19 +1300,14 @@ static void
 xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
 {
        struct rpc_rqst *req = task->tk_rqstp;
-       static u32      xid = 0;
-
-       if (!xid)
-               xid = get_seconds() << 12;
 
-       dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid, req, xid);
        req->rq_timeout = xprt->timeout;
        req->rq_task    = task;
        req->rq_xprt    = xprt;
-       req->rq_xid     = xid++;
-       if (!xid)
-               xid++;
+       req->rq_xid     = xprt_alloc_xid();
        INIT_LIST_HEAD(&req->rq_list);
+       dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
+                       req, req->rq_xid);
 }
 
 /*