From patchwork Sun Apr 22 16:23:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 10355769 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 8B2AE6019C for ; Sun, 22 Apr 2018 16:32:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 78208201A4 for ; Sun, 22 Apr 2018 16:32:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6C7B11FFEB; Sun, 22 Apr 2018 16:32:36 +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.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 0357D28949 for ; Sun, 22 Apr 2018 16:32:34 +0000 (UTC) Received: (qmail 19553 invoked by uid 550); 22 Apr 2018 16:31:34 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 18031 invoked from network); 22 Apr 2018 16:31:24 -0000 Message-Id: <20180422162512.363154748@linutronix.de> User-Agent: quilt/0.63-1 Date: Sun, 22 Apr 2018 18:23:46 +0200 From: Thomas Gleixner To: LKML Cc: Kees Cook , Segher Boessenkool , Kernel Hardening , Andrew Morton , Boris Brezillon , Richard Weinberger , David Woodhouse , Alasdair Kergon , Mike Snitzer , Anton Vorontsov , Colin Cross , Tony Luck , Neil Brown Subject: [patch V3 01/10] rslib: Add GFP aware init function References: <20180422162345.004292133@linutronix.de> MIME-Version: 1.0 Content-Disposition: inline; filename=rslib--Add-GFP-aware-init-function.patch X-Virus-Scanned: ClamAV using ClamSMTP The rslib usage in dm/verity_fec is broken because init_rs() can nest in GFP_NOIO mempool allocations as init_rs() is invoked from the mempool alloc callback. Provide a variant which takes gfp_t flags as argument. Signed-off-by: Thomas Gleixner Cc: Mike Snitzer Cc: Alasdair Kergon Cc: Neil Brown --- include/linux/rslib.h | 26 +++++++++++++++++++++++--- lib/reed_solomon/reed_solomon.c | 36 ++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 19 deletions(-) --- a/include/linux/rslib.h +++ b/include/linux/rslib.h @@ -77,10 +77,30 @@ int decode_rs16(struct rs_control *rs, u #endif /* Create or get a matching rs control structure */ -struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim, - int nroots); +struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim, + int nroots, gfp_t gfp); + +/** + * init_rs - Create a RS control struct and initialize it + * @symsize: the symbol size (number of bits) + * @gfpoly: the extended Galois field generator polynomial coefficients, + * with the 0th coefficient in the low order bit. The polynomial + * must be primitive; + * @fcr: the first consecutive root of the rs code generator polynomial + * in index form + * @prim: primitive element to generate polynomial roots + * @nroots: RS code generator polynomial degree (number of roots) + * + * Allocations use GFP_KERNEL. + */ +static inline struct rs_control *init_rs(int symsize, int gfpoly, int fcr, + int prim, int nroots) +{ + return init_rs_gfp(symsize, gfpoly, fcr, prim, nroots, GFP_KERNEL); +} + struct rs_control *init_rs_non_canonical(int symsize, int (*func)(int), - int fcr, int prim, int nroots); + int fcr, int prim, int nroots); /* Release a rs control structure */ void free_rs(struct rs_control *rs); --- a/lib/reed_solomon/reed_solomon.c +++ b/lib/reed_solomon/reed_solomon.c @@ -59,19 +59,20 @@ static DEFINE_MUTEX(rslistlock); * @fcr: first root of RS code generator polynomial, index form * @prim: primitive element to generate polynomial roots * @nroots: RS code generator polynomial degree (number of roots) + * @gfp: GFP_ flags for allocations * * Allocate a control structure and the polynom arrays for faster * en/decoding. Fill the arrays according to the given parameters. */ static struct rs_control *rs_init(int symsize, int gfpoly, int (*gffunc)(int), - int fcr, int prim, int nroots) + int fcr, int prim, int nroots, gfp_t gfp) { struct rs_control *rs; int i, j, sr, root, iprim; /* Allocate the control structure */ - rs = kmalloc(sizeof (struct rs_control), GFP_KERNEL); - if (rs == NULL) + rs = kmalloc(sizeof(*rs), gfp); + if (!rs) return NULL; INIT_LIST_HEAD(&rs->list); @@ -85,15 +86,15 @@ static struct rs_control *rs_init(int sy rs->gffunc = gffunc; /* Allocate the arrays */ - rs->alpha_to = kmalloc(sizeof(uint16_t) * (rs->nn + 1), GFP_KERNEL); + rs->alpha_to = kmalloc(sizeof(uint16_t) * (rs->nn + 1), gfp); if (rs->alpha_to == NULL) goto errrs; - rs->index_of = kmalloc(sizeof(uint16_t) * (rs->nn + 1), GFP_KERNEL); + rs->index_of = kmalloc(sizeof(uint16_t) * (rs->nn + 1), gfp); if (rs->index_of == NULL) goto erralp; - rs->genpoly = kmalloc(sizeof(uint16_t) * (rs->nroots + 1), GFP_KERNEL); + rs->genpoly = kmalloc(sizeof(uint16_t) * (rs->nroots + 1), gfp); if(rs->genpoly == NULL) goto erridx; @@ -195,13 +196,14 @@ void free_rs(struct rs_control *rs) * in index form * @prim: primitive element to generate polynomial roots * @nroots: RS code generator polynomial degree (number of roots) + * @gfp: GFP_ flags for allocations */ static struct rs_control *init_rs_internal(int symsize, int gfpoly, - int (*gffunc)(int), int fcr, - int prim, int nroots) + int (*gffunc)(int), int fcr, + int prim, int nroots, gfp_t gfp) { - struct list_head *tmp; - struct rs_control *rs; + struct list_head *tmp; + struct rs_control *rs; /* Sanity checks */ if (symsize < 1) @@ -236,7 +238,7 @@ static struct rs_control *init_rs_intern } /* Create a new one */ - rs = rs_init(symsize, gfpoly, gffunc, fcr, prim, nroots); + rs = rs_init(symsize, gfpoly, gffunc, fcr, prim, nroots, gfp); if (rs) { rs->users = 1; list_add(&rs->list, &rslist); @@ -247,7 +249,7 @@ static struct rs_control *init_rs_intern } /** - * init_rs - Find a matching or allocate a new rs control structure + * init_rs_gfp - Find a matching or allocate a new rs control structure * @symsize: the symbol size (number of bits) * @gfpoly: the extended Galois field generator polynomial coefficients, * with the 0th coefficient in the low order bit. The polynomial @@ -256,11 +258,12 @@ static struct rs_control *init_rs_intern * in index form * @prim: primitive element to generate polynomial roots * @nroots: RS code generator polynomial degree (number of roots) + * @gfp: GFP_ flags for allocations */ -struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim, - int nroots) +struct rs_control *init_rs_gfp(int symsize, int gfpoly, int fcr, int prim, + int nroots, gfp_t gfp) { - return init_rs_internal(symsize, gfpoly, NULL, fcr, prim, nroots); + return init_rs_internal(symsize, gfpoly, NULL, fcr, prim, nroots, gfp); } /** @@ -279,7 +282,8 @@ struct rs_control *init_rs(int symsize, struct rs_control *init_rs_non_canonical(int symsize, int (*gffunc)(int), int fcr, int prim, int nroots) { - return init_rs_internal(symsize, 0, gffunc, fcr, prim, nroots); + return init_rs_internal(symsize, 0, gffunc, fcr, prim, nroots, + GFP_KERNEL); } #ifdef CONFIG_REED_SOLOMON_ENC8