Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp217220imm; Tue, 15 May 2018 00:11:39 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrG/isX9aqzM+5b+QxrcUG91xMrxsrU/6V2MvtpD+AdaOmUWDda1OJrCDiGeJDs6YCQhMsr X-Received: by 2002:a63:7f49:: with SMTP id p9-v6mr10790449pgn.401.1526368299773; Tue, 15 May 2018 00:11:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526368299; cv=none; d=google.com; s=arc-20160816; b=z6ylHACH4bKNMulfNG/pe38cfx+T1/86nQZQKLSc7RFW+mLJrDUR+5T+57WaLwMipK u8R/HLSfgRHvqujNP5GhukYc4T1e3W1mU31bpdL+JLs1UbRxlD36LtE2OPw4ij8z7mni Zdnxev+nTS1kQ0rJfeV7/L7SW2BOCBpLbdBo9YMck9mRMvpKt1asAK3YOY0JXlPOKq0+ OZ1AvCLRUGzjfgLCBsBdCRXS7zj0idB4ig0kvVFvEM4YGDfYy/z0ZhyNoKI5ADgzKiLA KPkRJDIF2XDGZuXAu0z4Cq92OP8+qJhPiWDRW0lito9dDrQQtfeA1rDSfolMqfFslip+ 8CXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=+ARuFMY7l/NTdt/NjZG03UPrex6vQqLqVKgAYUceHNI=; b=LYzIgboEY5zlzCsDw3v7x+laRisxC5MaahG1q1LC5pXlT/8FbLtNAKlnP51SRjnZtV wEDwB3rDSu+yAikPM+rBhiaXBxSfE6DawV0N/Bvbhiw0CLRjoErjOia6Cns4L5vv6jT0 itlZK9/HkbKIw62C326EZ2bbPuRVDjPHjn/aj476mg6brevRprYaa2nptL4OcpoflWxi DLV5PD0TqrmkbKtF6FOPH1ivk2oW/+WksZu3vp6MJnTnVBxBzBW1UpMls9MsDGgcdFsi gJvdST3hVJUoYMWzSJ/AHf4QqYyaieytOE8utDUqvoMSKDOGRovOt93Q+klQbBGNHJk/ Kmsg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=a/nCpMvZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g7-v6si10974402plo.95.2018.05.15.00.11.25; Tue, 15 May 2018 00:11:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=a/nCpMvZ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752269AbeEOHKm (ORCPT + 99 others); Tue, 15 May 2018 03:10:42 -0400 Received: from mail-vk0-f68.google.com ([209.85.213.68]:36042 "EHLO mail-vk0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751626AbeEOHKk (ORCPT ); Tue, 15 May 2018 03:10:40 -0400 Received: by mail-vk0-f68.google.com with SMTP id i185-v6so9084192vkg.3; Tue, 15 May 2018 00:10:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=+ARuFMY7l/NTdt/NjZG03UPrex6vQqLqVKgAYUceHNI=; b=a/nCpMvZjLiR1Dp16ccTQ/t2IssrwWhNvpeNQwhJtPMsgRy7BJ5DptT6vN1cRWI3uN 78HZ+PJTKwPkJkcE2Y26yZT37MHvZp49RAFrIMVJpRYBJkctb1qu+XqhyqJonu7UcckK t+toP9ENNM1rgZSxoB8l3pu+gFThZu8VMgo1/392UEWIKe3wBAYid6fPt8eC31HQ0mTT 0M7ZWYY4IiEkNd0jWQ3r+lt+cyFCKIcrtLnhZ2h90GE5xTvwMF4ErdGNkLiOfKEpaWmp AIJYo1XOnOGKYgPcuY8mV3wIXcOSNm4dKpDuJKbr1CcQlsnlooejuXamfqMGmSey1f6q Pwog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=+ARuFMY7l/NTdt/NjZG03UPrex6vQqLqVKgAYUceHNI=; b=h0wmqY1wfRQ9Vt4/dJr/Pja7dXXkLICiAREZjZw2bcNkxUWloRu1vlv5EY1dy+wmGs hFQ5j4PGizwC0WsUAOrglErz/9MTKHOxHhi3W7+egDNvbQrb36+z4F7cz4d5udNW5r3y gbUWXeDx2ThQWr2BccL2ZoU+fFnNjEFVb73JE8odBrzsxO42KWiknhtUV5g8Ca363DiW JRCLTYTvyvehXsZ8nx+BwcyiE/Mr5/9Rkc5XFp21uh5xoWvU94o78aSyUOFDhax6o7Uu bRdQsdQwDx6rNahTQVANhEo39ujOccxG2YhTsOOgTWoXI63rG7qYYlAaIqCsRhSTOM6A 0FdA== X-Gm-Message-State: ALKqPwdewnCmFI6M8q/nMX8TNUi4/374uvqnKhRPClJrJ8SU0d28ktig E41/KWmL8sGT0/WY+dL2ZzK1JEliXYP3b/eGmDg= X-Received: by 2002:a1f:b508:: with SMTP id e8-v6mr13541142vkf.125.1526368239717; Tue, 15 May 2018 00:10:39 -0700 (PDT) MIME-Version: 1.0 Received: by 10.103.122.10 with HTTP; Tue, 15 May 2018 00:10:39 -0700 (PDT) In-Reply-To: <067d073f-556c-9df0-37f8-fd63fcdc7eb9@redhat.com> References: <20180413212427.18261-1-labbott@redhat.com> <067d073f-556c-9df0-37f8-fd63fcdc7eb9@redhat.com> From: Geert Uytterhoeven Date: Tue, 15 May 2018 09:10:39 +0200 X-Google-Sender-Auth: FGlYaer7MDCnWwCoGD2C6gV6bXA Message-ID: Subject: Re: [PATCHv5] gpio: Remove VLA from gpiolib To: Laura Abbott Cc: Linus Walleij , Kees Cook , Lukas Wunner , Rasmus Villemoes , "open list:GPIO SUBSYSTEM" , Linux Kernel Mailing List , kernel-hardening@lists.openwall.com Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Laura, On Tue, May 15, 2018 at 12:49 AM, Laura Abbott wrote: > On 04/20/2018 02:02 AM, Geert Uytterhoeven wrote: >> On Fri, Apr 13, 2018 at 11:24 PM, Laura Abbott wrote: >>> The new challenge is to remove VLAs from the kernel >>> (see https://lkml.org/lkml/2018/3/7/621) to eventually >>> turn on -Wvla. >>> >>> Using a kmalloc array is the easy way to fix this but kmalloc is still >>> more expensive than stack allocation. Introduce a fast path with a >>> fixed size stack array to cover most chip with gpios below some fixed >>> amount. The slow path dynamically allocates an array to cover those >>> chips with a large number of gpios. >> >> >> Blindly replacing VLAs by allocated arrays is IMHO not such a good >> solution. >> On the largest systems, NR_GPIOS is 2048, so that makes 2 arrays of 256 >> bytes. That's an uppper limit, and assumes they are all on the same >> gpiochip, >> which they probably aren't. >> >> Still, 2 x 256 bytes is a lot, so I agree it should be fixed. >> >> So, wouldn't it make more sense to not allocate memory, but just process >> the request in chunks (say, at most 128 gpios per chunk, i.e. 2 x >> 16 bytes)? The code already caters for handling chunks due to not all >> gpios >> belonging to the same gpiochip. That will probably also be faster than >> allocating memory, which is the main idea behind this API. >> >>> Reviewed-and-tested-by: Lukas Wunner >>> Signed-off-by: Lukas Wunner >>> Signed-off-by: Laura Abbott >> >> >>> --- a/drivers/gpio/gpiolib.c >>> +++ b/drivers/gpio/gpiolib.c >> >> >>> @@ -1192,6 +1196,10 @@ int gpiochip_add_data_with_key(struct gpio_chip >>> *chip, void *data, >>> goto err_free_descs; >>> } >>> >>> + if (chip->ngpio > FASTPATH_NGPIO) >>> + chip_warn(chip, "line cnt %d is greater than fast path >>> cnt %d\n", >>> + chip->ngpio, FASTPATH_NGPIO); >> >> >> FWIW, can this warning be triggered from userspace? >> >>> @@ -2662,16 +2670,28 @@ int gpiod_get_array_value_complex(bool raw, bool >>> can_sleep, >>> >>> while (i < array_size) { >>> struct gpio_chip *chip = desc_array[i]->gdev->chip; >>> - unsigned long mask[BITS_TO_LONGS(chip->ngpio)]; >>> - unsigned long bits[BITS_TO_LONGS(chip->ngpio)]; >> >> >> Hence just use a fixed size here... >> >>> + unsigned long fastpath[2 * >>> BITS_TO_LONGS(FASTPATH_NGPIO)]; >>> + unsigned long *mask, *bits; >>> int first, j, ret; >>> >>> + if (likely(chip->ngpio <= FASTPATH_NGPIO)) { >>> + memset(fastpath, 0, sizeof(fastpath)); >>> + mask = fastpath; >>> + bits = fastpath + BITS_TO_LONGS(FASTPATH_NGPIO); >>> + } else { >>> + mask = kcalloc(2 * BITS_TO_LONGS(chip->ngpio), >>> + sizeof(*mask), >>> + can_sleep ? GFP_KERNEL : >>> GFP_ATOMIC); >>> + if (!mask) >>> + return -ENOMEM; >>> + bits = mask + BITS_TO_LONGS(chip->ngpio); >>> + } >>> + >>> if (!can_sleep) >>> WARN_ON(chip->can_sleep); >>> >>> /* collect all inputs belonging to the same chip */ >>> first = i; >>> - memset(mask, 0, sizeof(mask)); >>> do { >>> const struct gpio_desc *desc = desc_array[i]; >>> int hwgpio = gpio_chip_hwgpio(desc); >> >> >> Out-of-context, the code does: >> >> | __set_bit(hwgpio, mask); >> | i++; >> | } while ((i < array_size) && >> >> ... and change this limit to "(i < min(array_size, first + >> ARRAY_SIZE(mask) * BITS_PER_BYTE))" >> >> | (desc_array[i]->gdev->chip == chip)); >> >> ... and you're done? >> > I don't think this approach will work since gpio_chip_{get,set}_multiple > expect to be working on arrays for the entire chip. There doesn't seem > to be a nice way to work on a subset of GPIOs without defeating the point > of the multiple API. You're right, sorry for missing that. > is 2*256 = 512 bytes really too much stack space? I guess we could > switch to a Kconfig to allow for better bounds. That's a good question. As long as a VLA is used, it's probably fine, as chip->ngpio is quite small. If you would change it to an array that can accommodate NR_GPIOS bits, you have to start caring about recursion (e.g. gpio-74x164 driven from spi-gpio, where I can extend the chain to increase the level of recursion arbitrarily). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds