Skip to content

Commit

Permalink
Separate into denki.rapl.sysfs and denki.rapl.msr, manpage fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
christianhorn committed Feb 2, 2025
1 parent db910f2 commit fe3cbfa
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 81 deletions.
102 changes: 48 additions & 54 deletions src/pmdas/denki/denki.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Denki (電気, Japanese for 'electricity'), PMDA for electricity related
* metrics
*
* Copyright (c) 2012-2014,2017,2021-2024 Red Hat.
* Copyright (c) 2012-2014,2017,2021-2025 Red Hat.
* Copyright (c) 1995,2004 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -842,8 +842,8 @@ static int read_batteries(void) {
/*
* Denki PMDA metrics
*
* denki.raplsysfs - energy counter from RAPL, read from sysfs
* denki.raplmsr - energy counter from RAPL, read from msr registers
* denki.rapl.sysfs - energy counter from RAPL, read from sysfs
* denki.rapl.msr - energy counter from RAPL, read from msr registers
* denki.bat.energy_now - <battery>/energy_now raw reading,
* current battery charge in Wh
* denki.bat.power_now - <battery>/power_now raw reading
Expand All @@ -858,49 +858,49 @@ static int read_batteries(void) {
*/

static pmdaIndom indomtab[] = {
#define RAPL_SYSFS_INDOM 0 /* serial number for RAPL sysfs instance domain */
#define RAPL_SYSFS_INDOM 0 /* serial number for rapl.sysfs instance domain */
{ RAPL_SYSFS_INDOM, 0, NULL },
#define RAPL_MSR_INDOM 1 /* serial number for RAPL msr instance domain */
#define RAPL_MSR_INDOM 1 /* serial number for rapl.msr instance domain */
{ RAPL_MSR_INDOM, 0, NULL },
#define ENERGYNOW_INDOM 2 /* serial number for energy_now instance domain */
{ ENERGYNOW_INDOM, 0, NULL },
#define POWERNOW_INDOM 3 /* serial number for power_now instance domain */
{ POWERNOW_INDOM, 0, NULL },
#define CAPACITY_INDOM 4 /* serial number for capacity instance domain */
{ CAPACITY_INDOM, 0, NULL }
#define BAT_ENERGYNOW_INDOM 2 /* serial number for bat.energy_now instance domain */
{ BAT_ENERGYNOW_INDOM, 0, NULL },
#define BAT_POWERNOW_INDOM 3 /* serial number for bat.power_now instance domain */
{ BAT_POWERNOW_INDOM, 0, NULL },
#define BAT_CAPACITY_INDOM 4 /* serial number for bat.capacity instance domain */
{ BAT_CAPACITY_INDOM, 0, NULL }
};

/* this is merely a convenience */
static pmInDom *rapl_sysfs_indom = &indomtab[RAPL_SYSFS_INDOM].it_indom;
static pmInDom *rapl_msr_indom = &indomtab[RAPL_MSR_INDOM].it_indom;
static pmInDom *energynow_indom = &indomtab[ENERGYNOW_INDOM].it_indom;
static pmInDom *powernow_indom = &indomtab[POWERNOW_INDOM].it_indom;
static pmInDom *capacity_indom = &indomtab[CAPACITY_INDOM].it_indom;
static pmInDom *bat_energynow_indom = &indomtab[BAT_ENERGYNOW_INDOM].it_indom;
static pmInDom *bat_powernow_indom = &indomtab[BAT_POWERNOW_INDOM].it_indom;
static pmInDom *bat_capacity_indom = &indomtab[BAT_CAPACITY_INDOM].it_indom;

/*
* All metrics supported in this PMDA - one table entry for each.
*/

static pmdaMetric metrictab[] = {
/* rapl sysfs */
/* rapl.sysfs */
{ NULL,
{ PMDA_PMID(0,0), PM_TYPE_U64, RAPL_SYSFS_INDOM, PM_SEM_COUNTER,
PMDA_PMUNITS(0,0,0,0,0,0) }, },
/* rapl msr */
/* rapl.msr */
{ NULL,
{ PMDA_PMID(1,0), PM_TYPE_U64, RAPL_MSR_INDOM, PM_SEM_COUNTER,
{ PMDA_PMID(0,1), PM_TYPE_U64, RAPL_MSR_INDOM, PM_SEM_COUNTER,
PMDA_PMUNITS(0,0,0,0,0,0) }, },
/* bat.energy_now */
{ NULL,
{ PMDA_PMID(2,0), PM_TYPE_DOUBLE, ENERGYNOW_INDOM, PM_SEM_INSTANT,
{ PMDA_PMID(1,0), PM_TYPE_DOUBLE, BAT_ENERGYNOW_INDOM, PM_SEM_INSTANT,
PMDA_PMUNITS(0,0,0,0,0,0) }, },
/* bat.power_now */
{ NULL,
{ PMDA_PMID(2,1), PM_TYPE_DOUBLE, POWERNOW_INDOM, PM_SEM_INSTANT,
{ PMDA_PMID(1,1), PM_TYPE_DOUBLE, BAT_POWERNOW_INDOM, PM_SEM_INSTANT,
PMDA_PMUNITS(0,0,0,0,0,0) }, },
/* bat.capacity */
{ NULL,
{ PMDA_PMID(2,2), PM_TYPE_32, CAPACITY_INDOM, PM_SEM_INSTANT,
{ PMDA_PMID(1,2), PM_TYPE_32, BAT_CAPACITY_INDOM, PM_SEM_INSTANT,
PMDA_PMUNITS(0,0,0,0,0,0) }, }
};

Expand Down Expand Up @@ -972,21 +972,15 @@ denki_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)

if (cluster == 0) {
switch (item) {
case 0: /* rapl sysfs */
case 0: /* rapl.sysfs */
if ((sts = pmdaCacheLookup(*rapl_sysfs_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if (sts < 0)
pmNotifyErr(LOG_ERR, "pmdaCacheLookup failed: inst=%d: %s", inst, pmErrStr(sts));
return PM_ERR_INST;
}
atom->ull = lookup_rapl_dom(inst)/1000000;
break;
default:
return PM_ERR_PMID;
}
}
else if (cluster == 1) {
switch (item) {
case 0: /* rapl msr */
case 1: /* rapl.msr */
if ((sts = pmdaCacheLookup(*rapl_msr_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if (sts < 0)
pmNotifyErr(LOG_ERR, "pmdaCacheLookup failed: inst=%d: %s", inst, pmErrStr(sts));
Expand All @@ -1013,26 +1007,26 @@ denki_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom)
return PM_ERR_PMID;
}
}
else if (cluster == 2) {
else if (cluster == 1) {
switch (item) {
case 0: /* denki.bat.energy_now */
if ((sts = pmdaCacheLookup(*energynow_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if ((sts = pmdaCacheLookup(*bat_energynow_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if (sts < 0)
pmNotifyErr(LOG_ERR, "pmdaCacheLookup failed: inst=%d: %s", inst, pmErrStr(sts));
return PM_ERR_INST;
}
atom->d = energy_now[inst]/energy_convert_factor[inst];
break;
case 1: /* denki.bat.power_now */
if ((sts = pmdaCacheLookup(*powernow_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if ((sts = pmdaCacheLookup(*bat_powernow_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if (sts < 0)
pmNotifyErr(LOG_ERR, "pmdaCacheLookup failed: inst=%d: %s", inst, pmErrStr(sts));
return PM_ERR_INST;
}
atom->d = power_now[inst]/1000000.0;
break;
case 2: /* denki.bat.capacity */
if ((sts = pmdaCacheLookup(*capacity_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if ((sts = pmdaCacheLookup(*bat_capacity_indom, inst, NULL, NULL)) != PMDA_CACHE_ACTIVE) {
if (sts < 0)
pmNotifyErr(LOG_ERR, "pmdaCacheLookup failed: inst=%d: %s", inst, pmErrStr(sts));
return PM_ERR_INST;
Expand Down Expand Up @@ -1244,21 +1238,21 @@ denki_bat_init(void)
pmsprintf(tmp,sizeof(tmp),"battery-%d",battery);

/* bat.energy_now */
sts = pmdaCacheStore(*energynow_indom, PMDA_CACHE_ADD, tmp, NULL);
sts = pmdaCacheStore(*bat_energynow_indom, PMDA_CACHE_ADD, tmp, NULL);
if (sts < 0) {
pmNotifyErr(LOG_ERR, "pmdaCacheStore failed: %s", pmErrStr(sts));
return;
}

/* bat.power_now */
sts = pmdaCacheStore(*powernow_indom, PMDA_CACHE_ADD, tmp, NULL);
sts = pmdaCacheStore(*bat_powernow_indom, PMDA_CACHE_ADD, tmp, NULL);
if (sts < 0) {
pmNotifyErr(LOG_ERR, "pmdaCacheStore failed: %s", pmErrStr(sts));
return;
}

/* bat.capacity */
sts = pmdaCacheStore(*capacity_indom, PMDA_CACHE_ADD, tmp, NULL);
sts = pmdaCacheStore(*bat_capacity_indom, PMDA_CACHE_ADD, tmp, NULL);
if (sts < 0) {
pmNotifyErr(LOG_ERR, "pmdaCacheStore failed: %s", pmErrStr(sts));
return;
Expand All @@ -1282,13 +1276,13 @@ denki_label(int ident, int type, pmLabelSet **lpp, pmdaExt *pmda)
case RAPL_MSR_INDOM:
pmdaAddLabels(lpp, "{\"indom_name\":\"raplmsr\"}");
break;
case ENERGYNOW_INDOM:
case BAT_ENERGYNOW_INDOM:
pmdaAddLabels(lpp, "{\"units\":\"watt hours\"}");
break;
case POWERNOW_INDOM:
case BAT_POWERNOW_INDOM:
pmdaAddLabels(lpp, "{\"units\":\"watt\"}");
break;
case CAPACITY_INDOM:
case BAT_CAPACITY_INDOM:
pmdaAddLabels(lpp, "{\"units\":\"percent\"}");
break;
}
Expand All @@ -1310,26 +1304,26 @@ __PMDA_INIT_CALL
denki_init(pmdaInterface *dp)
{
if (isDSO) {
int sep = pmPathSeparator();

if (strcmp(rootpath, "/") == 0) {
/*
* no -r ROOTPATH on the command line ... check for
* DENKI_SYSPATH in the environment
*/
char *envpath = getenv("DENKI_SYSPATH");
if (envpath)
pmsprintf(rootpath, sizeof(rootpath), "%s", envpath);
}
pmsprintf(mypath, sizeof(mypath), "%s%c" "denki" "%c" "help",
pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
pmdaDSO(dp, PMDA_INTERFACE_7, "denki DSO", mypath);
int sep = pmPathSeparator();
if (strcmp(rootpath, "/") == 0) {
/*
* no -r ROOTPATH on the command line ... check for
* DENKI_SYSPATH in the environment
*/
char *envpath = getenv("DENKI_SYSPATH");
if (envpath)
pmsprintf(rootpath, sizeof(rootpath), "%s", envpath);
}
pmsprintf(mypath, sizeof(mypath), "%s%c" "denki" "%c" "help",
pmGetConfig("PCP_PMDAS_DIR"), sep, sep);
pmdaDSO(dp, PMDA_INTERFACE_7, "denki DSO", mypath);
} else {
pmSetProcessIdentity(username);
pmSetProcessIdentity(username);
}

if (dp->status != 0)
return;
return;

dp->version.any.fetch = denki_fetch;
dp->version.any.instance = denki_instance;
Expand Down
4 changes: 2 additions & 2 deletions src/pmdas/denki/help
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

@ 156.4 set of all batteries reporting capacity

@ denki.raplsysfs cummulative energy consumption of RAPL components
@ denki.rapl.sysfs cummulative energy consumption of RAPL components
Cummulative electrical power consumption of x86 hardware components
in units of Joules.

Expand All @@ -47,7 +47,7 @@ Joules / second, or Watts.
The RAPL modules offered by the system are available as metric
instances.

@ denki.raplmsr cummulative energy consumption of RAPL components
@ denki.rapl.msr cummulative energy consumption of RAPL components
Cummulative electrical power consumption of x86 hardware components
in units of Joules.

Expand Down
41 changes: 21 additions & 20 deletions src/pmdas/denki/pmdadenki.1
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
.\"
.\" Copyright (c) 2021-2024 Red Hat.
.\"
'\"macro stdmacro
.\"
.\" Copyright (c) 2021-2025 Red Hat.
.\"
.\" This program is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License as published by the
.\" Free Software Foundation; either version 2 of the License, or (at your
.\" option) any later version.
.\"
.\"
.\" This program is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
.\" or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
.\" for more details.
.\"
.TH "PMDADENKI" "1" "PCP" "Performance Co-Pilot" ""
.SH "NAME"
.\"
.TH PMDADENKI 1 "PCP" "Performance Co-Pilot"
.SH NAME
\f3pmdadenki\f1 \- metrics related to the systems electrical consumption
.SH "SYNOPSIS"
.SH SYNOPSIS
\f3$PCP_PMDAS_DIR/denki/pmdadenki\f1
[\f3\-d\f1 \f2domain\f1]
[\f3\-l\f1 \f2logfile\f1]
.SH "DESCRIPTION"
.SH DESCRIPTION
.B pmdadenki
is a Performance Metrics Domain Agent (PMDA) which extracts
electricity related performance metrics.
.PP
.PP
Currently, metrics from RAPL (on Intel cpus) and battery
charge values are available, if supported by the hardware.
.PP
.PP
.B \-l
Location of the log file. By default, a log file named
.I denki.log
Expand All @@ -42,28 +43,28 @@ The
.B denki
PMDA is installed and available by default on Linux.
If you want to undo the installation, do the following as root:
.PP
.PP
.ft CR
.nf
.nf
.in +0.5i
# cd $PCP_PMDAS_DIR/denki
# ./Remove
.in
.fi
.fi
.ft 1
.PP
.PP
If you want to establish access to the names, help text and values for the
denki metrics once more, after removal, do the following as root:
.PP
.PP
.ft CR
.nf
.nf
.in +0.5i
# cd $PCP_PMDAS_DIR/denki
# ./Install
.in
.fi
.fi
.ft 1
.PP
.PP
.B pmdadenki
is launched by
.BR pmcd (1)
Expand Down Expand Up @@ -117,5 +118,5 @@ as described in
and
.BR pcp.env (5).

.\" control lines for scripts/man\-spell
.\" control lines for scripts/man-spell
.\" +ok+ pmdadenki denki RAPL cpus
14 changes: 9 additions & 5 deletions src/pmdas/denki/pmns
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
*/

denki {
raplsysfs DENKI:0:0
raplmsr DENKI:1:0
rapl
bat
}

denki.rapl {
sysfs DENKI:0:0
msr DENKI:0:1
}

denki.bat {
energy_now DENKI:2:0
power_now DENKI:2:1
capacity DENKI:2:2
energy_now DENKI:1:0
power_now DENKI:1:1
capacity DENKI:1:2
}

0 comments on commit fe3cbfa

Please sign in to comment.