linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Peter Oberparleiter <oberpar@linux.ibm.com>
To: Tri Vo <trong@android.com>
Cc: ghackmann@android.com, ndesaulniers@google.com,
	linux-kernel@vger.kernel.org, kernel-team@android.com,
	Greg Hackmann <ghackmann@google.com>,
	Trilok Soni <tsoni@quicinc.com>,
	Prasad Sodagudi <psodagud@quicinc.com>
Subject: Re: [PATCH 2/4] gcov: clang support
Date: Wed, 16 Jan 2019 17:06:36 +0100	[thread overview]
Message-ID: <6c97cdb9-7b7d-e95b-567e-1938ca7f4ac2@linux.ibm.com> (raw)
In-Reply-To: <20190114210426.177543-3-trong@android.com>

On 14.01.2019 22:04, Tri Vo wrote:
> From: Greg Hackmann <ghackmann@google.com>
> 
> LLVM uses profiling data that's deliberately similar to GCC, but has a very
> different way of exporting that data.  LLVM calls llvm_gcov_init() once per
> module, and provides a couple of callbacks that we can use to ask for more
> data.
> 
> We care about the "writeout" callback, which in turn calls back into
> compiler-rt/this module to dump all the gathered coverage data to disk:
> 
>    llvm_gcda_start_file()
>      llvm_gcda_emit_function()
>      llvm_gcda_emit_arcs()
>      llvm_gcda_emit_function()
>      llvm_gcda_emit_arcs()
>      [... repeats for each function ...]
>    llvm_gcda_summary_info()
>    llvm_gcda_end_file()
> 
> This design is much more stateless and unstructured than gcc's, and is
> intended to run at process exit.  This forces us to keep some local state
> about which module we're dealing with at the moment.  On the other hand, it
> also means we don't depend as much on how LLVM represents profiling data
> internally.
> 
> See LLVM's lib/Transforms/Instrumentation/GCOVProfiling.cpp for more
> details on how this works, particularly GCOVProfiler::emitProfileArcs(),
> GCOVProfiler::insertCounterWriteout(), and GCOVProfiler::insertFlush().
> 
> Signed-off-by: Greg Hackmann <ghackmann@google.com>
> Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
> Signed-off-by: Tri Vo <trong@android.com>
> Tested-by: Trilok Soni <tsoni@quicinc.com>
> Tested-by: Prasad Sodagudi <psodagud@quicinc.com>
> Tested-by: Tri Vo <trong@android.com>
> ---
>  kernel/gcov/Kconfig  |   5 +
>  kernel/gcov/Makefile |   1 +
>  kernel/gcov/clang.c  | 531 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 537 insertions(+)
>  create mode 100644 kernel/gcov/clang.c

Please consider adding a short section detailing usage differences
between GCC and Clang coverage to the GCOV documentation at

  Documentation/dev-tools/gcov.rst

> diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c
> new file mode 100644
> index 000000000000..b00795d28137
> --- /dev/null
> +++ b/kernel/gcov/clang.c

[...]

