Commit a01a9840 authored by Venkateswararao Jujjuri (JV)'s avatar Venkateswararao Jujjuri (JV) Committed by Eric Van Hensbergen

[net/9p] Set the condition just before waking up.

Given that the sprious wake-ups are common, we need to move the
condition setting right next to the wake_up().  After setting the condition
to req->status = REQ_STATUS_RCVD, sprious wakeups may cause the
virtqueue back on the free list for someone else to use.
This may result in kernel panic while relasing the pinned pages
in p9_release_req_pages().

Also rearranged the while loop in req_done() for better redability.
Signed-off-by: default avatarVenkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent 53bda3e5
...@@ -141,20 +141,22 @@ static void req_done(struct virtqueue *vq) ...@@ -141,20 +141,22 @@ static void req_done(struct virtqueue *vq)
P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n"); P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n");
do { while (1) {
spin_lock_irqsave(&chan->lock, flags); spin_lock_irqsave(&chan->lock, flags);
rc = virtqueue_get_buf(chan->vq, &len); rc = virtqueue_get_buf(chan->vq, &len);
if (rc != NULL) { if (rc == NULL) {
spin_unlock_irqrestore(&chan->lock, flags);
break;
}
chan->ring_bufs_avail = 1; chan->ring_bufs_avail = 1;
spin_unlock_irqrestore(&chan->lock, flags); spin_unlock_irqrestore(&chan->lock, flags);
/* Wakeup if anyone waiting for VirtIO ring space. */ /* Wakeup if anyone waiting for VirtIO ring space. */
wake_up(chan->vc_wq); wake_up(chan->vc_wq);
P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc); P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
rc->tag);
req = p9_tag_lookup(chan->client, rc->tag); req = p9_tag_lookup(chan->client, rc->tag);
req->status = REQ_STATUS_RCVD;
if (req->tc->private) { if (req->tc->private) {
struct trans_rpage_info *rp = req->tc->private; struct trans_rpage_info *rp = req->tc->private;
/*Release pages */ /*Release pages */
...@@ -163,11 +165,9 @@ static void req_done(struct virtqueue *vq) ...@@ -163,11 +165,9 @@ static void req_done(struct virtqueue *vq)
kfree(rp); kfree(rp);
req->tc->private = NULL; req->tc->private = NULL;
} }
req->status = REQ_STATUS_RCVD;
p9_client_cb(chan->client, req); p9_client_cb(chan->client, req);
} else {
spin_unlock_irqrestore(&chan->lock, flags);
} }
} while (rc != NULL);
} }
/** /**
......
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