Commit cd5d9d66 authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] Clean up and fix SMP issue w.r.t. XID allocation

This problem was identified by Olaf Kirch:

In xprt_request_init(), the XID allocation needs to be protected by a
global spinlock.
parent 49b04866
...@@ -1272,6 +1272,27 @@ do_xprt_reserve(struct rpc_task *task) ...@@ -1272,6 +1272,27 @@ do_xprt_reserve(struct rpc_task *task)
rpc_sleep_on(&xprt->backlog, task, NULL, NULL); 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 * Initialize RPC request
*/ */
...@@ -1279,19 +1300,14 @@ static void ...@@ -1279,19 +1300,14 @@ static void
xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt)
{ {
struct rpc_rqst *req = task->tk_rqstp; 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_timeout = xprt->timeout;
req->rq_task = task; req->rq_task = task;
req->rq_xprt = xprt; req->rq_xprt = xprt;
req->rq_xid = xid++; req->rq_xid = xprt_alloc_xid();
if (!xid)
xid++;
INIT_LIST_HEAD(&req->rq_list); INIT_LIST_HEAD(&req->rq_list);
dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
req, req->rq_xid);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment