On 09/24/2015 09:53 AM, Stephane Eranian wrote:
> Hi,
>
> Sorry for the delay.

No problem.

> Several remarks on this patch:
> - showevtinfo is a generic program that is meant to run even on non
> Linux systems, it cannot contain Linux specific knowledge

Thanks for explaining that. Will remove the showevtinfo changes.

> The rest is inlined below.
>
>
> On Mon, Sep 21, 2015 at 9:14 PM, Hemant Kumar <hem...@linux.vnet.ibm.com> 
> wrote:
>> Read the scale and unit values from the
>> sysfs 
>> (/sys/bus/event_source/devices/uncore_imc_*/events/cas_count_{read,write}.{scale,
>> unit}) for intel sandy-bridge uncore memory controllers' read and write
>> counters. These values are needed to scale the accumulated values to their
>> respective units.
>>
>> Signed-off-by: Hemant Kumar <hem...@linux.vnet.ibm.com>
>> ---
>>   examples/showevtinfo.c   |   5 ++-
>>   include/perfmon/pfmlib.h |   8 ++++
>>   lib/pfmlib_intel_x86.c   | 103 
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 115 insertions(+), 1 deletion(-)
>>
>> diff --git a/examples/showevtinfo.c b/examples/showevtinfo.c
>> index 45763ec..d182150 100644
>> --- a/examples/showevtinfo.c
>> +++ b/examples/showevtinfo.c
>> @@ -460,13 +460,16 @@ show_event_info(pfm_event_info_t *info)
>>
>>                          print_attr_flags(&ainfo);
>>
>> +                       printf(": %lf ", ainfo.scale);
>> +                       if (ainfo.unit == PFM_UNIT_MIB)
>> +                               printf(": MiB ");
>> +
> Why do you need to know it is MiB. The kernel exports everything you
> need. The perf tool has
>   no knowledge of MiB. The unit is just a string which you can print.

Right. Will just export the string then.

>>                          putchar(':');
>>
>>                          if (ainfo.equiv)
>>                                  printf(" Alias to %s", ainfo.equiv);
>>                          else
>>                                  printf(" %s", ainfo.desc);
>> -
>>                          putchar('\n');
>>                          um++;
>>                          break;
>> diff --git a/include/perfmon/pfmlib.h b/include/perfmon/pfmlib.h
>> index 2fb4744..ceea202 100644
>> --- a/include/perfmon/pfmlib.h
>> +++ b/include/perfmon/pfmlib.h
>> @@ -428,6 +428,8 @@ typedef struct {
>>                  int             dfl_bool;       /* default boolean value */
>>                  int             dfl_int;        /* default integer value */
>>          } SWIG_NAME(defaults);
>> +       double scale;
>> +       int unit;
>>   } pfm_event_attr_info_t;
>>
>>   /*
>> @@ -515,6 +517,12 @@ extern pfm_err_t pfm_get_event_encoding(const char 
>> *str, int dfl_plm, char **fst
>>   #define PFM_ERR_TOOMANY                -11     /* too many parameters */
>>   #define PFM_ERR_TOOSMALL       -12     /* parameter is too small */
>>
>> +typedef enum {
>> +       PFM_UNIT_UNKNOWN=0,     /* unknown units type */
>> +       PFM_UNIT_MIB,           /* The unit is MiB */
>> +       PFM_UNIT_MAX
>> +} pfm_attr_unit_t;
[SNIP]
>> +static int
>> +get_attr_unit(void *this, int pidx, int idx, intel_x86_umask_t umask)
>> +{
>> +       char unit_path[PATH_MAX];
>> +       FILE *fp;
>> +       size_t len = 0;
>> +       char *line = NULL, *unit_file = NULL;
>> +       ssize_t ret;
>> +       int unit;
>> +
>> +       unit_file = get_attr_file_name(this, pidx, idx, umask);
>> +       if (!unit_file)
>> +               goto end;
>> +
>> +       sprintf(unit_path, "/sys/bus/event_source/devices/%s/events/%s.unit",
>> +               (((pfmlib_pmu_t *)this)->perf_name), unit_file);
>> +       if (unit_file != NULL)
>> +               free(unit_file);
>> +
>> +       fp = fopen(unit_path, "r");
>> +       if (!fp)
>> +               goto end;
>> +
>> +       ret = getline(&line, &len, fp);
>> +       if (ret > 0) {
>> +               /* Remove the new line from the end of the string here */
>> +               if (line[strlen(line) - 1] == '\n')
>> +                       line[strlen(line) - 1] = '\0';
>> +               if (!strcmp(line, "MiB"))
>> +                       unit = PFM_UNIT_MIB;
>> +               free(line);
>> +               fclose(fp);
>> +               return unit;
>> +       }
>> +end:
>> +       return PFM_UNIT_UNKNOWN;
>> +}
>> +
>>   int
>>   pfm_intel_x86_get_event_attr_info(void *this, int pidx, int attr_idx, 
>> pfm_event_attr_info_t *info)
>>   {
>> @@ -915,6 +1016,8 @@ pfm_intel_x86_get_event_attr_info(void *this, int pidx, 
>> int attr_idx, pfm_event_
>>                  info->type = PFM_ATTR_UMASK;
>>                  info->is_dfl = intel_x86_uflag(this, pidx, idx, 
>> INTEL_X86_DFL);
>>                  info->is_precise = intel_x86_uflag(this, pidx, idx, 
>> INTEL_X86_PEBS);
>> +               info->scale = get_attr_scale(this, pidx, idx, 
>> pe[pidx].umasks[idx]);
>> +               info->unit = get_attr_unit(this, pidx, idx, 
>> pe[pidx].umasks[idx]);
> I think we could add those two fields to the info struct. However,
> that would need to come from the perf_event layer
> and not form the generic layer like you are doing now. In other words,
> those two info fields need to be filled out in an
> OS specific callback.

I have a question here. I may be wrong but Isn't
pfm_intel_x86_get_event_attr_info() being eventually called from
os->encode() through pfmlib_parse_event(),
pfmlib_build_event_pattrs() and pmu->get_event_attr_info() ?

Please let me know.

>>          } else {
>>                  idx = intel_x86_attr2mod(this, pidx, attr_idx);
>>                  info->name = atdesc[idx].name;
>> --
>> 1.9.3
>>

Thanks for the review and the suggestions.

-- 
Hemant Kumar


------------------------------------------------------------------------------
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel

Reply via email to