9P: Add memory barriers to protect request fields over cb/rpc threads handoff
We need barriers to guarantee this pattern works as intended: [w] req->rc, 1 [r] req->status, 1 wmb rmb [w] req->status, 1 [r] req->rc Where the wmb ensures that rc gets written before status, and the rmb ensures that if you observe status == 1, rc is the new value. Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:

committed by
Eric Van Hensbergen

parent
38dbfb59d1
commit
2b6e72ed74
@@ -415,9 +415,17 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
|
||||
* req: request received
|
||||
*
|
||||
*/
|
||||
void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
|
||||
void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status)
|
||||
{
|
||||
p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
|
||||
|
||||
/*
|
||||
* This barrier is needed to make sure any change made to req before
|
||||
* the other thread wakes up will indeed be seen by the waiting side.
|
||||
*/
|
||||
smp_wmb();
|
||||
req->status = status;
|
||||
|
||||
wake_up(req->wq);
|
||||
p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
|
||||
}
|
||||
@@ -751,6 +759,12 @@ again:
|
||||
err = wait_event_interruptible(*req->wq,
|
||||
req->status >= REQ_STATUS_RCVD);
|
||||
|
||||
/*
|
||||
* Make sure our req is coherent with regard to updates in other
|
||||
* threads - echoes to wmb() in the callback
|
||||
*/
|
||||
smp_rmb();
|
||||
|
||||
if ((err == -ERESTARTSYS) && (c->status == Connected)
|
||||
&& (type == P9_TFLUSH)) {
|
||||
sigpending = 1;
|
||||
|
Reference in New Issue
Block a user