[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CABVgOSnDF=Cfmf-4Fr67fJVEm5yS98Dh+LKCOLR4L3Bz+VzWdg@mail.gmail.com>
Date: Fri, 11 Aug 2023 16:27:59 +0800
From: David Gow <davidgow@...gle.com>
To: Richard Fitzgerald <rf@...nsource.cirrus.com>
Cc: brendan.higgins@...ux.dev, rmoar@...gle.com,
linux-kselftest@...r.kernel.org, kunit-dev@...glegroups.com,
linux-kernel@...r.kernel.org, patches@...nsource.cirrus.com
Subject: Re: [PATCH v3 7/7] kunit: Don't waste first attempt to format string
in kunit_log_append()
On Wed, 9 Aug 2023 at 23:54, Richard Fitzgerald
<rf@...nsource.cirrus.com> wrote:
>
> It's wasteful to call vsnprintf() only to figure out the length of the
> string. The string might fit in the available buffer space but we have to
> vsnprintf() again to do that.
>
> Instead, attempt to format the string to the available buffer at the same
> time as finding the string length. Only if the string didn't fit the
> available space is it necessary to extend the log and format the string
> again to a new fragment buffer.
>
> Signed-off-by: Richard Fitzgerald <rf@...nsource.cirrus.com>
> ---
This looks good.
The only case I'm not totally convinced about is the last one, where
the message doesn't fit in the current log fragment, but is not a
whole fragment itself. I'm not sure if the added efficiency of not
doing a second vsprintf() is worth the memory fragmentation of always
starting a new fragment: the worst case where a log message is just
over half the length of frag->buf would result in every message being
in its own fragment (which would not necessarily have a consistent
size), and memory use would be ~doubled.
But I could accept it either way: until there's a real-world example
which strongly benefits from either implementation, let's go with
whatever we have working.
Reviewed-by: David Gow <davidgow@...gle.com>
Cheers,
-- David
> lib/kunit/test.c | 33 +++++++++++++++++----------------
> 1 file changed, 17 insertions(+), 16 deletions(-)
>
> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
> index 28d0048d6171..230ec5e9824f 100644
> --- a/lib/kunit/test.c
> +++ b/lib/kunit/test.c
> @@ -196,11 +196,21 @@ void kunit_log_append(struct list_head *log, const char *fmt, ...)
> if (!log)
> return;
>
> - /* Evaluate length of line to add to log */
> + frag = list_last_entry(log, struct kunit_log_frag, list);
> + log_len = strlen(frag->buf);
> + len_left = sizeof(frag->buf) - log_len - 1;
> +
> + /* Attempt to print formatted line to current fragment */
> va_start(args, fmt);
> - len = vsnprintf(NULL, 0, fmt, args) + 1;
> + len = vsnprintf(frag->buf + log_len, len_left, fmt, args) + 1;
> va_end(args);
>
> + if (len <= len_left)
> + goto out_newline;
> +
> + /* Abandon the truncated result of vsnprintf */
> + frag->buf[log_len] = '\0';
> +
> if (len > sizeof(frag->buf) - 1) {
> va_start(args, fmt);
> tmp = kvasprintf(GFP_KERNEL, fmt, args);
> @@ -212,24 +222,15 @@ void kunit_log_append(struct list_head *log, const char *fmt, ...)
> return;
> }
>
> - frag = list_last_entry(log, struct kunit_log_frag, list);
> - log_len = strlen(frag->buf);
> - len_left = sizeof(frag->buf) - log_len - 1;
> -
> - if (len > len_left) {
> - frag = kunit_log_extend(log);
> - if (!frag)
> - return;
> -
> - len_left = sizeof(frag->buf) - 1;
> - log_len = 0;
> - }
> + frag = kunit_log_extend(log);
> + if (!frag)
> + return;
>
> /* Print formatted line to the log */
> va_start(args, fmt);
> - vsnprintf(frag->buf + log_len, min(len, len_left), fmt, args);
> + vsnprintf(frag->buf, sizeof(frag->buf) - 1, fmt, args);
> va_end(args);
> -
> +out_newline:
> /* Add newline to end of log if not already present. */
> kunit_log_newline(frag);
> }
> --
> 2.30.2
>
Download attachment "smime.p7s" of type "application/pkcs7-signature" (4003 bytes)
Powered by blists - more mailing lists