2023-10-11 11:17:29

by Kartik Rajput

[permalink] [raw]
Subject: [PATCH v4 1/8] mm/util: Introduce kmemdup_array() to duplicate an array

Introduce function kmemdup_array(), that will copy `n` number of
elements from a given array `src` to `dst`.

On success, kmemdup_array() returns 0 and copy the elements from `src`
to newly allocated array `dst`, it also stores number of elements
copied from `src` array to `dst_count` parameter. On failure, this
returns a negative integer value containing the error value.

Signed-off-by: Kartik <[email protected]>
---
include/linux/string.h | 2 ++
mm/util.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)

diff --git a/include/linux/string.h b/include/linux/string.h
index dbfc66400050..6245a7918b05 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -179,6 +179,8 @@ extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
+extern int kmemdup_array(void **dst, size_t *dst_count, const void *src, size_t element_size,
+ size_t count, gfp_t gfp);

extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
extern void argv_free(char **argv);
diff --git a/mm/util.c b/mm/util.c
index 6eddd891198e..a7c87a119be1 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -135,6 +135,40 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
}
EXPORT_SYMBOL(kmemdup);

+/**
+ * kmemdup_array - duplicate a given array.
+ *
+ * @dst: reference to the pointer to store address of duplicated array.
+ * @dst_count: number of elements in the duplicated array.
+ * @src: array to duplicate.
+ * @element_size: size of each element of array.
+ * @count: number of elements to duplicate from array.
+ * @gfp: GFP mask to use.
+ *
+ * Return: Returns 0 on success, on failure this returns a negative error value.
+ */
+int kmemdup_array(void **dst, size_t *dst_count, const void *src, size_t element_size, size_t count,
+ gfp_t gfp)
+{
+ size_t size;
+
+ *dst_count = 0;
+
+ if (!src || !element_size || !count)
+ return -EINVAL;
+
+ size = size_mul(element_size, count);
+
+ *dst = kmemdup(src, size, gfp);
+ if (*dst)
+ return -ENOMEM;
+
+ *dst_count = size / element_size;
+
+ return 0;
+}
+EXPORT_SYMBOL(kmemdup_array);
+
/**
* kvmemdup - duplicate region of memory
*
--
2.34.1


2023-10-11 15:37:01

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v4 1/8] mm/util: Introduce kmemdup_array() to duplicate an array

On Wed, Oct 11, 2023 at 2:17 PM Kartik <[email protected]> wrote:
>
> Introduce function kmemdup_array(), that will copy `n` number of
> elements from a given array `src` to `dst`.
>
> On success, kmemdup_array() returns 0 and copy the elements from `src`
> to newly allocated array `dst`, it also stores number of elements
> copied from `src` array to `dst_count` parameter. On failure, this
> returns a negative integer value containing the error value.

Hmm... Why is it so complicated?

Can it be as simple as

return kmemdup(size_mul());

?

--
With Best Regards,
Andy Shevchenko

2023-10-11 16:14:50

by Kartik Rajput

[permalink] [raw]
Subject: Re: [PATCH v4 1/8] mm/util: Introduce kmemdup_array() to duplicate an array

On Wed, 2023-10-11 at 18:36:11 +0300, Andy Shevchenko wrote:
> On Wed, Oct 11, 2023 at 2:17 PM Kartik <[email protected]> wrote:
> >
> > Introduce function kmemdup_array(), that will copy `n` number of
> > elements from a given array `src` to `dst`.
> >
> > On success, kmemdup_array() returns 0 and copy the elements from `src`
> > to newly allocated array `dst`, it also stores number of elements
> > copied from `src` array to `dst_count` parameter. On failure, this
> > returns a negative integer value containing the error value.
>
> Hmm... Why is it so complicated?
>
> Can it be as simple as
>
> return kmemdup(size_mul());
>
> ?
>
> --
> With Best Regards,
> Andy Shevchenko

The idea was to validate the arguments that are passed to kmemdup_array().
But I agree doing so complicates things here.

I will update this in the next patchset.

Thanks & Regards,
Kartik