From patchwork Mon Apr 23 18:41:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Babin X-Patchwork-Id: 903149 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="YWLuNyTW"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40VFgG0f9nz9ry1 for ; Tue, 24 Apr 2018 04:42:02 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932317AbeDWSmA (ORCPT ); Mon, 23 Apr 2018 14:42:00 -0400 Received: from mail-eopbgr00116.outbound.protection.outlook.com ([40.107.0.116]:29696 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932215AbeDWSlk (ORCPT ); Mon, 23 Apr 2018 14:41:40 -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; bh=zjocJBoPBEz92m5QHOmaAWSljwOX7S1PNL/mLkkkf3o=; b=YWLuNyTWJTfKuJmaExDBq0N971BQ7DUAxY9H87gRO5GRSEeqjhPpmT6CzoAehccWzhk2X7J9+KDCI/KwsSCUkyUg6IFJ+11YleDsAAzlL8+pzuMJGOp+dcfp+Y2Aqmk5CZvZY3hd7NXzqYxqGb3i728qGIQ8kC0A/NyAWsvNe+g= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=obabin@virtuozzo.com; Received: from ovbabin-vz.sw.ru (195.214.232.6) by AM6PR08MB3285.eurprd08.prod.outlook.com (2603:10a6:209:47::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.696.12; Mon, 23 Apr 2018 18:41:31 +0000 From: Oleg Babin To: netdev@vger.kernel.org, linux-sctp@vger.kernel.org Cc: "David S. Miller" , Vlad Yasevich , Neil Horman , Xin Long , Marcelo Ricardo Leitner , Andrey Ryabinin Subject: [PATCH net-next 1/2] net/sctp: Make wrappers for accessing in/out streams Date: Mon, 23 Apr 2018 21:41:05 +0300 Message-Id: <1524508866-317485-2-git-send-email-obabin@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> References: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: AM5PR0701CA0008.eurprd07.prod.outlook.com (2603:10a6:203:51::18) To AM6PR08MB3285.eurprd08.prod.outlook.com (2603:10a6:209:47::26) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM6PR08MB3285; X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 3:EipF+7PceXIc1PtNj4rqjAsQm0PvXwfOsqcGAIQKTO3dysZdKzrPas3NQlcHURcoTFKh7I7nGDWbatOrn+3el2cDItAmnsLj/abylQfIPC9UrXWwVB7WcgRyDg5L+S5QKgx9ixfygcdtkZFWFTq7uIgWV4EYvXYU1ajajSb8TElzvRAFEMF+7tvZG4Qj/O1FYg7D3Kv9NpqoFYKswmsxg9W0aMC8kBDwCL05L7ozeCC931vt5F+0z3hggvTc5T2s; 25:jtv1pPoQ8Y8ATiK/LdG//Oz1KNVj2n/pDBdfY/AFmibkrBGLOs2hljFxdaLam8393Jb+h83tqf740LQ/5rNDAPFCqJ2wQCLKKqeeM3szetfkXJA1nxTefuusDRL2bRbqEjeQh89oPsZeSN+egA+kkEHQdCly1UhrigYqNZBUoY1QrSTrut+1NFPYV1riDsJ6mroMOpE+EFew3GBFExbyLQsswv9kOeu6d60FD9A4ZHgJXeeimrGwNGO8UdMzIY1dmCetEd+Wh4tPbRfuGhVFCCbeo9sDyU6eSPChZYq2Bmu0CwgtIQovTutoSqc24k92IAd1IrmHBmOzoow0A5vzxw==; 31:DX+Oer+qwQE6XZc7IitAo1+9/WwiVeK014brooh9S5b6ol+hIMkDOhhxhmkFU54GoUbAWiUaAxDo761IUDGrSRKy1/893bfhvk4LejQ4J1pXLgcxNWYFbrMnPNct0PO9XPL79WYkBvXSqUvYwAv/O/kMzLUW8+VID58SAYa8SQ7iJ3kSAUTEM3WixqEyNBLd6H8FfJ528Jakk2aKpK1uH5k7gMKtLY+PDrFLHqahMz4= X-MS-TrafficTypeDiagnostic: AM6PR08MB3285: X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 20:Dab49h9ps6f2BwS+7BkyxVtZQ+Cza7COJji90CJKSRKMJjQg84OCuJIQy9y6C/Rw6rLwFP75OOesU5Ua0oXXPfW82ekEZU+qixUTsIy+QCY+ip2Orrgz1PW6Rop6JpJ7QwppL3T7NVG12QZskd8u/YCe93ZK7L4EFfceyIqRSVul65fXEDLplDlhf5eKpyA5nLUq3sYCNd+qtXOsIohJ3YlhuXuAEij2p3Ulcc72IsL2ZWxepSdOT3YcUvdG84Edogx1HHgo6hdhOev6V9JVKPzjpXl5Z6gs2Gd04/2/ZcbUuvXk2Fr9V3MTsxfFQCdJxMt0k+1rxtHTPL4uEDrHkai6rtdAqn4dcZ3Fvgcg6db6a2xZifxg+V2fcwMxCOXr9TFBm5th64KrwziGZpUvJUejkp/JAfT5ZS9e64l6xMT+awR8rhB3lAksPAoJlc5/NmPMGoiZfSjaGUEXBgzEBxR4R8a1rBKdtAr7FzZWa+U5dQIvVC1fjg02G7wRBjpm; 4:COFDmB4ekBwGEePx+pSATc4nmWs6K247MSF80h3UqgSyALG+qVdS2ypZLwuxk38NKQYfEiLn3zR+6e1+NiRjfENIKCFXKbCQvuolTgmvUQSgV+x9zL56Y5k5hq5wdOIMUcy+QMSMWCwWW3rHvv4WtFVg4vL6SIh+hE5jRuVwQ0JBpHj5esg9KoJb7AnEIG2MDxRnk+IrQuoTV0HotOChd/cwGXnlmlN+HfApeVH15rsnYztBHXKwn25bWKXQh3aV9GbvRhmo/+h14Q59IiSllllXlELs4KiQxqxHbh5s8jIhBwBV8bW/QBW9Vrs62GL1 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(788757137089); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(10201501046)(3231232)(944501410)(52105095)(3002001)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011); SRVR:AM6PR08MB3285; BCL:0; PCL:0; RULEID:; SRVR:AM6PR08MB3285; X-Forefront-PRVS: 06515DA04B X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(346002)(376002)(396003)(366004)(39850400004)(39380400002)(55236004)(25786009)(51416003)(59450400001)(52116002)(6506007)(386003)(107886003)(39060400002)(76176011)(6116002)(3846002)(2906002)(53416004)(6666003)(4720700003)(8936002)(4326008)(50226002)(81166006)(8676002)(7736002)(305945005)(5660300001)(36756003)(6512007)(53936002)(6486002)(66066001)(478600001)(47776003)(446003)(2616005)(575784001)(16526019)(186003)(48376002)(956004)(11346002)(316002)(26005)(50466002)(54906003)(476003)(86362001)(16586007); DIR:OUT; SFP:1102; SCL:1; SRVR:AM6PR08MB3285; H:ovbabin-vz.sw.ru; FPR:; SPF:None; LANG:en; MLV:ovrnspm; PTR:InfoNoRecords; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 23:eeqkFPJzBHJiO1/uewhTs/smVFd4KOqpN3AvBU7ux+KgFN7+d9ThWuKu//U4apYH0K1bVs1VZlsIxN9noLKbHNUo3u3rgy5QwEHKuOu+Qg2+6AbQFZL8GL5j4QiOCm49cTGvXoWzGlEzPdcY9ykJdO3FZoOjYQHNRWYigvyEZR34q4g2lAjwmvRQOEZ/NO4NW5mMq4A2Eu5XhQkNRKug0yO9VLu+n1qQ0ciOLEG1bm1N/nMB3CZL8Q6eO/lkjuA5lXM4vmU+AXzy2ocToZL8jkhOdtDs0y3WMd/aEwPAOp7EUT6hah3I+LOYBQRnjojzAPkl/wR2ZpcRNO40ijkc0t+U2Z9w5nEzk07rhN4eVTJVa6CVMajjESaU2DM+Zhj6bGS16H2eGNjGGo56fHoet7ZLJAD0p7KMWth+muJ096b5Y8t1syTy8Qola97kuJw9aZiWyLQWafQn1iQjB55vP1pUsRUj7vZrcRz/scHVikxa1mYSrhllCP6StlVv83PDBw2VfOs5v4jvmUg5PgzO1qcMKMEAKLinKHFjpIw+MFCI6f8F7wC92Wn6SS7D3YATZzbC3iZaq1Yfstpuq5C1UtGVIezh7XP3EMgSLAf/7Pqxn5vhDU6Cj8kqg71iIzEmHhWh+n1UmLDpXlP1HBPySkHWUgDKn/g1US8IRU58uCpj6GCuF50oMImxYT7w01jOz9jvu3ND3moN6w/1SFw1masU5Ak/ODRxPzZXM0Qp3WIWnM+YbwsWGQs4Cvc4bUDXvH1cSI+AXOoNt0aC8FS8CLdIJLRFcaEzm0HbWmsUsrg3mIJpJDEND+z5psy+FQZc17mam+J6Hsz/vhfp33koanNdfz3FDYkwzxdjJ5BDm0yEEhoW1DLTWG3JhDgQLnHLXriWJiDK99Fhx7aHsjbt6ewx1TDfbvADU5WFoaB5/D0lKzkclQOLXlEp02Vv6cP2J14c+sVPuVhLRjz+t7Iz+guP6DBj/vm9c5zcgIcPmOcYzm9jxbVD25Ip2E5URfMZyhVylsNx4K+KBqDheTMLk+PKZ+tGJ3mwD8cINfyRh5F2hQD7CTMISK9HVI+r0Uuq0Bvh9EE6wLxiUNC8C/iaCyegfCmHcisG7trjGXLR6h53mjj9e1U3oG4JT3xpRyKHzYUJg7OJEHQaZKlwjHUtv8Ua//N76NK+NXVajZfPkfo= X-Microsoft-Antispam-Message-Info: hY8bRYxiBqS3pNrwnqdvIy+BIKVfLgTC+gCuptKwmgaTsUFQosdCZkqlhgMTqxVDT66I8X5y6BruodddiRaZ6+sXCE9PPe4fkEveYtB2yuibrwKwCymAheQUEvLt1yUCkYpavETiX60I837r+WyhsnzGLmAoAKut6UY/bu91iT/XxwQGj9sj4U3Mby4kPf1H X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 6:l4nPcXyNdajbZbHnIvtjgtOB8fwVM+4404/6rQF9ufIhtW46hyznZddaY3WUnrX3cCmR1G8hHG8/JB5tJIScmnr6LZdwM404EnUbRwl89N0AdhUYZmpZGPtfZllRdritaeavoRNn1TgC21/KSqbinVQIELTwwW6WqlrTp9eqsZV4f1H77Ls5cR65CcwZaHFIIK6puJazyEGNdV09ekRVI2vAPEaDpbmgi4uWBreWmXy1AEnFp48euyvpIt6+YGBPOFotRfV4qsUAo11a/grDODdtWsjSyfd7hr8O5Y2FLYdBhSHio90gUm2BMN+4LWVAiyyMsXRZPc6vJWdrtWXOR9ABvMbmq+LQdgUUAz2es5NotE3gXpkd5cAKwO9vD5Lr07PNaDmk0BkUQQiDxOpbO2sAIDZqYi7K93g8KVRONnjfkn7E8p6eJtTKOuet8c6PI1xSBehJToWFxWvBBuqS0Q==; 5:OT5BVIWKBzdqOZJDbB0Qz2RUCWW5Ta0mjg5URWm3uDYupgalEhudKYjpyFYIrmSHBaMxfGRggZBKT6QrcdccSAY03+rKoy2qOJ7bUijIopBNO6J6AZxqqY8HkEivg4bmzhNPdjRQ7MrO8Y+gMfxY+EeBQrfDR98KCLh9VCd2tDM=; 24:9DXlugrwngEjar5VXgdDu9R7ljdAQg8Wj3fQ/OWDvBCTBQQhjca6Je4sdoNlBxn3FM/utwgXGgu2crVsEs9lbDjHm2d+cm5+BKEarZhwCtI= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 7:GbGmZeugeDfuY260WSpUMUrbmWeSbwXhewODXhmjb4VgAAniqgWgTjW/jKNU/IWyLpgmcl+q89tpMy6DsWeBpg0BSj9hijO8GiyhuJmXT/shySF9oBCDzDt7vlv/0R/PvwQWMmCggYhoOt/5qghWt4Ad1b07fFmxzu3KUMOqt64pT1XUdMrPZ9BHTPcOOc3AEyWSt62adOZX1Y403/f4ZdUNVRtcfY9HvVs6iOO//sxuyqx67X2DRbfxyt26IQYt; 20:cPWvqsAFIvQ5sH8umhgo3FcKgkYPq+2xCx43mrXMf1h766g+5IUbt/PkoldPDQcG5YZ7hxtUm6qCuao5skevh+Ake072sjSaveV0KdEPcP7JLq0XeLXF/ofSxnYekFZFEOFQYwCDXsVDndysV/nBZB+8CMIj5fBjpCzv8zpXNMU= X-MS-Office365-Filtering-Correlation-Id: f79c1eda-04d9-4ee7-e3ec-08d5a949d53f X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Apr 2018 18:41:31.3234 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: f79c1eda-04d9-4ee7-e3ec-08d5a949d53f X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB3285 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch introduces wrappers for accessing in/out streams indirectly. This will enable to replace physically contiguous memory arrays of streams with flexible arrays (or maybe any other appropriate mechanism) which do memory allocation on a per-page basis. Signed-off-by: Oleg Babin --- include/net/sctp/structs.h | 30 +++++++----- net/sctp/chunk.c | 6 ++- net/sctp/outqueue.c | 11 +++-- net/sctp/socket.c | 4 +- net/sctp/stream.c | 107 +++++++++++++++++++++++++------------------ net/sctp/stream_interleave.c | 2 +- net/sctp/stream_sched.c | 13 +++--- net/sctp/stream_sched_prio.c | 22 ++++----- net/sctp/stream_sched_rr.c | 8 ++-- 9 files changed, 116 insertions(+), 87 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index a0ec462..578bb40 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -394,37 +394,37 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, /* What is the current SSN number for this stream? */ #define sctp_ssn_peek(stream, type, sid) \ - ((stream)->type[sid].ssn) + (sctp_stream_##type##_ptr((stream), (sid))->ssn) /* Return the next SSN number for this stream. */ #define sctp_ssn_next(stream, type, sid) \ - ((stream)->type[sid].ssn++) + (sctp_stream_##type##_ptr((stream), (sid))->ssn++) /* Skip over this ssn and all below. */ #define sctp_ssn_skip(stream, type, sid, ssn) \ - ((stream)->type[sid].ssn = ssn + 1) + (sctp_stream_##type##_ptr((stream), (sid))->ssn = ssn + 1) /* What is the current MID number for this stream? */ #define sctp_mid_peek(stream, type, sid) \ - ((stream)->type[sid].mid) + (sctp_stream_##type##_ptr((stream), (sid))->mid) /* Return the next MID number for this stream. */ #define sctp_mid_next(stream, type, sid) \ - ((stream)->type[sid].mid++) + (sctp_stream_##type##_ptr((stream), (sid))->mid++) /* Skip over this mid and all below. */ #define sctp_mid_skip(stream, type, sid, mid) \ - ((stream)->type[sid].mid = mid + 1) + (sctp_stream_##type##_ptr((stream), (sid))->mid = mid + 1) -#define sctp_stream_in(asoc, sid) (&(asoc)->stream.in[sid]) +#define sctp_stream_in(asoc, sid) sctp_stream_in_ptr(&(asoc)->stream, (sid)) /* What is the current MID_uo number for this stream? */ #define sctp_mid_uo_peek(stream, type, sid) \ - ((stream)->type[sid].mid_uo) + (sctp_stream_##type##_ptr((stream), (sid))->mid_uo) /* Return the next MID_uo number for this stream. */ #define sctp_mid_uo_next(stream, type, sid) \ - ((stream)->type[sid].mid_uo++) + (sctp_stream_##type##_ptr((stream), (sid))->mid_uo++) /* * Pointers to address related SCTP functions. @@ -1428,8 +1428,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 */ @@ -1451,6 +1451,14 @@ struct sctp_stream { struct sctp_stream_interleave *si; }; +struct sctp_stream_out *sctp_stream_out_ptr(const struct sctp_stream *stream, + __u16 sid); +struct sctp_stream_in *sctp_stream_in_ptr(const struct sctp_stream *stream, + __u16 sid); + +#define SCTP_SO(s, i) sctp_stream_out_ptr((s), (i)) +#define SCTP_SI(s, i) sctp_stream_in_ptr((s), (i)) + #define SCTP_STREAM_CLOSED 0x00 #define SCTP_STREAM_OPEN 0x01 diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index be296d6..4b9310e 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -333,7 +333,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) && time_after(jiffies, chunk->msg->expires_at)) { struct sctp_stream_out *streamout = - &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; + SCTP_SO(&chunk->asoc->stream, + chunk->sinfo.sinfo_stream); if (chunk->sent_count) { chunk->asoc->abandoned_sent[SCTP_PR_INDEX(TTL)]++; @@ -347,7 +348,8 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) } else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) && chunk->sent_count > chunk->sinfo.sinfo_timetolive) { struct sctp_stream_out *streamout = - &chunk->asoc->stream.out[chunk->sinfo.sinfo_stream]; + SCTP_SO(&chunk->asoc->stream, + chunk->sinfo.sinfo_stream); chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++; streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++; diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index f211b3d..8d5d811 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -80,7 +80,7 @@ static inline void sctp_outq_head_data(struct sctp_outq *q, q->out_qlen += ch->skb->len; stream = sctp_chunk_stream_no(ch); - oute = q->asoc->stream.out[stream].ext; + oute = SCTP_SO(&q->asoc->stream, stream)->ext; list_add(&ch->stream_list, &oute->outq); } @@ -101,7 +101,7 @@ static inline void sctp_outq_tail_data(struct sctp_outq *q, q->out_qlen += ch->skb->len; stream = sctp_chunk_stream_no(ch); - oute = q->asoc->stream.out[stream].ext; + oute = SCTP_SO(&q->asoc->stream, stream)->ext; list_add_tail(&ch->stream_list, &oute->outq); } @@ -372,7 +372,7 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, sctp_insert_list(&asoc->outqueue.abandoned, &chk->transmitted_list); - streamout = &asoc->stream.out[chk->sinfo.sinfo_stream]; + streamout = SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream); asoc->sent_cnt_removable--; asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; @@ -416,7 +416,7 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc, asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; if (chk->sinfo.sinfo_stream < asoc->stream.outcnt) { struct sctp_stream_out *streamout = - &asoc->stream.out[chk->sinfo.sinfo_stream]; + SCTP_SO(&asoc->stream, chk->sinfo.sinfo_stream); streamout->ext->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; } @@ -1050,6 +1050,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) /* Finally, transmit new packets. */ while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { __u32 sid = ntohs(chunk->subh.data_hdr->stream); + __u8 stream_state = SCTP_SO(&asoc->stream, sid)->state; /* Has this chunk expired? */ if (sctp_chunk_abandoned(chunk)) { @@ -1059,7 +1060,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) continue; } - if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { + if (stream_state == SCTP_STREAM_CLOSED) { sctp_outq_head_data(q, chunk); goto sctp_flush_out; } diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 80835ac..3442f7c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1907,7 +1907,7 @@ static int sctp_sendmsg_to_asoc(struct sctp_association *asoc, goto err; } - if (unlikely(!asoc->stream.out[sinfo->sinfo_stream].ext)) { + if (unlikely(!SCTP_SO(&asoc->stream, sinfo->sinfo_stream)->ext)) { err = sctp_stream_init_ext(&asoc->stream, sinfo->sinfo_stream); if (err) goto err; @@ -6942,7 +6942,7 @@ static int sctp_getsockopt_pr_streamstatus(struct sock *sk, int len, if (!asoc || params.sprstat_sid >= asoc->stream.outcnt) goto out; - streamoute = asoc->stream.out[params.sprstat_sid].ext; + streamoute = SCTP_SO(&asoc->stream, params.sprstat_sid)->ext; if (!streamoute) { /* Not allocated yet, means all stats are 0 */ params.sprstat_abandoned_unsent = 0; diff --git a/net/sctp/stream.c b/net/sctp/stream.c index f799043..16e36c0 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c @@ -37,6 +37,18 @@ #include #include +struct sctp_stream_out *sctp_stream_out_ptr(const struct sctp_stream *stream, + __u16 sid) +{ + return ((struct sctp_stream_out *)(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; +} + /* 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 +90,35 @@ 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 = kmalloc_array(outcnt, elem_size, gfp); if (!out) return -ENOMEM; if (stream->out) { memcpy(out, stream->out, min(outcnt, stream->outcnt) * - sizeof(*out)); + elem_size); kfree(stream->out); } if (outcnt > stream->outcnt) - memset(out + stream->outcnt, 0, - (outcnt - stream->outcnt) * sizeof(*out)); + memset(((struct sctp_stream_out *)out) + stream->outcnt, 0, + (outcnt - stream->outcnt) * elem_size); stream->out = out; @@ -115,22 +128,23 @@ 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; + struct flex_array *in; + size_t elem_size = sizeof(struct sctp_stream_in); - in = kmalloc_array(incnt, sizeof(*stream->in), gfp); + in = kmalloc_array(incnt, elem_size, gfp); if (!in) return -ENOMEM; if (stream->in) { memcpy(in, stream->in, min(incnt, stream->incnt) * - sizeof(*in)); + elem_size); kfree(stream->in); } if (incnt > stream->incnt) - memset(in + stream->incnt, 0, - (incnt - stream->incnt) * sizeof(*in)); + memset(((struct sctp_stream_in *)in) + stream->incnt, 0, + (incnt - stream->incnt) * elem_size); stream->in = in; @@ -162,7 +176,7 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, stream->outcnt = outcnt; for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; sched->init(stream); @@ -193,7 +207,7 @@ int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid) soute = kzalloc(sizeof(*soute), GFP_KERNEL); if (!soute) return -ENOMEM; - stream->out[sid].ext = soute; + SCTP_SO(stream, sid)->ext = soute; return sctp_sched_init_sid(stream, sid, GFP_KERNEL); } @@ -205,7 +219,7 @@ void sctp_stream_free(struct sctp_stream *stream) sched->free(stream); for (i = 0; i < stream->outcnt; i++) - kfree(stream->out[i].ext); + kfree(SCTP_SO(stream, i)->ext); kfree(stream->out); kfree(stream->in); } @@ -215,12 +229,12 @@ void sctp_stream_clear(struct sctp_stream *stream) int i; for (i = 0; i < stream->outcnt; i++) { - stream->out[i].mid = 0; - stream->out[i].mid_uo = 0; + SCTP_SO(stream, i)->mid = 0; + SCTP_SO(stream, i)->mid_uo = 0; } for (i = 0; i < stream->incnt; i++) - stream->in[i].mid = 0; + SCTP_SI(stream, i)->mid = 0; } void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new) @@ -271,8 +285,8 @@ static bool sctp_stream_outq_is_empty(struct sctp_stream *stream, for (i = 0; i < str_nums; i++) { __u16 sid = ntohs(str_list[i]); - if (stream->out[sid].ext && - !list_empty(&stream->out[sid].ext->outq)) + if (SCTP_SO(stream, sid)->ext && + !list_empty(&SCTP_SO(stream, sid)->ext->outq)) return false; } @@ -359,11 +373,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc, if (out) { if (str_nums) for (i = 0; i < str_nums; i++) - stream->out[str_list[i]].state = + SCTP_SO(stream, str_list[i])->state = SCTP_STREAM_CLOSED; else for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_CLOSED; + SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED; } asoc->strreset_chunk = chunk; @@ -378,11 +392,11 @@ int sctp_send_reset_streams(struct sctp_association *asoc, if (str_nums) for (i = 0; i < str_nums; i++) - stream->out[str_list[i]].state = + SCTP_SO(stream, str_list[i])->state = SCTP_STREAM_OPEN; else for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; goto out; } @@ -416,7 +430,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc) /* Block further xmit of data until this request is completed */ for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_CLOSED; + SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED; asoc->strreset_chunk = chunk; sctp_chunk_hold(asoc->strreset_chunk); @@ -427,7 +441,7 @@ int sctp_send_reset_assoc(struct sctp_association *asoc) asoc->strreset_chunk = NULL; for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; return retval; } @@ -607,10 +621,10 @@ struct sctp_chunk *sctp_process_strreset_outreq( } for (i = 0; i < nums; i++) - stream->in[ntohs(str_p[i])].mid = 0; + SCTP_SI(stream, ntohs(str_p[i]))->mid = 0; } else { for (i = 0; i < stream->incnt; i++) - stream->in[i].mid = 0; + SCTP_SI(stream, i)->mid = 0; } result = SCTP_STRRESET_PERFORMED; @@ -681,11 +695,11 @@ struct sctp_chunk *sctp_process_strreset_inreq( if (nums) for (i = 0; i < nums; i++) - stream->out[ntohs(str_p[i])].state = + SCTP_SO(stream, ntohs(str_p[i]))->state = SCTP_STREAM_CLOSED; else for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_CLOSED; + SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED; asoc->strreset_chunk = chunk; asoc->strreset_outstanding = 1; @@ -784,11 +798,11 @@ struct sctp_chunk *sctp_process_strreset_tsnreq( * incoming and outgoing streams. */ for (i = 0; i < stream->outcnt; i++) { - stream->out[i].mid = 0; - stream->out[i].mid_uo = 0; + SCTP_SO(stream, i)->mid = 0; + SCTP_SO(stream, i)->mid_uo = 0; } for (i = 0; i < stream->incnt; i++) - stream->in[i].mid = 0; + SCTP_SI(stream, i)->mid = 0; result = SCTP_STRRESET_PERFORMED; @@ -977,15 +991,18 @@ struct sctp_chunk *sctp_process_strreset_resp( sizeof(__u16); if (result == SCTP_STRRESET_PERFORMED) { + struct sctp_stream_out *sout; if (nums) { for (i = 0; i < nums; i++) { - stream->out[ntohs(str_p[i])].mid = 0; - stream->out[ntohs(str_p[i])].mid_uo = 0; + sout = SCTP_SO(stream, ntohs(str_p[i])); + sout->mid = 0; + sout->mid_uo = 0; } } else { for (i = 0; i < stream->outcnt; i++) { - stream->out[i].mid = 0; - stream->out[i].mid_uo = 0; + sout = SCTP_SO(stream, i); + sout->mid = 0; + sout->mid_uo = 0; } } @@ -993,7 +1010,7 @@ struct sctp_chunk *sctp_process_strreset_resp( } for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags, nums, str_p, GFP_ATOMIC); @@ -1048,15 +1065,15 @@ struct sctp_chunk *sctp_process_strreset_resp( asoc->adv_peer_ack_point = asoc->ctsn_ack_point; for (i = 0; i < stream->outcnt; i++) { - stream->out[i].mid = 0; - stream->out[i].mid_uo = 0; + SCTP_SO(stream, i)->mid = 0; + SCTP_SO(stream, i)->mid_uo = 0; } for (i = 0; i < stream->incnt; i++) - stream->in[i].mid = 0; + SCTP_SI(stream, i)->mid = 0; } for (i = 0; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags, stsn, rtsn, GFP_ATOMIC); @@ -1070,7 +1087,7 @@ struct sctp_chunk *sctp_process_strreset_resp( if (result == SCTP_STRRESET_PERFORMED) for (i = number; i < stream->outcnt; i++) - stream->out[i].state = SCTP_STREAM_OPEN; + SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN; else stream->outcnt = number; diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c index d3764c1..46f9fb6 100644 --- a/net/sctp/stream_interleave.c +++ b/net/sctp/stream_interleave.c @@ -1053,7 +1053,7 @@ static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp) __u16 sid; for (sid = 0; sid < stream->incnt; sid++) { - struct sctp_stream_in *sin = &stream->in[sid]; + struct sctp_stream_in *sin = SCTP_SI(stream, sid); __u32 mid; if (sin->pd_mode_uo) { diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c index f5fcd42..a6c04a9 100644 --- a/net/sctp/stream_sched.c +++ b/net/sctp/stream_sched.c @@ -161,7 +161,7 @@ int sctp_sched_set_sched(struct sctp_association *asoc, /* Give the next scheduler a clean slate. */ for (i = 0; i < asoc->stream.outcnt; i++) { - void *p = asoc->stream.out[i].ext; + void *p = SCTP_SO(&asoc->stream, i)->ext; if (!p) continue; @@ -175,7 +175,7 @@ int sctp_sched_set_sched(struct sctp_association *asoc, asoc->outqueue.sched = n; n->init(&asoc->stream); for (i = 0; i < asoc->stream.outcnt; i++) { - if (!asoc->stream.out[i].ext) + if (!SCTP_SO(&asoc->stream, i)->ext) continue; ret = n->init_sid(&asoc->stream, i, GFP_KERNEL); @@ -217,7 +217,7 @@ int sctp_sched_set_value(struct sctp_association *asoc, __u16 sid, if (sid >= asoc->stream.outcnt) return -EINVAL; - if (!asoc->stream.out[sid].ext) { + if (!SCTP_SO(&asoc->stream, sid)->ext) { int ret; ret = sctp_stream_init_ext(&asoc->stream, sid); @@ -234,7 +234,7 @@ int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid, if (sid >= asoc->stream.outcnt) return -EINVAL; - if (!asoc->stream.out[sid].ext) + if (!SCTP_SO(&asoc->stream, sid)->ext) return 0; return asoc->outqueue.sched->get(&asoc->stream, sid, value); @@ -252,7 +252,7 @@ void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch) * priority stream comes in. */ sid = sctp_chunk_stream_no(ch); - sout = &q->asoc->stream.out[sid]; + sout = SCTP_SO(&q->asoc->stream, sid); q->asoc->stream.out_curr = sout; return; } @@ -272,8 +272,9 @@ void sctp_sched_dequeue_common(struct sctp_outq *q, struct sctp_chunk *ch) int sctp_sched_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) { struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream); + struct sctp_stream_out_ext *ext = SCTP_SO(stream, sid)->ext; - INIT_LIST_HEAD(&stream->out[sid].ext->outq); + INIT_LIST_HEAD(&ext->outq); return sched->init_sid(stream, sid, gfp); } diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c index 7997d35..2245083 100644 --- a/net/sctp/stream_sched_prio.c +++ b/net/sctp/stream_sched_prio.c @@ -75,10 +75,10 @@ static struct sctp_stream_priorities *sctp_sched_prio_get_head( /* No luck. So we search on all streams now. */ for (i = 0; i < stream->outcnt; i++) { - if (!stream->out[i].ext) + if (!SCTP_SO(stream, i)->ext) continue; - p = stream->out[i].ext->prio_head; + p = SCTP_SO(stream, i)->ext->prio_head; if (!p) /* Means all other streams won't be initialized * as well. @@ -165,7 +165,7 @@ static void sctp_sched_prio_sched(struct sctp_stream *stream, static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid, __u16 prio, gfp_t gfp) { - struct sctp_stream_out *sout = &stream->out[sid]; + struct sctp_stream_out *sout = SCTP_SO(stream, sid); struct sctp_stream_out_ext *soute = sout->ext; struct sctp_stream_priorities *prio_head, *old; bool reschedule = false; @@ -186,7 +186,7 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid, return 0; for (i = 0; i < stream->outcnt; i++) { - soute = stream->out[i].ext; + soute = SCTP_SO(stream, i)->ext; if (soute && soute->prio_head == old) /* It's still in use, nothing else to do here. */ return 0; @@ -201,7 +201,7 @@ static int sctp_sched_prio_set(struct sctp_stream *stream, __u16 sid, static int sctp_sched_prio_get(struct sctp_stream *stream, __u16 sid, __u16 *value) { - *value = stream->out[sid].ext->prio_head->prio; + *value = SCTP_SO(stream, sid)->ext->prio_head->prio; return 0; } @@ -215,7 +215,7 @@ static int sctp_sched_prio_init(struct sctp_stream *stream) static int sctp_sched_prio_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) { - INIT_LIST_HEAD(&stream->out[sid].ext->prio_list); + INIT_LIST_HEAD(&SCTP_SO(stream, sid)->ext->prio_list); return sctp_sched_prio_set(stream, sid, 0, gfp); } @@ -233,9 +233,9 @@ static void sctp_sched_prio_free(struct sctp_stream *stream) */ sctp_sched_prio_unsched_all(stream); for (i = 0; i < stream->outcnt; i++) { - if (!stream->out[i].ext) + if (!SCTP_SO(stream, i)->ext) continue; - prio = stream->out[i].ext->prio_head; + prio = SCTP_SO(stream, i)->ext->prio_head; if (prio && list_empty(&prio->prio_sched)) list_add(&prio->prio_sched, &list); } @@ -255,7 +255,7 @@ static void sctp_sched_prio_enqueue(struct sctp_outq *q, ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list); sid = sctp_chunk_stream_no(ch); stream = &q->asoc->stream; - sctp_sched_prio_sched(stream, stream->out[sid].ext); + sctp_sched_prio_sched(stream, SCTP_SO(stream, sid)->ext); } static struct sctp_chunk *sctp_sched_prio_dequeue(struct sctp_outq *q) @@ -297,7 +297,7 @@ static void sctp_sched_prio_dequeue_done(struct sctp_outq *q, * this priority. */ sid = sctp_chunk_stream_no(ch); - soute = q->asoc->stream.out[sid].ext; + soute = SCTP_SO(&q->asoc->stream, sid)->ext; prio = soute->prio_head; sctp_sched_prio_next_stream(prio); @@ -317,7 +317,7 @@ static void sctp_sched_prio_sched_all(struct sctp_stream *stream) __u16 sid; sid = sctp_chunk_stream_no(ch); - sout = &stream->out[sid]; + sout = SCTP_SO(stream, sid); if (sout->ext) sctp_sched_prio_sched(stream, sout->ext); } diff --git a/net/sctp/stream_sched_rr.c b/net/sctp/stream_sched_rr.c index 1155692..52ba743 100644 --- a/net/sctp/stream_sched_rr.c +++ b/net/sctp/stream_sched_rr.c @@ -100,7 +100,7 @@ static int sctp_sched_rr_init(struct sctp_stream *stream) static int sctp_sched_rr_init_sid(struct sctp_stream *stream, __u16 sid, gfp_t gfp) { - INIT_LIST_HEAD(&stream->out[sid].ext->rr_list); + INIT_LIST_HEAD(&SCTP_SO(stream, sid)->ext->rr_list); return 0; } @@ -120,7 +120,7 @@ static void sctp_sched_rr_enqueue(struct sctp_outq *q, ch = list_first_entry(&msg->chunks, struct sctp_chunk, frag_list); sid = sctp_chunk_stream_no(ch); stream = &q->asoc->stream; - sctp_sched_rr_sched(stream, stream->out[sid].ext); + sctp_sched_rr_sched(stream, SCTP_SO(stream, sid)->ext); } static struct sctp_chunk *sctp_sched_rr_dequeue(struct sctp_outq *q) @@ -154,7 +154,7 @@ static void sctp_sched_rr_dequeue_done(struct sctp_outq *q, /* Last chunk on that msg, move to the next stream */ sid = sctp_chunk_stream_no(ch); - soute = q->asoc->stream.out[sid].ext; + soute = SCTP_SO(&q->asoc->stream, sid)->ext; sctp_sched_rr_next_stream(&q->asoc->stream); @@ -173,7 +173,7 @@ static void sctp_sched_rr_sched_all(struct sctp_stream *stream) __u16 sid; sid = sctp_chunk_stream_no(ch); - soute = stream->out[sid].ext; + soute = SCTP_SO(stream, sid)->ext; if (soute) sctp_sched_rr_sched(stream, soute); } From patchwork Mon Apr 23 18:41:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Babin X-Patchwork-Id: 903148 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="a9fK+pvA"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40VFg6692Mz9rxx for ; Tue, 24 Apr 2018 04:41:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932299AbeDWSlv (ORCPT ); Mon, 23 Apr 2018 14:41:51 -0400 Received: from mail-eopbgr00116.outbound.protection.outlook.com ([40.107.0.116]:29696 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932085AbeDWSlo (ORCPT ); Mon, 23 Apr 2018 14:41:44 -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; bh=PrjHQDHM9HIIfude5uPPUNGSIB6fBr4It2oIWo2fhvE=; b=a9fK+pvAUr/wISVZJnUaUtAfAdTYEQ5YyTSSLrH9ojyV2bFTuNZ5hrHQ2DvEWucw9/GU73fla6YmxntPDzNFzHl2mFRhlEDjwF276ZAK8N/vZes1zCgCYAX63mThET3fb+cH61npoRRR8PWrMuVQQJ6UF/noef80tj02XKWc8ps= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=obabin@virtuozzo.com; Received: from ovbabin-vz.sw.ru (195.214.232.6) by AM6PR08MB3285.eurprd08.prod.outlook.com (2603:10a6:209:47::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.696.12; Mon, 23 Apr 2018 18:41:38 +0000 From: Oleg Babin To: netdev@vger.kernel.org, linux-sctp@vger.kernel.org Cc: "David S. Miller" , Vlad Yasevich , Neil Horman , Xin Long , Marcelo Ricardo Leitner , Andrey Ryabinin 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 Message-Id: <1524508866-317485-3-git-send-email-obabin@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> References: <1524508866-317485-1-git-send-email-obabin@virtuozzo.com> MIME-Version: 1.0 X-Originating-IP: [195.214.232.6] X-ClientProxiedBy: AM5PR0701CA0008.eurprd07.prod.outlook.com (2603:10a6:203:51::18) To AM6PR08MB3285.eurprd08.prod.outlook.com (2603:10a6:209:47::26) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(7168020)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:AM6PR08MB3285; X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 3:buTHyom6JAUgu7J0nhm9XjTlwp6I3gOYoaxtSbs9qQ8q52ouufM2/iS9soGmohEdn40yaZqbCvb1H1hUgedbXb9u9n13XswDM9z3UcskRpSvmGibDm69jNHBk4bZmQV1fFuyQQ0DT0J1urEoE+4rb8IZwglmsmmb3jEdQs5rdwISvczDYrTzLvBZByajRRVf7voDWLlCca6kAj70sGoX/V18G7XLIV4BxMFPxwpWj0ZX5qfNHBT0+i8j9yksDzw8; 25:fqpOXXI7tcV69lnwihMvRAXvwZEVYFCG1FA7Q/CKZzHGHD3sn0n/uzWbnY1fsarRdPaueSngW+FOt0N3iRRovEEs/sFftcDah4sp/XivStZEqC7aujUk3y+1m7F9U+RwGWH/01caXmfMloIeiru6EVeWmTHc3IwwG333XiXQB11AQGGo/uonRL6idbw/EobqXs6Irxfo9QkUeQHTWNS3yd31c5qT083oBkRYc4GfLAeam0d02PF9HxTJrMqvNpkEQ682nSS8WUDNFUnT9PXbLx9Km/oYaMdlO94q0MMk1QNEoXxgF9wRIidw4dcGzVoPir5aOyH6/Hg2QqIOQZ1bhA==; 31:+pnXWfG6z5KlKlXX4W4dwQy2CgsEU8cvqzZ7euygAamFBT7VV7d1fr2UE1r//VJdz5C4EJ+2wkOIY0q0EO51L8rcj6jLa6vJFS2ONsUV3PGY5YlYsPI+dSXSkFtxmjrA+k77AjlEheeM4HfUCBG4xv3eeEP1L4TtAuyLkl1+zoWi1pyeZfTQNY30Mq+0hrHTh/L9ZAUQ/yvApffYtJgmvGQDDOOqP07rmwIjAK8cCEY= X-MS-TrafficTypeDiagnostic: AM6PR08MB3285: X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 20:L37W6XNbTzm61jpO7GkvA1GsAEO/kc8RgQ6lVFw9xuqsPlUXyLyn06NFVnL79wZvl3iI+Su4COJArCdmJ1PC1jLdEWii+10PT1jWdK3iu4Tizn2EQf0ftdDdOUm+2GcBLlqirJJP15RbGmCnUlaRGyPhomV/APgFuqC7UXMDFwMiGnVIWlBkEE8Stvq7Dc+aNyry4ARv1Gn0JOAmQia5ZNmvY2DYNClwBt1F5CScoIkA8UaoxDd0cm47aQ61+3CqZ2FLswh85z5V4aUG0KBMct1pzSKQF6FOPcqiZ1VauZOdVd1kiawMMWtL30tc3OIGIVZkN/J1uMVMhtQGHCrVR+S1vbhXrulMWascgXGpjfQOzvMFYwA21xXhQFerTVXkCuKb7tsyBfQb01PWynb7zVTRGGIQC0sGmrPT7NFCoLI1KVFNv3gv8JJEfw341bEEm783ICCuw1E30/LPWJN3PctDWz3VFBPytPEZkZF8aAWoDmfzAEINykvaTM59rJU7; 4:KhwkFY+KeLTpDB6JTbJSOcN4OCdaOPok+7D/0cblUJk9DMiQcwpR2Bq/PQyj+APQc6/MqPh7P/H6AH1fMX7wJqkyGf/yJXEiKhcTUoFlToal8M58tLHEqGF4CugyFNFZIkMIhEZTdonRm4WP4N6NbtPKoVKlr3ZPXI7LH8ptiBY8RBylvyIpN6DAWhY2TC8bcOhBDq1/+UY9DBGvt4Q0VnsAp9Ga0kFjiviBmUkPyhCnELuBiTcLQKi8SanTk8EYmHhASNr3va5jXHO03SR7UzWLDBj9ndw1kGBaq+LCJdoGBFyLpBu9qs6jTnaN2e5/ X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(788757137089); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(10201501046)(3231232)(944501410)(52105095)(3002001)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123564045)(20161123558120)(20161123562045)(6072148)(201708071742011); SRVR:AM6PR08MB3285; BCL:0; PCL:0; RULEID:; SRVR:AM6PR08MB3285; X-Forefront-PRVS: 06515DA04B X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(39380400002)(39850400004)(366004)(396003)(346002)(376002)(6486002)(36756003)(5660300001)(53936002)(6512007)(26005)(54906003)(50466002)(956004)(48376002)(316002)(11346002)(16586007)(476003)(86362001)(446003)(66066001)(478600001)(47776003)(16526019)(186003)(2616005)(6116002)(3846002)(2906002)(53416004)(51416003)(52116002)(25786009)(6506007)(386003)(55236004)(107886003)(76176011)(39060400002)(8676002)(4326008)(8936002)(50226002)(81166006)(305945005)(7736002)(4720700003)(6666003); DIR:OUT; SFP:1102; SCL:1; SRVR:AM6PR08MB3285; H:ovbabin-vz.sw.ru; FPR:; SPF:None; LANG:en; MLV:ovrnspm; PTR:InfoNoRecords; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 23:1IagGtWfMlbHBaxSG8M617T/7Rm0iZBXfe73TPN/Qe/QNlnGEnhFyxXiL/+ehFkSwLj5iiPZt3aH64X7tQSJ228t4BDfJmZgNKCUmdCzvixBRidqvY4aeCEZy3WM6OT66Y3FWMGOp+axErg1KuGY5Ig4Mnqy4namAEOjwTnGuLrWAQAEIBBZeM0731izuGa6DNKRFeBkh51BhvIMDoD7RVmMDb6a7uqSl4ygI52bmkBMGJqJf9v0Fzn63PPnJDLtrMuDkiF5e7c27GDtwG4H8xRg5PUE+ec+DTHvcG/+HYuSLvONi8/39ARlt6C4mbDjIyL96yUAVSRT6Q/io+0UftBiRR17Bb2+BaSwzQ29g3wN+BUQOaUrAZLo3vXtTvotl2r2sH1Upn77IdBjBCb8cCo06DCvF+YvDeiS7xSfPlK9EWtfizSoiIgeI1BvkFPiUQBVR0EzNfSoAI1Jkmlua6s2d5acEbwUz5ywuw/USLVbSDi6eMUsTSYencPi8/+4alSdC7FWYVlMgUQop1jfwjiGO7j4+0vQlxD3rN57pccmEdfcOXXOe3WZUN2QscZJUIt+Jpp6jU05p3BuHco1HIsvDqg4+OfphAr0xpn408hcfSuHS8mFhMc7qqeYwssqtFquwHruFVz2D/zZ7CCjrfVviZI9lXRNUz0hof8VYuqIpxr9gUI0PaDjAn60yEnygS7gM5M+s1M2InjoBEi/iRORnm1Hoz9qji6CtQ1vwhZUpOXUNISxgZjCnTQzF2QYgI1oS4YIIwk8++aZbDT7Y5LnZNKx8caI3UfvcsXbn536LriOXSU6MRLyZxlc2OWKw4ddCmAEuYUorl0bLkd5uq7pwZUhgqjz97Blbe1g0AzLfWxpKNxYc2XXSKGOf1MWBTRS2150J0NrhAcFObJvIqBTQG+cMdghDijBT/xXcX/R6STh4lyVpdMm/vkAsCsB1/Zd0gNURngRxEbb+wgPj+o8gF8s8GJUZlV+qAvy5e/P+EbuoUpmfOGbgJfJ+uGUEDjYBGwi5G9AW8jfEQmAoSR6a94OeajwDpOj1iEddUecm95HONVpKsUwz1thoB7UnI5Ymrr5zgiGl5LCGikaN0zPAIgKWEphTHRE530nasiqu7PAYXCRzCxPiM41PVgl X-Microsoft-Antispam-Message-Info: dZAtoL/WNMLCiVMFEkNbtCS3RsnsOnYVpafl8Nh9aPELZ6saWrQiCzAoVc9YgZRnYN1P9ht4C4fPLsKlvMTe5A37gPZcm8HHD9jJfBgjzD43y9eaeM39mE5Vq8lPuTx+okI8svuUTCsVErEzg38k4o04F+82ZBO8cEoVSXJC5kgaUFfLjZGUbk74JD2zBQ7r X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 6:x9T4gLqHLTvZ8z+n6GT7k3u291vyQazVn9acHqOxVmx5f3faoSvPeNtp41EE+HArKo8jTtxa7TaXNBFfQQtgCVUkrPPROaIkqeauwuzxGSd0XLAofKrJK77rzbo4/p7rkVTKnJst29KO+IfFEV10CYOdT1f/2ubHj+CNAiDDgt5rPA/rsEuAe2xwRX1zdu7x61cy/Wu6UAzrKvZvA071P7X+Su39a8OWPtclthhj+4pz1jx86m/1OPLkfA6lUzuqM1pXRHN1w31ipGZ3QYUhm4N2GxlQX1UBlgrWWR5lW/QqLQHdemol8qQOx2sFLhu9vzuAX+TtHBQ8BBBNVxnWgGQG8en/QvNFPLtaFh4LTyfh/+6DHIUT9SkgY54rEW7ZI6PFM6fo2AIlriJvleP01100FndfQpHOb4V08LbMOJu01uiFeRWLnZBt7wroyy4mc6RUhEhL4FERUhyp0+PhXQ==; 5:nmXYI5N7bZiP4cWoeOhZJnH6RJM1T+yhPqSoEm94hfvG/XhSmB4cCIsKrM2BmfUMKflLPUHfO+7R3i1zoxgT6wTrgM+zL4y8x0nreq7U2M29SnfS6Hwde4fXgFV9khlc2EF2GICqnA9QL4REESa8PdoYtJk4GCQtSsGg//oqdM0=; 24:wCa6VHm0X1CgZBiU6eRxvPZ+mZ6P6CvryHT89xO1bLjwfTQkND7D07Vv5lTINye50ya4NHBHNC99gDE99S/WpUifsDthaVa+XIUruIeAfA4= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; AM6PR08MB3285; 7:APJ65UR1HeTz+5eltLyqLsAPMPmOXUjklQB2v4mnUzK01gQMYjfn4mityQmXQw85l1czcmEcOrfzYq56lEe4eqIXq75oYKxznse7NnyY2+j9ks7roz2uaRsabLXUOi8Xe3sDIyY0RHp+JEgw9Wyu4dWtSjkr4h876exHuLp/2Jif1wkp135UHhQzr4p0gCLEimwOt2Bjju7itciutgmLOi4yuGdWny101d8cg5pMbpeyRNG4RgWInGWfPlt2Ligp; 20:o+trTNYIAcMEkJRJlWQMteaG+5iWHzxnuwk4Gg+sdfQyU0Jrmkew1eXmBy0wwnUl2Hf9Eh5ic1xdkttk74euAxq2yLD5S3hctyCXj/MaN7mD4WrU+VRWEm3ZoocqEcvAaIY/HRcIrK2NyDm/+FRrEvDsM96KzqDW7I7Gw2+S1WA= X-MS-Office365-Filtering-Correlation-Id: 8a830132-1a51-4616-a2db-08d5a949d969 X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Apr 2018 18:41:38.3547 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 8a830132-1a51-4616-a2db-08d5a949d969 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR08MB3285 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 --- 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 /* 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 */ 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)