Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp236717imm; Tue, 15 May 2018 00:33:40 -0700 (PDT) X-Google-Smtp-Source: AB8JxZq4f70ri3MFVQsaG7NBjUbsWGHl/FZl9uHEgrbg8dRHpp/eJ+nWqLMzVizysL9o3UHZuxrd X-Received: by 2002:a17:902:265:: with SMTP id 92-v6mr13027096plc.368.1526369620225; Tue, 15 May 2018 00:33:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526369620; cv=none; d=google.com; s=arc-20160816; b=HMCaJBd7GtLMcGPh+H/j5TG7YuhDlE3TG17+Q9jCMWZTN6dxnKMhzkHnENZwQeC0VF 3lLwaExglcpEybgOTuZrvCz0OOcFuc/oS/HskPXoNDUSsE6c110y9bzdstqnVBu7Qep3 NjK4uxovF/yhHSK+9EHMtQOyVMxWxCwwiDYbIJdlEgYAIsevvuflNFFjlsfXzr6gCjbY Ob1uVnHCkhW7OsYfe0wjv6VyCoef7eBwoAPCAZMefMervdgxPv9ptcullv4jrYK5iJZ1 u7rvbALAICm3vK7+4F8Ys+21hxsiO+S7YqkWM+b4oOjVmALeUW4nAgkKJt5Bl5XsE8ks SLaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:arc-authentication-results; bh=0/a+8R9UaI+JgVNKqD4csmeMbulDc8spwRg6XNhUDMQ=; b=tdNPWqkp17k7dv8iatcd3uL2xCYn6scuqcWtrMhDa+bXvWl+oUKDDSfE3fbzqgTceG lixpJ17OfIuN8h6GtZlEKyf3S61ENJAX2k+z56coUGcAOF+4TG8T4VD/gg99wTHGx+8Y Mh6ut6vB0c6NlHyTFau0Ss+/r26BMkmFB65Y11D5RRN3ejN3/Y/Y5lwGhbeASZhDRyNZ IspmDld8pq1ifx2z1Fbw7SC4E/FgvKkfN57R+pc0RcLMRPFsad4whTCCG+wSP2ZHilFF /5h1iitY+rrhtzfeaBEUpev+0R2FqaqfVW90BFS0FMIeEDMIbXhBU1QXWnLJ3OF5uJv+ sJag== ARC-Authentication-Results: i=1; mx.google.com; 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 w6-v6si10888370plq.382.2018.05.15.00.33.25; Tue, 15 May 2018 00:33:40 -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; 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 S1752340AbeEOHaZ (ORCPT + 99 others); Tue, 15 May 2018 03:30:25 -0400 Received: from anchovy2.45ru.net.au ([203.30.46.146]:57966 "EHLO anchovy2.45ru.net.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752139AbeEOHaX (ORCPT ); Tue, 15 May 2018 03:30:23 -0400 Received: (qmail 31869 invoked by uid 5089); 15 May 2018 07:30:21 -0000 Received: by simscan 1.2.0 ppid: 31727, pid: 31728, t: 0.0834s scanners: regex: 1.2.0 attach: 1.2.0 clamav: 0.88.3/m:40/d:1950 Received: from unknown (HELO ?192.168.0.122?) (preid@electromag.com.au@203.59.235.95) by anchovy3.45ru.net.au with ESMTPA; 15 May 2018 07:30:20 -0000 Subject: Re: [PATCHv5] gpio: Remove VLA from gpiolib To: Geert Uytterhoeven , Laura Abbott Cc: Linus Walleij , Kees Cook , Lukas Wunner , Rasmus Villemoes , "open list:GPIO SUBSYSTEM" , Linux Kernel Mailing List , kernel-hardening@lists.openwall.com References: <20180413212427.18261-1-labbott@redhat.com> <067d073f-556c-9df0-37f8-fd63fcdc7eb9@redhat.com> From: Phil Reid Message-ID: <0f48484b-9c01-b79b-5b2b-e0da1b312ebc@electromag.com.au> Date: Tue, 15 May 2018 15:30:09 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-AU Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 15/05/2018 15:10, Geert Uytterhoeven wrote: > 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). > I think a config option for FASTPATH_NGPIO is preferable. As I've mentioned ARCH_NR_GPIOS is much greater than any chip->ngpio on my platform. It's at least one order of magnitude, almost 2. -- Regards Phil Reid