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

[net/9p]Serialize virtqueue operations to make VirtIO transport SMP safe.

Signed-off-by: default avatarVenkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent 329176cc
...@@ -134,16 +134,24 @@ static void req_done(struct virtqueue *vq) ...@@ -134,16 +134,24 @@ static void req_done(struct virtqueue *vq)
struct p9_fcall *rc; struct p9_fcall *rc;
unsigned int len; unsigned int len;
struct p9_req_t *req; struct p9_req_t *req;
unsigned long flags;
P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n"); P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n");
while ((rc = virtqueue_get_buf(chan->vq, &len)) != NULL) { do {
spin_lock_irqsave(&chan->lock, flags);
rc = virtqueue_get_buf(chan->vq, &len);
spin_unlock_irqrestore(&chan->lock, flags);
if (rc != NULL) {
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", rc->tag); P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n",
rc->tag);
req = p9_tag_lookup(chan->client, rc->tag); req = p9_tag_lookup(chan->client, rc->tag);
req->status = REQ_STATUS_RCVD; req->status = REQ_STATUS_RCVD;
p9_client_cb(chan->client, req); p9_client_cb(chan->client, req);
} }
} while (rc != NULL);
} }
/** /**
...@@ -199,23 +207,29 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) ...@@ -199,23 +207,29 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
int in, out; int in, out;
struct virtio_chan *chan = client->trans; struct virtio_chan *chan = client->trans;
char *rdata = (char *)req->rc+sizeof(struct p9_fcall); char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
unsigned long flags;
int err;
P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n"); P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
req->status = REQ_STATUS_SENT;
spin_lock_irqsave(&chan->lock, flags);
out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata, out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata,
req->tc->size); req->tc->size);
in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata,
client->msize); client->msize);
req->status = REQ_STATUS_SENT; err = virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc);
if (err < 0) {
if (virtqueue_add_buf(chan->vq, chan->sg, out, in, req->tc) < 0) { spin_unlock_irqrestore(&chan->lock, flags);
P9_DPRINTK(P9_DEBUG_TRANS, P9_DPRINTK(P9_DEBUG_TRANS,
"9p debug: virtio rpc add_buf returned failure"); "9p debug: virtio rpc add_buf returned failure");
return -EIO; return -EIO;
} }
virtqueue_kick(chan->vq); virtqueue_kick(chan->vq);
spin_unlock_irqrestore(&chan->lock, flags);
P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n"); P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
return 0; return 0;
......
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