From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Venkateswararao Jujjuri (JV)" Subject: [PATCH 3/5] [net/9p] Add support for placing page addresses directly on the sg list. Date: Tue, 17 Aug 2010 10:27:23 -0700 Message-ID: <1282066045-3945-4-git-send-email-jvrao@linux.vnet.ibm.com> References: <1282066045-3945-1-git-send-email-jvrao@linux.vnet.ibm.com> Cc: linux-fsdevel@vger.kernel.org, "Venkateswararao Jujjuri (JV)" , Badari Pulavarty To: v9fs-developer@lists.sourceforge.net Return-path: Received: from e37.co.us.ibm.com ([32.97.110.158]:40529 "EHLO e37.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758012Ab0HQRTu (ORCPT ); Tue, 17 Aug 2010 13:19:50 -0400 Received: from d03relay03.boulder.ibm.com (d03relay03.boulder.ibm.com [9.17.195.228]) by e37.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id o7HHHqUk027609 for ; Tue, 17 Aug 2010 11:17:52 -0600 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay03.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o7HHJd5V116426 for ; Tue, 17 Aug 2010 11:19:39 -0600 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o7HHJaaX002298 for ; Tue, 17 Aug 2010 11:19:37 -0600 In-Reply-To: <1282066045-3945-1-git-send-email-jvrao@linux.vnet.ibm.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: This patch adds necessary infrastructure for placing page addresses directly on the sg list for the server to consume. The newly added routine pack_sg_list_p() is just like pack_sg_list() except that it takes page array as an input and directly places them on the sg list after taking care of the first page offset. Signed-off-by: Venkateswararao Jujjuri Signed-off-by: Badari Pulavarty --- include/net/9p/9p.h | 6 ++++- net/9p/client.c | 4 +++ net/9p/trans_virtio.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index a8de812..382ef22 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h @@ -651,7 +651,11 @@ struct p9_fcall { size_t offset; size_t capacity; - + struct page **pdata; + uint32_t pdata_mapped_pages; + uint32_t pdata_off; + uint32_t pdata_write_len; + uint32_t pdata_read_len; uint8_t *sdata; }; diff --git a/net/9p/client.c b/net/9p/client.c index 29bbbbd..5487896 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -244,8 +244,12 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) } req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall); req->tc->capacity = c->msize; + req->tc->pdata_write_len = 0; + req->tc->pdata_read_len = 0; req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall); req->rc->capacity = c->msize; + req->rc->pdata_write_len = 0; + req->rc->pdata_read_len = 0; } p9pdu_reset(req->tc); diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 762c19f..8f86cb5 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -180,6 +180,44 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, return index-start; } +/** + * pack_sg_list_p - Pack a scatter gather list from an array of pages. + * @sg: scatter/gather list to pack into + * @start: which segment of the sg_list to start at + * @limit: maximum segment to pack data to + * @pdu: pdu prepared to put on the wire. + * @count: amount of data to pack into the scatter/gather list + * + * This is just like pack_sg_list() except that it takes page array + * as an input and directly places them on the sg list after taking + * care of the first page offset. + */ + +static int +pack_sg_list_p(struct scatterlist *sg, int start, int limit, + struct p9_fcall *pdu, int count) +{ + int s; + int i = 0; + int index = start; + + if (pdu->pdata_off) { + s = min((int)(PAGE_SIZE - pdu->pdata_off), count); + sg_set_page(&sg[index++], pdu->pdata[i++], s, pdu->pdata_off); + count -= s; + } + + while (count) { + BUG_ON(index > limit); + s = min((int)PAGE_SIZE, count); + sg_set_page(&sg[index++], pdu->pdata[i++], s, 0); + count -= s; + } + + return index-start; +} + + /* We don't currently allow canceling of virtio requests */ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req) { @@ -196,16 +234,31 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req) static int p9_virtio_request(struct p9_client *client, struct p9_req_t *req) { - int in, out; + int in, out, outp, inp; struct virtio_chan *chan = client->trans; char *rdata = (char *)req->rc+sizeof(struct p9_fcall); P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n"); out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata, - req->tc->size); - in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, + req->tc->size); + + BUG_ON(req->tc->pdata_write_len && req->tc->pdata_read_len); + + if (req->tc->pdata_write_len) { + outp = pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, + req->tc, req->tc->pdata_write_len); + out += outp; + } + if (req->tc->pdata_read_len) { + inp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, 11); + in = pack_sg_list_p(chan->sg, out+inp, VIRTQUEUE_NUM, + req->tc, req->tc->pdata_read_len); + in += inp; + } else { + in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, rdata, client->msize); + } req->status = REQ_STATUS_SENT; -- 1.6.5.2