All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <fweisbec@gmail.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org,
	Steven Rostedt <rostedt@goodmis.org>,
	Lai Jiangshan <laijs@cn.fujitsu.com>,
	Peter Zijlstra <peterz@infradead.org>
Subject: Re: [PATCH 1/3] add binary printf
Date: Thu, 26 Feb 2009 19:52:09 +0100	[thread overview]
Message-ID: <20090226185208.GA6658@nowhere> (raw)
In-Reply-To: <20090226183415.GE5889@nowhere>

On Thu, Feb 26, 2009 at 07:34:16PM +0100, Frederic Weisbecker wrote:
> On Thu, Feb 26, 2009 at 06:52:25PM +0100, Ingo Molnar wrote:
> > 
> > * Frederic Weisbecker <fweisbec@gmail.com> wrote:
> > 
> > > On Thu, Feb 26, 2009 at 06:43:03PM +0100, Ingo Molnar wrote:
> > > > 
> > > > * Frederic Weisbecker <fweisbec@gmail.com> wrote:
> > > > 
> > > > > On Thu, Feb 26, 2009 at 02:02:43PM +0100, Ingo Molnar wrote:
> > > > > > 
> > > > > > * Frederic Weisbecker <fweisbec@gmail.com> wrote:
> > > > > > 
> > > > > > > From: Lai Jiangshan <laijs@cn.fujitsu.com>
> > > > > > > 
> > > > > > > Impact: Add APIs for binary trace printk infrastructure
> > > > > > > 
> > > > > > > vbin_printf(): write args to binary buffer, string is copied
> > > > > > > when "%s" is occurred.
> > > > > > > 
> > > > > > > bstr_printf(): read from binary buffer for args and format a string
> > > > > > > 
> > > > > > > [fweisbec@gmail.com: ported to latest -tip]
> > > > > > > 
> > > > > > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
> > > > > > > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > > > > > > Cc: Steven Rostedt <rostedt@goodmis.org>
> > > > > > > ---
> > > > > > >  include/linux/string.h |    7 +
> > > > > > >  lib/Kconfig            |    3 +
> > > > > > >  lib/vsprintf.c         |  442 ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > > > >  3 files changed, 452 insertions(+), 0 deletions(-)
> > > > > > 
> > > > > > OK, it's a nice idea and speedup for printf based tracing - 
> > > > > > which is common and convenient. Would you mind to post the 
> > > > > > performance measurements you've done using the new bstr_printf() 
> > > > > > facility? (the nanoseconds latency figures you did in the timer 
> > > > > > irq in a system under load and on a system that is idle)
> > > > > 
> > > > > 
> > > > > Ok.
> > > > > 
> > > > >  
> > > > > > The new printf code itself should be done cleaner i think and is 
> > > > > > not acceptable in its current form.
> > > > > > 
> > > > > > These two new functions:
> > > > > > 
> > > > > > > +#ifdef CONFIG_BINARY_PRINTF
> > > > > > > +/*
> > > > > > > + * bprintf service:
> > > > > > > + * vbin_printf() - VA arguments to binary data
> > > > > > > + * bstr_printf() - Binary data to text string
> > > > > > > + */
> > > > > > 
> > > > > > Duplicate hundreds of lines of code into three large functions 
> > > > > > (vsnprintf, vbin_printf, bstr_printf). These functions only have 
> > > > > > a difference in the way the argument list is iterated and the 
> > > > > > way the parsed result is stored:
> > > > > > 
> > > > > >   vsnprintf:   iterates va_list, stores into string
> > > > > >   bstr_printf: iterates bin_buf, stores into string
> > > > > >   vbin_printf: iterates va_list, stores into bin_buf
> > > > > > 
> > > > > > We should try _much_ harder at unifying these functions before 
> > > > > > giving up and duplicating them...
> > > > > > 
> > > > > > An opaque in_buf/out_buf handle plus two helper function 
> > > > > > pointers passed in would be an obvious implementation.
> > > > > > 
> > > > > > That way we'd have a single generic (inline) function that knows 
> > > > > > about the printf format itself:
> > > > > > 
> > > > > >  __generic_printf(void *in_buf,
> > > > > > 		  void *out_buf,
> > > > > > 		  void * (*read_in_buf)(void **),
> > > > > > 		  void * (*store_out_buf)(void **));
> > > > > > 
> > > > > > And we'd have various variants for read_in_buf and 
> > > > > > store_out_buf. The generic function iterates the following way:
> > > > > > 
> > > > > > 	in_val = read_in_buf(&in_buf);
> > > > > > 	...
> > > > > > 	store_out_buf(&out_buf, in_val);
> > > > > > 
> > > > > > (where in_val is wide enough to store a single argument.) The 
> > > > > > iterators modify the in_buf / out_buf pointers. Argument 
> > > > > > skipping can be done by reading the in-buf and not using it. I 
> > > > > > think we can do it with just two iterator methods.
> > > > > > 
> > > > > > Or something like that - you get the idea. It can all be inlined 
> > > > > > so that we'd end up with essentially the same vsnprint() 
> > > > > > instruction sequence we have today.
> > > > > > 
> > > > > > 	Ingo
> > > > > 
> > > > > 
> > > > > Ok, I just looked deeply inside vsnprintf, and I don't think 
> > > > > such a generic interface would allow that. We need to know the 
> > > > > size of the argument, it's precision, width and flags.... And 
> > > > > we need to know if we want to skip the non format char.
> > > > > 
> > > > > 
> > > > > What do you think of the following:
> > > > > 
> > > > > __ generic_printf(void *in,
> > > > > 		  void *out,
> > > > > 		  void *(*read_in)(void **buf, int size),
> > > > > 		  void *(store_char)(char *dst, char *end, char val, int field_width, int flags),
> > > > > 		  void *(*store_string)(char *dst, char *end, char *val, int field_width, int precision, int flags),
> > > > > 		  void *(*store_pointer)(char type, char *dst, char *end, void *val,
> > > > > 					int field_width, int precision, int flags),
> > > > > 		  void *(*store_number)(char *dst, char *size, int base,int field_width, int precision, int flags),
> > > > > 		  bool skip_non_format
> > > > > 		  )
> > > > > 
> > > > > 
> > > > > Well, something like that...
> > > > > 
> > > > > read_in can advance the pointer to the buffer itself (buf can 
> > > > > be a va_args or u32 *) and it returns a value, void * is 
> > > > > generic for the type.
> > > > > 
> > > > > The storage functions are more specialized because of the 
> > > > > interpretation of flags, precision... So we can easily pass 
> > > > > the usual string(), pointer(), .... that are already present 
> > > > > in vsnprintf.c or use custom ones. They return the advanced 
> > > > > dst pointer.
> > > > > 
> > > > > And at last, skip_non_format will decide if we want to 
> > > > > consider non-format characters from fmt to be copied as common 
> > > > > %c characters or if we want to ignore them (useful for 
> > > > > vbin_printf()).
> > > > 
> > > > hm, that indeed looks very wide - storing into a binary buffer 
> > > > does complicate the iterator interface significantly.
> > > > 
> > > > But at least vsnprintf() and bstr_printf() could be unified - 
> > > > they both output into a string buffer, just have different 
> > > > methods to iterate arguments.
> > > > 
> > > > 	Ingo
> > > 
> > > Right, ok I'm on it.
> > 
> > hm, it would still be nice to get vbin_printf() into the same 
> > scheme too.
> > 
> > And i think we can do it by unconditionally tracking field type 
> > and width in the generic helper - instead of passing this across 
> > the abstraction barrier like your proposal did. vsnprintf() and 
> > bstr_printf() wont make use of it - but vbin_printf() will.
> > 
> > Am i missing anything?
> > 
> > 	Ingo
> 
> Hm, I have some trouble to visualize it globally.
> 
> vsnprintf: takes char * for dest and va_list as src, write formatted in dest
> bstr_printf: takes char * as dest and u32 * as src, read from src is specialized
> vbin_printf: takes u32 * buf as dest and va_list as src, write to dest is specialized
> 
> The only thing that can be generic between the three is the format decoding.
> All in-out operations must be abstracted if we want a common interface from the three.
> 
> So I'm not sure I have the choice.
> 


