* [PATCH v1 1/2] vsprintf: introduce %dE for error constants @ 2019-08-24 23:37 Uwe Kleine-König 2019-08-24 23:37 ` [PATCH v1 2/2] gpiolib: print an error name instead of a plain number in error string Uwe Kleine-König ` (4 more replies) 0 siblings, 5 replies; 12+ messages in thread From: Uwe Kleine-König @ 2019-08-24 23:37 UTC (permalink / raw) To: Andrew Morton Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski 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 <uwe@kleine-koenig.org> --- 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 <type> 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(ENOENT), + ERRORCODE(ESRCH), + ERRORCODE(EINTR), + ERRORCODE(EIO), + ERRORCODE(ENXIO), + ERRORCODE(E2BIG), + ERRORCODE(ENOEXEC), + ERRORCODE(EBADF), + ERRORCODE(ECHILD), + ERRORCODE(EAGAIN), + ERRORCODE(ENOMEM), + ERRORCODE(EACCES), + ERRORCODE(EFAULT), + ERRORCODE(ENOTBLK), + ERRORCODE(EBUSY), + ERRORCODE(EEXIST), + ERRORCODE(EXDEV), + ERRORCODE(ENODEV), + ERRORCODE(ENOTDIR), + ERRORCODE(EISDIR), + ERRORCODE(EINVAL), + ERRORCODE(ENFILE), + ERRORCODE(EMFILE), + ERRORCODE(ENOTTY), + ERRORCODE(ETXTBSY), + ERRORCODE(EFBIG), + ERRORCODE(ENOSPC), + ERRORCODE(ESPIPE), + ERRORCODE(EROFS), + ERRORCODE(EMLINK), + ERRORCODE(EPIPE), + ERRORCODE(EDOM), + ERRORCODE(ERANGE), + ERRORCODE(EDEADLK), + ERRORCODE(ENAMETOOLONG), + ERRORCODE(ENOLCK), + ERRORCODE(ENOSYS), + ERRORCODE(ENOTEMPTY), + ERRORCODE(ELOOP), + ERRORCODE(EWOULDBLOCK), + ERRORCODE(ENOMSG), + ERRORCODE(EIDRM), + ERRORCODE(ECHRNG), + ERRORCODE(EL2NSYNC), + ERRORCODE(EL3HLT), + ERRORCODE(EL3RST), + ERRORCODE(ELNRNG), + ERRORCODE(EUNATCH), + ERRORCODE(ENOCSI), + ERRORCODE(EL2HLT), + ERRORCODE(EBADE), + ERRORCODE(EBADR), + ERRORCODE(EXFULL), + ERRORCODE(ENOANO), + ERRORCODE(EBADRQC), + ERRORCODE(EBADSLT), + ERRORCODE(EBFONT), + ERRORCODE(ENOSTR), + ERRORCODE(ENODATA), + ERRORCODE(ETIME), + ERRORCODE(ENOSR), + ERRORCODE(ENONET), + ERRORCODE(ENOPKG), + ERRORCODE(EREMOTE), + ERRORCODE(ENOLINK), + ERRORCODE(EADV), + ERRORCODE(ESRMNT), + ERRORCODE(ECOMM), + ERRORCODE(EPROTO), + ERRORCODE(EMULTIHOP), + ERRORCODE(EDOTDOT), + ERRORCODE(EBADMSG), + ERRORCODE(EOVERFLOW), + ERRORCODE(ENOTUNIQ), + ERRORCODE(EBADFD), + ERRORCODE(EREMCHG), + ERRORCODE(ELIBACC), + ERRORCODE(ELIBBAD), + ERRORCODE(ELIBSCN), + ERRORCODE(ELIBMAX), + ERRORCODE(ELIBEXEC), + ERRORCODE(EILSEQ), + ERRORCODE(ERESTART), + ERRORCODE(ESTRPIPE), + ERRORCODE(EUSERS), + ERRORCODE(ENOTSOCK), + ERRORCODE(EDESTADDRREQ), + ERRORCODE(EMSGSIZE), + ERRORCODE(EPROTOTYPE), + ERRORCODE(ENOPROTOOPT), + ERRORCODE(EPROTONOSUPPORT), + ERRORCODE(ESOCKTNOSUPPORT), + ERRORCODE(EOPNOTSUPP), + ERRORCODE(EPFNOSUPPORT), + ERRORCODE(EAFNOSUPPORT), + ERRORCODE(EADDRINUSE), + ERRORCODE(EADDRNOTAVAIL), + ERRORCODE(ENETDOWN), + ERRORCODE(ENETUNREACH), + ERRORCODE(ENETRESET), + ERRORCODE(ECONNABORTED), + ERRORCODE(ECONNRESET), + ERRORCODE(ENOBUFS), + ERRORCODE(EISCONN), + ERRORCODE(ENOTCONN), + ERRORCODE(ESHUTDOWN), + ERRORCODE(ETOOMANYREFS), + ERRORCODE(ETIMEDOUT), + ERRORCODE(ECONNREFUSED), + ERRORCODE(EHOSTDOWN), + ERRORCODE(EHOSTUNREACH), + ERRORCODE(EALREADY), + ERRORCODE(EINPROGRESS), + ERRORCODE(ESTALE), + ERRORCODE(EUCLEAN), + ERRORCODE(ENOTNAM), + ERRORCODE(ENAVAIL), + ERRORCODE(EISNAM), + ERRORCODE(EREMOTEIO), + ERRORCODE(EDQUOT), + ERRORCODE(ENOMEDIUM), + ERRORCODE(EMEDIUMTYPE), + ERRORCODE(ECANCELED), + ERRORCODE(ENOKEY), + ERRORCODE(EKEYEXPIRED), + ERRORCODE(EKEYREVOKED), + ERRORCODE(EKEYREJECTED), + ERRORCODE(EOWNERDEAD), + ERRORCODE(ENOTRECOVERABLE), + ERRORCODE(ERFKILL), + ERRORCODE(EHWPOISON), + ERRORCODE(ERESTARTSYS), + ERRORCODE(ERESTARTNOINTR), + ERRORCODE(ERESTARTNOHAND), + ERRORCODE(ENOIOCTLCMD), + ERRORCODE(ERESTART_RESTARTBLOCK), + ERRORCODE(EPROBE_DEFER), + ERRORCODE(EOPENSTALE), + ERRORCODE(ENOPARAM), + ERRORCODE(EBADHANDLE), + ERRORCODE(ENOTSYNC), + ERRORCODE(EBADCOOKIE), + ERRORCODE(ENOTSUPP), + ERRORCODE(ETOOSMALL), + ERRORCODE(ESERVERFAULT), + ERRORCODE(EBADTYPE), + ERRORCODE(EJUKEBOX), + ERRORCODE(EIOCBQUEUED), + 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; + } + } + + 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); + + 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); + } else { + str = number(str, end, num, spec); + } } } -- 2.20.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v1 2/2] gpiolib: print an error name instead of a plain number in error string 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König @ 2019-08-24 23:37 ` Uwe Kleine-König 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton ` (3 subsequent siblings) 4 siblings, 0 replies; 12+ messages in thread From: Uwe Kleine-König @ 2019-08-24 23:37 UTC (permalink / raw) To: Andrew Morton, Linus Walleij, Bartosz Golaszewski Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio This is an example that makes use of the just introduced printk format %dE that prints (e.g.) "EIO" when the matching integer is -EIO (or EIO). Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org> --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f497003f119c..b50ea24f087f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1247,7 +1247,7 @@ static void gpiochip_setup_devs(void) list_for_each_entry(gdev, &gpio_devices, list) { err = gpiochip_setup_dev(gdev); if (err) - pr_err("%s: Failed to initialize gpio device (%d)\n", + pr_err("%s: Failed to initialize gpio device (%dE)\n", dev_name(&gdev->dev), err); } } -- 2.20.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König 2019-08-24 23:37 ` [PATCH v1 2/2] gpiolib: print an error name instead of a plain number in error string Uwe Kleine-König @ 2019-08-24 23:58 ` Andrew Morton 2019-08-25 9:14 ` Uwe Kleine-König ` (2 more replies) 2019-08-26 10:13 ` Rasmus Villemoes ` (2 subsequent siblings) 4 siblings, 3 replies; 12+ messages in thread From: Andrew Morton @ 2019-08-24 23:58 UTC (permalink / raw) To: Uwe Kleine-König Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski, Petr Mladek, Sergey Senozhatsky, Steven Rostedt (cc printk maintainers). On Sun, 25 Aug 2019 01:37:23 +0200 Uwe Kleine-König <uwe@kleine-koenig.org> 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. Huh. I'm surprised we don't already have this. Seems that this will be applicable in a lot of places? Although we shouldn't go blindly converting everything in sight - that would risk breaking userspace which parses kernel strings. Is it really necessary to handle the positive errnos? Does much kernel code actually do that (apart from kernel code which is buggy)? > Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org> > --- > Hello > > there are many code sites that benefit from this. Just grep for > "(%d)" ... Yup. This observation shouldn't be below the "^---$" ;) An approximate grep|wc would be interesting. > --- 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[] = { It's a bit of a hack, but an array of char*'s and a separate array of ushorts would save a bit of space. > + ERRORCODE(EPERM), > + ERRORCODE(ENOENT), > + ERRORCODE(ESRCH), > > ... > > +static noinline_for_stack Why this? I'm suspecting this will actually increase stack use? > +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; > + } > + } > + > + 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); > + > + return buf + errnamelen; > +} OK, I guess `errstr' is an OK name for a static function and we can use this to add a new strerror() should the need arise. > > ... > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton @ 2019-08-25 9:14 ` Uwe Kleine-König 2019-08-26 12:05 ` Petr Mladek 2019-08-26 5:55 ` Sergey Senozhatsky 2019-08-26 9:58 ` Jani Nikula 2 siblings, 1 reply; 12+ messages in thread From: Uwe Kleine-König @ 2019-08-25 9:14 UTC (permalink / raw) To: Andrew Morton Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski, Petr Mladek, Sergey Senozhatsky, Steven Rostedt [-- Attachment #1: Type: text/plain, Size: 5632 bytes --] Hello Andrew, On Sat, Aug 24, 2019 at 04:58:29PM -0700, Andrew Morton wrote: > (cc printk maintainers). Ah, I wasn't aware there is something like them. Thanks > On Sun, 25 Aug 2019 01:37:23 +0200 Uwe Kleine-König <uwe@kleine-koenig.org> 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. > > Huh. I'm surprised we don't already have this. Seems that this will > be applicable in a lot of places? Although we shouldn't go blindly > converting everything in sight - that would risk breaking userspace > which parses kernel strings. Uah, even the kernel log is API? But I agree so far that this is merge window material and shouldn't make it into v5.3 :-) > Is it really necessary to handle the positive errnos? Does much kernel > code actually do that (apart from kernel code which is buggy)? I didn't check; probably not. But the whole positive range seems so unused and interpreting EIO (and not only -EIO) as "EIO" seems straight forward. But I don't feel strong either way. > > Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org> > > --- > > Hello > > > > there are many code sites that benefit from this. Just grep for > > "(%d)" ... > > Yup. This observation shouldn't be below the "^---$" ;) An approximate > grep|wc would be interesting. I didn't check how many false positives there are using "(%d)", but I'd use an a bit more elaborate expression for the commit log: $ git grep '(%d)' | wc -l 7336 $ git grep -E '^\s*(printk|(kv?as|sn?|vs(c?n)?)printf|(kvm|dev|pr)_(emerg|alert|crit|err|warn(ing)?|notice|info|cont|devel|debug|dbg))\(.*(\(%d\)|: %d)\\n' | wc -l 9140 The latter matches several printk-variants emitting a string ending in one of '(%d)\n' (1839 matches) ': %d\n' (7301 matches) . I would expect that many of the 7336 matches for '(%d)' that are not matched by the longer expression are false negatives because the function name is in the previous line. So I would estimate around 10k strings that could benefit from %dE. > > --- 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[] = { > > It's a bit of a hack, but an array of char*'s and a separate array of > ushorts would save a bit of space. Hmm, true. Currently we have 150 entries taking 150 * (sizeof(void *) * 2). Is it worth to think about the hacky solution to go down to 150 * (sizeof(void *) + 2)? For an ARM build bloat-o-meter reports (comparing linus/master to linus/master + my patch): add/remove: 2/0 grow/shrink: 4/2 up/down: 1488/-8 (1480) Function old new delta errorcodes - 1200 +1200 errstr - 200 +200 vsnprintf 884 960 +76 set_precision 148 152 +4 resource_string 1380 1384 +4 flags_string 400 404 +4 num_to_str 288 284 -4 format_decode 1024 1020 -4 Total: Before=21686, After=23166, chg +6.82% But that doesn't seem to include the size increase for all the added strings which seems to be around another 1300 bytes. > > + ERRORCODE(EPERM), > > + ERRORCODE(ENOENT), > > + ERRORCODE(ESRCH), > > > > ... > > > > +static noinline_for_stack > > Why this? I'm suspecting this will actually increase stack use? I don't know what it does, just copied it from number() which is used similarly. > > +char *errstr(char *buf, char *end, unsigned long long num, > > + struct printf_spec spec) > > +{ > > + char *errname = NULL; I missed a warning during my tests, there is a const missing in this line. > > + 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; > > + } > > + } > > + > > + 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); > > + > > + return buf + errnamelen; > > +} > > OK, I guess `errstr' is an OK name for a static function IMHO the name is very generic (which is bad), but it is in good company, as there is also pointer() and number(). > and we can use this to add a new strerror() should the need arise. In userspace the purpose of strerror is different. It would yield "I/O error" not "EIO". So strerror using this array would only be a "strerror light". In my first prototype I even used %m instead of %dE, but as %m (in glibc) doesn't consume an argument and produces the more verbose variant, I changed my mind and went for %dE. (Also my patch has the undocumented side effect that you can use %ldE if the error is held by a long int. I didn't test that though.) Best regards Uwe [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-25 9:14 ` Uwe Kleine-König @ 2019-08-26 12:05 ` Petr Mladek 0 siblings, 0 replies; 12+ messages in thread From: Petr Mladek @ 2019-08-26 12:05 UTC (permalink / raw) To: Uwe Kleine-König Cc: Andrew Morton, Bartosz Golaszewski, Sergey Senozhatsky, Steven Rostedt, Linus Walleij, Jonathan Corbet, linux-doc, linux-gpio, linux-kernel On Sun 2019-08-25 11:14:42, Uwe Kleine-König wrote: > Hello Andrew, > > On Sat, Aug 24, 2019 at 04:58:29PM -0700, Andrew Morton wrote: > > (cc printk maintainers). > > Ah, I wasn't aware there is something like them. Thanks > > > On Sun, 25 Aug 2019 01:37:23 +0200 Uwe Kleine-König <uwe@kleine-koenig.org> 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. What was the motivation for this patch, please? Did it look like a good idea? Did anyone got tired by searching for the error codes many times a day? Did the idea came from a developer, support, or user, please? > add/remove: 2/0 grow/shrink: 4/2 up/down: 1488/-8 (1480) > Function old new delta > errorcodes - 1200 +1200 > errstr - 200 +200 > vsnprintf 884 960 +76 > set_precision 148 152 +4 > resource_string 1380 1384 +4 > flags_string 400 404 +4 > num_to_str 288 284 -4 > format_decode 1024 1020 -4 > Total: Before=21686, After=23166, chg +6.82% > > But that doesn't seem to include the size increase for all the added > strings which seems to be around another 1300 bytes. This non-trivial increase of the size and the table still includes only part of the error codes. The array is long, created by cpu&paste, the index of each code is not obvious. There are ideas to make the code even more tricky to reduce the size, keep it fast. Both, %dE modifier and the output format (ECODE) is non-standard. Upper letters gain a lot of attention. But the error code is only helper information. Also many error codes are misleading because they are used either wrongly or there was no better available. There is no proof that this approach would be widely acceptable for subsystem maintainers. Some might not like mass and "blind" code changes. Some might not like the output at all. I am not persuaded that all this is worth it. Also I do not like the non-standard solution. Best Regards, Petr ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton 2019-08-25 9:14 ` Uwe Kleine-König @ 2019-08-26 5:55 ` Sergey Senozhatsky 2019-08-26 9:58 ` Jani Nikula 2 siblings, 0 replies; 12+ messages in thread From: Sergey Senozhatsky @ 2019-08-26 5:55 UTC (permalink / raw) To: Andrew Morton Cc: Uwe Kleine-König, Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski, Petr Mladek, Sergey Senozhatsky, Steven Rostedt On (08/24/19 16:58), Andrew Morton wrote: > On Sun, 25 Aug 2019 01:37:23 +0200 Uwe Kleine-König <uwe@kleine-koenig.org> 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. > > Huh. I'm surprised we don't already have this. Seems that this will > be applicable in a lot of places? Although we shouldn't go blindly > converting everything in sight - that would risk breaking userspace > which parses kernel strings. > > Is it really necessary to handle the positive errnos? Does much kernel > code actually do that (apart from kernel code which is buggy)? Good point. POSIX functions on error usually return -1 (negative value) and set errno (positive value). Positive errno value can be passed to strerror() or strerror_r() that decode that value and return a human readable representation. E.g. strerr(9) returns "Bad file descriptor". We don't have errno. Instead, and I may be wrong on this, kernel functions are expected to return negative error codes. A very quick grep shows that there are, however, patterns like "return positive errno". E.g. drivers/xen/xenbus/xenbus_xs.c: get_error() return EINVAL; But this EINVAL eventually becomes negative err = get_error(ret); return ERR_PTR(-err); or net/bluetooth/lib.c: bt_to_errno(). But, once again, bt_to_errno() return value eventually becomes negative: err = -bt_to_errno(hdev->req_result); So errstr() probably can handle only negative values. And, may be, I'd rename errstr() to strerror(); just because there is a well known function, which "translates" errnos. Unlike strerror(), errstr() just returns a macro name. Example: "Request failed: EJUKEBOX" EJUKEBOX does not tell me anything. A quick way to find out what does EJUKEBOX stand for is to grep include/linux/errno.h #define EJUKEBOX 528 /* Request initiated, but will not complete before timeout */ One still has to grep; either for 528 or for EJUKEBOX. I think that it might be simpler, however, to grep for EJUKEBOX, because one can grep the source code immediately, while in case of 528 one has to map 528 to the corresponding macro first and then grep the source code for EJUKEBOX. Overall %dE looks interesting. -ss ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton 2019-08-25 9:14 ` Uwe Kleine-König 2019-08-26 5:55 ` Sergey Senozhatsky @ 2019-08-26 9:58 ` Jani Nikula 2019-08-26 10:04 ` Jani Nikula 2 siblings, 1 reply; 12+ messages in thread From: Jani Nikula @ 2019-08-26 9:58 UTC (permalink / raw) To: Andrew Morton, Uwe Kleine-König Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski, Petr Mladek, Sergey Senozhatsky, Steven Rostedt On Sat, 24 Aug 2019, Andrew Morton <akpm@linux-foundation.org> wrote: >> --- 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[] = { > > It's a bit of a hack, but an array of char*'s and a separate array of > ushorts would save a bit of space. Or just #define ERRORCODE(x) [x] = #x static const char * const errorcodes[] = { ERRORCODE(EPERM), ERRORCODE(ENOENT), ... }; Saves space, faster lookup, discovers at build time why EWOULDBLOCK would always show up as EAGAIN in the logs. We don't have holes to speak of in the error codes. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-26 9:58 ` Jani Nikula @ 2019-08-26 10:04 ` Jani Nikula 0 siblings, 0 replies; 12+ messages in thread From: Jani Nikula @ 2019-08-26 10:04 UTC (permalink / raw) To: Andrew Morton, Uwe Kleine-König Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski, Petr Mladek, Sergey Senozhatsky, Steven Rostedt On Mon, 26 Aug 2019, Jani Nikula <jani.nikula@linux.intel.com> wrote: > On Sat, 24 Aug 2019, Andrew Morton <akpm@linux-foundation.org> wrote: >>> --- 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[] = { >> >> It's a bit of a hack, but an array of char*'s and a separate array of >> ushorts would save a bit of space. > > Or just > > #define ERRORCODE(x) [x] = #x > > static const char * const errorcodes[] = { > ERRORCODE(EPERM), > ERRORCODE(ENOENT), > ... > }; > > Saves space, faster lookup, discovers at build time why EWOULDBLOCK > would always show up as EAGAIN in the logs. We don't have holes to speak > of in the error codes. Meh, failed to notice the range ERESTARTSYS..ERECALLCONFLICT. Other than that, it's nicer. ;) BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König 2019-08-24 23:37 ` [PATCH v1 2/2] gpiolib: print an error name instead of a plain number in error string Uwe Kleine-König 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton @ 2019-08-26 10:13 ` Rasmus Villemoes 2019-08-26 13:29 ` Enrico Weigelt, metux IT consult 2019-08-29 13:27 ` Andy Shevchenko 4 siblings, 0 replies; 12+ messages in thread From: Rasmus Villemoes @ 2019-08-26 10:13 UTC (permalink / raw) To: Uwe Kleine-König, Andrew Morton Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski 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 <uwe@kleine-koenig.org> > --- > 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 <type> 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König ` (2 preceding siblings ...) 2019-08-26 10:13 ` Rasmus Villemoes @ 2019-08-26 13:29 ` Enrico Weigelt, metux IT consult 2019-08-30 13:21 ` David Laight 2019-08-29 13:27 ` Andy Shevchenko 4 siblings, 1 reply; 12+ messages in thread From: Enrico Weigelt, metux IT consult @ 2019-08-26 13:29 UTC (permalink / raw) To: Uwe Kleine-König, Andrew Morton Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski On 25.08.19 01:37, Uwe Kleine-König wrote: Hi, > +static noinline_for_stack > +char *errstr(char *buf, char *end, unsigned long long num,> + struct printf_spec spec)> +{ #1: why not putting that into some separate strerror() lib function ? This is something I've been looking for quite some time (actually already hacked it up somewhere, sometime, but forgotten ...) #2: why not just having a big case statement and leave the actual lookup logic to the compiler ? IMHO, could be written in a very compact way by some macro magic > + for (i = 0; i < ARRAY_SIZE(errorcodes); ++i) { > + if (num == errorcodes[i].err || num == -errorcodes[i].err) { why not taking the abs value only once, instead of duplicate comp on each iteration ? --mtx -- Enrico Weigelt, metux IT consult Free software and Linux embedded engineering info@metux.net -- +49-151-27565287 ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-26 13:29 ` Enrico Weigelt, metux IT consult @ 2019-08-30 13:21 ` David Laight 0 siblings, 0 replies; 12+ messages in thread From: David Laight @ 2019-08-30 13:21 UTC (permalink / raw) To: 'Enrico Weigelt, metux IT consult', Uwe Kleine-König, Andrew Morton Cc: Jonathan Corbet, linux-doc, linux-kernel, linux-gpio, Linus Walleij, Bartosz Golaszewski From: Enrico Weigelt, metux IT consult > Sent: 26 August 2019 14:29 > On 25.08.19 01:37, Uwe Kleine-König wrote: > > Hi, > > > +static noinline_for_stack > +char *errstr(char *buf, char *end, unsigned long long num,> + > struct printf_spec spec)> +{ > #1: why not putting that into some separate strerror() lib function ? > This is something I've been looking for quite some time (actually > already hacked it up somewhere, sometime, but forgotten ...) > > #2: why not just having a big case statement and leave the actual lookup > logic to the compiler ? IMHO, could be written in a very compact way > by some macro magic And generate an enormous amount of code and long chains of mispredicted branches. Is it also worth looking at how long the strings are. If they can be truncated to 16 bytes then char[][16] will generate much better code than the array of pointers. OTOH I'm not really sure it is all a good idea. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König ` (3 preceding siblings ...) 2019-08-26 13:29 ` Enrico Weigelt, metux IT consult @ 2019-08-29 13:27 ` Andy Shevchenko 4 siblings, 0 replies; 12+ messages in thread From: Andy Shevchenko @ 2019-08-29 13:27 UTC (permalink / raw) To: Uwe Kleine-König Cc: Andrew Morton, Jonathan Corbet, Linux Documentation List, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM, Linus Walleij, Bartosz Golaszewski On Sun, Aug 25, 2019 at 2:40 AM Uwe Kleine-König <uwe@kleine-koenig.org> 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 <uwe@kleine-koenig.org> > --- > 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. > Let's not do this! We have already a lot of pain with pointer extension, but here is just a misleading stuff. Besides above, how you print (float) number out of kernel in sysfs in very well standard format? Please, use %p<SMTH> instead. > 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 <type> 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(ENOENT), > + ERRORCODE(ESRCH), > + ERRORCODE(EINTR), > + ERRORCODE(EIO), > + ERRORCODE(ENXIO), > + ERRORCODE(E2BIG), > + ERRORCODE(ENOEXEC), > + ERRORCODE(EBADF), > + ERRORCODE(ECHILD), > + ERRORCODE(EAGAIN), > + ERRORCODE(ENOMEM), > + ERRORCODE(EACCES), > + ERRORCODE(EFAULT), > + ERRORCODE(ENOTBLK), > + ERRORCODE(EBUSY), > + ERRORCODE(EEXIST), > + ERRORCODE(EXDEV), > + ERRORCODE(ENODEV), > + ERRORCODE(ENOTDIR), > + ERRORCODE(EISDIR), > + ERRORCODE(EINVAL), > + ERRORCODE(ENFILE), > + ERRORCODE(EMFILE), > + ERRORCODE(ENOTTY), > + ERRORCODE(ETXTBSY), > + ERRORCODE(EFBIG), > + ERRORCODE(ENOSPC), > + ERRORCODE(ESPIPE), > + ERRORCODE(EROFS), > + ERRORCODE(EMLINK), > + ERRORCODE(EPIPE), > + ERRORCODE(EDOM), > + ERRORCODE(ERANGE), > + ERRORCODE(EDEADLK), > + ERRORCODE(ENAMETOOLONG), > + ERRORCODE(ENOLCK), > + ERRORCODE(ENOSYS), > + ERRORCODE(ENOTEMPTY), > + ERRORCODE(ELOOP), > + ERRORCODE(EWOULDBLOCK), > + ERRORCODE(ENOMSG), > + ERRORCODE(EIDRM), > + ERRORCODE(ECHRNG), > + ERRORCODE(EL2NSYNC), > + ERRORCODE(EL3HLT), > + ERRORCODE(EL3RST), > + ERRORCODE(ELNRNG), > + ERRORCODE(EUNATCH), > + ERRORCODE(ENOCSI), > + ERRORCODE(EL2HLT), > + ERRORCODE(EBADE), > + ERRORCODE(EBADR), > + ERRORCODE(EXFULL), > + ERRORCODE(ENOANO), > + ERRORCODE(EBADRQC), > + ERRORCODE(EBADSLT), > + ERRORCODE(EBFONT), > + ERRORCODE(ENOSTR), > + ERRORCODE(ENODATA), > + ERRORCODE(ETIME), > + ERRORCODE(ENOSR), > + ERRORCODE(ENONET), > + ERRORCODE(ENOPKG), > + ERRORCODE(EREMOTE), > + ERRORCODE(ENOLINK), > + ERRORCODE(EADV), > + ERRORCODE(ESRMNT), > + ERRORCODE(ECOMM), > + ERRORCODE(EPROTO), > + ERRORCODE(EMULTIHOP), > + ERRORCODE(EDOTDOT), > + ERRORCODE(EBADMSG), > + ERRORCODE(EOVERFLOW), > + ERRORCODE(ENOTUNIQ), > + ERRORCODE(EBADFD), > + ERRORCODE(EREMCHG), > + ERRORCODE(ELIBACC), > + ERRORCODE(ELIBBAD), > + ERRORCODE(ELIBSCN), > + ERRORCODE(ELIBMAX), > + ERRORCODE(ELIBEXEC), > + ERRORCODE(EILSEQ), > + ERRORCODE(ERESTART), > + ERRORCODE(ESTRPIPE), > + ERRORCODE(EUSERS), > + ERRORCODE(ENOTSOCK), > + ERRORCODE(EDESTADDRREQ), > + ERRORCODE(EMSGSIZE), > + ERRORCODE(EPROTOTYPE), > + ERRORCODE(ENOPROTOOPT), > + ERRORCODE(EPROTONOSUPPORT), > + ERRORCODE(ESOCKTNOSUPPORT), > + ERRORCODE(EOPNOTSUPP), > + ERRORCODE(EPFNOSUPPORT), > + ERRORCODE(EAFNOSUPPORT), > + ERRORCODE(EADDRINUSE), > + ERRORCODE(EADDRNOTAVAIL), > + ERRORCODE(ENETDOWN), > + ERRORCODE(ENETUNREACH), > + ERRORCODE(ENETRESET), > + ERRORCODE(ECONNABORTED), > + ERRORCODE(ECONNRESET), > + ERRORCODE(ENOBUFS), > + ERRORCODE(EISCONN), > + ERRORCODE(ENOTCONN), > + ERRORCODE(ESHUTDOWN), > + ERRORCODE(ETOOMANYREFS), > + ERRORCODE(ETIMEDOUT), > + ERRORCODE(ECONNREFUSED), > + ERRORCODE(EHOSTDOWN), > + ERRORCODE(EHOSTUNREACH), > + ERRORCODE(EALREADY), > + ERRORCODE(EINPROGRESS), > + ERRORCODE(ESTALE), > + ERRORCODE(EUCLEAN), > + ERRORCODE(ENOTNAM), > + ERRORCODE(ENAVAIL), > + ERRORCODE(EISNAM), > + ERRORCODE(EREMOTEIO), > + ERRORCODE(EDQUOT), > + ERRORCODE(ENOMEDIUM), > + ERRORCODE(EMEDIUMTYPE), > + ERRORCODE(ECANCELED), > + ERRORCODE(ENOKEY), > + ERRORCODE(EKEYEXPIRED), > + ERRORCODE(EKEYREVOKED), > + ERRORCODE(EKEYREJECTED), > + ERRORCODE(EOWNERDEAD), > + ERRORCODE(ENOTRECOVERABLE), > + ERRORCODE(ERFKILL), > + ERRORCODE(EHWPOISON), > + ERRORCODE(ERESTARTSYS), > + ERRORCODE(ERESTARTNOINTR), > + ERRORCODE(ERESTARTNOHAND), > + ERRORCODE(ENOIOCTLCMD), > + ERRORCODE(ERESTART_RESTARTBLOCK), > + ERRORCODE(EPROBE_DEFER), > + ERRORCODE(EOPENSTALE), > + ERRORCODE(ENOPARAM), > + ERRORCODE(EBADHANDLE), > + ERRORCODE(ENOTSYNC), > + ERRORCODE(EBADCOOKIE), > + ERRORCODE(ENOTSUPP), > + ERRORCODE(ETOOSMALL), > + ERRORCODE(ESERVERFAULT), > + ERRORCODE(EBADTYPE), > + ERRORCODE(EJUKEBOX), > + ERRORCODE(EIOCBQUEUED), > + 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; > + } > + } > + > + 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); > + > + 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); > + } else { > + str = number(str, end, num, spec); > + } > } > } > > -- > 2.20.1 > -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2019-08-30 13:21 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-08-24 23:37 [PATCH v1 1/2] vsprintf: introduce %dE for error constants Uwe Kleine-König 2019-08-24 23:37 ` [PATCH v1 2/2] gpiolib: print an error name instead of a plain number in error string Uwe Kleine-König 2019-08-24 23:58 ` [PATCH v1 1/2] vsprintf: introduce %dE for error constants Andrew Morton 2019-08-25 9:14 ` Uwe Kleine-König 2019-08-26 12:05 ` Petr Mladek 2019-08-26 5:55 ` Sergey Senozhatsky 2019-08-26 9:58 ` Jani Nikula 2019-08-26 10:04 ` Jani Nikula 2019-08-26 10:13 ` Rasmus Villemoes 2019-08-26 13:29 ` Enrico Weigelt, metux IT consult 2019-08-30 13:21 ` David Laight 2019-08-29 13:27 ` Andy Shevchenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).