Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1354436 > unrolled thread
| Started by | Jiri Olsa <jolsa@kernel.org> |
|---|---|
| First post | 2016-03-09 21:50 +0100 |
| Last post | 2016-03-15 20:50 +0100 |
| Articles | 7 — 4 participants |
Back to article view | Back to linux.kernel
[RFC 0/5] ftrace perf: Fixes and speedup Jiri Olsa <jolsa@kernel.org> - 2016-03-09 21:50 +0100
[PATCH 5/5] ftrace: Update dynamic ftrace calls only if necessary Jiri Olsa <jolsa@kernel.org> - 2016-03-09 21:50 +0100
[PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool Jiri Olsa <jolsa@kernel.org> - 2016-03-09 21:50 +0100
Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool Namhyung Kim <namhyung@kernel.org> - 2016-03-11 15:30 +0100
Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool Jiri Olsa <jolsa@redhat.com> - 2016-03-11 19:20 +0100
Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool Namhyung Kim <namhyung@kernel.org> - 2016-03-12 09:40 +0100
Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool Steven Rostedt <rostedt@goodmis.org> - 2016-03-15 20:50 +0100
| From | Jiri Olsa <jolsa@kernel.org> |
|---|---|
| Date | 2016-03-09 21:50 +0100 |
| Subject | [RFC 0/5] ftrace perf: Fixes and speedup |
| Message-ID | <raTdn-4Ll-3@gated-at.bofh.it> |
hi,
sending some small perf related fixes plus one change
to speedup ftrace:function perf registration. I'm still
testing this, but any feedback would be great.
Also available in here:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
ftrace/fixes
thanks,
jirka
---
Jiri Olsa (5):
ftrace perf: Check sample types only for sampling events
ftrace perf: Move exclude_kernel tracepoint check to init event
ftrace perf: Use ftrace_ops::private to store event pointer
ftrace: Make ftrace_hash_rec_enable return update bool
ftrace: Update dynamic ftrace calls only if necessary
include/linux/perf_event.h | 3 +++
kernel/events/core.c | 27 ++++++++++++++++++++++-----
kernel/trace/ftrace.c | 36 +++++++++++++++++++++---------------
kernel/trace/trace_event_perf.c | 39 ++++++++++++++++++++++++++++++---------
4 files changed, 76 insertions(+), 29 deletions(-)
[toc] | [next] | [standalone]
| From | Jiri Olsa <jolsa@kernel.org> |
|---|---|
| Date | 2016-03-09 21:50 +0100 |
| Subject | [PATCH 5/5] ftrace: Update dynamic ftrace calls only if necessary |
| Message-ID | <raTdo-4Ll-11@gated-at.bofh.it> |
| In reply to | #1354436 |
Currently dynamic ftrace calls are updated any time
the ftrace_ops is un/registered. If we do this update
only when it's needed, we save lot of time for perf
system wide ftrace function sampling/counting.
The reason is that for system wide sampling/counting,
perf creates event for each cpu in the system.
Each event then registers separate copy of ftrace_ops,
which ends up in FTRACE_UPDATE_CALLS updates. On servers
with many cpus that means serious stall (240 cpus server):
Counting:
# time ./perf stat -e ftrace:function -a sleep 1
Performance counter stats for 'system wide':
370,663 ftrace:function
1.401427505 seconds time elapsed
real 3m51.743s
user 0m0.023s
sys 3m48.569s
Sampling:
# time ./perf record -e ftrace:function -a sleep 1
[ perf record: Woken up 0 times to write data ]
Warning:
Processed 141200 events and lost 5 chunks!
[ perf record: Captured and wrote 10.703 MB perf.data (135950 samples) ]
real 2m31.429s
user 0m0.213s
sys 2m29.494s
There's no reason to do the FTRACE_UPDATE_CALLS update
for each event in perf case, because all the ftrace_ops
always share the same filter, so the updated calls are
always the same.
It's required that only first ftrace_ops registration
does the FTRACE_UPDATE_CALLS update (also sometimes
the second if the first one used the trampoline), but
the rest can be only cheaply linked into the ftrace_ops
list.
Counting:
# time ./perf stat -e ftrace:function -a sleep 1
Performance counter stats for 'system wide':
398,571 ftrace:function
1.377503733 seconds time elapsed
real 0m2.787s
user 0m0.005s
sys 0m1.883s
Sampling:
# time ./perf record -e ftrace:function -a sleep 1
[ perf record: Woken up 0 times to write data ]
Warning:
Processed 261730 events and lost 9 chunks!
[ perf record: Captured and wrote 19.907 MB perf.data (256293 samples) ]
real 1m31.948s
user 0m0.309s
sys 1m32.051s
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/trace/ftrace.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 123dddc660e9..48b491463549 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2650,7 +2650,6 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
return ret;
ftrace_start_up++;
- command |= FTRACE_UPDATE_CALLS;
/*
* Note that ftrace probes uses this to start up
@@ -2671,7 +2670,8 @@ static int ftrace_startup(struct ftrace_ops *ops, int command)
return ret;
}
- ftrace_hash_rec_enable(ops, 1);
+ if (ftrace_hash_rec_enable(ops, 1))
+ command |= FTRACE_UPDATE_CALLS;
ftrace_startup_enable(command);
@@ -2701,11 +2701,11 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
/* Disabling ipmodify never fails */
ftrace_hash_ipmodify_disable(ops);
- ftrace_hash_rec_disable(ops, 1);
- ops->flags &= ~FTRACE_OPS_FL_ENABLED;
+ if (ftrace_hash_rec_disable(ops, 1))
+ command |= FTRACE_UPDATE_CALLS;
- command |= FTRACE_UPDATE_CALLS;
+ ops->flags &= ~FTRACE_OPS_FL_ENABLED;
if (saved_ftrace_func != ftrace_trace_function) {
saved_ftrace_func = ftrace_trace_function;
--
2.4.3
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@kernel.org> |
|---|---|
| Date | 2016-03-09 21:50 +0100 |
| Subject | [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool |
| Message-ID | <raTdp-4Ll-17@gated-at.bofh.it> |
| In reply to | #1354436 |
Change __ftrace_hash_rec_update to return true in case
we need to update dynamic ftrace call records. It return
false in case no update is needed.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/trace/ftrace.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index eca592f977b2..123dddc660e9 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1610,7 +1610,7 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec)
return keep_regs;
}
-static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
+static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
int filter_hash,
bool inc)
{
@@ -1618,12 +1618,13 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
struct ftrace_hash *other_hash;
struct ftrace_page *pg;
struct dyn_ftrace *rec;
+ bool update = false;
int count = 0;
int all = 0;
/* Only update if the ops has been registered */
if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
- return;
+ return false;
/*
* In the filter_hash case:
@@ -1650,7 +1651,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
* then there's nothing to do.
*/
if (ftrace_hash_empty(hash))
- return;
+ return false;
}
do_for_each_ftrace_rec(pg, rec) {
@@ -1694,7 +1695,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
if (inc) {
rec->flags++;
if (FTRACE_WARN_ON(ftrace_rec_count(rec) == FTRACE_REF_MAX))
- return;
+ return false;
/*
* If there's only a single callback registered to a
@@ -1720,7 +1721,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
rec->flags |= FTRACE_FL_REGS;
} else {
if (FTRACE_WARN_ON(ftrace_rec_count(rec) == 0))
- return;
+ return false;
rec->flags--;
/*
@@ -1753,22 +1754,27 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
*/
}
count++;
+
+ update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
+
/* Shortcut, if we handled all records, we are done. */
if (!all && count == hash->count)
- return;
+ return update;
} while_for_each_ftrace_rec();
+
+ return update;
}
-static void ftrace_hash_rec_disable(struct ftrace_ops *ops,
+static bool ftrace_hash_rec_disable(struct ftrace_ops *ops,
int filter_hash)
{
- __ftrace_hash_rec_update(ops, filter_hash, 0);
+ return __ftrace_hash_rec_update(ops, filter_hash, 0);
}
-static void ftrace_hash_rec_enable(struct ftrace_ops *ops,
+static bool ftrace_hash_rec_enable(struct ftrace_ops *ops,
int filter_hash)
{
- __ftrace_hash_rec_update(ops, filter_hash, 1);
+ return __ftrace_hash_rec_update(ops, filter_hash, 1);
}
static void ftrace_hash_rec_update_modify(struct ftrace_ops *ops,
--
2.4.3
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-03-11 15:30 +0100 |
| Subject | Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool |
| Message-ID | <rbweK-7tE-11@gated-at.bofh.it> |
| In reply to | #1354439 |
On Wed, Mar 09, 2016 at 09:46:44PM +0100, Jiri Olsa wrote:
> Change __ftrace_hash_rec_update to return true in case
> we need to update dynamic ftrace call records. It return
> false in case no update is needed.
>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> kernel/trace/ftrace.c | 26 ++++++++++++++++----------
> 1 file changed, 16 insertions(+), 10 deletions(-)
>
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index eca592f977b2..123dddc660e9 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -1610,7 +1610,7 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec)
> return keep_regs;
> }
>
> -static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> +static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
> int filter_hash,
> bool inc)
> {
> @@ -1618,12 +1618,13 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> struct ftrace_hash *other_hash;
> struct ftrace_page *pg;
> struct dyn_ftrace *rec;
> + bool update = false;
> int count = 0;
> int all = 0;
>
> /* Only update if the ops has been registered */
> if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
> - return;
> + return false;
>
> /*
> * In the filter_hash case:
> @@ -1650,7 +1651,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> * then there's nothing to do.
> */
> if (ftrace_hash_empty(hash))
> - return;
> + return false;
> }
>
> do_for_each_ftrace_rec(pg, rec) {
> @@ -1694,7 +1695,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> if (inc) {
> rec->flags++;
> if (FTRACE_WARN_ON(ftrace_rec_count(rec) == FTRACE_REF_MAX))
> - return;
> + return false;
>
> /*
> * If there's only a single callback registered to a
> @@ -1720,7 +1721,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> rec->flags |= FTRACE_FL_REGS;
> } else {
> if (FTRACE_WARN_ON(ftrace_rec_count(rec) == 0))
> - return;
> + return false;
> rec->flags--;
>
> /*
> @@ -1753,22 +1754,27 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> */
> }
> count++;
> +
> + update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
Shouldn't it use 'inc' instead of 1 for the second argument of
the ftrace_test_record()?
Thanks,
Namhyung
> +
> /* Shortcut, if we handled all records, we are done. */
> if (!all && count == hash->count)
> - return;
> + return update;
> } while_for_each_ftrace_rec();
> +
> + return update;
> }
>
> -static void ftrace_hash_rec_disable(struct ftrace_ops *ops,
> +static bool ftrace_hash_rec_disable(struct ftrace_ops *ops,
> int filter_hash)
> {
> - __ftrace_hash_rec_update(ops, filter_hash, 0);
> + return __ftrace_hash_rec_update(ops, filter_hash, 0);
> }
>
> -static void ftrace_hash_rec_enable(struct ftrace_ops *ops,
> +static bool ftrace_hash_rec_enable(struct ftrace_ops *ops,
> int filter_hash)
> {
> - __ftrace_hash_rec_update(ops, filter_hash, 1);
> + return __ftrace_hash_rec_update(ops, filter_hash, 1);
> }
>
> static void ftrace_hash_rec_update_modify(struct ftrace_ops *ops,
> --
> 2.4.3
>
[toc] | [prev] | [next] | [standalone]
| From | Jiri Olsa <jolsa@redhat.com> |
|---|---|
| Date | 2016-03-11 19:20 +0100 |
| Subject | Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool |
| Message-ID | <rbzPl-1I3-27@gated-at.bofh.it> |
| In reply to | #1355948 |
On Fri, Mar 11, 2016 at 11:28:00PM +0900, Namhyung Kim wrote:
SNIP
> > @@ -1694,7 +1695,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > if (inc) {
> > rec->flags++;
> > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == FTRACE_REF_MAX))
> > - return;
> > + return false;
> >
> > /*
> > * If there's only a single callback registered to a
> > @@ -1720,7 +1721,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > rec->flags |= FTRACE_FL_REGS;
> > } else {
> > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == 0))
> > - return;
> > + return false;
> > rec->flags--;
> >
> > /*
> > @@ -1753,22 +1754,27 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > */
> > }
> > count++;
> > +
> > + update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
>
> Shouldn't it use 'inc' instead of 1 for the second argument of
> the ftrace_test_record()?
I dont think so, 1 is to update calls (FTRACE_UPDATE_CALLS)
check ftrace_modify_all_code:
if (command & FTRACE_UPDATE_CALLS)
ftrace_replace_code(1);
else if (command & FTRACE_DISABLE_CALLS)
ftrace_replace_code(0);
both ftrace_startup, ftrace_shutdown use FTRACE_UPDATE_CALLS
you'd use 0 only to disable all, check ftrace_check_record comments:
/*
* If we are updating calls:
*
* If the record has a ref count, then we need to enable it
* because someone is using it.
*
* Otherwise we make sure its disabled.
*
* If we are disabling calls, then disable all records that
* are enabled.
*/
if (enable && ftrace_rec_count(rec))
flag = FTRACE_FL_ENABLED;
used by ftrace_shutdown_sysctl
thanks,
jirka
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2016-03-12 09:40 +0100 |
| Subject | Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool |
| Message-ID | <rbNfA-3dT-9@gated-at.bofh.it> |
| In reply to | #1356116 |
Hi Jiri,
On Fri, Mar 11, 2016 at 07:15:06PM +0100, Jiri Olsa wrote:
> On Fri, Mar 11, 2016 at 11:28:00PM +0900, Namhyung Kim wrote:
>
> SNIP
>
> > > @@ -1694,7 +1695,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > if (inc) {
> > > rec->flags++;
> > > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == FTRACE_REF_MAX))
> > > - return;
> > > + return false;
> > >
> > > /*
> > > * If there's only a single callback registered to a
> > > @@ -1720,7 +1721,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > rec->flags |= FTRACE_FL_REGS;
> > > } else {
> > > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == 0))
> > > - return;
> > > + return false;
> > > rec->flags--;
> > >
> > > /*
> > > @@ -1753,22 +1754,27 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > */
> > > }
> > > count++;
> > > +
> > > + update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
> >
> > Shouldn't it use 'inc' instead of 1 for the second argument of
> > the ftrace_test_record()?
>
> I dont think so, 1 is to update calls (FTRACE_UPDATE_CALLS)
> check ftrace_modify_all_code:
>
> if (command & FTRACE_UPDATE_CALLS)
> ftrace_replace_code(1);
> else if (command & FTRACE_DISABLE_CALLS)
> ftrace_replace_code(0);
>
> both ftrace_startup, ftrace_shutdown use FTRACE_UPDATE_CALLS
Ah, ok. So the second argument of the ftrace_test_record() is not
'enable' actually.. :-/
>
> you'd use 0 only to disable all, check ftrace_check_record comments:
>
> /*
> * If we are updating calls:
> *
> * If the record has a ref count, then we need to enable it
> * because someone is using it.
> *
> * Otherwise we make sure its disabled.
> *
> * If we are disabling calls, then disable all records that
> * are enabled.
> */
> if (enable && ftrace_rec_count(rec))
> flag = FTRACE_FL_ENABLED;
>
>
> used by ftrace_shutdown_sysctl
I got it. Thank you for the explanation!
Thanks,
Namhyung
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2016-03-15 20:50 +0100 |
| Subject | Re: [PATCH 4/5] ftrace: Make ftrace_hash_rec_enable return update bool |
| Message-ID | <rd38B-6Bt-1@gated-at.bofh.it> |
| In reply to | #1356378 |
On Sat, 12 Mar 2016 17:35:02 +0900
Namhyung Kim <namhyung@kernel.org> wrote:
> Hi Jiri,
>
> On Fri, Mar 11, 2016 at 07:15:06PM +0100, Jiri Olsa wrote:
> > On Fri, Mar 11, 2016 at 11:28:00PM +0900, Namhyung Kim wrote:
> >
> > SNIP
> >
> > > > @@ -1694,7 +1695,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > > if (inc) {
> > > > rec->flags++;
> > > > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == FTRACE_REF_MAX))
> > > > - return;
> > > > + return false;
> > > >
> > > > /*
> > > > * If there's only a single callback registered to a
> > > > @@ -1720,7 +1721,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > > rec->flags |= FTRACE_FL_REGS;
> > > > } else {
> > > > if (FTRACE_WARN_ON(ftrace_rec_count(rec) == 0))
> > > > - return;
> > > > + return false;
> > > > rec->flags--;
> > > >
> > > > /*
> > > > @@ -1753,22 +1754,27 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
> > > > */
> > > > }
> > > > count++;
> > > > +
> > > > + update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
Yeah, this is confusing. Mind adding a comment above this:
/* Must match FTRACE_UPDATE_CALLS in ftrace_modify_all_code() */
That way others will know why this is a '1'.
-- Steve
> > >
> > > Shouldn't it use 'inc' instead of 1 for the second argument of
> > > the ftrace_test_record()?
> >
> > I dont think so, 1 is to update calls (FTRACE_UPDATE_CALLS)
> > check ftrace_modify_all_code:
> >
> > if (command & FTRACE_UPDATE_CALLS)
> > ftrace_replace_code(1);
> > else if (command & FTRACE_DISABLE_CALLS)
> > ftrace_replace_code(0);
> >
> > both ftrace_startup, ftrace_shutdown use FTRACE_UPDATE_CALLS
>
> Ah, ok. So the second argument of the ftrace_test_record() is not
> 'enable' actually.. :-/
>
> >
> > you'd use 0 only to disable all, check ftrace_check_record comments:
> >
> > /*
> > * If we are updating calls:
> > *
> > * If the record has a ref count, then we need to enable it
> > * because someone is using it.
> > *
> > * Otherwise we make sure its disabled.
> > *
> > * If we are disabling calls, then disable all records that
> > * are enabled.
> > */
> > if (enable && ftrace_rec_count(rec))
> > flag = FTRACE_FL_ENABLED;
> >
> >
> > used by ftrace_shutdown_sysctl
>
> I got it. Thank you for the explanation!
>
> Thanks,
> Namhyung
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web