Instead of calling the in/out helper from the decoder,
why not calling the decoder from these three functions and let them
take the appropriate actions for each decoded format token?

Naive example:

bstr_printf() {
	while (decode_format(...))
		if (type == number)
			read_number_from_buf()
			str = number(....)
		....
}

vsnprintf {
	while (decode_format(...))
		if (type == number)
			var_arg(...)
			str = number(....)
		....
}

vbin_printf {
	while (decode_format(...))
		if (type == number)
			var_arg(...)
			write_number_to_buffer()
		...
}

And the standard in/out pieces can be invoked through helpers.


  parent reply	other threads:[~2009-02-26 18:52 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-24  5:17 [PATCH 1/3] add binary printf Frederic Weisbecker
2009-02-26 13:02 ` Ingo Molnar
2009-02-26 17:05   ` Frederic Weisbecker
2009-02-26 17:43     ` Ingo Molnar
2009-02-26 17:45       ` Frederic Weisbecker
2009-02-26 17:52         ` Ingo Molnar
2009-02-26 18:34           ` Frederic Weisbecker
2009-02-26 18:45             ` Ingo Molnar
2009-02-26 18:52             ` Frederic Weisbecker [this message]
2009-02-26 18:56               ` Ingo Molnar
2009-02-26 19:05                 ` Frederic Weisbecker
2009-02-27  6:19                 ` [PATCH][RFC] vsprintf: unify the format decoding layer for its 3 users Frederic Weisbecker
2009-02-27  6:46                   ` Andrew Morton
2009-02-27  7:12                     ` Frederic Weisbecker
2009-02-27  7:39                       ` Andrew Morton
2009-02-27  8:32                         ` Ingo Molnar
2009-02-27  8:45                           ` Andrew Morton
2009-02-27  9:35                             ` Ingo Molnar
2009-02-27  8:20                     ` Ingo Molnar
2009-02-27  8:33                       ` Andrew Morton
2009-02-27 15:03                     ` Steven Rostedt
2009-02-28  0:30                       ` Linus Torvalds
2009-02-28  0:39                   ` Linus Torvalds
2009-02-28  8:11                     ` Frederic Weisbecker
2009-02-28  9:13                       ` Ingo Molnar
2009-02-28 19:45                         ` [PATCH 1/5] add binary printf Frederic Weisbecker
2009-02-28 20:16                         ` [PATCH 2/5] ftrace: infrastructure for supporting binary record Frederic Weisbecker
2009-03-02 16:27                           ` Steven Rostedt
2009-03-02 17:39                             ` Frédéric Weisbecker
2009-02-28 21:30                         ` [PATCH 3/5] ftrace: add ftrace_bprintk() Frederic Weisbecker
2009-03-02 16:34                           ` Steven Rostedt
2009-03-02 17:45                             ` Frédéric Weisbecker
2009-03-02 17:53                               ` Steven Rostedt
2009-03-02 18:06                                 ` Frédéric Weisbecker
2009-03-02 18:23                                   ` Steven Rostedt
2009-03-02 18:55                                     ` Frédéric Weisbecker
2009-02-28 22:16                         ` [PATCH 4/5] tracing/core: drop the old ftrace_printk implementation in favour of ftrace_bprintk Frederic Weisbecker
2009-03-02 16:37                           ` Steven Rostedt
2009-03-02 17:47                             ` Frédéric Weisbecker
2009-02-28 23:11                         ` [PATCH][RFC] vsprintf: unify the format decoding layer for its 3 users Frederic Weisbecker
2009-03-01  2:34                         ` [PATCH 5/5 v3] " Frederic Weisbecker
2009-03-01  3:31                         ` [PATCH 0/5] Binary ftrace_printk Frederic Weisbecker
2009-02-28 16:54                       ` [PATCH][RFC] vsprintf: unify the format decoding layer for its 3 users Linus Torvalds
2009-02-28 17:18                         ` Frederic Weisbecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090226185208.GA6658@nowhere \
    --to=fweisbec@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=laijs@cn.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.