> +/**
> + * gcov_info_add - add up profiling data
> + * @dest: profiling data set to which data is added
> + * @source: profiling data set which is added
> + *
> + * Adds profiling counts of @source to @dest.
> + */
> +void gcov_info_add(struct gcov_info *dst, struct gcov_info *src)
> +{
> +	struct gcov_fn_info *dfn_ptr;
> +	struct gcov_fn_info *sfn_ptr = list_first_entry_or_null(&src->functions,
> +			struct gcov_fn_info, head);
> +
> +	list_for_each_entry(dfn_ptr, &dst->functions, head) {
> +		u32 i;
> +
> +		for (i = 0; i < sfn_ptr->num_counters; i++)
> +			dfn_ptr->counters[i] += sfn_ptr->counters[i];
> +
> +		if (!list_is_last(&sfn_ptr->head, &src->functions))

This check seems wrong - both dst and src should contain the same amount
of functions and counters per function (the GCC support is based on the
same assumption).

Even if not, the next iteration would try to add counters for different
functions which would be incorrect and could cause access violations due
to differing values for num_counters.

> +			sfn_ptr = list_next_entry(sfn_ptr, head);
> +	}
> +}
> +
> +static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn)
> +{
> +	struct gcov_fn_info *fn_dup = kmemdup(fn, sizeof(*fn),
> +			GFP_KERNEL);
> +	if (!fn_dup)
> +		return NULL;
> +	INIT_LIST_HEAD(&fn_dup->head);
> +
> +	fn_dup->name = kstrdup(fn->name, GFP_KERNEL);

Since struct gcov_fn_info does not define a member named 'name', this
should fail during compilation. I saw that this is fixed with the next
patch, but this really needs to be merged into this one.

> +	if (!fn_dup->name)
> +		goto err_name;
> +
> +	fn_dup->counters = kmemdup(fn->counters,
> +			fn->num_counters * sizeof(fn->counters[0]),
> +			GFP_KERNEL);

Please consider using vmalloc() here (like the GCC support does) because
the number of counters can be quite large and there might be situations
where the required amount of physically contiguous memory is not
available at run-time.

> +	if (!fn_dup->counters)
> +		goto err_counters;
> +
> +	return fn_dup;
> +
> +err_counters:
> +	kfree(fn_dup->name);
> +err_name:
> +	kfree(fn_dup);
> +	return NULL;
> +}
> +
> +/**
> + * gcov_info_dup - duplicate profiling data set
> + * @info: profiling data set to duplicate
> + *
> + * Return newly allocated duplicate on success, %NULL on error.
> + */
> +struct gcov_info *gcov_info_dup(struct gcov_info *info)
> +{
> +	struct gcov_info *dup;
> +	struct gcov_fn_info *fn, *tmp;
> +
> +	dup = kmemdup(info, sizeof(*dup), GFP_KERNEL);
> +	if (!dup)
> +		return NULL;
> +	INIT_LIST_HEAD(&dup->head);
> +	INIT_LIST_HEAD(&dup->functions);
> +	dup->filename = kstrdup(info->filename, GFP_KERNEL);

To be consistent, please also check for a failed allocation here.

> +
> +	list_for_each_entry_safe(fn, tmp, &info->functions, head) {

It should not be necessary to use the _safe variant here as
info->functions is not modified during traversal.


-- 
Peter Oberparleiter
Linux on Z Development - IBM Germany


  reply	other threads:[~2019-01-16 16:06 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-14 21:04 [PATCH 0/4] gcov: add Clang support Tri Vo
2019-01-14 21:04 ` [PATCH 1/4] gcov: clang: move common gcc code into gcc_base.c Tri Vo
2019-01-16 15:32   ` Peter Oberparleiter
2019-01-14 21:04 ` [PATCH 2/4] gcov: clang support Tri Vo
2019-01-16 16:06   ` Peter Oberparleiter [this message]
2019-01-14 21:04 ` [PATCH 3/4] gcov: clang: link/unlink profiling data set Tri Vo
2019-01-16 16:14   ` Peter Oberparleiter
2019-01-14 21:04 ` [PATCH 4/4] gcov: clang: pick GCC vs Clang format depending on compiler Tri Vo
2019-01-14 21:11   ` Nick Desaulniers
2019-01-15  1:24   ` Masahiro Yamada
2019-01-15 17:52     ` Tri Vo
2019-01-14 21:32 ` [PATCH 0/4] gcov: add Clang support Nick Desaulniers
2019-01-14 21:53   ` Tri Vo
2019-01-14 22:00     ` Nick Desaulniers

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=6c97cdb9-7b7d-e95b-567e-1938ca7f4ac2@linux.ibm.com \
    --to=oberpar@linux.ibm.com \
    --cc=ghackmann@android.com \
    --cc=ghackmann@google.com \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=psodagud@quicinc.com \
    --cc=trong@android.com \
    --cc=tsoni@quicinc.com \
    /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 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).