[PATCH 11/19] perf metric: Compute referenced metrics

2020-07-29 Thread Jiri Olsa
Adding computation (expr__parse call) of referenced metric at
the point when it needs to be resolved during the parent metric
computation.

Once the inner metric is computed, the result is stored and
used if there's another usage of that metric.

Signed-off-by: Jiri Olsa 
Reviewed-by: Kajol Jain 
Acked-by: Ian Rogers 
Cc: Alexander Shishkin 
Cc: Andi Kleen 
Cc: John Garry 
Cc: Michael Petlan 
Cc: Namhyung Kim 
Cc: Paul Clarke 
Cc: Peter Zijlstra 
Cc: Stephane Eranian 
Link: http://lore.kernel.org/lkml/20200719181320.785305-12-jo...@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo 
---
 tools/perf/util/expr.c | 31 +++
 tools/perf/util/expr.h |  3 +++
 tools/perf/util/expr.y |  4 ++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index d3997c2b4a90..a346ca590513 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -112,6 +112,7 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct 
metric_ref *ref)
 */
data_ptr->ref.metric_name = ref->metric_name;
data_ptr->ref.metric_expr = ref->metric_expr;
+   data_ptr->ref.counted = false;
data_ptr->is_ref = true;
 
ret = hashmap__set(>ids, name, data_ptr,
@@ -133,6 +134,34 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char 
*id,
return hashmap__find(>ids, id, (void **)data) ? 0 : -1;
 }
 
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap)
+{
+   struct expr_id_data *data;
+
+   if (expr__get_id(ctx, id, datap) || !*datap) {
+   pr_debug("%s not found\n", id);
+   return -1;
+   }
+
+   data = *datap;
+
+   pr_debug2("lookup: is_ref %d, counted %d, val %f: %s\n",
+ data->is_ref, data->ref.counted, data->val, id);
+
+   if (data->is_ref && !data->ref.counted) {
+   data->ref.counted = true;
+   pr_debug("processing metric: %s ENTRY\n", id);
+   if (expr__parse(>val, ctx, data->ref.metric_expr, 1)) {
+   pr_debug("%s failed to count\n", id);
+   return -1;
+   }
+   pr_debug("processing metric: %s EXIT: %f\n", id, data->val);
+   }
+
+   return 0;
+}
+
 void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
 {
struct expr_id_data *old_val = NULL;
@@ -173,6 +202,8 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, 
const char *expr,
void *scanner;
int ret;
 
+   pr_debug2("parsing metric: %s\n", expr);
+
ret = expr_lex_init_extra(_ctx, );
if (ret)
return ret;
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 81d04ff7f857..9ed208d93418 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -23,6 +23,7 @@ struct expr_id_data {
struct {
const char *metric_name;
const char *metric_expr;
+   bool counted;
} ref;
};
 
@@ -42,6 +43,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val);
 int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 struct expr_id_data **data);
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
const char *expr, int runtime);
 int expr__find_other(const char *expr, const char *one,
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 0d4f5d324be7..d34b370391c6 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -88,11 +88,11 @@ expr: NUMBER
| ID{
struct expr_id_data *data;
 
-   if (expr__get_id(ctx, $1, ) || 
!data) {
-   pr_debug("%s not found\n", $1);
+   if (expr__resolve_id(ctx, $1, )) {
free($1);
YYABORT;
}
+
$$ = data->val;
free($1);
}
-- 
2.25.4



Re: [PATCH 11/19] perf metric: Compute referenced metrics

2020-07-28 Thread Arnaldo Carvalho de Melo
Em Sun, Jul 26, 2020 at 02:49:04PM +0530, kajoljain escreveu:
> 
> 
> On 7/19/20 11:43 PM, Jiri Olsa wrote:
> > Adding computation (expr__parse call) of referenced metric at
> > the point when it needs to be resolved during the parent metric
> > computation.
> > 
> > Once the inner metric is computed, the result is stored and
> > used if there's another usage of that metric.
> > 
> > Acked-by: Ian Rogers 
> > Signed-off-by: Jiri Olsa 
> 
> Reviewed-By : Kajol Jain

Thanks, applied.

- Arnaldo
 
> Thanks,
> Kajol Jain
> > ---
> >  tools/perf/util/expr.c | 31 +++
> >  tools/perf/util/expr.h |  3 +++
> >  tools/perf/util/expr.y |  4 ++--
> >  3 files changed, 36 insertions(+), 2 deletions(-)
> > 
> > diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
> > index d3997c2b4a90..a346ca590513 100644
> > --- a/tools/perf/util/expr.c
> > +++ b/tools/perf/util/expr.c
> > @@ -112,6 +112,7 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct 
> > metric_ref *ref)
> >  */
> > data_ptr->ref.metric_name = ref->metric_name;
> > data_ptr->ref.metric_expr = ref->metric_expr;
> > +   data_ptr->ref.counted = false;
> > data_ptr->is_ref = true;
> >  
> > ret = hashmap__set(>ids, name, data_ptr,
> > @@ -133,6 +134,34 @@ int expr__get_id(struct expr_parse_ctx *ctx, const 
> > char *id,
> > return hashmap__find(>ids, id, (void **)data) ? 0 : -1;
> >  }
> >  
> > +int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
> > +struct expr_id_data **datap)
> > +{
> > +   struct expr_id_data *data;
> > +
> > +   if (expr__get_id(ctx, id, datap) || !*datap) {
> > +   pr_debug("%s not found\n", id);
> > +   return -1;
> > +   }
> > +
> > +   data = *datap;
> > +
> > +   pr_debug2("lookup: is_ref %d, counted %d, val %f: %s\n",
> > + data->is_ref, data->ref.counted, data->val, id);
> > +
> > +   if (data->is_ref && !data->ref.counted) {
> > +   data->ref.counted = true;
> > +   pr_debug("processing metric: %s ENTRY\n", id);
> > +   if (expr__parse(>val, ctx, data->ref.metric_expr, 1)) {
> > +   pr_debug("%s failed to count\n", id);
> > +   return -1;
> > +   }
> > +   pr_debug("processing metric: %s EXIT: %f\n", id, data->val);
> > +   }
> > +
> > +   return 0;
> > +}
> > +
> >  void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
> >  {
> > struct expr_id_data *old_val = NULL;
> > @@ -173,6 +202,8 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, 
> > const char *expr,
> > void *scanner;
> > int ret;
> >  
> > +   pr_debug2("parsing metric: %s\n", expr);
> > +
> > ret = expr_lex_init_extra(_ctx, );
> > if (ret)
> > return ret;
> > diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
> > index 81d04ff7f857..9ed208d93418 100644
> > --- a/tools/perf/util/expr.h
> > +++ b/tools/perf/util/expr.h
> > @@ -23,6 +23,7 @@ struct expr_id_data {
> > struct {
> > const char *metric_name;
> > const char *metric_expr;
> > +   bool counted;
> > } ref;
> > };
> >  
> > @@ -42,6 +43,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const 
> > char *id, double val);
> >  int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
> >  int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
> >  struct expr_id_data **data);
> > +int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
> > +struct expr_id_data **datap);
> >  int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
> > const char *expr, int runtime);
> >  int expr__find_other(const char *expr, const char *one,
> > diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
> > index 0d4f5d324be7..d34b370391c6 100644
> > --- a/tools/perf/util/expr.y
> > +++ b/tools/perf/util/expr.y
> > @@ -88,11 +88,11 @@ expr: NUMBER
> > | ID{
> > struct expr_id_data *data;
> >  
> > -   if (expr__get_id(ctx, $1, ) || 
> > !data) {
> > -   pr_debug("%s not found\n", $1);
> > +   if (expr__resolve_id(ctx, $1, )) {
> > free($1);
> > YYABORT;
> > }
> > +
> > $$ = data->val;
> > free($1);
> > }
> > 

-- 

- Arnaldo


Re: [PATCH 11/19] perf metric: Compute referenced metrics

2020-07-26 Thread kajoljain



On 7/19/20 11:43 PM, Jiri Olsa wrote:
> Adding computation (expr__parse call) of referenced metric at
> the point when it needs to be resolved during the parent metric
> computation.
> 
> Once the inner metric is computed, the result is stored and
> used if there's another usage of that metric.
> 
> Acked-by: Ian Rogers 
> Signed-off-by: Jiri Olsa 

Reviewed-By : Kajol Jain

Thanks,
Kajol Jain
> ---
>  tools/perf/util/expr.c | 31 +++
>  tools/perf/util/expr.h |  3 +++
>  tools/perf/util/expr.y |  4 ++--
>  3 files changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
> index d3997c2b4a90..a346ca590513 100644
> --- a/tools/perf/util/expr.c
> +++ b/tools/perf/util/expr.c
> @@ -112,6 +112,7 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct 
> metric_ref *ref)
>*/
>   data_ptr->ref.metric_name = ref->metric_name;
>   data_ptr->ref.metric_expr = ref->metric_expr;
> + data_ptr->ref.counted = false;
>   data_ptr->is_ref = true;
>  
>   ret = hashmap__set(>ids, name, data_ptr,
> @@ -133,6 +134,34 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char 
> *id,
>   return hashmap__find(>ids, id, (void **)data) ? 0 : -1;
>  }
>  
> +int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
> +  struct expr_id_data **datap)
> +{
> + struct expr_id_data *data;
> +
> + if (expr__get_id(ctx, id, datap) || !*datap) {
> + pr_debug("%s not found\n", id);
> + return -1;
> + }
> +
> + data = *datap;
> +
> + pr_debug2("lookup: is_ref %d, counted %d, val %f: %s\n",
> +   data->is_ref, data->ref.counted, data->val, id);
> +
> + if (data->is_ref && !data->ref.counted) {
> + data->ref.counted = true;
> + pr_debug("processing metric: %s ENTRY\n", id);
> + if (expr__parse(>val, ctx, data->ref.metric_expr, 1)) {
> + pr_debug("%s failed to count\n", id);
> + return -1;
> + }
> + pr_debug("processing metric: %s EXIT: %f\n", id, data->val);
> + }
> +
> + return 0;
> +}
> +
>  void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
>  {
>   struct expr_id_data *old_val = NULL;
> @@ -173,6 +202,8 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, 
> const char *expr,
>   void *scanner;
>   int ret;
>  
> + pr_debug2("parsing metric: %s\n", expr);
> +
>   ret = expr_lex_init_extra(_ctx, );
>   if (ret)
>   return ret;
> diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
> index 81d04ff7f857..9ed208d93418 100644
> --- a/tools/perf/util/expr.h
> +++ b/tools/perf/util/expr.h
> @@ -23,6 +23,7 @@ struct expr_id_data {
>   struct {
>   const char *metric_name;
>   const char *metric_expr;
> + bool counted;
>   } ref;
>   };
>  
> @@ -42,6 +43,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
> *id, double val);
>  int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
>  int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
>struct expr_id_data **data);
> +int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
> +  struct expr_id_data **datap);
>  int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
>   const char *expr, int runtime);
>  int expr__find_other(const char *expr, const char *one,
> diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
> index 0d4f5d324be7..d34b370391c6 100644
> --- a/tools/perf/util/expr.y
> +++ b/tools/perf/util/expr.y
> @@ -88,11 +88,11 @@ expr:   NUMBER
>   | ID{
>   struct expr_id_data *data;
>  
> - if (expr__get_id(ctx, $1, ) || 
> !data) {
> - pr_debug("%s not found\n", $1);
> + if (expr__resolve_id(ctx, $1, )) {
>   free($1);
>   YYABORT;
>   }
> +
>   $$ = data->val;
>   free($1);
>   }
> 


[PATCH 11/19] perf metric: Compute referenced metrics

2020-07-19 Thread Jiri Olsa
Adding computation (expr__parse call) of referenced metric at
the point when it needs to be resolved during the parent metric
computation.

Once the inner metric is computed, the result is stored and
used if there's another usage of that metric.

Acked-by: Ian Rogers 
Signed-off-by: Jiri Olsa 
---
 tools/perf/util/expr.c | 31 +++
 tools/perf/util/expr.h |  3 +++
 tools/perf/util/expr.y |  4 ++--
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index d3997c2b4a90..a346ca590513 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -112,6 +112,7 @@ int expr__add_ref(struct expr_parse_ctx *ctx, struct 
metric_ref *ref)
 */
data_ptr->ref.metric_name = ref->metric_name;
data_ptr->ref.metric_expr = ref->metric_expr;
+   data_ptr->ref.counted = false;
data_ptr->is_ref = true;
 
ret = hashmap__set(>ids, name, data_ptr,
@@ -133,6 +134,34 @@ int expr__get_id(struct expr_parse_ctx *ctx, const char 
*id,
return hashmap__find(>ids, id, (void **)data) ? 0 : -1;
 }
 
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap)
+{
+   struct expr_id_data *data;
+
+   if (expr__get_id(ctx, id, datap) || !*datap) {
+   pr_debug("%s not found\n", id);
+   return -1;
+   }
+
+   data = *datap;
+
+   pr_debug2("lookup: is_ref %d, counted %d, val %f: %s\n",
+ data->is_ref, data->ref.counted, data->val, id);
+
+   if (data->is_ref && !data->ref.counted) {
+   data->ref.counted = true;
+   pr_debug("processing metric: %s ENTRY\n", id);
+   if (expr__parse(>val, ctx, data->ref.metric_expr, 1)) {
+   pr_debug("%s failed to count\n", id);
+   return -1;
+   }
+   pr_debug("processing metric: %s EXIT: %f\n", id, data->val);
+   }
+
+   return 0;
+}
+
 void expr__del_id(struct expr_parse_ctx *ctx, const char *id)
 {
struct expr_id_data *old_val = NULL;
@@ -173,6 +202,8 @@ __expr__parse(double *val, struct expr_parse_ctx *ctx, 
const char *expr,
void *scanner;
int ret;
 
+   pr_debug2("parsing metric: %s\n", expr);
+
ret = expr_lex_init_extra(_ctx, );
if (ret)
return ret;
diff --git a/tools/perf/util/expr.h b/tools/perf/util/expr.h
index 81d04ff7f857..9ed208d93418 100644
--- a/tools/perf/util/expr.h
+++ b/tools/perf/util/expr.h
@@ -23,6 +23,7 @@ struct expr_id_data {
struct {
const char *metric_name;
const char *metric_expr;
+   bool counted;
} ref;
};
 
@@ -42,6 +43,8 @@ int expr__add_id_val(struct expr_parse_ctx *ctx, const char 
*id, double val);
 int expr__add_ref(struct expr_parse_ctx *ctx, struct metric_ref *ref);
 int expr__get_id(struct expr_parse_ctx *ctx, const char *id,
 struct expr_id_data **data);
+int expr__resolve_id(struct expr_parse_ctx *ctx, const char *id,
+struct expr_id_data **datap);
 int expr__parse(double *final_val, struct expr_parse_ctx *ctx,
const char *expr, int runtime);
 int expr__find_other(const char *expr, const char *one,
diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y
index 0d4f5d324be7..d34b370391c6 100644
--- a/tools/perf/util/expr.y
+++ b/tools/perf/util/expr.y
@@ -88,11 +88,11 @@ expr: NUMBER
| ID{
struct expr_id_data *data;
 
-   if (expr__get_id(ctx, $1, ) || 
!data) {
-   pr_debug("%s not found\n", $1);
+   if (expr__resolve_id(ctx, $1, )) {
free($1);
YYABORT;
}
+
$$ = data->val;
free($1);
}
-- 
2.25.4