From patchwork Wed May 23 01:18:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 10421019 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 76B2860224 for ; Wed, 23 May 2018 12:06:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61D2128DDC for ; Wed, 23 May 2018 12:06:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 55A8028EEF; Wed, 23 May 2018 12:06:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from uhil19pa12.eemsg.mail.mil (uhil19pa12.eemsg.mail.mil [214.24.21.85]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 175D028F2C for ; Wed, 23 May 2018 12:06:24 +0000 (UTC) Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.2]) by uhil19pa12.eemsg.mail.mil with ESMTP; 23 May 2018 12:06:23 +0000 X-IronPort-AV: E=Sophos;i="5.49,432,1520899200"; d="scan'208";a="12082857" IronPort-PHdr: =?us-ascii?q?9a23=3AJ9/QaRNsmKZrsdQH1Xsl6mtUPXoX/o7sNwtQ0K?= =?us-ascii?q?IMzox0L/T7pMbcNUDSrc9gkEXOFd2Cra4c0KyO6+jJYi8p2d65qncMcZhBBV?= =?us-ascii?q?cuqP49uEgeOvODElDxN/XwbiY3T4xoXV5h+GynYwAOQJ6tL1LdrWev4jEMBx?= =?us-ascii?q?7xKRR6JvjvGo7Vks+7y/2+94fcbglUijexe69+IAmrpgjNq8cahpdvJLwswR?= =?us-ascii?q?XTuHtIfOpWxWJsJV2Nmhv3+9m98p1+/SlOovwt78FPX7n0cKQ+VrxYES8pM3?= =?us-ascii?q?sp683xtBnMVhWA630BWWgLiBVIAgzF7BbnXpfttybxq+Rw1DWGMcDwULs7Vy?= =?us-ascii?q?6i76N2QxH2jikJOSMy/GXOhsBtkK5XpRSsrAF9zYHJeoGYLPpwcL3Tc90ZQm?= =?us-ascii?q?ROXMhRWTFZAo6+cocCAeUOMvpXoYbjvFsDtge+CAu2Ce/z0DJEmmH60Ksn2O?= =?us-ascii?q?ohCwHG2wkgEsoLvnvKqtX1KLoZX/mrzKbW1zXDdO9W2S3j54fWbhAqvPaBXb?= =?us-ascii?q?FufsrX1UkjDQTFjkuOpoz/JDOVyv4NvHaF4Op8Tu+vhGsnpBtwojir3Msjlo?= =?us-ascii?q?7JhocMx13C6C53w541KMWlREN0btOoCptduzyAO4doTc4uXXtktDsixrAEpJ?= =?us-ascii?q?K3ZjYGxZooyhLFdvCKcZaE7gj9WOqMLjp1gm9udqiliBao60egz/XxVsyz0F?= =?us-ascii?q?lXsCVIisLMtnUR1xzL7ciHV+d98l+h2TmR0wDT7flJIVwumqrBKp4h36Uwmo?= =?us-ascii?q?APsUXDAiD2mEL2gLWQdko44ein9/7rYrDnpp+YL4N0iwf+PboymsGnHOg1PQ?= =?us-ascii?q?cDU3Kb9OihzrHv40L0TKtQgvEriqXZtYrVJcUfpq63GQ9V1YMj5g6kDzi41N?= =?us-ascii?q?QYnH8HLE9KeR6elIfpPEzOIPbkAvihmFShiytrxvDaMb3hBZXBNH7DkKz7cr?= =?us-ascii?q?pn5E5czxQzwchF551IErEBPO7zWkjpudzaCR85NRa7w/rnCNpn0IMTQmCPAq?= =?us-ascii?q?ifMKPXq1CI/f4vLPeWZI8Oojr9LOIl5/H2h38jhVAdZbWp3YcQaH2gHPRmIV?= =?us-ascii?q?+WbmbvgtcaFmcKuAs+TPLxhV2MVT5TenmzULkh5jE9FIKmEJ3PRoe3gLyOxC?= =?us-ascii?q?27BIFZZnhaClCQFnflb52EVOkXZy2MJM9hkyAEVb+6Ro8gyx6hqhH1x6BgLu?= =?us-ascii?q?rO9S0SrYjj28Rt5+3PiREy8iR5ANma02GLSWF7g30HRzs33K1ku0Ny1E2D0a?= =?us-ascii?q?9ij/xfD9xT6OtDUh0mOp7E0+x6F9fyVxrccdeVUlmmWM6rDi02TtI039ABeV?= =?us-ascii?q?19G8m4ghDFwSWqH6cfl6aXC5ws7qLcw3/xKt58y3bAyKkukV0mTdVKNWK4mq?= =?us-ascii?q?5/7QjSCpXOk0WBiamqc6Ec0zTM9GeH1mWOu05ZXBR3UaXfUnAVflHWosjh5k?= =?us-ascii?q?PeU7+uDqwqPRVZycGYMKtKa8bpgE5eRPj5ItTeYnmxm3+0BRmS2ryDcpDme2?= =?us-ascii?q?IH3CXSEEIEiRwc/W6aNQgiASesu2zfDD1qFVLqfUzs6/JzqH2lQUApyAGKdV?= =?us-ascii?q?du16Kv+h4Sh/yTVe8c3q4etCcmsTV0E06338jKBNqYuwphYKJcbMsz4Fddz2?= =?us-ascii?q?3ZsRByPp27L615g14eawV3s1r11xR5EYVMi88qrGklzABqM6KXzEtBdy+E3Z?= =?us-ascii?q?D3IrDXKXP9/BOoa67LwVze08yZ+qQI6PQlsVnjuxupFkU6+XV9z9ZVy2ec5o?= =?us-ascii?q?nNDAcKS53+T1w39xlkqLHAeSQy/Z/b1Xh2PamzqD/C1MojBPE5xRa4Y9dfLK?= =?us-ascii?q?SEGRfuHMIAA8ihNvcqm0SpbxIDJ+1S77I7P8K4ePuAxK6rPfxvkCigjWtZ/I?= =?us-ascii?q?B3yliM+DZkSu7Uw5YFxOmV3hGaWDjhl1qhvcX3mI9eaTEUAGW/1TDuBJRNaa?= =?us-ascii?q?1qYYYLFWCuLtWsxtVwnZ7tXGVY9EK4ClMd3s+pfhSTb1nn0g1Wz0gXp2KomT?= =?us-ascii?q?egxTxujz4ptraf3DDJw+n6ehsIIGpLRHV8glf2Ooi5lM4aU1aybwcyiRul4F?= =?us-ascii?q?z2x69BpKRwN2PTW1tHfzDqL2F+Vau9rqSCY89T55M0tiVXSv6wbkyaSr76pR?= =?us-ascii?q?sa3DjuH29fxDA9bT6qoJL5kwZ9iGKHI3Z5tGDZdt1oxRfD+NzcQuZc3j4HRC?= =?us-ascii?q?ljlTnbH0O8MMet/dWVkZfDr++/Wnm6Vp1LcCnry4KAuzeg5WFwBx2wgeyzkM?= =?us-ascii?q?X9EQcmyS/7y8VqVSLQoRbmZYnr06C6Pvx9fkZ0A1/95dF3GppjkoQsn5Ecw3?= =?us-ascii?q?8aho+a/XAfi2f8Lc1b2b7ibHoKXTMLwMDa4A7+2EB4LXKG2YT5Vm6bwsR/e9?= =?us-ascii?q?m2eGQW2jgy78pSEqeb8KREnTdpolq/tQ/ReeJynioZyfQw8H4VmecJuBYzwS?= =?us-ascii?q?WHGb0SAFJYMjL2lxST9dy+t6JXZHu1cbesykV+k9ehDKuNog5CQnr5fIktHT?= =?us-ascii?q?No5MVlLF3MyGHz6p3jeNTIc9ITsACbngzej+hTNZ0xluAGhSx5NmLhpXcl0f?= =?us-ascii?q?I0jQRy3ZGmu4iKM31t87ikAh5cLTD6e8IT+i3tjKpHkMaZxYavEo9mGjURU5?= =?us-ascii?q?viVeioHy4KtfT7KwaOFyUxqnSbGLrbAwCS80Jmr3XBE5ClKX6XOGUZzdVlRB?= =?us-ascii?q?mYOkNTmgYUUysmnpQhDACl2NThcFtl5jAW/lP4pAFDyuR0Nxn4V2fSvwmoZS?= =?us-ascii?q?kpR5iYNhpZ9BlC513SMcyc8O18Az1Y8oemrAyXJWyRfx5IAn0RWkyYG1DjOa?= =?us-ascii?q?Gj6sTc/OidAeq+KefObaiVpOxASfiI35Ov04ph/zaKLMmPOGdtD+Ej0EpZQX?= =?us-ascii?q?95A9jZmykISyEPmSLNddCUqwqn+iJtqMC/7PPrWBn06ISVF7RSNM9j+xesga?= =?us-ascii?q?eML+SQnjp2KS5E1pMQwn/F0L4f3EQIhCF2bzmgCroAtS/XTKLLhq9XAR8bay?= =?us-ascii?q?VpO8tO86083xNCOcrBhtPyzL54geY/C01ZWlz5hsGpecsKLnmmO1zcA0qLML?= =?us-ascii?q?WGJSbXw8Hse6+8UqNfg/lOux2rpzmbF07jPjKelzjmTB2gLeFNjDuGPBxFoo?= =?us-ascii?q?28fAxiCXT4TNLhbB23Kth3jSc5wbcsnHPFKXYcMSRgc0NKtrCQ6yJYgvF7G2?= =?us-ascii?q?Nf9XpoNvOLlDiD7+nfMJoWtuFrAitsneJA/Hs606dV7D1DRPFtgyTSr9Fuo1?= =?us-ascii?q?agkuSU1zVoTgFBqjdRi4KNp0liPr/Z9pZYU3be4B0N9XmQCwgNp9Z9ENLvtL?= =?us-ascii?q?pfysbRm6/oLzdC68zb/c0ZB8fOKcKHNGEuMR3mGTLOCwsFVzGrP3nFh0NBiP?= =?us-ascii?q?GS6mGVrp8ip5jwn5oOT6VXVEYyFvIbFEtlGscNII1wXjw6kr6Wl9IH5X27rB?= =?us-ascii?q?bNXspapYzHWuiUAfrxNDaTlaNEaAcQwbPkMYQTMZX2205ialh6hITKHE7QXd?= =?us-ascii?q?FRoiJ/dQI0pURN8GRkTmItwU7lbRmt4HALH/6ughE2khd+Yfgq9Dr05Vc4OE?= =?us-ascii?q?DFpC8rnUkyntXlmiyRfyT3LKerXoFWCjD4t04vPZPnWwx1dxG9nVR4NDfYQL?= =?us-ascii?q?Jcl6Fgen5wiADCo5RPA+JTTa1fbRALxPGXfegn0VNSqiW/309I++vEBYFklA?= =?us-ascii?q?Q0bZ6mt2hA1B57bN4pOazQI7JEwUVKiaKQvy+ny/sxzRQEKEYX6mOSfyAJuF?= =?us-ascii?q?cWObY6Oiqo5O1s6RCCmjdZfmgDSeYqqOpw9kwhI+SA0z7g07lbJ0C1MOyfNb?= =?us-ascii?q?2Wu27BlM6PWV4w2UUIl1Rf8bhxy8cjfFKeV1ozw7uJCxQJKc3CJBlOb8VM8H?= =?us-ascii?q?jTfCCOsfjCwJ9uI4q9EeXoQvOUu6YPnkKoBgApEJoQ7s4ZBJmjzFnYLdv7LL?= =?us-ascii?q?4C0Rgt+AXrJFCCDPRVeBKKkCwKrNy+zJ53x4ZSPSsRAWNjPiWr/rzXvBMlgO?= =?us-ascii?q?KfXNcqZXcXRpELNnY3WMKmhSFWp3FADTmx0uIezgiN9STxqT/RDDbmadpvff?= =?us-ascii?q?mUZQ52BNGw5zo/77C8iUTL/ZXGO2H6KdNit8fU5uwEoZaKEOlbQqRjs0jCgY?= =?us-ascii?q?lYXGalU3TPENKvIJjwcYYsZ8TuCnmmSly/ly41T8DpMda3KKiIgB3nRYZTsI?= =?us-ascii?q?mfxzAtLdazGCwEFRpsoO8O/75zZQoGY5UnexHorBg+O7a5IAiGztWkW3ytJi?= =?us-ascii?q?dOT/lD0eW6YKRawDYubuCg1HQtVY01z+6z8U4JRZEFkAvexeq9aIZCUSj/AH?= =?us-ascii?q?tdex/ApSAhjWhuKv4ywvsjwBPPqVQcKSqEdPZuaGNfpNw8GUmSLm9oCmUmQ1?= =?us-ascii?q?+cjIzD4gGo37AT8Ctdn8pU0eNfv3jku5/TejSsV7K3qZ/NqSovccAmo7FtMY?= =?us-ascii?q?zkOsaHuonSkSDfTJnRtw2FUTS1F/lBl9hRPi1XXudHlXsiOcwctopL8VAxWd?= =?us-ascii?q?smJ7xTFKksoainaT9+Ai4Izi8WSZ+A3D0EguezwLbbmA2fcJI+PxwAt5VCn8?= =?us-ascii?q?YSUzVsbiMYuqCjS53cl3WYRWgTPAcT8QNM6RoYlo93euDq+pDITZFLyz5Srf?= =?us-ascii?q?J5SS7LFp5v91vgVG6ZnUL4SPK6k+yy3AJSyv3s3sMcWB5lBkhX3/xWmVcwKL?= =?us-ascii?q?FrN6kQuZbHvSWSdUPnumLh0uimKUJQyc3Vdl34EJHKuXD6UiIC5X0eXZVPx2?= =?us-ascii?q?3HFZQOjwp5b74mpElLIICjYUv++yAox4FyELWiU8Ck2Uolp24cRyi2C9pBF/?= =?us-ascii?q?1msFXPVT1leZ+rso/qO5FPTWJL5ZKStU9ZkF1zPC6915VcMdtB4jkWXDhAuT?= =?us-ascii?q?+dpse9SNVf2c9qCJ8BOtV/u3DjF65fJZeevWY2taL1yn/F5T8zrU22xDOtFK?= =?us-ascii?q?+kV+hZ5XERGh01J2SCrUkiF/cs/XrP/VDMqF90+/xWCaSIjUV0vDlyBItOBi?= =?us-ascii?q?pT2XCjMVtzUGFMs/9GJ6TNb8xcX/4yaAe0NBwwCfEqw06E8Vx6kHrifyNysQ?= =?us-ascii?q?5a9DzHUAkvSSkZmLHtliMCqsu/Iz8VV4pIbSk9byfCMw+bgz5Yswtfa05wR5?= =?us-ascii?q?AUGdJF+7YF3YRK4MbNVUGsJjwbUxB4MAI3z+Zfn1ZZsEqEYSDdERaodfHXvx?= =?us-ascii?q?1vZseRsNSmI+nl/ApckYPnt/04978fSHK4nw2tXcreoJX4ttGQsUuObqj4Of?= =?us-ascii?q?WmYXDdVDjMkQywhbA8ApnW5SjcLhRUJIRhxHo5ZZjhFXTLMg5YJ6IaIEpbUb?= =?us-ascii?q?51aclcruBdfc9kd74D+bVxCRKfWhPvBIuvoeFDLlnJQTTeKzuO8vCjoY3J97?= =?us-ascii?q?PQUu7gadKQx3bcX614JI965ifhF7fsz4Be5lL82u1x+UNiVVjGLyeBoczjJg?= =?us-ascii?q?wR/smicVDivpkzEjPIG5pwlWftxkVcd8oWXyKq8Y4XyJVC6HrqTuJ4yEfzuv?= =?us-ascii?q?VI97Z48Yk3/6xpycCsKKfQM/tat0FnAgKTBgp36JogG3R/SHpXYu8KL/fdZ6?= =?us-ascii?q?IZgt7yq+rvDawY9AWV+/BFadvAP0zBldS/CjCYSRxAgggBrCUXIRaC2PGemq?= =?us-ascii?q?97U8ClqfL+2kI37Fi0NgQGw6x15YeY5qqIo/fabxnQzbgBQaXqQ938r7QytE?= =?us-ascii?q?OI5P0kkrEOdnZzYwK5DOgXTtQdyXv4zaA20SIsFNvOH7Tk+PNYVnI5mDfgl4?= =?us-ascii?q?p8H1UQFPMUB6CE/Z9CnmcihuzWKsEWcr1YmmmRDxKkFaUCyXGz4SuNPGZlmg?= =?us-ascii?q?3O0w33QW6r6V/2qil4QTfDz9j9iUdVU7i3Cl1UXyW3JU95vjSPPBDrtNrso6?= =?us-ascii?q?g16l85MnD8vtKXiGShIK9XH9H4JNGEJSk0v1cXgZ0qS9yhx48UBN29IM0L/3?= =?us-ascii?q?FmdPve7GGrnDFdrKdbnYbe5duV+vrPF3m6k6Kas6mNxCxfynUgvFE+68qvOe?= =?us-ascii?q?vS6NCRWPSnyXoRQDljtAfbWB61sLPbpUgOOUOXyEfLhJAKPtZB0HYj10Hm/+?= =?us-ascii?q?YiT8gx9AVfCobAf+kNpS33ODbv3VmfZM84WTeE3DtKBFL1FkN4F7Im1GL3ps?= =?us-ascii?q?LJmm/a+0c0SYloa0znmRt3Ap0gKU039FgY3ioDEAYKaRCBD7GkHF/lIpUAVU?= =?us-ascii?q?gCbxSHwbe7d7wv3UJp3rOg+O/TbOJ7B6oXNfZRlA2Ok0ZBGpIQr6IeRKhwe1?= =?us-ascii?q?hH9K7YvgLiEZToX+D6lXosMv24Ws9a/toDt3Q8/ga/RwGt6ZNC77YHlp+Idr?= =?us-ascii?q?RLYYXXvMxm6Udo+yIPfDRXgBdjlxO5TfwcpOf779jUrpWo7PquVKEqR+kQ7B?= =?us-ascii?q?g7GWB+j5r2gFA+rtDazONcRZPPiYX/6g9BOXiKt5jG0xNkM+oBN5qrfKp893?= =?us-ascii?q?UAPyUeIXMOMsaRa/k4+SBtKy/f511FAsMLftMYJ9HAmQVbh0zmQr1T8dDbGl?= =?us-ascii?q?CAAYdpa88o93b3yCwy8ZYkXebv9CS2JYvG419QMP1NiiRslNTfpOka2vfSBy?= =?us-ascii?q?0X7mOfaxdr2C+CzIONC/no9+WW1N7UT08GHjIxU4pFJjqC/gynRuyvmJr1Ug?= =?us-ascii?q?OU7tLzj48/dUKRQHyxh6cFsqdXHO5eiyX7wCJRFoToiPKUqdas7nVYtkFfGo?= =?us-ascii?q?Zp8RLFALlfPol8ORngl8mrWFJzBi3kdcHQaxohpeuWxuAX4+lkMEv+f4AbKA?= =?us-ascii?q?oey73m8XpVUhduSLnus1abQ+0RatVmSPffo3Fb841gLbEAPESHqJzssDhItE?= =?us-ascii?q?g8ABU1Z78osjxaak7OkRVaW6bwv74BhBUTUdp9uUJXAmKwP2Q+5zvbWqhPiq?= =?us-ascii?q?meFuAV+C2JTqMSS0VoLj9+QxSt1ZVrerupnvNHsmRdkyN/uvcq0DtmRB2iti?= =?us-ascii?q?3qva4N3ywv+K2gvjUbpXNFVvmekzvPCVhb1/sFk6EcC2r55FynZHkDa5fy4K?= =?us-ascii?q?V5Jcv+6IYt+XM/YQ8sfyceR+SvFznwj7+UAoyIqN9cigCCuMHPbb+rMycfLb?= =?us-ascii?q?U8yRPmR3h4zAfehhJo/3URTjWn9t8kK523Odw5ySqwBWjbaFEM77tHscvpr1?= =?us-ascii?q?4LTfc5Zk16zWVm08iHWjcNS9LVF2YylAgkZn1OcIhf5h8CC6konjGIs7FB/g?= =?us-ascii?q?EQfjjZCZyl+o3KksfTxXk9TMtlxn7MpqKbmJwmyntllM1o7iSWonQda/TYU9?= =?us-ascii?q?NwAnj0zopfze3+Z/OwsuEIUYdmzLWhUOQeMsm44ma22Y9lWkmixrgEGFq5Ku?= =?us-ascii?q?ADzK/BUyi5UW2YRfiLc2+UkjY8KEH9+RmoLlwxaMdNtEI9LOrChphCmA3lUL?= =?us-ascii?q?N0QDiQpFDBwGwkK+MaeBo8uJ27dAwSUO4Re++cKPAswPIkC1sMaGTGEDBrC+?= =?us-ascii?q?+wrV6tnI97O2hv4UX6feTh6AbmP8WOGhMcC47VsoZx+eCmRmKGIXJgzhhyPE?= =?us-ascii?q?5u9+fFFlQxrfRRc5CLktjVmdt70PQJd/B3MS0yotQTgJ5s6ZGI0MeWdhHc1o?= =?us-ascii?q?3yJd/QoveEAvDSzF8nen9EXboDYAP05oI6PtgjV73VA7RZoUdUOa9vRJ0nKn?= =?us-ascii?q?e096xuKg53WhDeaa7ygcTwoO+PIJxOqDue8FMqKw/OthsC1LqwTApmf9atnX?= =?us-ascii?q?q0PZN0DjtCt9hFDhpgAZsKFcQdqQauH5+Tnue8kdD1s1x7v+sbmav2BOrD2N?= =?us-ascii?q?mw08N2RZcerUORMTnSBIFvg0J4nuq1n/HM24XwDsWkfskLEKB/Q2jYevrdE4?= =?us-ascii?q?6iMDOSK4f5fEJb97O0zr10SFOSaTr/Uq7AszercL1/7EE6zJFoVPbCxzwqqb?= =?us-ascii?q?fA0Z39YH8f7iuus1aOLJZZ8kfVBPDVX1RTU/XBuH1lGaw/bobu8uoKd9s4z5?= =?us-ascii?q?zU5wh18SQHysKEL4C/oULWnEF2b5TWKA3uwSlqd5MNJUGcPE0wyUjHp27GHW?= =?us-ascii?q?5RI9TsfcpghsrTCQLg/VJtg2wgekZOH2PpQZGaPm1NiJH2XxGD6A8eV4VLpO?= =?us-ascii?q?WwY0Nt8/TqE7M6M4hZmeisqLQMmMpoLCeKXsVBIiXMN+AnbCdSA+GW9UAhO0?= =?us-ascii?q?5CvrUwQYhzYJGPJAUCMUPTrEG6wQjD1Bjsfse3nOaSISkQ+2la1b+NzzVWpg?= =?us-ascii?q?e4tPrYys3uWbzUdtf3CdbdNSMkUneRQjE/?= X-IPAS-Result: =?us-ascii?q?A2BbDQDoWAVb/wHyM5BcHAEBAQQBAQoBAYNBA4EEKQExK?= =?us-ascii?q?It7X4wEgm4akzcUgWEOGBMBgUuCdYInITQYAQIBAQEBAQECAWscDEIBAQMHB?= =?us-ascii?q?IFjJIJQAwMBAhcBDBMGAQ0OEgsBAgECCQEBBRArCAgDAR0CDgMBBQELEQcHC?= =?us-ascii?q?wUWAgSDAYFoAQMVA55nPIxuFgUBF4JwBX8EAYJIChkmDVVXgXQCBhKHKHyBV?= =?us-ascii?q?D+BD4JYgwSBaQgBEgELKYU/AodDhGUMi2MXLAcCgWeJc4J0C4dWhSsrigSGK?= =?us-ascii?q?QIEAgQFAgUPIYEEHDhhcXBQMYISghQJAxeDRYocUlMBL0kBAQEohFGCPoJiD?= =?us-ascii?q?heCIAEB?= Received: from tarius.tycho.ncsc.mil ([144.51.242.1]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 23 May 2018 12:06:21 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w4NC6K3K020976; Wed, 23 May 2018 08:06:20 -0400 Received: from tarius.tycho.ncsc.mil (tarius.infosec.tycho.ncsc.mil [144.51.242.1]) by prometheus.infosec.tycho.ncsc.mil (8.15.2/8.15.2) with ESMTP id w4N1Iu4T036675 for ; Tue, 22 May 2018 21:18:56 -0400 Received: from goalie.tycho.ncsc.mil (goalie [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w4N1J0hr026120 for ; Tue, 22 May 2018 21:19:00 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1BkAwABwQRblywWGNZcHgEGDINAgTABM?= =?us-ascii?q?SiMWYwWgm4akzYUgWQLLIFLgnUCgiEhNRcBAgEBAQEBAQIUAQEBAQEGGAZLhTU?= =?us-ascii?q?DAxoBDBkBGx0BAwwGEDshAhEBBQEcBxIbgweBaAEDFQOeYDyMbhYFAReCcAV/B?= =?us-ascii?q?AGCSAoZJg1UV4F0AgYShyd8gVQ/gQ+CWIMEgWknhWgChz2EZAyLXxcsBwKBZ4l?= =?us-ascii?q?xgnQLh1OFKyuJf4YpAgQCBAUCBQ8hgQQeA4IFcIEBghKCFAkDDgmDRYocUlMBL?= =?us-ascii?q?0krilWCRQEB?= X-IPAS-Result: =?us-ascii?q?A1BkAwABwQRblywWGNZcHgEGDINAgTABMSiMWYwWgm4akzY?= =?us-ascii?q?UgWQLLIFLgnUCgiEhNRcBAgEBAQEBAQIUAQEBAQEGGAZLhTUDAxoBDBkBGx0BA?= =?us-ascii?q?wwGEDshAhEBBQEcBxIbgweBaAEDFQOeYDyMbhYFAReCcAV/BAGCSAoZJg1UV4F?= =?us-ascii?q?0AgYShyd8gVQ/gQ+CWIMEgWknhWgChz2EZAyLXxcsBwKBZ4lxgnQLh1OFKyuJf?= =?us-ascii?q?4YpAgQCBAUCBQ8hgQQeA4IFcIEBghKCFAkDDgmDRYocUlMBL0krilWCRQEB?= X-IronPort-AV: E=Sophos;i="5.49,431,1520913600"; d="scan'208";a="283116" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.34]) by goalie.tycho.ncsc.mil with ESMTP; 22 May 2018 21:18:58 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3AbPymNBZZ55L37419F5iIn0L/LSx+4OfEezUN45?= =?us-ascii?q?9isYplN5qZrsW7bnLW6fgltlLVR4KTs6sC17KN9fi4EUU7or+5+EgYd5JNUx?= =?us-ascii?q?JXwe43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQ?= =?us-ascii?q?viPgRpOOv1BpTSj8Oq3Oyu5pHfeQpFiCazbL9oMBm6sRjau9ULj4dlNqs/0A?= =?us-ascii?q?bCrGFSe+RRy2NoJFaTkAj568yt4pNt8Dletuw4+cJYXqr0Y6o3TbpDDDQ7KG?= =?us-ascii?q?81/9HktQPCTQSU+HQRVHgdnwdSDAjE6BH6WYrxsjf/u+Fg1iSWIdH6QLYpUj?= =?us-ascii?q?mk8qxlSgLniD0fOjAk8G/ZlMJ+gqFcrh2jqRxy2JLYbJ2POfZiZK7RYc8WSG?= =?us-ascii?q?xcVchRTSxBBYa8YpMKAeUfO+ZYs5T2qUIQrRSgHwmsH//vyiVWiXDowa0xzu?= =?us-ascii?q?MsEQLY0wwmA9ICqnPUrMvrO6cISuC10LPIwivdYPNKwjr9543IfQogofGIR7?= =?us-ascii?q?5/bc3RyUw2Gg7Dk16eqpTlMiuL2ugQvGWX9fRsWO21h2I5tQ19uDeiy8g0ho?= =?us-ascii?q?TLm44Z0E7I+Ct2zYovONG1SlB3bcS6HJdNuCyXMZZ9TNk4TGFyoik6z6ULuZ?= =?us-ascii?q?6lcygOz5Qq3xDQZeGbfoaW7B/uSvyfLCtkiH9kYr6wmQi98U27yu3zTMW01U?= =?us-ascii?q?xFritBktXWs3AN1hjT5tCGSvt74EihxS6C2x7O5uxLO0w4i6XWJ4Q/zrIujJ?= =?us-ascii?q?YevkvOEjfzmErsja+Wcksk+vKv6+TierjmpYGTN4loig3kNaQuhNKwAf4jMg?= =?us-ascii?q?gSRWiU5/qz1KH48E32RbVFlPw2kq3DvJ/GIsQbo7a1AxVJ3YY79xa/EzCm3c?= =?us-ascii?q?wDnXYZKFJFeRSHj5XmOlzVPPD5Deuwg1SrkDtxwfDGJafuDo/CLnjEjreyNY?= =?us-ascii?q?p6vkpdzhcjiNNS/ZRZDpkfL//pHEz8rtrVClk+KQPwi/jmEtJVxI4YWHzJBq?= =?us-ascii?q?6fLbOUtkWHoP8sZ6GFZ5cQkDL8LeU1ovDpkHk1kEMceq/v2oEYLDinH/BiMm?= =?us-ascii?q?2YZ3T2i9sMGGtMuRAxCKTlklCNUj57Y3e0QrIy4Sw9BIu6DIDFAIe3j/jJ2C?= =?us-ascii?q?a9A40TfW1NF0qNDWatcoKIRvMBQDydL9UnkTEeU7WlDYg72lXmrwL+yrx6Ps?= =?us-ascii?q?LI6yYYstTlz9Ez6OrN0Vk++CJcCNyQ1X+WUGBolWNOQCU5mOhkoUh84lSOy6?= =?us-ascii?q?51h7pfD9MXr/dIVBoqcITVzuBSFd//QETCc82PRVLgRc+pUh8rSddk4NIIfw?= =?us-ascii?q?5aBdi4lQzZ0ie2S+sWmrqXQpsq/7jHw2L8KtpVxHPP1a1nhF4jFJgcfVa6j7?= =?us-ascii?q?JyolCAT7XClF+Uwv7wL/YVwTLN+WGfzGGHoEBfVktqXL7YWWwEORSEsNf04h?= =?us-ascii?q?qTV7b3WfIqPw5axoiHI6pOLNjoiQYOSPTiPYHGanmq0yerBBmOz6+RdoeiZW?= =?us-ascii?q?gH3SvcBURF2wAe9HqLL04/Uw+upmvfCHplElfi?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0BmAwALwARblywWGNZcHgEGDINAgTA?= =?us-ascii?q?BMSiMWYwWgm4akzYUgWQLLIFLgnUCgiEhNRcBAgEBAQEBAQIBEwEBAQEBBhg?= =?us-ascii?q?GSwyCNSKCUgMDGgEMGQEbHQEDDAYQOyECEQEFARwHEhuDB4FoAQMVA55kPIx?= =?us-ascii?q?uFgUBF4JwBX8EAYJIChkmDVRXgXQCBhKHJ3yBVD+BD4JYgwSBaSeFaAKHPYR?= =?us-ascii?q?kDItfFywHAoFniXGCdAuHU4UrK4l/hikCBAIEBQIFDyGBBB4DggVwgQGCEoI?= =?us-ascii?q?UCQMOCYNFihxSUwEvSSuKVYJFAQE?= X-IPAS-Result: =?us-ascii?q?A0BmAwALwARblywWGNZcHgEGDINAgTABMSiMWYwWgm4ak?= =?us-ascii?q?zYUgWQLLIFLgnUCgiEhNRcBAgEBAQEBAQIBEwEBAQEBBhgGSwyCNSKCUgMDG?= =?us-ascii?q?gEMGQEbHQEDDAYQOyECEQEFARwHEhuDB4FoAQMVA55kPIxuFgUBF4JwBX8EA?= =?us-ascii?q?YJIChkmDVRXgXQCBhKHJ3yBVD+BD4JYgwSBaSeFaAKHPYRkDItfFywHAoFni?= =?us-ascii?q?XGCdAuHU4UrK4l/hikCBAIEBQIFDyGBBB4DggVwgQGCEoIUCQMOCYNFihxSU?= =?us-ascii?q?wEvSSuKVYJFAQE?= X-IronPort-AV: E=Sophos;i="5.49,431,1520899200"; d="scan'208";a="12074946" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from usat3cpa06.eemsg.mail.mil ([214.24.22.44]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 23 May 2018 01:18:56 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;3790b29e-5d6d-4ae7-8dcb-22f864adc9eb Authentication-Results: ukel19pa18.eemsg.mail.mil; dkim=pass (signature verified) header.i=@gmail.com X-EEMSG-check-008: 304280470|UKEL19PA18_EEMSG_MP11.csd.disa.mil X-EEMSG-SBRS: 2.7 X-EEMSG-ORIG-IP: 209.85.220.196 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DKAQBrvgRbf8TcVdFcHgEGDIRwAVmMWYwWgm4akzYUgWQLLIFLgnUCgiEhNBgBAgEBAQEBAQIUAQEJCwsIJiUMQgwBhFoDAxoBDBkBGx0BAwwGEDshAhEBBQEcBxIbgweBaAEDFZ5mPIxuFgUBF4JwBX8EAYJIChkmDVRXgXQCBgkBCIcnfIFUP4EPgliDBIFpJ4VoAoc9hGQMi18XLAcCgWeJcYJ0C4dThSsriX+GKQIEAgQFAgUPIYEEHIIKcIEBghKCFAkDF4NFihxSUwEvSSuEO4YagkUBAQ X-IPAS-Result: A0DKAQBrvgRbf8TcVdFcHgEGDIRwAVmMWYwWgm4akzYUgWQLLIFLgnUCgiEhNBgBAgEBAQEBAQIUAQEJCwsIJiUMQgwBhFoDAxoBDBkBGx0BAwwGEDshAhEBBQEcBxIbgweBaAEDFZ5mPIxuFgUBF4JwBX8EAYJIChkmDVRXgXQCBgkBCIcnfIFUP4EPgliDBIFpJ4VoAoc9hGQMi18XLAcCgWeJcYJ0C4dThSsriX+GKQIEAgQFAgUPIYEEHIIKcIEBghKCFAkDF4NFihxSUwEvSSuEO4YagkUBAQ Received: from mail-qk0-f196.google.com ([209.85.220.196]) by ukel19pa18.eemsg.mail.mil with ESMTP; 23 May 2018 01:18:53 +0000 Received: by mail-qk0-f196.google.com with SMTP id z75-v6so16189072qkb.6 for ; Tue, 22 May 2018 18:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=a7qYcMWnlYGLkKfy/kMVE6WyKKaTlBDQVDqz0L6kagQ=; b=LxGbiI4/BWJpYddrxYHCmDYWQ1A+ToyGOO+NSo6Th3V8Y8UtIr9VkTMjucb9q8igRe 3e0oVx6rL/389RYGGT++QB4kBVXzrK6PopzJcIS7biec3s7yMLIUlPHfk32IYj5lEu14 sIjajupeLzij8pTFMCrIGuwNszkUpHObKxCF7DRUCpVqvFADW2jQQ2OKFvg9Nl644Fpv EkiQObL6OsPINQ3KqCRnmAKFZtGQm+0z4U2GHwRH9l2QsXZhcX2zM650Pg5TTNeRJZ1g JiU7Pw/9hhPcv+WKFSV95u3MM3kdk/0fXC2rrtEG30RIMarrsqNg0BGInSSUEfH6z3i2 y7EA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=a7qYcMWnlYGLkKfy/kMVE6WyKKaTlBDQVDqz0L6kagQ=; b=FxCWph5KVOxoWJ9vxBuxWn2edFaBCuE4Z84kLkFSPTQ/BdJSKWZgpDz0pQzMQW2qDX gO9DOKjuBfnjYlLgmyRAJXzVcM6uKKJB9JdbUK6uofy0IWBZ8/NsAN14DD23qcZ28auU tHOCgzENXe+DKVhyPe8CJiMJV5zTx4GT/FDoAnJIgLn/x8HDjBlK0uUjBJgqiU9mjx88 2ep+0HGWDPN2lDQwuTvRAPyf20wr86dndJU4/byQOIfHsMfMkRY40gklNoR0qCRWQNmZ u3rVUwQAlt2TVnSuMHyc5GAJqh5m3Q1izayBRzgjcPo6vCFyPQgwUJcshv2rRGpbAawU s4sQ== X-Gm-Message-State: ALKqPwekTmuDoPUqHBHwnPMVeyXzWkGAUIpDqMQf44cLT+LGmQ0TrYdc jUFu9stQytUBH5oPNyB3fQ== X-Google-Smtp-Source: ADUXVKIbZkEqt+RnDpGpUX6IwG1LqNyPfE2IsqAoFn13xt+TpSfb453yoVlKEcI9Xe/H/szAyVY6KQ== X-Received: by 2002:a37:9684:: with SMTP id y126-v6mr665154qkd.297.1527038332300; Tue, 22 May 2018 18:18:52 -0700 (PDT) Received: from localhost.localdomain (c-71-234-172-214.hsd1.vt.comcast.net. [71.234.172.214]) by smtp.gmail.com with ESMTPSA id s127-v6sm12604251qkf.21.2018.05.22.18.18.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 May 2018 18:18:51 -0700 (PDT) X-EEMSG-check-009: 444-444 From: Kent Overstreet To: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, akpm@linux-foundation.org, willy@infradead.org, gregkh@linuxfoundation.org, linux-security-module@vger.kernel.org, selinux@tycho.nsa.gov, dev@openvswitch.org, shli@kernel.org, linux-raid@vger.kernel.org Date: Tue, 22 May 2018 21:18:21 -0400 Message-Id: <20180523011821.12165-6-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180523011821.12165-1-kent.overstreet@gmail.com> References: <20180523011821.12165-1-kent.overstreet@gmail.com> X-Mailman-Approved-At: Wed, 23 May 2018 08:03:44 -0400 Subject: [PATCH 6/6] Drop flex_arrays X-BeenThere: selinux@tycho.nsa.gov X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: Cc: Kent Overstreet MIME-Version: 1.0 Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP All existing users have been converted to generic radix trees Signed-off-by: Kent Overstreet --- Documentation/core-api/flexible-arrays.rst | 130 ------- Documentation/flexible-arrays.txt | 123 ------- include/linux/flex_array.h | 149 -------- include/linux/poison.h | 3 - lib/Makefile | 2 +- lib/flex_array.c | 398 --------------------- tools/include/linux/poison.h | 3 - 7 files changed, 1 insertion(+), 807 deletions(-) delete mode 100644 Documentation/core-api/flexible-arrays.rst delete mode 100644 Documentation/flexible-arrays.txt delete mode 100644 include/linux/flex_array.h delete mode 100644 lib/flex_array.c diff --git a/Documentation/core-api/flexible-arrays.rst b/Documentation/core-api/flexible-arrays.rst deleted file mode 100644 index b6b85a1b51..0000000000 --- a/Documentation/core-api/flexible-arrays.rst +++ /dev/null @@ -1,130 +0,0 @@ - -=================================== -Using flexible arrays in the kernel -=================================== - -Large contiguous memory allocations can be unreliable in the Linux kernel. -Kernel programmers will sometimes respond to this problem by allocating -pages with :c:func:`vmalloc()`. This solution not ideal, though. On 32-bit -systems, memory from vmalloc() must be mapped into a relatively small address -space; it's easy to run out. On SMP systems, the page table changes required -by vmalloc() allocations can require expensive cross-processor interrupts on -all CPUs. And, on all systems, use of space in the vmalloc() range increases -pressure on the translation lookaside buffer (TLB), reducing the performance -of the system. - -In many cases, the need for memory from vmalloc() can be eliminated by piecing -together an array from smaller parts; the flexible array library exists to make -this task easier. - -A flexible array holds an arbitrary (within limits) number of fixed-sized -objects, accessed via an integer index. Sparse arrays are handled -reasonably well. Only single-page allocations are made, so memory -allocation failures should be relatively rare. The down sides are that the -arrays cannot be indexed directly, individual object size cannot exceed the -system page size, and putting data into a flexible array requires a copy -operation. It's also worth noting that flexible arrays do no internal -locking at all; if concurrent access to an array is possible, then the -caller must arrange for appropriate mutual exclusion. - -The creation of a flexible array is done with :c:func:`flex_array_alloc()`:: - - #include - - struct flex_array *flex_array_alloc(int element_size, - unsigned int total, - gfp_t flags); - -The individual object size is provided by ``element_size``, while total is the -maximum number of objects which can be stored in the array. The flags -argument is passed directly to the internal memory allocation calls. With -the current code, using flags to ask for high memory is likely to lead to -notably unpleasant side effects. - -It is also possible to define flexible arrays at compile time with:: - - DEFINE_FLEX_ARRAY(name, element_size, total); - -This macro will result in a definition of an array with the given name; the -element size and total will be checked for validity at compile time. - -Storing data into a flexible array is accomplished with a call to -:c:func:`flex_array_put()`:: - - int flex_array_put(struct flex_array *array, unsigned int element_nr, - void *src, gfp_t flags); - -This call will copy the data from src into the array, in the position -indicated by ``element_nr`` (which must be less than the maximum specified when -the array was created). If any memory allocations must be performed, flags -will be used. The return value is zero on success, a negative error code -otherwise. - -There might possibly be a need to store data into a flexible array while -running in some sort of atomic context; in this situation, sleeping in the -memory allocator would be a bad thing. That can be avoided by using -``GFP_ATOMIC`` for the flags value, but, often, there is a better way. The -trick is to ensure that any needed memory allocations are done before -entering atomic context, using :c:func:`flex_array_prealloc()`:: - - int flex_array_prealloc(struct flex_array *array, unsigned int start, - unsigned int nr_elements, gfp_t flags); - -This function will ensure that memory for the elements indexed in the range -defined by ``start`` and ``nr_elements`` has been allocated. Thereafter, a -``flex_array_put()`` call on an element in that range is guaranteed not to -block. - -Getting data back out of the array is done with :c:func:`flex_array_get()`:: - - void *flex_array_get(struct flex_array *fa, unsigned int element_nr); - -The return value is a pointer to the data element, or NULL if that -particular element has never been allocated. - -Note that it is possible to get back a valid pointer for an element which -has never been stored in the array. Memory for array elements is allocated -one page at a time; a single allocation could provide memory for several -adjacent elements. Flexible array elements are normally initialized to the -value ``FLEX_ARRAY_FREE`` (defined as 0x6c in ), so errors -involving that number probably result from use of unstored array entries. -Note that, if array elements are allocated with ``__GFP_ZERO``, they will be -initialized to zero and this poisoning will not happen. - -Individual elements in the array can be cleared with -:c:func:`flex_array_clear()`:: - - int flex_array_clear(struct flex_array *array, unsigned int element_nr); - -This function will set the given element to ``FLEX_ARRAY_FREE`` and return -zero. If storage for the indicated element is not allocated for the array, -``flex_array_clear()`` will return ``-EINVAL`` instead. Note that clearing an -element does not release the storage associated with it; to reduce the -allocated size of an array, call :c:func:`flex_array_shrink()`:: - - int flex_array_shrink(struct flex_array *array); - -The return value will be the number of pages of memory actually freed. -This function works by scanning the array for pages containing nothing but -``FLEX_ARRAY_FREE`` bytes, so (1) it can be expensive, and (2) it will not work -if the array's pages are allocated with ``__GFP_ZERO``. - -It is possible to remove all elements of an array with a call to -:c:func:`flex_array_free_parts()`:: - - void flex_array_free_parts(struct flex_array *array); - -This call frees all elements, but leaves the array itself in place. -Freeing the entire array is done with :c:func:`flex_array_free()`:: - - void flex_array_free(struct flex_array *array); - -As of this writing, there are no users of flexible arrays in the mainline -kernel. The functions described here are also not exported to modules; -that will probably be fixed when somebody comes up with a need for it. - - -Flexible array functions ------------------------- - -.. kernel-doc:: include/linux/flex_array.h diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt deleted file mode 100644 index a0f2989dd8..0000000000 --- a/Documentation/flexible-arrays.txt +++ /dev/null @@ -1,123 +0,0 @@ -=================================== -Using flexible arrays in the kernel -=================================== - -:Updated: Last updated for 2.6.32 -:Author: Jonathan Corbet - -Large contiguous memory allocations can be unreliable in the Linux kernel. -Kernel programmers will sometimes respond to this problem by allocating -pages with vmalloc(). This solution not ideal, though. On 32-bit systems, -memory from vmalloc() must be mapped into a relatively small address space; -it's easy to run out. On SMP systems, the page table changes required by -vmalloc() allocations can require expensive cross-processor interrupts on -all CPUs. And, on all systems, use of space in the vmalloc() range -increases pressure on the translation lookaside buffer (TLB), reducing the -performance of the system. - -In many cases, the need for memory from vmalloc() can be eliminated by -piecing together an array from smaller parts; the flexible array library -exists to make this task easier. - -A flexible array holds an arbitrary (within limits) number of fixed-sized -objects, accessed via an integer index. Sparse arrays are handled -reasonably well. Only single-page allocations are made, so memory -allocation failures should be relatively rare. The down sides are that the -arrays cannot be indexed directly, individual object size cannot exceed the -system page size, and putting data into a flexible array requires a copy -operation. It's also worth noting that flexible arrays do no internal -locking at all; if concurrent access to an array is possible, then the -caller must arrange for appropriate mutual exclusion. - -The creation of a flexible array is done with:: - - #include - - struct flex_array *flex_array_alloc(int element_size, - unsigned int total, - gfp_t flags); - -The individual object size is provided by element_size, while total is the -maximum number of objects which can be stored in the array. The flags -argument is passed directly to the internal memory allocation calls. With -the current code, using flags to ask for high memory is likely to lead to -notably unpleasant side effects. - -It is also possible to define flexible arrays at compile time with:: - - DEFINE_FLEX_ARRAY(name, element_size, total); - -This macro will result in a definition of an array with the given name; the -element size and total will be checked for validity at compile time. - -Storing data into a flexible array is accomplished with a call to:: - - int flex_array_put(struct flex_array *array, unsigned int element_nr, - void *src, gfp_t flags); - -This call will copy the data from src into the array, in the position -indicated by element_nr (which must be less than the maximum specified when -the array was created). If any memory allocations must be performed, flags -will be used. The return value is zero on success, a negative error code -otherwise. - -There might possibly be a need to store data into a flexible array while -running in some sort of atomic context; in this situation, sleeping in the -memory allocator would be a bad thing. That can be avoided by using -GFP_ATOMIC for the flags value, but, often, there is a better way. The -trick is to ensure that any needed memory allocations are done before -entering atomic context, using:: - - int flex_array_prealloc(struct flex_array *array, unsigned int start, - unsigned int nr_elements, gfp_t flags); - -This function will ensure that memory for the elements indexed in the range -defined by start and nr_elements has been allocated. Thereafter, a -flex_array_put() call on an element in that range is guaranteed not to -block. - -Getting data back out of the array is done with:: - - void *flex_array_get(struct flex_array *fa, unsigned int element_nr); - -The return value is a pointer to the data element, or NULL if that -particular element has never been allocated. - -Note that it is possible to get back a valid pointer for an element which -has never been stored in the array. Memory for array elements is allocated -one page at a time; a single allocation could provide memory for several -adjacent elements. Flexible array elements are normally initialized to the -value FLEX_ARRAY_FREE (defined as 0x6c in ), so errors -involving that number probably result from use of unstored array entries. -Note that, if array elements are allocated with __GFP_ZERO, they will be -initialized to zero and this poisoning will not happen. - -Individual elements in the array can be cleared with:: - - int flex_array_clear(struct flex_array *array, unsigned int element_nr); - -This function will set the given element to FLEX_ARRAY_FREE and return -zero. If storage for the indicated element is not allocated for the array, -flex_array_clear() will return -EINVAL instead. Note that clearing an -element does not release the storage associated with it; to reduce the -allocated size of an array, call:: - - int flex_array_shrink(struct flex_array *array); - -The return value will be the number of pages of memory actually freed. -This function works by scanning the array for pages containing nothing but -FLEX_ARRAY_FREE bytes, so (1) it can be expensive, and (2) it will not work -if the array's pages are allocated with __GFP_ZERO. - -It is possible to remove all elements of an array with a call to:: - - void flex_array_free_parts(struct flex_array *array); - -This call frees all elements, but leaves the array itself in place. -Freeing the entire array is done with:: - - void flex_array_free(struct flex_array *array); - -As of this writing, there are no users of flexible arrays in the mainline -kernel. The functions described here are also not exported to modules; -that will probably be fixed when somebody comes up with a need for it. diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h deleted file mode 100644 index b94fa61b51..0000000000 --- a/include/linux/flex_array.h +++ /dev/null @@ -1,149 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _FLEX_ARRAY_H -#define _FLEX_ARRAY_H - -#include -#include -#include - -#define FLEX_ARRAY_PART_SIZE PAGE_SIZE -#define FLEX_ARRAY_BASE_SIZE PAGE_SIZE - -struct flex_array_part; - -/* - * This is meant to replace cases where an array-like - * structure has gotten too big to fit into kmalloc() - * and the developer is getting tempted to use - * vmalloc(). - */ - -struct flex_array { - union { - struct { - int element_size; - int total_nr_elements; - int elems_per_part; - struct reciprocal_value reciprocal_elems; - struct flex_array_part *parts[]; - }; - /* - * This little trick makes sure that - * sizeof(flex_array) == PAGE_SIZE - */ - char padding[FLEX_ARRAY_BASE_SIZE]; - }; -}; - -/* Number of bytes left in base struct flex_array, excluding metadata */ -#define FLEX_ARRAY_BASE_BYTES_LEFT \ - (FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts)) - -/* Number of pointers in base to struct flex_array_part pages */ -#define FLEX_ARRAY_NR_BASE_PTRS \ - (FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *)) - -/* Number of elements of size that fit in struct flex_array_part */ -#define FLEX_ARRAY_ELEMENTS_PER_PART(size) \ - (FLEX_ARRAY_PART_SIZE / size) - -/* - * Defines a statically allocated flex array and ensures its parameters are - * valid. - */ -#define DEFINE_FLEX_ARRAY(__arrayname, __element_size, __total) \ - struct flex_array __arrayname = { { { \ - .element_size = (__element_size), \ - .total_nr_elements = (__total), \ - } } }; \ - static inline void __arrayname##_invalid_parameter(void) \ - { \ - BUILD_BUG_ON((__total) > FLEX_ARRAY_NR_BASE_PTRS * \ - FLEX_ARRAY_ELEMENTS_PER_PART(__element_size)); \ - } - -/** - * flex_array_alloc() - Creates a flexible array. - * @element_size: individual object size. - * @total: maximum number of objects which can be stored. - * @flags: GFP flags - * - * Return: Returns an object of structure flex_array. - */ -struct flex_array *flex_array_alloc(int element_size, unsigned int total, - gfp_t flags); - -/** - * flex_array_prealloc() - Ensures that memory for the elements indexed in the - * range defined by start and nr_elements has been allocated. - * @fa: array to allocate memory to. - * @start: start address - * @nr_elements: number of elements to be allocated. - * @flags: GFP flags - * - */ -int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int nr_elements, gfp_t flags); - -/** - * flex_array_free() - Removes all elements of a flexible array. - * @fa: array to be freed. - */ -void flex_array_free(struct flex_array *fa); - -/** - * flex_array_free_parts() - Removes all elements of a flexible array, but - * leaves the array itself in place. - * @fa: array to be emptied. - */ -void flex_array_free_parts(struct flex_array *fa); - -/** - * flex_array_put() - Stores data into a flexible array. - * @fa: array where element is to be stored. - * @element_nr: position to copy, must be less than the maximum specified when - * the array was created. - * @src: data source to be copied into the array. - * @flags: GFP flags - * - * Return: Returns zero on success, a negative error code otherwise. - */ -int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, - gfp_t flags); - -/** - * flex_array_clear() - Clears an individual element in the array, sets the - * given element to FLEX_ARRAY_FREE. - * @element_nr: element position to clear. - * @fa: array to which element to be cleared belongs. - * - * Return: Returns zero on success, -EINVAL otherwise. - */ -int flex_array_clear(struct flex_array *fa, unsigned int element_nr); - -/** - * flex_array_get() - Retrieves data into a flexible array. - * - * @element_nr: Element position to retrieve data from. - * @fa: array from which data is to be retrieved. - * - * Return: Returns a pointer to the data element, or NULL if that - * particular element has never been allocated. - */ -void *flex_array_get(struct flex_array *fa, unsigned int element_nr); - -/** - * flex_array_shrink() - Reduces the allocated size of an array. - * @fa: array to shrink. - * - * Return: Returns number of pages of memory actually freed. - * - */ -int flex_array_shrink(struct flex_array *fa); - -#define flex_array_put_ptr(fa, nr, src, gfp) \ - flex_array_put(fa, nr, (void *)&(src), gfp) - -void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr); - -#endif /* _FLEX_ARRAY_H */ diff --git a/include/linux/poison.h b/include/linux/poison.h index 15927ebc22..10173f989a 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -83,9 +83,6 @@ #define MUTEX_DEBUG_FREE 0x22 #define MUTEX_POISON_WW_CTX ((void *) 0x500 + POISON_POINTER_DELTA) -/********** lib/flex_array.c **********/ -#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ - /********** security/ **********/ #define KEY_DESTROY 0xbd diff --git a/lib/Makefile b/lib/Makefile index 5db5a7fb1e..2c5245d683 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -36,7 +36,7 @@ obj-y += lockref.o obj-y += bcd.o div64.o sort.o parser.o debug_locks.o random32.o \ bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ - gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ + gcd.o lcm.o list_sort.o uuid.o iov_iter.o clz_ctz.o \ bsearch.o find_bit.o llist.o memweight.o kfifo.o \ percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ once.o refcount.o usercopy.o errseq.o bucket_locks.o \ diff --git a/lib/flex_array.c b/lib/flex_array.c deleted file mode 100644 index 2eed22fa50..0000000000 --- a/lib/flex_array.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Flexible array managed in PAGE_SIZE parts - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright IBM Corporation, 2009 - * - * Author: Dave Hansen - */ - -#include -#include -#include -#include -#include - -struct flex_array_part { - char elements[FLEX_ARRAY_PART_SIZE]; -}; - -/* - * If a user requests an allocation which is small - * enough, we may simply use the space in the - * flex_array->parts[] array to store the user - * data. - */ -static inline int elements_fit_in_base(struct flex_array *fa) -{ - int data_size = fa->element_size * fa->total_nr_elements; - if (data_size <= FLEX_ARRAY_BASE_BYTES_LEFT) - return 1; - return 0; -} - -/** - * flex_array_alloc - allocate a new flexible array - * @element_size: the size of individual elements in the array - * @total: total number of elements that this should hold - * @flags: page allocation flags to use for base array - * - * Note: all locking must be provided by the caller. - * - * @total is used to size internal structures. If the user ever - * accesses any array indexes >=@total, it will produce errors. - * - * The maximum number of elements is defined as: the number of - * elements that can be stored in a page times the number of - * page pointers that we can fit in the base structure or (using - * integer math): - * - * (PAGE_SIZE/element_size) * (PAGE_SIZE-8)/sizeof(void *) - * - * Here's a table showing example capacities. Note that the maximum - * index that the get/put() functions is just nr_objects-1. This - * basically means that you get 4MB of storage on 32-bit and 2MB on - * 64-bit. - * - * - * Element size | Objects | Objects | - * PAGE_SIZE=4k | 32-bit | 64-bit | - * ---------------------------------| - * 1 bytes | 4177920 | 2088960 | - * 2 bytes | 2088960 | 1044480 | - * 3 bytes | 1392300 | 696150 | - * 4 bytes | 1044480 | 522240 | - * 32 bytes | 130560 | 65408 | - * 33 bytes | 126480 | 63240 | - * 2048 bytes | 2040 | 1020 | - * 2049 bytes | 1020 | 510 | - * void * | 1044480 | 261120 | - * - * Since 64-bit pointers are twice the size, we lose half the - * capacity in the base structure. Also note that no effort is made - * to efficiently pack objects across page boundaries. - */ -struct flex_array *flex_array_alloc(int element_size, unsigned int total, - gfp_t flags) -{ - struct flex_array *ret; - int elems_per_part = 0; - int max_size = 0; - struct reciprocal_value reciprocal_elems = { 0 }; - - if (element_size) { - elems_per_part = FLEX_ARRAY_ELEMENTS_PER_PART(element_size); - reciprocal_elems = reciprocal_value(elems_per_part); - max_size = FLEX_ARRAY_NR_BASE_PTRS * elems_per_part; - } - - /* max_size will end up 0 if element_size > PAGE_SIZE */ - if (total > max_size) - return NULL; - ret = kzalloc(sizeof(struct flex_array), flags); - if (!ret) - return NULL; - ret->element_size = element_size; - ret->total_nr_elements = total; - ret->elems_per_part = elems_per_part; - ret->reciprocal_elems = reciprocal_elems; - if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO)) - memset(&ret->parts[0], FLEX_ARRAY_FREE, - FLEX_ARRAY_BASE_BYTES_LEFT); - return ret; -} -EXPORT_SYMBOL(flex_array_alloc); - -static int fa_element_to_part_nr(struct flex_array *fa, - unsigned int element_nr) -{ - /* - * if element_size == 0 we don't get here, so we never touch - * the zeroed fa->reciprocal_elems, which would yield invalid - * results - */ - return reciprocal_divide(element_nr, fa->reciprocal_elems); -} - -/** - * flex_array_free_parts - just free the second-level pages - * @fa: the flex array from which to free parts - * - * This is to be used in cases where the base 'struct flex_array' - * has been statically allocated and should not be free. - */ -void flex_array_free_parts(struct flex_array *fa) -{ - int part_nr; - - if (elements_fit_in_base(fa)) - return; - for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; part_nr++) - kfree(fa->parts[part_nr]); -} -EXPORT_SYMBOL(flex_array_free_parts); - -void flex_array_free(struct flex_array *fa) -{ - flex_array_free_parts(fa); - kfree(fa); -} -EXPORT_SYMBOL(flex_array_free); - -static unsigned int index_inside_part(struct flex_array *fa, - unsigned int element_nr, - unsigned int part_nr) -{ - unsigned int part_offset; - - part_offset = element_nr - part_nr * fa->elems_per_part; - return part_offset * fa->element_size; -} - -static struct flex_array_part * -__fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags) -{ - struct flex_array_part *part = fa->parts[part_nr]; - if (!part) { - part = kmalloc(sizeof(struct flex_array_part), flags); - if (!part) - return NULL; - if (!(flags & __GFP_ZERO)) - memset(part, FLEX_ARRAY_FREE, - sizeof(struct flex_array_part)); - fa->parts[part_nr] = part; - } - return part; -} - -/** - * flex_array_put - copy data into the array at @element_nr - * @fa: the flex array to copy data into - * @element_nr: index of the position in which to insert - * the new element. - * @src: address of data to copy into the array - * @flags: page allocation flags to use for array expansion - * - * - * Note that this *copies* the contents of @src into - * the array. If you are trying to store an array of - * pointers, make sure to pass in &ptr instead of ptr. - * You may instead wish to use the flex_array_put_ptr() - * helper function. - * - * Locking must be provided by the caller. - */ -int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, - gfp_t flags) -{ - int part_nr = 0; - struct flex_array_part *part; - void *dst; - - if (element_nr >= fa->total_nr_elements) - return -ENOSPC; - if (!fa->element_size) - return 0; - if (elements_fit_in_base(fa)) - part = (struct flex_array_part *)&fa->parts[0]; - else { - part_nr = fa_element_to_part_nr(fa, element_nr); - part = __fa_get_part(fa, part_nr, flags); - if (!part) - return -ENOMEM; - } - dst = &part->elements[index_inside_part(fa, element_nr, part_nr)]; - memcpy(dst, src, fa->element_size); - return 0; -} -EXPORT_SYMBOL(flex_array_put); - -/** - * flex_array_clear - clear element in array at @element_nr - * @fa: the flex array of the element. - * @element_nr: index of the position to clear. - * - * Locking must be provided by the caller. - */ -int flex_array_clear(struct flex_array *fa, unsigned int element_nr) -{ - int part_nr = 0; - struct flex_array_part *part; - void *dst; - - if (element_nr >= fa->total_nr_elements) - return -ENOSPC; - if (!fa->element_size) - return 0; - if (elements_fit_in_base(fa)) - part = (struct flex_array_part *)&fa->parts[0]; - else { - part_nr = fa_element_to_part_nr(fa, element_nr); - part = fa->parts[part_nr]; - if (!part) - return -EINVAL; - } - dst = &part->elements[index_inside_part(fa, element_nr, part_nr)]; - memset(dst, FLEX_ARRAY_FREE, fa->element_size); - return 0; -} -EXPORT_SYMBOL(flex_array_clear); - -/** - * flex_array_prealloc - guarantee that array space exists - * @fa: the flex array for which to preallocate parts - * @start: index of first array element for which space is allocated - * @nr_elements: number of elements for which space is allocated - * @flags: page allocation flags - * - * This will guarantee that no future calls to flex_array_put() - * will allocate memory. It can be used if you are expecting to - * be holding a lock or in some atomic context while writing - * data into the array. - * - * Locking must be provided by the caller. - */ -int flex_array_prealloc(struct flex_array *fa, unsigned int start, - unsigned int nr_elements, gfp_t flags) -{ - int start_part; - int end_part; - int part_nr; - unsigned int end; - struct flex_array_part *part; - - if (!start && !nr_elements) - return 0; - if (start >= fa->total_nr_elements) - return -ENOSPC; - if (!nr_elements) - return 0; - - end = start + nr_elements - 1; - - if (end >= fa->total_nr_elements) - return -ENOSPC; - if (!fa->element_size) - return 0; - if (elements_fit_in_base(fa)) - return 0; - start_part = fa_element_to_part_nr(fa, start); - end_part = fa_element_to_part_nr(fa, end); - for (part_nr = start_part; part_nr <= end_part; part_nr++) { - part = __fa_get_part(fa, part_nr, flags); - if (!part) - return -ENOMEM; - } - return 0; -} -EXPORT_SYMBOL(flex_array_prealloc); - -/** - * flex_array_get - pull data back out of the array - * @fa: the flex array from which to extract data - * @element_nr: index of the element to fetch from the array - * - * Returns a pointer to the data at index @element_nr. Note - * that this is a copy of the data that was passed in. If you - * are using this to store pointers, you'll get back &ptr. You - * may instead wish to use the flex_array_get_ptr helper. - * - * Locking must be provided by the caller. - */ -void *flex_array_get(struct flex_array *fa, unsigned int element_nr) -{ - int part_nr = 0; - struct flex_array_part *part; - - if (!fa->element_size) - return NULL; - if (element_nr >= fa->total_nr_elements) - return NULL; - if (elements_fit_in_base(fa)) - part = (struct flex_array_part *)&fa->parts[0]; - else { - part_nr = fa_element_to_part_nr(fa, element_nr); - part = fa->parts[part_nr]; - if (!part) - return NULL; - } - return &part->elements[index_inside_part(fa, element_nr, part_nr)]; -} -EXPORT_SYMBOL(flex_array_get); - -/** - * flex_array_get_ptr - pull a ptr back out of the array - * @fa: the flex array from which to extract data - * @element_nr: index of the element to fetch from the array - * - * Returns the pointer placed in the flex array at element_nr using - * flex_array_put_ptr(). This function should not be called if the - * element in question was not set using the _put_ptr() helper. - */ -void *flex_array_get_ptr(struct flex_array *fa, unsigned int element_nr) -{ - void **tmp; - - tmp = flex_array_get(fa, element_nr); - if (!tmp) - return NULL; - - return *tmp; -} -EXPORT_SYMBOL(flex_array_get_ptr); - -static int part_is_free(struct flex_array_part *part) -{ - int i; - - for (i = 0; i < sizeof(struct flex_array_part); i++) - if (part->elements[i] != FLEX_ARRAY_FREE) - return 0; - return 1; -} - -/** - * flex_array_shrink - free unused second-level pages - * @fa: the flex array to shrink - * - * Frees all second-level pages that consist solely of unused - * elements. Returns the number of pages freed. - * - * Locking must be provided by the caller. - */ -int flex_array_shrink(struct flex_array *fa) -{ - struct flex_array_part *part; - int part_nr; - int ret = 0; - - if (!fa->total_nr_elements || !fa->element_size) - return 0; - if (elements_fit_in_base(fa)) - return ret; - for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; part_nr++) { - part = fa->parts[part_nr]; - if (!part) - continue; - if (part_is_free(part)) { - fa->parts[part_nr] = NULL; - kfree(part); - ret++; - } - } - return ret; -} -EXPORT_SYMBOL(flex_array_shrink); diff --git a/tools/include/linux/poison.h b/tools/include/linux/poison.h index 9fdcd3eaac..d297257691 100644 --- a/tools/include/linux/poison.h +++ b/tools/include/linux/poison.h @@ -87,9 +87,6 @@ #define MUTEX_DEBUG_INIT 0x11 #define MUTEX_DEBUG_FREE 0x22 -/********** lib/flex_array.c **********/ -#define FLEX_ARRAY_FREE 0x6c /* for use-after-free poisoning */ - /********** security/ **********/ #define KEY_DESTROY 0xbd