From patchwork Fri Aug 10 17:11:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Khorenko X-Patchwork-Id: 956349 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=virtuozzo.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=virtuozzo.com header.i=@virtuozzo.com header.b="Ln58J5ae"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41nBWX0BrRz9s4Z for ; Sat, 11 Aug 2018 03:12:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728947AbeHJTnF (ORCPT ); Fri, 10 Aug 2018 15:43:05 -0400 Received: from mail-ve1eur01on0098.outbound.protection.outlook.com ([104.47.1.98]:45257 "EHLO EUR01-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727666AbeHJTnF (ORCPT ); Fri, 10 Aug 2018 15:43:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=uitworvKyKhRW2TT+LvbctyYmSGjqSztT1Nst3XnKy4=; b=Ln58J5aevDXInae58rzH33VujFKXiFmVfcBrK1SOKJBqMZY43sttns+2/B/s8XtidCtWfMItnpil3XofDjiW0UOfR5Mo7pJKO9p12NIflTXcIAYJ2S7mES7dAECR+X6uHYRFA6FLGIJ2sxydkYRukJeYxdFJf+qYvybf+8V01jU= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=khorenko@virtuozzo.com; Received: from finist_ce7.work (185.231.240.5) by AM0PR08MB3105.eurprd08.prod.outlook.com (2603:10a6:208:5c::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1038.22; Fri, 10 Aug 2018 17:11:54 +0000 From: Konstantin Khorenko To: Marcelo Ricardo Leitner Cc: oleg.babin@gmail.com, netdev@vger.kernel.org, linux-sctp@vger.kernel.org, "David S . Miller" , Vlad Yasevich , Neil Horman , Xin Long , Andrey Ryabinin , Konstantin Khorenko Subject: [PATCH v3 2/2] net/sctp: Replace in/out stream arrays with flex_array Date: Fri, 10 Aug 2018 20:11:43 +0300 Message-Id: <20180810171143.21592-3-khorenko@virtuozzo.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180810171143.21592-1-khorenko@virtuozzo.com> References: <20180810171143.21592-1-khorenko@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [185.231.240.5] X-ClientProxiedBy: HE1PR05CA0161.eurprd05.prod.outlook.com (2603:10a6:7:28::48) To AM0PR08MB3105.eurprd08.prod.outlook.com (2603:10a6:208:5c::30) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: c68c35c4-6bf2-4ae3-43f1-08d5fee45ff3 X-Microsoft-Antispam: BCL:0; PCL:0; RULEID:(7020095)(4652040)(8989117)(4534165)(4627221)(201703031133081)(201702281549075)(8990107)(5600074)(711020)(2017052603328)(7153060)(7193020); SRVR:AM0PR08MB3105; X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3105; 3:gG+IPA1F5yTBsyq2z0P334k6RQkJfcQDeNb7qQZpb4+V3JU/xrpxtSS06H0We29E7f1PDL+yiu/QRsUGwvyMQ58WXLftxSrSo3t1PGAFsYtXCUGK2PYnElN7fG4icEK0IXXqMcrRyNUTwPZZY08g5+gO3FWvSFR339B7N3I+rBzuPsVL267lkLrHyx34mX1Q73w17+LW1wOQpjTETH/QWMxKpi8MDqi5Bh9c/sQdLX9m6ekzr1MlkTDnDPy17GLL; 25:f14fDCia3wDcRzBYyQPxpN2x9Ue7YW3kXPN26akqtYFZg5AnwK0XP/Y5UZ5rkEKN+2PHGKqkdjabLdfYyiMX3LLIGJlyniprYF3Ru99k5YycQUvXKuvbCCw81hIINRjjA+bHQKNvOvr6w4OzAMWVSBAZGA/UQxKnGguuQyds3jAhpimVSHts9F7OOgmjowYkR6Iec/KiE+ioJBfNoypqcr4WWSF1tepbOaqGQcDX9FwErcAZwgtB/v307vW28mLt9MUy5fDGjmBC+qWUaeAhHpthcVIuZK83k9iz8fvA6Eeermp8GijkfEfqxmiJ/UO+7dj21m0xpVwE9EXNc/oc5Q==; 31:h3aOU/VrFRTlc7PwdOkjrY9qaWddQ/JVX+u9iGX8Rwb/a7PJGUKSkQyIwjIQ7xtyi/rFahVAjsEcx2NQ5aAgeMGX5RI6eYBSA5I3VY/MNSHIesjz50UiuQLhGT0/iz9UIIqtkrinhkgmNb7HBy7xPiD8p/Y7RkDMxjzE/1Ge0z8uSsmJmeK7Z17qLMYpzoPat7oT2XGDbQc1xBWYNM2GATfM+PDDNTbgj9p3jVbJ9Cg= X-MS-TrafficTypeDiagnostic: AM0PR08MB3105: X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3105; 20:xBkT/0f2nOsDab7v/efLQZYPB5Qcp6cYF6COS/GnsAzaAK0zjiytlWoFFznnuP3e2jAfSLVr5TwL1OjT26+bEPfxSYML44OMWWqPvBi6WFyXU8TenJw3rkbAmpSLcynVZsAa9BVGkV8F4esIR8XxHTXUfMUnAxNy488181W9O5k+7ITSOtGHLFkjtjlrhlkCl7eb6IMZZipySDThOVnRlVtXXMZRRUlYUIX0alWxyFngN0mxigDcoI4BGU/2l/d7W+jPTXFmE8yqO2sai4G68qlfxmMrqlsjYDNvZcYeQnnA/BPayEjPRFQXLF8l95YVUo7l83acp+5cpr3w0RWbHq8pXVvH2yRnCI0ElG/K/7w4ZKZmZzUNOY/E4ZOEPD81+ylladWmH3fT29Z0DTmQtzTmOqWd8TtDraEa7tM8nbyIA+VJrFYsLRPdPvTKaS45I073dljlD3jZqwOtC8C5fLO3HLmhYteCu9IAK27QFnTbLqfB3zK291lbf/jWMvMl; 4:xt+I2cbKmk7lbrmzKmfASkv3WcTjtphykZiG5sBsu3Cz1Oari9LY5DiQZkT1n6MPkFdNXXvDEKSZ8ASHfemrYGPHlQVDeQudT6g/6ok0DFW0Rl1bVvb3R4WSBRMrzW192CjpKRl9j2RQdXwpIOYkQ7JEnds9f40x76iGk//PcW2vuTE+cv6/6DE/e/eNf8EaWFp69GsRh7EwsoK0jN3nwj4Iq2vXs+d0GrWb5hlYNvCI56lyjOMNzUzsflR8zf/Ep3uSf8KlPYNt72yKGz4E952nedJWwFMfftA+TwlL/a00LD0Lh9k7jz7dmZ7UPe+v X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(788757137089); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231311)(944501410)(52105095)(3002001)(10201501046)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(20161123560045)(20161123564045)(20161123558120)(6072148)(201708071742011)(7699016); SRVR:AM0PR08MB3105; BCL:0; PCL:0; RULEID:; SRVR:AM0PR08MB3105; X-Forefront-PRVS: 07607ED19A X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(396003)(366004)(376002)(39850400004)(136003)(189003)(199004)(50226002)(97736004)(8936002)(76176011)(81156014)(48376002)(6486002)(81166006)(446003)(486006)(50466002)(6116002)(7736002)(305945005)(476003)(6512007)(8676002)(51416003)(11346002)(53936002)(386003)(52116002)(956004)(16526019)(3846002)(2616005)(186003)(6506007)(21086003)(2906002)(316002)(54906003)(36756003)(106356001)(69596002)(47776003)(26005)(478600001)(105586002)(39060400002)(107886003)(6666003)(14444005)(66066001)(4326008)(5660300001)(68736007)(16586007)(1076002)(6916009)(25786009)(86362001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM0PR08MB3105; H:finist_ce7.work; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3105; 23:6CjKeXoe62guiA98ajIy2bTEbrH3xL1uN2a7xzyWtG4reZZWcT6N/+NSq/0knJRJh7mNzWeG7FiAoOwjsa4UzGqvMm6vZX791ODqL6n2/9NREenow7SwBVATydKa1PxjwnJ0tK2nOlRuLvIVIbX0GaQMIqZe6Bt5fL/dYw8OFJdHlna7fg7gEIVACpsvLr3R6DhIqeARTBJ2xwOzONNKtLAL3AQpWemAWMRiz/XYiFy2jnPKZsiAjk32BVJn2XCUfQZu3Z5xs9CF9MTk13sHt+O8baVcY5oPmBs7pZJmDby0p2pBxXUr6Fo2ftSXm4KGKqKlQZo08b1jlMVmwMQQSiAOApzIMTzoObS69EoZgYy6vhJMc6f03RkvShm72RO9SBExLy4DUcmts/p/UweVvxdKKbUT52fmiQVFBqvXHCI+Kj19wjGm6RVFyEwcldXro39pKKfJChzCVjaZ9MwbFniIRj0j4NIXJJCY0My4TVeTe+yDQ7V3SMmOC9Vl3I0InQNekmfQw1IKtn8qpL9eWiwM6tQlrslH5lVovMAs+13E4TJRrLeAzTuIxwwkhC5Zhhsg/BKHsPc8lk1GDvssZ76BPoOPcAPL5x0f9q82RDMt2CeYystPLuPhLUcL9P5G6o1pYDVv+1JFA+F2Sut12r2rkxaOfawWyjW4+olGSxJODUXokMdJJ1bv0y2/okSlmZrK66Mqi2fyrpuB19YywtkQjb+/SKYegUnPYic19mxUKX5GJllhrYsNQZe/owmzSf8YFYhkBja5zDdAlBKID0211NQ+gKdQwZvusLmXS6nuZu+LZ28vZ1RkVfJyBpWYe8KFYNS4S0IZyMB9aFPBrmE0QA/ULxcOxSE8gGPkIP2eVESj793DmzvXCZTvGQUhPxetVyrue+qtLpjz38pny+XcOfhG2AzN5GBioLYdaK95RHchZPILZRl05tWoS4IeSgaiwtOOeUrPbbmATQkaQh5hL4KtzCD4dyFQDHcb1y7RRnVuAVTtbYERAiwogZtgsTkOd4iKU3TCb57wl1jCBxG7H4xwLLQwjWN4Ih0zNojtnbcqa9kdaEl/k76c8Gzi0S/WoFfsvlp5Y/Kv8U84AfTD8TF+ZYZ8gXG0Xi8zHUaw4gSZrmVeyv+Q8WaQeFgmdqfeLE5prW2U8hyh+gdCII1Qu1H75GBS8kxsSQi15cgYF62qM+I0guule40suntuoAUlLS82vivU9A0ZdlIYCe9i40XQqE3Fra470T0PYMBB0Lz16BFVWt195Lfar+AkPr6jTvZRBqCdkApCf1k0WDWESr98NnVK5AL7ko5QunA= X-Microsoft-Antispam-Message-Info: ZzBxcDTuwYALaWhc+OPx2vPntKpbA+aqjVSv/OdTcZRNzCmvyI4Qvyo/tdwTDTQYqn3njvM5RYFR20bun/z2TC7k+Q25Z8DCLoSD6nIRXvG7AqdQ/9KS5OqkIp3d0Rat671BRE8l51IYiSizCRnJiMTVKQnPmDROqLla7h5EkwtR9DOcnRid49p5R9jN//NJFK4cqWapsbs7H+xs3mnds8IpKvsbUv0WAkcDONG6B/+o8df93nrCmy5wwY3QMlffhs3NgUdpQX5VGCRJW7APJlNNBA/LR5yMJrzTRMSTfiA+94LkSPsNrVs8w9I7q+bMvLKKNqw060P+z6SJ1neJJAenYOw5T9nr6MmXkzDjM2s= X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3105; 6:J+ChM6ncioUDuGC3XRFbc0bXz/NDI0oOzdmnvWIDBM9/VnLbLcNEZTEXMuxVtffnkc22V1TDrtNui0Pa7KETDi6CfWs15PSnMjVHm/yKZFaueQXKbQlfxlAxWcZk7NeikElVMCdG1+atzEaVlxoeE1L/Tuw7xpbek/uKcq3Ox8N7QU16b9rYrVN0UTMhFABNKca0Qn206/IkllJk8wkMGgzqYonIaQEY/IPXoOUwkrPiNKXg+KknjjV8cX1NZDe5FKm1P8Sg2QLhAQAiUCGrz5nVl/p4gy2B06c5xdJiA1bEBIGvP9qfjGjWXE/TzPmjMdf/YYaViOevKxmf0/vtk3a4upJzz5nwWd5HyZHxk2fDwiUA0sVZsvFpkUXfqIW2JxQy1s9hOOdXKfJxWI75yAkVnjF5CAozYfdQeag2xb2PKUxcoBcvA1hkJp3bC5T5UX//CCk9xH3pUq68E39+9w==; 5:Z8YPENADcpdmNIp+8atEMjU7amdJjJTi1qMd2Qyb/2Zh3NaV2Rdo7FWQ+C620NVKkQFN+SYsnMAs1K0dYfZDsVH53Nd/L+jL06Tp+a7minrhV6R7ppMtnYKhp/mtFssyOZio4exQX/MTKzzUrIkMgKa468o81pOcZlTsp/tRo+o=; 7:SZCQoppV1kaKSyYzpu9EbKtlR67NIh7cICS+6NUQtMUxjlSsMf+SiZfJzIFnOnZObaK9YpNQWe+orvtEtpd4czBliUDWEdwhQXb9C2y6KEiPANLSms0y6A50JLgzDvSSB+qF8cZjtMLnvPV+gp7ujNUKPFKf8fNFE3YgeUogwjeaIsU66QORfs50DRqOhlo3/ZwZJVYeMqeP40DfMBzSN7JxVYHvjGK4I90OlRo62Z0N3LQd2p+hyALYIZcLc6IB SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM0PR08MB3105; 20:iISGMrsF5mupGxhv+H1X7cUN9j/ok5Ms4JXTvVT+PuMxY/3riHrOha/Si/tCRAc6l3jQ30apZ/Qd0fiGU3ytrG5rwWJktvWD8iBpSeDzSD/+23nH8V6yGW/hZY4LJTGLtuEXUvPmDMO0VRhOI7D6lvy5jsLjpQcrEkr/+GIB0Yw= X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 10 Aug 2018 17:11:54.8726 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c68c35c4-6bf2-4ae3-43f1-08d5fee45ff3 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR08MB3105 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Signed-off-by: Konstantin Khorenko --- include/net/sctp/structs.h | 9 ++--- net/sctp/stream.c | 88 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index ce4bf844f573..f922db8029e6 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -57,6 +57,7 @@ #include /* This gets us atomic counters. */ #include /* We need sk_buff_head. */ #include /* We need tq_struct. */ +#include /* We need flex_array. */ #include /* We need sctp* header structs. */ #include /* We need auth specific structs */ #include /* For inet_skb_parm */ @@ -1431,8 +1432,8 @@ struct sctp_stream_in { }; struct sctp_stream { - struct sctp_stream_out *out; - struct sctp_stream_in *in; + struct flex_array *out; + struct flex_array *in; __u16 outcnt; __u16 incnt; /* Current stream being sent, if any */ @@ -1458,14 +1459,14 @@ static inline struct sctp_stream_out *sctp_stream_out( const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_out *)(stream->out)) + sid; + return flex_array_get(stream->out, sid); } static inline struct sctp_stream_in *sctp_stream_in( const struct sctp_stream *stream, __u16 sid) { - return ((struct sctp_stream_in *)(stream->in)) + sid; + return flex_array_get(stream->in, sid); } #define SCTP_SO(s, i) sctp_stream_out((s), (i)) diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 7ca6fe4e7882..ffb940d3b57c 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c @@ -37,6 +37,53 @@ #include #include +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, * but not across associations. Also, removes those chunks to streams * higher than the new max. @@ -78,34 +125,33 @@ static void sctp_stream_outq_migrate(struct sctp_stream *stream, * sctp_stream_update will swap ->out pointers. */ for (i = 0; i < outcnt; i++) { - kfree(new->out[i].ext); - new->out[i].ext = stream->out[i].ext; - stream->out[i].ext = NULL; + kfree(SCTP_SO(new, i)->ext); + SCTP_SO(new, i)->ext = SCTP_SO(stream, i)->ext; + SCTP_SO(stream, i)->ext = NULL; } } for (i = outcnt; i < stream->outcnt; i++) - kfree(stream->out[i].ext); + kfree(SCTP_SO(stream, i)->ext); } static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, gfp_t gfp) { - struct sctp_stream_out *out; + struct flex_array *out; + size_t elem_size = sizeof(struct sctp_stream_out); - out = kmalloc_array(outcnt, sizeof(*out), gfp); + out = fa_alloc(elem_size, outcnt, gfp); if (!out) return -ENOMEM; if (stream->out) { - memcpy(out, stream->out, min(outcnt, stream->outcnt) * - sizeof(*out)); - kfree(stream->out); + fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt)); + fa_free(stream->out); } if (outcnt > stream->outcnt) - memset(out + stream->outcnt, 0, - (outcnt - stream->outcnt) * sizeof(*out)); + fa_zero(out, stream->outcnt, (outcnt - stream->outcnt)); stream->out = out; @@ -115,22 +161,20 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt, static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt, gfp_t gfp) { - struct sctp_stream_in *in; - - in = kmalloc_array(incnt, sizeof(*stream->in), gfp); + struct flex_array *in; + size_t elem_size = sizeof(struct sctp_stream_in); + in = fa_alloc(elem_size, incnt, gfp); if (!in) return -ENOMEM; if (stream->in) { - memcpy(in, stream->in, min(incnt, stream->incnt) * - sizeof(*in)); - kfree(stream->in); + fa_copy(in, stream->in, 0, min(incnt, stream->incnt)); + fa_free(stream->in); } if (incnt > stream->incnt) - memset(in + stream->incnt, 0, - (incnt - stream->incnt) * sizeof(*in)); + fa_zero(in, stream->incnt, (incnt - stream->incnt)); stream->in = in; @@ -174,7 +218,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; @@ -206,8 +250,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)