From: Leon Romanovsky <leon@kernel.org>
To: Christoph Hellwig <hch@lst.de>,
Doug Ledford <dledford@redhat.com>,
Jason Gunthorpe <jgg@nvidia.com>
Cc: Maor Gottlieb <maorg@nvidia.com>,
linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org
Subject: [PATCH rdma-next 1/4] lib/scatterlist: Refactor sg_alloc_table_from_pages
Date: Thu, 3 Sep 2020 18:54:34 +0300 [thread overview]
Message-ID: <20200903155434.1153934-1-leon@kernel.org> (raw)
In-Reply-To: <20200903121853.1145976-1-leon@kernel.org>
From: Maor Gottlieb <maorg@nvidia.com>
Currently, sg_alloc_table_from_pages doesn't support dynamic chaining of
SG entries. Therefore it requires from user to allocate all the pages in
advance and hold them in a large buffer. Such a buffer consumes a lot of
temporary memory in HPC systems which do a very large memory registration.
The next patches introduce API for dynamically allocation from pages and
it requires us to do the following:
* Extract the code to alloc_from_pages_common.
* Change the build of the table to iterate on the chunks and not on the
SGEs. It will allow dynamic allocation of more SGEs.
Since sg_alloc_table_from_pages allocate exactly the number of chunks,
therefore chunks are equal to the number of SG entries.
Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
---
lib/scatterlist.c | 75 ++++++++++++++++++++++++++++-------------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 5d63a8857f36..292e785d21ee 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -365,38 +365,18 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
}
EXPORT_SYMBOL(sg_alloc_table);
-/**
- * __sg_alloc_table_from_pages - Allocate and initialize an sg table from
- * an array of pages
- * @sgt: The sg table header to use
- * @pages: Pointer to an array of page pointers
- * @n_pages: Number of pages in the pages array
- * @offset: Offset from start of the first page to the start of a buffer
- * @size: Number of valid bytes in the buffer (after offset)
- * @max_segment: Maximum size of a scatterlist node in bytes (page aligned)
- * @gfp_mask: GFP allocation mask
- *
- * Description:
- * Allocate and initialize an sg table from a list of pages. Contiguous
- * ranges of the pages are squashed into a single scatterlist node up to the
- * maximum size specified in @max_segment. An user may provide an offset at a
- * start and a size of valid data in a buffer specified by the page array.
- * The returned sg table is released by sg_free_table.
- *
- * Returns:
- * 0 on success, negative error on failure
- */
-int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
- unsigned int n_pages, unsigned int offset,
- unsigned long size, unsigned int max_segment,
- gfp_t gfp_mask)
+static struct scatterlist *
+alloc_from_pages_common(struct sg_table *sgt, struct page **pages,
+ unsigned int n_pages, unsigned int offset,
+ unsigned long size, unsigned int max_segment,
+ gfp_t gfp_mask)
{
unsigned int chunks, cur_page, seg_len, i;
+ struct scatterlist *prv, *s = NULL;
int ret;
- struct scatterlist *s;
if (WARN_ON(!max_segment || offset_in_page(max_segment)))
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
/* compute number of contiguous chunks */
chunks = 1;
@@ -412,11 +392,12 @@ int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
ret = sg_alloc_table(sgt, chunks, gfp_mask);
if (unlikely(ret))
- return ret;
+ return ERR_PTR(ret);
/* merging chunks and putting them into the scatterlist */
cur_page = 0;
- for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+ s = sgt->sgl;
+ for (i = 0; i < chunks; i++) {
unsigned int j, chunk_size;
/* look for the end of the current chunk */
@@ -435,9 +416,43 @@ int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
size -= chunk_size;
offset = 0;
cur_page = j;
+ prv = s;
+ s = sg_next(s);
}
+ return prv;
+}
- return 0;
+/**
+ * __sg_alloc_table_from_pages - Allocate and initialize an sg table from
+ * an array of pages
+ * @sgt: The sg table header to use
+ * @pages: Pointer to an array of page pointers
+ * @n_pages: Number of pages in the pages array
+ * @offset: Offset from start of the first page to the start of a buffer
+ * @size: Number of valid bytes in the buffer (after offset)
+ * @max_segment: Maximum size of a scatterlist node in bytes (page aligned)
+ * @gfp_mask: GFP allocation mask
+ *
+ * Description:
+ * Allocate and initialize an sg table from a list of pages. Contiguous
+ * ranges of the pages are squashed into a single scatterlist node up to the
+ * maximum size specified in @max_segment. A user may provide an offset at a
+ * start and a size of valid data in a buffer specified by the page array.
+ * The returned sg table is released by sg_free_table.
+ *
+ * Returns:
+ * 0 on success, negative error on failure
+ */
+int __sg_alloc_table_from_pages(struct sg_table *sgt, struct page **pages,
+ unsigned int n_pages, unsigned int offset,
+ unsigned long size, unsigned int max_segment,
+ gfp_t gfp_mask)
+{
+ struct scatterlist *sg;
+
+ sg = alloc_from_pages_common(sgt, pages, n_pages, offset, size,
+ max_segment, gfp_mask);
+ return PTR_ERR_OR_ZERO(sg);
}
EXPORT_SYMBOL(__sg_alloc_table_from_pages);
--
2.26.2
next prev parent reply other threads:[~2020-09-03 15:54 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-03 12:18 [PATCH rdma-next 0/4] scatterlist: add sg_alloc_table_append function Leon Romanovsky
2020-09-03 12:18 ` [PATCH rdma-next 2/4] lib/scatterlist: Add support in dynamically allocation of SG entries Leon Romanovsky
2020-09-07 7:29 ` Christoph Hellwig
2020-09-07 12:34 ` Maor Gottlieb
2020-09-03 12:18 ` [PATCH rdma-next 3/4] lib/scatterlist: Add support in dynamic allocation of SG table from pages Leon Romanovsky
2020-09-07 7:29 ` Christoph Hellwig
2020-09-07 12:44 ` Maor Gottlieb
2020-09-08 15:54 ` Christoph Hellwig
2020-09-08 16:13 ` Jason Gunthorpe
2020-09-03 12:18 ` [PATCH rdma-next 4/4] RDMA/umem: Move to allocate " Leon Romanovsky
2020-09-07 7:29 ` Christoph Hellwig
2020-09-08 14:10 ` Jason Gunthorpe
2020-09-03 15:32 ` [PATCH rdma-next 0/4] scatterlist: add sg_alloc_table_append function Christoph Hellwig
2020-09-03 15:55 ` Leon Romanovsky
2020-09-03 15:54 ` Leon Romanovsky [this message]
2020-09-07 7:29 ` [PATCH rdma-next 1/4] lib/scatterlist: Refactor sg_alloc_table_from_pages Christoph Hellwig
2020-09-07 12:32 ` Maor Gottlieb
2020-09-08 15:52 ` Christoph Hellwig
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=20200903155434.1153934-1-leon@kernel.org \
--to=leon@kernel.org \
--cc=dledford@redhat.com \
--cc=hch@lst.de \
--cc=jgg@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=maorg@nvidia.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).