From: Oleg Babin <obabin@virtuozzo.com> To: netdev@vger.kernel.org, linux-sctp@vger.kernel.org Cc: "David S. Miller" <davem@davemloft.net>, Vlad Yasevich <vyasevich@gmail.com>, Neil Horman <nhorman@tuxdriver.com>, Xin Long <lucien.xin@gmail.com>, Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>, Andrey Ryabinin <aryabinin@virtuozzo.com> Subject: [PATCH net-next 2/2] net/sctp: Replace in/out stream arrays with flex_array Date: Mon, 23 Apr 2018 21:41:06 +0300 [thread overview] Message-ID: <1524508866-317485-3-git-send-email-obabin@virtuozzo.com> (raw) In-Reply-To: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> This path replaces physically contiguous memory arrays allocated using kmalloc_array() with flexible arrays. This enables to avoid memory allocation failures on the systems under a memory stress. Signed-off-by: Oleg Babin <obabin@virtuozzo.com> --- include/net/sctp/structs.h | 1 + net/sctp/stream.c | 78 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 578bb40..c7f42b4 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -57,6 +57,7 @@ #include <linux/atomic.h> /* This gets us atomic counters. */ #include <linux/skbuff.h> /* We need sk_buff_head. */ #include <linux/workqueue.h> /* We need tq_struct. */ +#include <linux/flex_array.h> /* We need flex_array. */ #include <linux/sctp.h> /* We need sctp* header structs. */ #include <net/sctp/auth.h> /* We need auth specific structs */ #include <net/ip.h> /* For inet_skb_parm */ diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 16e36c0..be372b0 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c @@ -40,13 +40,60 @@ struct sctp_stream_out *sctp_stream_out_ptr(const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_out *)(stream->out)) + sid; + return flex_array_get(stream->out, sid); } struct sctp_stream_in *sctp_stream_in_ptr(const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_in *)(stream->in)) + sid; + return flex_array_get(stream->in, sid); +} + +static struct flex_array *fa_alloc(size_t elem_size, size_t elem_count, + gfp_t gfp) +{ + struct flex_array *result; + int err; + + result = flex_array_alloc(elem_size, elem_count, gfp); + if (result) { + err = flex_array_prealloc(result, 0, elem_count, gfp); + if (err) { + flex_array_free(result); + result = NULL; + } + } + + return result; +} + +static void fa_free(struct flex_array *fa) +{ + if (fa) + flex_array_free(fa); +} + +static void fa_copy(struct flex_array *fa, struct flex_array *from, + size_t index, size_t count) +{ + void *elem; + + while (count--) { + elem = flex_array_get(from, index); + flex_array_put(fa, index, elem, 0); + index++; + } +} + +static void fa_zero(struct flex_array *fa, size_t index, size_t count) +{ + void *elem; + + while (count--) { + elem = flex_array_get(fa, index); + memset(elem, 0, fa->element_size); + index++; + } } /* Migrates chunks from stream queues to new stream queues if needed, @@ -106,19 +153,17 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, struct flex_array *out; size_t elem_size = sizeof(struct sctp_stream_out); - out = kmalloc_array(outcnt, elem_size, gfp); + out = fa_alloc(elem_size, outcnt, gfp); if (!out) return -ENOMEM; if (stream->out) { - memcpy(out, stream->out, min(outcnt, stream->outcnt) * - elem_size); - kfree(stream->out); + fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt)); + fa_free(stream->out); } if (outcnt > stream->outcnt) - memset(((struct sctp_stream_out *)out) + stream->outcnt, 0, - (outcnt - stream->outcnt) * elem_size); + fa_zero(out, stream->outcnt, (outcnt - stream->outcnt)); stream->out = out; @@ -131,20 +176,17 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, struct flex_array *in; size_t elem_size = sizeof(struct sctp_stream_in); - in = kmalloc_array(incnt, elem_size, gfp); - + in = fa_alloc(elem_size, incnt, gfp); if (!in) return -ENOMEM; if (stream->in) { - memcpy(in, stream->in, min(incnt, stream->incnt) * - elem_size); - kfree(stream->in); + fa_copy(in, stream->in, 0, min(incnt, stream->incnt)); + fa_free(stream->in); } if (incnt > stream->incnt) - memset(((struct sctp_stream_in *)in) + stream->incnt, 0, - (incnt - stream->incnt) * elem_size); + fa_zero(in, stream->incnt, (incnt - stream->incnt)); stream->in = in; @@ -188,7 +230,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, ret = sctp_stream_alloc_in(stream, incnt, gfp); if (ret) { sched->free(stream); - kfree(stream->out); + fa_free(stream->out); stream->out = NULL; stream->outcnt = 0; goto out; @@ -220,8 +262,8 @@ void sctp_stream_free(struct sctp_stream *stream) sched->free(stream); for (i = 0; i < stream->outcnt; i++) kfree(SCTP_SO(stream, i)->ext); - kfree(stream->out); - kfree(stream->in); + fa_free(stream->out); + fa_free(stream->in); } void sctp_stream_clear(struct sctp_stream *stream) -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Oleg Babin <obabin@virtuozzo.com> To: netdev@vger.kernel.org, linux-sctp@vger.kernel.org Cc: "David S. Miller" <davem@davemloft.net>, Vlad Yasevich <vyasevich@gmail.com>, Neil Horman <nhorman@tuxdriver.com>, Xin Long <lucien.xin@gmail.com>, Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>, Andrey Ryabinin <aryabinin@virtuozzo.com> Subject: [PATCH net-next 2/2] net/sctp: Replace in/out stream arrays with flex_array Date: Mon, 23 Apr 2018 18:41:06 +0000 [thread overview] Message-ID: <1524508866-317485-3-git-send-email-obabin@virtuozzo.com> (raw) In-Reply-To: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> This path replaces physically contiguous memory arrays allocated using kmalloc_array() with flexible arrays. This enables to avoid memory allocation failures on the systems under a memory stress. Signed-off-by: Oleg Babin <obabin@virtuozzo.com> --- include/net/sctp/structs.h | 1 + net/sctp/stream.c | 78 +++++++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 578bb40..c7f42b4 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -57,6 +57,7 @@ #include <linux/atomic.h> /* This gets us atomic counters. */ #include <linux/skbuff.h> /* We need sk_buff_head. */ #include <linux/workqueue.h> /* We need tq_struct. */ +#include <linux/flex_array.h> /* We need flex_array. */ #include <linux/sctp.h> /* We need sctp* header structs. */ #include <net/sctp/auth.h> /* We need auth specific structs */ #include <net/ip.h> /* For inet_skb_parm */ diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 16e36c0..be372b0 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c @@ -40,13 +40,60 @@ struct sctp_stream_out *sctp_stream_out_ptr(const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_out *)(stream->out)) + sid; + return flex_array_get(stream->out, sid); } struct sctp_stream_in *sctp_stream_in_ptr(const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_in *)(stream->in)) + sid; + return flex_array_get(stream->in, sid); +} + +static struct flex_array *fa_alloc(size_t elem_size, size_t elem_count, + gfp_t gfp) +{ + struct flex_array *result; + int err; + + result = flex_array_alloc(elem_size, elem_count, gfp); + if (result) { + err = flex_array_prealloc(result, 0, elem_count, gfp); + if (err) { + flex_array_free(result); + result = NULL; + } + } + + return result; +} + +static void fa_free(struct flex_array *fa) +{ + if (fa) + flex_array_free(fa); +} + +static void fa_copy(struct flex_array *fa, struct flex_array *from, + size_t index, size_t count) +{ + void *elem; + + while (count--) { + elem = flex_array_get(from, index); + flex_array_put(fa, index, elem, 0); + index++; + } +} + +static void fa_zero(struct flex_array *fa, size_t index, size_t count) +{ + void *elem; + + while (count--) { + elem = flex_array_get(fa, index); + memset(elem, 0, fa->element_size); + index++; + } } /* Migrates chunks from stream queues to new stream queues if needed, @@ -106,19 +153,17 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, struct flex_array *out; size_t elem_size = sizeof(struct sctp_stream_out); - out = kmalloc_array(outcnt, elem_size, gfp); + out = fa_alloc(elem_size, outcnt, gfp); if (!out) return -ENOMEM; if (stream->out) { - memcpy(out, stream->out, min(outcnt, stream->outcnt) * - elem_size); - kfree(stream->out); + fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt)); + fa_free(stream->out); } if (outcnt > stream->outcnt) - memset(((struct sctp_stream_out *)out) + stream->outcnt, 0, - (outcnt - stream->outcnt) * elem_size); + fa_zero(out, stream->outcnt, (outcnt - stream->outcnt)); stream->out = out; @@ -131,20 +176,17 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, struct flex_array *in; size_t elem_size = sizeof(struct sctp_stream_in); - in = kmalloc_array(incnt, elem_size, gfp); - + in = fa_alloc(elem_size, incnt, gfp); if (!in) return -ENOMEM; if (stream->in) { - memcpy(in, stream->in, min(incnt, stream->incnt) * - elem_size); - kfree(stream->in); + fa_copy(in, stream->in, 0, min(incnt, stream->incnt)); + fa_free(stream->in); } if (incnt > stream->incnt) - memset(((struct sctp_stream_in *)in) + stream->incnt, 0, - (incnt - stream->incnt) * elem_size); + fa_zero(in, stream->incnt, (incnt - stream->incnt)); stream->in = in; @@ -188,7 +230,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, ret = sctp_stream_alloc_in(stream, incnt, gfp); if (ret) { sched->free(stream); - kfree(stream->out); + fa_free(stream->out); stream->out = NULL; stream->outcnt = 0; goto out; @@ -220,8 +262,8 @@ void sctp_stream_free(struct sctp_stream *stream) sched->free(stream); for (i = 0; i < stream->outcnt; i++) kfree(SCTP_SO(stream, i)->ext); - kfree(stream->out); - kfree(stream->in); + fa_free(stream->out); + fa_free(stream->in); } void sctp_stream_clear(struct sctp_stream *stream) -- 1.8.3.1
next prev parent reply other threads:[~2018-04-23 18:41 UTC|newest] Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-04-23 18:41 [PATCH net-next 0/2] net/sctp: Avoid allocating high order memory with kmalloc() Oleg Babin 2018-04-23 18:41 ` Oleg Babin 2018-04-23 18:41 ` [PATCH net-next 1/2] net/sctp: Make wrappers for accessing in/out streams Oleg Babin 2018-04-23 18:41 ` Oleg Babin 2018-04-23 21:33 ` Marcelo Ricardo Leitner 2018-04-23 21:33 ` Marcelo Ricardo Leitner 2018-04-26 22:19 ` Oleg Babin 2018-04-26 22:19 ` Oleg Babin 2018-04-23 18:41 ` Oleg Babin [this message] 2018-04-23 18:41 ` [PATCH net-next 2/2] net/sctp: Replace in/out stream arrays with flex_array Oleg Babin 2018-04-23 21:33 ` [PATCH net-next 0/2] net/sctp: Avoid allocating high order memory with kmalloc() Marcelo Ricardo Leitner 2018-04-23 21:33 ` Marcelo Ricardo Leitner 2018-04-26 22:14 ` Oleg Babin 2018-04-26 22:14 ` Oleg Babin 2018-04-26 22:28 ` Marcelo Ricardo Leitner 2018-04-26 22:28 ` Marcelo Ricardo Leitner 2018-04-26 22:45 ` Oleg Babin 2018-04-26 22:45 ` Oleg Babin 2018-07-24 15:35 ` Konstantin Khorenko 2018-07-24 15:35 ` Konstantin Khorenko 2018-07-24 17:36 ` Marcelo Ricardo Leitner 2018-07-24 17:36 ` Marcelo Ricardo Leitner 2018-08-03 16:21 ` [PATCH v2 " Konstantin Khorenko 2018-08-03 16:21 ` Konstantin Khorenko 2018-08-03 16:21 ` [PATCH v2 1/2] net/sctp: Make wrappers for accessing in/out streams Konstantin Khorenko 2018-08-03 16:21 ` Konstantin Khorenko 2018-08-03 16:41 ` David Laight 2018-08-03 16:41 ` David Laight 2018-08-03 19:50 ` David Miller 2018-08-03 19:50 ` David Miller 2018-08-09 8:39 ` Konstantin Khorenko 2018-08-09 8:39 ` Konstantin Khorenko 2018-08-03 20:40 ` Marcelo Ricardo Leitner 2018-08-03 20:40 ` Marcelo Ricardo Leitner 2018-08-09 8:40 ` Konstantin Khorenko 2018-08-09 8:40 ` Konstantin Khorenko 2018-08-03 16:21 ` [PATCH v2 2/2] net/sctp: Replace in/out stream arrays with flex_array Konstantin Khorenko 2018-08-03 16:21 ` Konstantin Khorenko 2018-08-03 16:43 ` [PATCH v2 0/2] net/sctp: Avoid allocating high order memory with kmalloc() David Laight 2018-08-03 16:43 ` David Laight 2018-08-03 20:30 ` Marcelo Ricardo Leitner 2018-08-03 20:30 ` Marcelo Ricardo Leitner 2018-08-03 20:56 ` Michael Tuexen 2018-08-03 20:56 ` Michael Tuexen 2018-08-06 9:34 ` David Laight 2018-08-06 9:34 ` David Laight 2018-08-08 14:48 ` Marcelo Ricardo Leitner 2018-08-08 14:48 ` Marcelo Ricardo Leitner 2018-08-03 23:36 ` Marcelo Ricardo Leitner 2018-08-03 23:36 ` Marcelo Ricardo Leitner 2018-08-09 8:43 ` Konstantin Khorenko 2018-08-09 8:43 ` Konstantin Khorenko 2018-08-10 17:03 ` Konstantin Khorenko 2018-08-10 17:03 ` Konstantin Khorenko 2018-08-10 17:11 ` [PATCH v3 " Konstantin Khorenko 2018-08-10 17:11 ` Konstantin Khorenko 2018-08-10 17:11 ` [PATCH v3 1/2] net/sctp: Make wrappers for accessing in/out streams Konstantin Khorenko 2018-08-10 17:11 ` Konstantin Khorenko 2018-08-10 17:11 ` [PATCH v3 2/2] net/sctp: Replace in/out stream arrays with flex_array Konstantin Khorenko 2018-08-10 17:11 ` Konstantin Khorenko 2018-08-11 19:36 ` [PATCH v3 0/2] net/sctp: Avoid allocating high order memory with kmalloc() David Miller 2018-08-11 19:36 ` David Miller 2018-08-10 17:41 ` [PATCH v2 " Marcelo Ricardo Leitner 2018-08-10 17:41 ` Marcelo Ricardo Leitner
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=1524508866-317485-3-git-send-email-obabin@virtuozzo.com \ --to=obabin@virtuozzo.com \ --cc=aryabinin@virtuozzo.com \ --cc=davem@davemloft.net \ --cc=linux-sctp@vger.kernel.org \ --cc=lucien.xin@gmail.com \ --cc=marcelo.leitner@gmail.com \ --cc=netdev@vger.kernel.org \ --cc=nhorman@tuxdriver.com \ --cc=vyasevich@gmail.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: linkBe 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.