From: Douglas Gilbert <dgilbert@interlog.com>
To: linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, jejb@linux.vnet.ibm.com,
hare@suse.de, bvanassche@acm.org, Jason Gunthorpe <jgg@ziepe.ca>,
Bodo Stroesser <bostroesser@gmail.com>
Subject: [PATCH 1/5] sgl_alloc_order: remove 4 GiB limit
Date: Sun, 23 Oct 2022 21:02:40 -0400 [thread overview]
Message-ID: <20221024010244.9522-2-dgilbert@interlog.com> (raw)
In-Reply-To: <20221024010244.9522-1-dgilbert@interlog.com>
This patch fixes a check done by sgl_alloc_order() before it starts
any allocations. The comment in the original said: "Check for integer
overflow" but the right hand side of the expression in the condition
is resolved as u32 so it can not exceed UINT32_MAX (4 GiB) which
means 'length' can not exceed that value.
This function may be used to replace vmalloc(unsigned long) for a
large allocation (e.g. a ramdisk). vmalloc has no limit at 4 GiB so
it seems unreasonable that sgl_alloc_order() whose length type is
unsigned long long should be limited to 4 GB.
Solutions to this issue were discussed by Jason Gunthorpe
<jgg@ziepe.ca> and Bodo Stroesser <bostroesser@gmail.com>. This
version is base on a linux-scsi post by Jason titled: "Re:
[PATCH v7 1/4] sgl_alloc_order: remove 4 GiB limit" dated 20220201.
An earlier patch fixed a memory leak in sg_alloc_order() due to the
misuse of sgl_free(). Take the opportunity to put a one line comment
above sgl_free()'s declaration warning that it is not suitable when
order > 0 .
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Bodo Stroesser <bostroesser@gmail.com>
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
include/linux/scatterlist.h | 1 +
lib/scatterlist.c | 21 ++++++++++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 375a5e90d86a..0930755a756e 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -426,6 +426,7 @@ struct scatterlist *sgl_alloc(unsigned long long length, gfp_t gfp,
unsigned int *nent_p);
void sgl_free_n_order(struct scatterlist *sgl, int nents, int order);
void sgl_free_order(struct scatterlist *sgl, int order);
+/* Only use sgl_free() when order is 0 */
void sgl_free(struct scatterlist *sgl);
#endif /* CONFIG_SGL_ALLOC */
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index c8c3d675845c..f633e2d669fe 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -585,13 +585,16 @@ EXPORT_SYMBOL(sg_alloc_table_from_pages_segment);
#ifdef CONFIG_SGL_ALLOC
/**
- * sgl_alloc_order - allocate a scatterlist and its pages
+ * sgl_alloc_order - allocate a scatterlist with equally sized elements each
+ * of which has 2^@order continuous pages
* @length: Length in bytes of the scatterlist. Must be at least one
- * @order: Second argument for alloc_pages()
+ * @order: Second argument for alloc_pages(). Each sgl element size will
+ * be (PAGE_SIZE*2^@order) bytes. @order must not exceed 16.
* @chainable: Whether or not to allocate an extra element in the scatterlist
- * for scatterlist chaining purposes
+ * for scatterlist chaining purposes
* @gfp: Memory allocation flags
- * @nent_p: [out] Number of entries in the scatterlist that have pages
+ * @nent_p: [out] Number of entries in the scatterlist that have pages.
+ * Ignored if @nent_p is NULL.
*
* Returns: A pointer to an initialized scatterlist or %NULL upon failure.
*/
@@ -601,14 +604,14 @@ struct scatterlist *sgl_alloc_order(unsigned long long length,
{
struct scatterlist *sgl, *sg;
struct page *page;
- unsigned int nent, nalloc;
+ uint64_t nent;
+ unsigned int nalloc;
u32 elem_len;
nent = round_up(length, PAGE_SIZE << order) >> (PAGE_SHIFT + order);
- /* Check for integer overflow */
- if (length > (nent << (PAGE_SHIFT + order)))
+ if (nent > UINT_MAX)
return NULL;
- nalloc = nent;
+ nalloc = (unsigned int)nent;
if (chainable) {
/* Check for integer overflow */
if (nalloc + 1 < nalloc)
@@ -636,7 +639,7 @@ struct scatterlist *sgl_alloc_order(unsigned long long length,
}
WARN_ONCE(length, "length = %lld\n", length);
if (nent_p)
- *nent_p = nent;
+ *nent_p = (unsigned int)nent;
return sgl;
}
EXPORT_SYMBOL(sgl_alloc_order);
--
2.37.3
next prev parent reply other threads:[~2022-10-24 1:12 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-24 1:02 [PATCH 0/5] scatterlist: add operations for scsi_debug Douglas Gilbert
2022-10-24 1:02 ` Douglas Gilbert [this message]
2022-10-24 12:21 ` [PATCH 1/5] sgl_alloc_order: remove 4 GiB limit Jason Gunthorpe
2022-10-24 14:32 ` Bodo Stroesser
2022-10-24 17:32 ` Jason Gunthorpe
2022-10-24 19:58 ` Douglas Gilbert
2022-10-25 12:19 ` Jason Gunthorpe
2022-10-25 10:46 ` Bodo Stroesser
2022-10-25 12:18 ` Jason Gunthorpe
2022-10-24 1:02 ` [PATCH 2/5] scatterlist: add sgl_copy_sgl() function Douglas Gilbert
2022-10-24 1:02 ` [PATCH 3/5] scatterlist: add sgl_equal_sgl() function Douglas Gilbert
2022-10-24 1:02 ` [PATCH 4/5] scatterlist: add sgl_memset() Douglas Gilbert
2022-10-24 1:02 ` [PATCH 5/5] scsi_debug: change store from vmalloc to sgl Douglas Gilbert
2022-10-24 15:08 ` Bodo Stroesser
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=20221024010244.9522-2-dgilbert@interlog.com \
--to=dgilbert@interlog.com \
--cc=bostroesser@gmail.com \
--cc=bvanassche@acm.org \
--cc=hare@suse.de \
--cc=jejb@linux.vnet.ibm.com \
--cc=jgg@ziepe.ca \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.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 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.