Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp4914972imm; Mon, 14 May 2018 15:49:52 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpuZ9+Lj0Cm7AINwGH0S4SiikK6SmknIjs19fbOioFP9YNHk3ttuwKte/yI8TQm+wjeJksH X-Received: by 2002:a17:902:3181:: with SMTP id x1-v6mr11802562plb.198.1526338192788; Mon, 14 May 2018 15:49:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526338192; cv=none; d=google.com; s=arc-20160816; b=PKq6FZeFyJ8oTL0p8eRUDf0KCXw/rvnynYq0t4TCaL+ttPrxnDZ5SxYgMIuNOPcdHD 2CxRS0lTVKoQgul4artOCwgG853nGejaD0nTPRKTga+uS+XD1Rb2E7zxqezSuvTGqiJ1 Xt5qOUSVzWP1jKebnsfzEhzFnEHSI7a7m/O15Q80mQyCg8ozl2n5dbMUr8jbRZutnnec Ew6o4p/TPWcwiBOR6P8EBckKyoTuLDN1mK3ocdfVchmS6vz4oCL3UcdttbQdI4nfWnWJ 8l/iheF/pAPUa4G/M9iY+i4e67nHTQCtAEHTTFAaqEkvbD5Tr3SHx/P73qAZVN/VGUpL WeAw== 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=HoSTDbajleqfISsUaYjLk3VyHlHfplWEwsa3etP+Mw8=; b=RZeLTX2/lI1f6Tr8aGmzVJthWJGAx2jZ4fePwrHig7C0gYYTzCSl2jsjzXfCvw1VSa FHjn1rQG7ZduHNcmxWli8OWolsYaUB79NVSf2jQCw96IPIqERS8EI9uPimOiIPL5zy1E 2+gpTD5iiLV8NzLK6TxKtH/xcEt96/c5p8CeLpf0chF3RZzVvgPINNJqsB/mB5zM+yY6 S00hEG04zsXckEINS1MsrBZo5nrhX8sx6YxLcDJzRjfkzI7eiwJV6tRaBGIGy3dlZo60 foo83Irb/UntCQgJqOpHS+CUmuWYOAb6509TNl85c/ySErpONciH3MwD+olPUFV5qQNw AfYw== 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y9-v6si8444812pgc.601.2018.05.14.15.49.37; Mon, 14 May 2018 15:49:52 -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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752161AbeENWt1 (ORCPT + 99 others); Mon, 14 May 2018 18:49:27 -0400 Received: from mail-ot0-f175.google.com ([74.125.82.175]:34337 "EHLO mail-ot0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752077AbeENWtZ (ORCPT ); Mon, 14 May 2018 18:49:25 -0400 Received: by mail-ot0-f175.google.com with SMTP id i5-v6so16252184otf.1 for ; Mon, 14 May 2018 15:49:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=HoSTDbajleqfISsUaYjLk3VyHlHfplWEwsa3etP+Mw8=; b=PqhXHD8xZ3sSm33WX8F+SARtF/eyLlFGV7wioV2sK6L3XkOmSB4BmyE/3GDUN+8XC2 jekS7Vr5KUWzDSuJSswHUdxz+nRURq/lt1FcFyP3o35xiR0LY8ef2siCqSp+GlfQUh/1 8t/uvieu3822wqzvEtqBZSW2ENY3/aUJnjCE/bB99B/erKp7czgF6mcPqzLCl9xwAKyc MmhMgpTt1C8gbtLL5saQkptpPsI8ygoO8cRViAXkwzZosqgGAkiiPk40Wxb1tS8dzx1D Z4fXgCtzX7NiZ/VLvjlY4j619wQ/9K3vTwpM2kup6OGgo1OmEGxVJMvV9yat3VNqPojh Myvw== X-Gm-Message-State: ALKqPweeDR51FumweO1ST//8OV0VCgE3kqo8XaYnbaBJrVGEuihNdZfT TZvYcuZPGMydwvrIITv1Kv1Jww== X-Received: by 2002:a9d:1bc7:: with SMTP id v7-v6mr8289769otv.344.1526338164486; Mon, 14 May 2018 15:49:24 -0700 (PDT) Received: from ?IPv6:2601:602:9802:a8dc::d2dd? ([2601:602:9802:a8dc::d2dd]) by smtp.gmail.com with ESMTPSA id r31-v6sm7220267otc.11.2018.05.14.15.49.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 14 May 2018 15:49:23 -0700 (PDT) Subject: Re: [PATCHv5] gpio: Remove VLA from gpiolib To: Geert Uytterhoeven 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> From: Laura Abbott Message-ID: <067d073f-556c-9df0-37f8-fd63fcdc7eb9@redhat.com> Date: Mon, 14 May 2018 15:49:21 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; 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-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 04/20/2018 02:02 AM, Geert Uytterhoeven wrote: > Hi Laura, > > Thanks for your patch! > > 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. is 2*256 = 512 bytes really too much stack space? I guess we could switch to a Kconfig to allow for better bounds. Thanks, Laura >> @@ -2878,7 +2904,7 @@ static void gpio_chip_set_multiple(struct gpio_chip *chip, >> } >> } >> >> -void gpiod_set_array_value_complex(bool raw, bool can_sleep, >> +int gpiod_set_array_value_complex(bool raw, bool can_sleep, > > Same here. > > Gr{oetje,eeting}s, > > Geert >