All of lore.kernel.org
 help / color / mirror / Atom feed
From: Asias He <asias@redhat.com>
To: Nicholas Bellinger <nab@linux-iscsi.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	Rusty Russell <rusty@rustcorp.com.au>,
	kvm@vger.kernel.org, virtualization@lists.linux-foundation.org,
	target-devel@vger.kernel.org
Subject: [PATCH 2/3] tcm_vhost: Optimize gup in vhost_scsi_map_to_sgl
Date: Mon, 21 Jan 2013 16:05:27 +0800	[thread overview]
Message-ID: <1358755528-31421-3-git-send-email-asias@redhat.com> (raw)
In-Reply-To: <1358755528-31421-1-git-send-email-asias@redhat.com>

We can get all the pages in one time instead of calling
gup N times.

Signed-off-by: Asias He <asias@redhat.com>
---
 drivers/vhost/tcm_vhost.c | 33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index ca35c16..59be442 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -430,37 +430,45 @@ static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd(
  * Returns the number of scatterlist entries used or -errno on error.
  */
 static int vhost_scsi_map_to_sgl(struct scatterlist *sgl,
-	unsigned int sgl_count, void __user *ptr, size_t len, int write)
+	unsigned int sgl_count, struct iovec *iov, int write)
 {
 	struct scatterlist *sg = sgl;
 	unsigned int npages = 0;
+	void __user *ptr = iov->iov_base;
+	size_t len = iov->iov_len;
 	int ret;
+	unsigned int pages_nr, offset, nbytes;
+	struct page **pages;
+
+	pages_nr = iov_num_pages(iov);
+	pages = kmalloc(pages_nr * sizeof(struct page *), GFP_ATOMIC);
+	if (!pages)
+		return -ENOMEM;
+
+	ret = get_user_pages_fast((unsigned long)ptr, pages_nr, write, pages);
+	if (ret != pages_nr)
+		goto err;
 
 	while (len > 0) {
-		struct page *page;
-		unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK;
-		unsigned int nbytes = min_t(unsigned int,
-				PAGE_SIZE - offset, len);
+		offset = (uintptr_t)ptr & ~PAGE_MASK;
+		nbytes = min_t(unsigned int, PAGE_SIZE - offset, len);
 
 		if (npages == sgl_count) {
 			ret = -ENOBUFS;
 			goto err;
 		}
 
-		ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page);
-		BUG_ON(ret == 0); /* we should either get our page or fail */
-		if (ret < 0)
-			goto err;
-
-		sg_set_page(sg, page, nbytes, offset);
+		sg_set_page(sg, pages[npages], nbytes, offset);
 		ptr += nbytes;
 		len -= nbytes;
 		sg++;
 		npages++;
 	}
+	kfree(pages);
 	return npages;
 
 err:
+	kfree(pages);
 	/* Put pages that we hold */
 	for (sg = sgl; sg != &sgl[npages]; sg++)
 		put_page(sg_page(sg));
@@ -498,8 +506,7 @@ static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd,
 
 	pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count);
 	for (i = 0; i < niov; i++) {
-		ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base,
-					iov[i].iov_len, write);
+		ret = vhost_scsi_map_to_sgl(sg, sgl_count, &iov[i], write);
 		if (ret < 0) {
 			for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
 				put_page(sg_page(&tv_cmd->tvc_sgl[i]));
-- 
1.8.1


  parent reply	other threads:[~2013-01-21  8:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-21  8:05 [PATCH 0/3] tcm_vhost: Optimize gup in vhost_scsi_map_to_sgl Asias He
2013-01-21  8:05 ` [PATCH 1/3] tcm_vhost: Introduce iov_num_pages Asias He
2013-01-21  8:05 ` Asias He [this message]
2013-01-21 18:57   ` [PATCH 2/3] tcm_vhost: Optimize gup in vhost_scsi_map_to_sgl Marcelo Tosatti
2013-01-22  1:33     ` Asias He
2013-01-21 18:57   ` Marcelo Tosatti
2013-01-21  8:05 ` Asias He
2013-01-21  8:05 ` [PATCH 3/3] tcm_vhost: Use iov_num_pages to calculate sgl_count Asias He

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1358755528-31421-3-git-send-email-asias@redhat.com \
    --to=asias@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mst@redhat.com \
    --cc=nab@linux-iscsi.org \
    --cc=rusty@rustcorp.com.au \
    --cc=target-devel@vger.kernel.org \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.