Add a printk modifier %ppf (for pixel format) for printing V4L2 and DRM
pixel formats denoted by 4ccs. The 4cc encoding is the same for both so
the same implementation can be used.
Suggested-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Sakari Ailus <[email protected]>
---
Documentation/core-api/printk-formats.rst | 11 +++++++++
lib/vsprintf.c | 29 +++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index 8ebe46b1af39..b6249f513c09 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -545,6 +545,17 @@ For printing netdev_features_t.
Passed by reference.
+V4L2 and DRM fourcc code (pixel format)
+---------------------------------------
+
+::
+
+ %ppf
+
+Print a 4cc code used by V4L2 or DRM.
+
+Passed by reference.
+
Thanks
======
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 7c488a1ce318..b39f0ac317c5 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1721,6 +1721,32 @@ char *netdev_bits(char *buf, char *end, const void *addr,
return special_hex_number(buf, end, num, size);
}
+static noinline_for_stack
+char *pixel_format_string(char *buf, char *end, const u32 *fourcc,
+ struct printf_spec spec, const char *fmt)
+{
+ char ch[2] = { 0 };
+ unsigned int i;
+
+ if (check_pointer(&buf, end, fourcc, spec))
+ return buf;
+
+ switch (fmt[1]) {
+ case 'f':
+ for (i = 0; i < sizeof(*fourcc); i++) {
+ ch[0] = *fourcc >> (i << 3);
+ buf = string(buf, end, ch, spec);
+ }
+
+ if (*fourcc & BIT(31))
+ buf = string(buf, end, "-BE", spec);
+
+ return buf;
+ default:
+ return error_string(buf, end, "(%pp?)", spec);
+ }
+}
+
static noinline_for_stack
char *address_val(char *buf, char *end, const void *addr,
struct printf_spec spec, const char *fmt)
@@ -2131,6 +2157,7 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
* correctness of the format string and va_list arguments.
* - 'K' For a kernel pointer that should be hidden from unprivileged users
* - 'NF' For a netdev_features_t
+ * - 'pf' V4L2 or DRM pixel format.
* - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
* a certain separator (' ' by default):
* C colon
@@ -2223,6 +2250,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
return restricted_pointer(buf, end, ptr, spec);
case 'N':
return netdev_bits(buf, end, ptr, spec, fmt);
+ case 'p':
+ return pixel_format_string(buf, end, ptr, spec, fmt);
case 'a':
return address_val(buf, end, ptr, spec, fmt);
case 'd':
--
2.20.1
On Wed, 01 Apr 2020, Sakari Ailus <[email protected]> wrote:
> Add a printk modifier %ppf (for pixel format) for printing V4L2 and DRM
> pixel formats denoted by 4ccs. The 4cc encoding is the same for both so
> the same implementation can be used.
I'm not going to take a strong stand in one way or the other regarding
the patch at hand, but I do think at some point we have to draw a line
what should be included in printk formats. Arguably they should be
reserved to things that are generally useful across large parts of the
kernel, right?
I think the more specialized you get, the more you should think about
just using the plain old %s, and your own helpers. Because frankly, the
kernel printk specifiers also start getting more than a little obscure.
Or could we conceive of a way to make this locally extensible yet safe,
letting callers use something like %{foo}, as well as providing a
locally relevant function to do the conversion?
BR,
Jani.
>
> Suggested-by: Mauro Carvalho Chehab <[email protected]>
> Signed-off-by: Sakari Ailus <[email protected]>
> ---
> Documentation/core-api/printk-formats.rst | 11 +++++++++
> lib/vsprintf.c | 29 +++++++++++++++++++++++
> 2 files changed, 40 insertions(+)
>
> diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
> index 8ebe46b1af39..b6249f513c09 100644
> --- a/Documentation/core-api/printk-formats.rst
> +++ b/Documentation/core-api/printk-formats.rst
> @@ -545,6 +545,17 @@ For printing netdev_features_t.
>
> Passed by reference.
>
> +V4L2 and DRM fourcc code (pixel format)
> +---------------------------------------
> +
> +::
> +
> + %ppf
> +
> +Print a 4cc code used by V4L2 or DRM.
> +
> +Passed by reference.
> +
> Thanks
> ======
>
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 7c488a1ce318..b39f0ac317c5 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -1721,6 +1721,32 @@ char *netdev_bits(char *buf, char *end, const void *addr,
> return special_hex_number(buf, end, num, size);
> }
>
> +static noinline_for_stack
> +char *pixel_format_string(char *buf, char *end, const u32 *fourcc,
> + struct printf_spec spec, const char *fmt)
> +{
> + char ch[2] = { 0 };
> + unsigned int i;
> +
> + if (check_pointer(&buf, end, fourcc, spec))
> + return buf;
> +
> + switch (fmt[1]) {
> + case 'f':
> + for (i = 0; i < sizeof(*fourcc); i++) {
> + ch[0] = *fourcc >> (i << 3);
> + buf = string(buf, end, ch, spec);
> + }
> +
> + if (*fourcc & BIT(31))
> + buf = string(buf, end, "-BE", spec);
> +
> + return buf;
> + default:
> + return error_string(buf, end, "(%pp?)", spec);
> + }
> +}
> +
> static noinline_for_stack
> char *address_val(char *buf, char *end, const void *addr,
> struct printf_spec spec, const char *fmt)
> @@ -2131,6 +2157,7 @@ char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode,
> * correctness of the format string and va_list arguments.
> * - 'K' For a kernel pointer that should be hidden from unprivileged users
> * - 'NF' For a netdev_features_t
> + * - 'pf' V4L2 or DRM pixel format.
> * - 'h[CDN]' For a variable-length buffer, it prints it as a hex string with
> * a certain separator (' ' by default):
> * C colon
> @@ -2223,6 +2250,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
> return restricted_pointer(buf, end, ptr, spec);
> case 'N':
> return netdev_bits(buf, end, ptr, spec, fmt);
> + case 'p':
> + return pixel_format_string(buf, end, ptr, spec, fmt);
> case 'a':
> return address_val(buf, end, ptr, spec, fmt);
> case 'd':
--
Jani Nikula, Intel Open Source Graphics Center
Moi,
On Thu, Apr 02, 2020 at 11:34:48AM +0300, Jani Nikula wrote:
> On Wed, 01 Apr 2020, Sakari Ailus <[email protected]> wrote:
> > Add a printk modifier %ppf (for pixel format) for printing V4L2 and DRM
> > pixel formats denoted by 4ccs. The 4cc encoding is the same for both so
> > the same implementation can be used.
>
> I'm not going to take a strong stand in one way or the other regarding
> the patch at hand, but I do think at some point we have to draw a line
> what should be included in printk formats. Arguably they should be
> reserved to things that are generally useful across large parts of the
> kernel, right?
>
> I think the more specialized you get, the more you should think about
> just using the plain old %s, and your own helpers. Because frankly, the
> kernel printk specifiers also start getting more than a little obscure.
I don't really disagree... While this is functionality very commonly needed
in drivers, there are alternatives such as posted here:
<URL:https://lore.kernel.org/linux-media/[email protected]/>
The 4cc codes added by this set is still relatively generic (while still
Linux subsystem specific and not related to e.g. hardware standards), but I
wonder how many other, possibly similar cases there could be in the kernel,
and how many new specifiers we might get with those all added.
For what it's worth, even C99 defines macros for printing some formats
such as PRIu64 for uint64_t.
--
Terveisin,
Sakari Ailus
Em Thu, 02 Apr 2020 11:34:48 +0300
Jani Nikula <[email protected]> escreveu:
> On Wed, 01 Apr 2020, Sakari Ailus <[email protected]> wrote:
> > Add a printk modifier %ppf (for pixel format) for printing V4L2 and DRM
> > pixel formats denoted by 4ccs. The 4cc encoding is the same for both so
> > the same implementation can be used.
>
> I'm not going to take a strong stand in one way or the other regarding
> the patch at hand, but I do think at some point we have to draw a line
> what should be included in printk formats. Arguably they should be
> reserved to things that are generally useful across large parts of the
> kernel, right?
>
> I think the more specialized you get, the more you should think about
> just using the plain old %s, and your own helpers.
As I suggested it, from my side, I'd like to have it inside printk :-)
There is a subset of formats that are subsystem-specific anyway at
printk, like the network ones. We use extensively fourcc along the
media subsystem (and you probably also use fourcc at DRM). Even some input
devices nowadays may be using V4L2 core (some multi-sensor touching
devices), with depends on it.
So, those fourcc codes are pretty common. Having it at the printk
infra makes a lot easier for people to use them.
> Because frankly, the
> kernel printk specifiers also start getting more than a little obscure.
I liked one of the suggestions of using "%p4cc" (or maybe something
similar, if having a number there is a problem, like "%pAcc" or "%pfcc")
for this printk. This would be very easy for people to identify and
remember about its meaning.
> Or could we conceive of a way to make this locally extensible yet safe,
> letting callers use something like %{foo}, as well as providing a
> locally relevant function to do the conversion?
That's something that it makes sense to be implemented in the future,
for things that would be self-contained inside an specific subsystem.
Thanks,
Mauro
On Thu, 2020-04-02 at 11:34 +0300, Jani Nikula wrote:
> On Wed, 01 Apr 2020, Sakari Ailus <[email protected]> wrote:
> > Add a printk modifier %ppf (for pixel format) for printing V4L2 and DRM
> > pixel formats denoted by 4ccs. The 4cc encoding is the same for both so
> > the same implementation can be used.
>
> I'm not going to take a strong stand in one way or the other regarding
> the patch at hand, but I do think at some point we have to draw a line
> what should be included in printk formats. Arguably they should be
> reserved to things that are generally useful across large parts of the
> kernel, right?
Definitely yes.
> I think the more specialized you get, the more you should think about
> just using the plain old %s, and your own helpers. Because frankly, the
> kernel printk specifiers also start getting more than a little obscure.
>
> Or could we conceive of a way to make this locally extensible yet safe,
> letting callers use something like %{foo}, as well as providing a
> locally relevant function to do the conversion?
No. printf validation would be broken.
On Thu, 2020-04-02 at 15:53 +0200, Mauro Carvalho Chehab wrote:
> I liked one of the suggestions of using "%p4cc" (or maybe something
> similar, if having a number there is a problem, like "%pAcc" or "%pfcc")
Using a number is not a problem.
On Thu, 02 Apr 2020, Joe Perches <[email protected]> wrote:
> On Thu, 2020-04-02 at 11:34 +0300, Jani Nikula wrote:
>> Or could we conceive of a way to make this locally extensible yet safe,
>> letting callers use something like %{foo}, as well as providing a
>> locally relevant function to do the conversion?
>
> No. printf validation would be broken.
I tossed the idea on a whim, and thinking further I could probably come
up with a number of challenges, but care to elaborate on what you see as
the problem in validation?
BR,
Jani.
--
Jani Nikula, Intel Open Source Graphics Center
On Fri, 2020-04-03 at 09:37 +0300, Jani Nikula wrote:
> On Thu, 02 Apr 2020, Joe Perches <[email protected]> wrote:
> > On Thu, 2020-04-02 at 11:34 +0300, Jani Nikula wrote:
> > > Or could we conceive of a way to make this locally extensible yet safe,
> > > letting callers use something like %{foo}, as well as providing a
> > > locally relevant function to do the conversion?
> >
> > No. printf validation would be broken.
>
> I tossed the idea on a whim, and thinking further I could probably come
> up with a number of challenges, but care to elaborate on what you see as
> the problem in validation?
I understand you to want to add something like
%<m> where m is a non-standard format specifier
so using using gcc's extension of
__attribute__((__format__(printf, string_index, first_to_check))
could not validate the argument type against use of the %<m>
in the format string.
printk("%a\n", a);
Compiler bleats.