Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp3980455ybl; Mon, 26 Aug 2019 03:40:01 -0700 (PDT) X-Google-Smtp-Source: APXvYqx8rzWHdaNSdZg2mUfafyJTipVEnEYvkLfVE0aBX2k0+t/xvA6XfPXOm/7kodWiRGHuD83+ X-Received: by 2002:a62:87c8:: with SMTP id i191mr19387126pfe.133.1566816001135; Mon, 26 Aug 2019 03:40:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566816001; cv=none; d=google.com; s=arc-20160816; b=VbYJH/eatP33Uhxli5VPofDq6y7dWS8m67OD/6npWJA7SE7k1yVeecRZIBEm6ANBuL RPcMiA7yJ0GVW28uVDmRPPpvga8hLbzuRmJMUxT4X/e3v0A2aR8/zkvUjtFxEVDjmZIy aKYR/6GYoKtQbPEvF2cQMAdj3YpAWmu9g+WNFNzITUJjM7UbNoxz83P62fIIiofcBqLb qgFgs0Ub1uN1+TkrGTcpYD1dIQQI6Dh1r8po8W50KR1g3vsSuFOVcf1LQqzygcIkunre F6c9HDxhd3Qh696YlFGmpLPeNiDvipb7f4qcOICpR2OYevn3yUeTXjbi9zGbtSX/T3ex +bsA== 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:dkim-signature; bh=t5IFyVt9ycUTswozYtX7dDQi6y3j9+8f5c65D6FhaJk=; b=IoPa1zeOVBZJv1CM17ZgR+BoMsQUk67RdmCdpRIQHex8KAGt8iua81IGGKMkOCT4PF rUxsIp6E5eNRMf4VZJVctRkb4wJ2MjOT8N5NxlzPZXVD7Tlzzou/t+5sk6cT6OE2wA5s Ow30SfZZGHFbgVEbwpRJYvcE9nyopcUxQoP6ChlTu+JJYLgoSQ5inwdVXAcubPqwvcRT wpkDtTnm4sEWv8Noj2EVGUbZo56Vb5HJysKOJ2hSeP/ZVt9DcMiINESNhui3EOWO/Fp2 ofEfBLaI4HTuceyln80ii4ShiWSFxPt6qxvHnF2sR0j8nh+bc0+1XVzcJSKQYg3V54iM pzDg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@rasmusvillemoes.dk header.s=google header.b=V2kDrxIw; 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 w10si63078pll.357.2019.08.26.03.39.45; Mon, 26 Aug 2019 03:40:01 -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=pass header.i=@rasmusvillemoes.dk header.s=google header.b=V2kDrxIw; 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 S1730527AbfHZKNb (ORCPT + 99 others); Mon, 26 Aug 2019 06:13:31 -0400 Received: from mail-lf1-f66.google.com ([209.85.167.66]:46426 "EHLO mail-lf1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730469AbfHZKNb (ORCPT ); Mon, 26 Aug 2019 06:13:31 -0400 Received: by mail-lf1-f66.google.com with SMTP id n19so11810590lfe.13 for ; Mon, 26 Aug 2019 03:13:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rasmusvillemoes.dk; s=google; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=t5IFyVt9ycUTswozYtX7dDQi6y3j9+8f5c65D6FhaJk=; b=V2kDrxIwe3zBsUdenFJteBOLthl93Ehz+6GkRgF8H67aCPc6C4NT6avkNNDp2rA9vB q8hjjP7wJE+alfVoFDtR03iPo3a1VZ96woLncoAgaLqYQWF2kCNFc0yPd2wWOT3AxmXq 8t/dP0va+AY6rAeI9PlV7NUMYU9dUZSNJMeGE= 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=t5IFyVt9ycUTswozYtX7dDQi6y3j9+8f5c65D6FhaJk=; b=jslPNrSBNYdPZQW6jsNmHeOBg3ahW8u+YTuVG9RrmDELxNQa6r8XhAr9OSHVGNdK9E eq/VDjGnVLM6W5wV8Ioxr4RBfZPgK5rLuIv8pC9KTu6eOv6qvRmidUY+oo82d3/f2Gv+ CHezdyfkKvkWNU/zdq8Ren/AciFFMI5dyAlGAVnxAIazd1of2Wnm/VUt9NZhZ092dcwb hGKzwYcyYvYojX6H9rFHwwVIPacwiblLKek2Qts/hjU4L1zofyoasfjuSrLUkURS6aNt fU0vjkMFGfs8PKigiSKYzLdKGDOKKU2vBpUab6q9odd/hRRQz8p73w3E9AwWmXxvy1nX e1hQ== X-Gm-Message-State: APjAAAW8COSFun4rp6vUiZSN9Fuae0K4lftqYKe6XSGKMNQGW/28N9RV NFcKwMEekrm/6cxNMlqnghDvvw== X-Received: by 2002:a19:2d19:: with SMTP id k25mr1777488lfj.76.1566814408505; Mon, 26 Aug 2019 03:13:28 -0700 (PDT) Received: from [172.16.11.28] ([81.216.59.226]) by smtp.gmail.com with ESMTPSA id n2sm2026320lfl.62.2019.08.26.03.13.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 26 Aug 2019 03:13:27 -0700 (PDT) Subject: Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants To: =?UTF-8?Q?Uwe_Kleine-K=c3=b6nig?= , Andrew Morton Cc: Jonathan Corbet , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, Linus Walleij , Bartosz Golaszewski References: <20190824233724.1775-1-uwe@kleine-koenig.org> From: Rasmus Villemoes Message-ID: Date: Mon, 26 Aug 2019 12:13:26 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <20190824233724.1775-1-uwe@kleine-koenig.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 25/08/2019 01.37, Uwe Kleine-König wrote: > pr_info("probing failed (%dE)\n", ret); > > expands to > > probing failed (EIO) > > if ret holds -EIO (or EIO). This introduces an array of error codes. If > the error code is missing, %dE falls back to %d and so prints the plain > number. > > Signed-off-by: Uwe Kleine-König > --- > Hello > > there are many code sites that benefit from this. Just grep for > "(%d)" ... > > As an example the follow up patch converts a printk to use this new > format escape. > > Best regards > Uwe > > Documentation/core-api/printk-formats.rst | 3 + > lib/vsprintf.c | 193 +++++++++++++++++++++- > 2 files changed, 195 insertions(+), 1 deletion(-) > > diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst > index c6224d039bcb..81002414f956 100644 > --- a/Documentation/core-api/printk-formats.rst > +++ b/Documentation/core-api/printk-formats.rst > @@ -35,6 +35,9 @@ Integer types > u64 %llu or %llx > > > +To print the name that corresponds to an integer error constant, use %dE and > +pass the int. > + > If is dependent on a config option for its size (e.g., sector_t, > blkcnt_t) or is architecture-dependent for its size (e.g., tcflag_t), use a > format specifier of its largest possible type and explicitly cast to it. > diff --git a/lib/vsprintf.c b/lib/vsprintf.c > index b0967cf17137..672eab8dab84 100644 > --- a/lib/vsprintf.c > +++ b/lib/vsprintf.c > @@ -533,6 +533,192 @@ char *number(char *buf, char *end, unsigned long long num, > return buf; > } > > +#define ERRORCODE(x) { .str = #x, .err = x } > + > +static const struct { > + const char *str; > + int err; > +} errorcodes[] = { > + ERRORCODE(EPERM), ... > + ERRORCODE(ERECALLCONFLICT), > +}; > + > +static noinline_for_stack > +char *errstr(char *buf, char *end, unsigned long long num, > + struct printf_spec spec) > +{ > + char *errname = NULL; > + size_t errnamelen, copy; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(errorcodes); ++i) { > + if (num == errorcodes[i].err || num == -errorcodes[i].err) { > + errname = errorcodes[i].str; > + break; > + } > + } Not sure I'm a fan of iterating this array. Yes, the errno values are a bit sparse, but maybe one could use a dense array with O(1) lookup for those < 128 and then have an exceptional table like yours for the rest. But if you do keep this whole array thing, please do as Andrew suggested and compact it somewhat (4 bytes per entry plus the storage for the strings themselves is enough, see e.g. e1f0bce3), and put EINVAL and other common things near the start (at least EINVAL is a lot more common than ENOEXEC). > + if (!errname) { > + /* fall back to ordinary number */ > + return number(buf, end, num, spec); > + } > + > + copy = errnamelen = strlen(errname); > + if (copy > end - buf) > + copy = end - buf; > + buf = memcpy(buf, errname, copy); This is buggy, AFAICT. buf may be beyond end (that's the convention), so end-buf (which is a ptrdiff_t, which is probably a signed type, but it gets converted to a size_t when compared to copy) can be a huge number, so copy>end-buf is false. Please just use the string() helper that gets used for printing other fixed strings (as well as %s input). And add tests to lib/test_printf.c, that would catch this sort of thing immediately. > + return buf + errnamelen; > +} > + > static noinline_for_stack > char *special_hex_number(char *buf, char *end, unsigned long long num, int size) > { > @@ -2566,7 +2752,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) > num = va_arg(args, unsigned int); > } > > - str = number(str, end, num, spec); > + if (spec.type == FORMAT_TYPE_INT && *fmt == 'E') { > + fmt++; > + str = errstr(str, end, num, spec); drivers/staging/speakup/speakup_bns.c has a %dE, have you checked whether you're breaking that one? It's hard to grep for all the variations, %-0*.5dE is also legal and would be caught here. This has previously been suggested as a %p extension, and I think users would just as often have an ERR_PTR() as a plain int or long. Since we already have %p[alphanumeric] as a special kernel thing, why not do that? It's more convenient to convert from ints/longs to error pointers pr_err("Uh-oh: %pE", ERR_PTR(ret)); than the other way around pr_err("Uh-oh: %dE", PTR_ERR(p)); // oops, must be %ldE Kernel size impact? Have you considered making it possible to opt-out and have %dE just mean %d? Rasmus