diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2005-05-01 14:11:49 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2005-05-01 14:11:49 +0000 |
commit | a21392e3accd60fd407365553a29a3b7250316cc (patch) | |
tree | 1e7573a97fa735d4770310305b9ec83d8767f4a7 /lib | |
parent | 88ecd82ce992dc5add7c7c4e8a56fd3c6fed65a3 (diff) | |
download | FreeBSD-src-a21392e3accd60fd407365553a29a3b7250316cc.zip FreeBSD-src-a21392e3accd60fd407365553a29a3b7250316cc.tar.gz |
Add convenience APIs pmc_width() and pmc_capabilities() to -lpmc.
Have pmcstat(8) and pmccontrol(8) use these APIs.
Return PMC class-related constants (PMC widths and capabilities)
with the OP GETCPUINFO call leaving OP PMCINFO to return only the
dynamic information associated with a PMC (i.e., whether enabled,
owner pid, reload count etc.).
Allow pmc_read() (i.e., OPS PMCRW) on active self-attached PMCs to
get upto-date values from hardware since we can guarantee that the
hardware is running the correct PMC at the time of the call.
Bug fixes:
- (x86 class processors) Fix a bug that prevented an RDPMC
instruction from being recognized as permitted till after the
attached process had context switched out and back in again after
a pmc_start() call.
Tighten the rules for using RDPMC class instructions: a GETMSR
OP is now allowed only after an OP ATTACH has been done by the
PMC's owner to itself. OP GETMSR is not allowed for PMCs that
track descendants, for PMCs attached to processes other than
their owner processes.
- (P4/HTT processors only) Fix a bug that caused the MI and MD
layers to get out of sync. Add a new MD operation 'get_config()'
as part of this fix.
- Allow multiple system-mode PMCs at the same row-index but on
different CPUs to be allocated.
- Reject allocation of an administratively disabled PMC.
Misc. code cleanups and refactoring. Improve a few comments.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libpmc/Makefile | 2 | ||||
-rw-r--r-- | lib/libpmc/libpmc.c | 30 | ||||
-rw-r--r-- | lib/libpmc/pmc.3 | 24 | ||||
-rw-r--r-- | lib/libpmc/pmc.h | 2 |
4 files changed, 57 insertions, 1 deletions
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile index 39f6198..7d24d85 100644 --- a/lib/libpmc/Makefile +++ b/lib/libpmc/Makefile @@ -12,6 +12,7 @@ MAN= pmc.3 MLINKS+= \ pmc.3 pmc_allocate.3 \ pmc.3 pmc_attach.3 \ + pmc.3 pmc_capabilities.3 \ pmc.3 pmc_configure_logfile.3 \ pmc.3 pmc_cpuinfo.3 \ pmc.3 pmc_detach.3 \ @@ -35,6 +36,7 @@ MLINKS+= \ pmc.3 pmc_set.3 \ pmc.3 pmc_start.3 \ pmc.3 pmc_stop.3 \ + pmc.3 pmc_width.3 \ pmc.3 pmc_write.3 \ pmc.3 pmc_x86_get_msr.3 diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 526f071..272d25a 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -1981,6 +1981,36 @@ pmc_cpuinfo(const struct pmc_op_getcpuinfo **pci) return 0; } +int +pmc_width(pmc_id_t pmcid, uint32_t *width) +{ + unsigned int i; + enum pmc_class cl; + + cl = PMC_ID_TO_CLASS(pmcid); + for (i = 0; i < cpu_info.pm_nclass; i++) + if (cpu_info.pm_classes[i].pm_class == cl) { + *width = cpu_info.pm_classes[i].pm_width; + return 0; + } + return EINVAL; +} + +int +pmc_capabilities(pmc_id_t pmcid, uint32_t *caps) +{ + unsigned int i; + enum pmc_class cl; + + cl = PMC_ID_TO_CLASS(pmcid); + for (i = 0; i < cpu_info.pm_nclass; i++) + if (cpu_info.pm_classes[i].pm_class == cl) { + *caps = cpu_info.pm_classes[i].pm_caps; + return 0; + } + return EINVAL; +} + const char * pmc_name_of_cputype(enum pmc_cputype cp) { diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3 index aed6735..0612ce7 100644 --- a/lib/libpmc/pmc.3 +++ b/lib/libpmc/pmc.3 @@ -29,6 +29,7 @@ .Sh NAME .Nm pmc_allocate , .Nm pmc_attach , +.Nm pmc_capabilities , .Nm pmc_configure_logfile , .Nm pmc_cpuinfo , .Nm pmc_detach , @@ -53,6 +54,7 @@ .Nm pmc_start , .Nm pmc_stop , .Nm pmc_write , +.Nm pmc_width , .Nm pmc_x86_get_msr .Nd programming API for using hardware performance monitoring counters .Sh LIBRARY @@ -73,6 +75,8 @@ .Fa "pid_t pid" .Fc .Ft int +.Fn pmc_capabilities "pmc_id_t pmc" "uint32_t *caps" +.Ft int .Fn pmc_configure_logfile "int fd" .Ft int .Fn pmc_cpuinfo "const struct pmc_op_getcpuinfo **cpu_info" @@ -130,6 +134,8 @@ .Ft int .Fn pmc_write "pmc_id_t pmc" "pmc_value_t value" .Ft int +.Fn pmc_width "pmc_id_t pmc" "uint32_t *width" +.Ft int .Fn pmc_x86_get_msr "int pmc" "uint32_t *msr" .Sh DESCRIPTION These functions implement a high-level library for using the @@ -252,6 +258,20 @@ the allocated PMC. The read and write operation may be combined using .Fn pmc_rw . .Pp +The function +.Fn pmc_capabilities +sets argument +.Fa caps +to a bitmask of capabilities supported by the PMC denoted by +argument +.Fa pmc . +The function +.Fn pmc_width +sets argument +.Fa width +to the width of the PMC denoted by argument +.Fa pmc . +.Pp The .Fn pmc_configure_logfile function causes the @@ -3011,13 +3031,15 @@ library. .El .Pp A call to +.Fn pmc_capabilities , .Fn pmc_name_of_capability , .Fn pmc_name_of_disposition , .Fn pmc_name_of_state , .Fn pmc_name_of_event , .Fn pmc_name_of_mode -and .Fn pmc_name_of_class +and +.Fn pmc_width may fail with the following error: .Bl -tag -width Er .It Bq Er EINVAL diff --git a/lib/libpmc/pmc.h b/lib/libpmc/pmc.h index 98c4af2..7ee257b 100644 --- a/lib/libpmc/pmc.h +++ b/lib/libpmc/pmc.h @@ -38,6 +38,7 @@ int pmc_allocate(const char *_ctrspec, enum pmc_mode _mode, uint32_t _flags, int _cpu, pmc_id_t *_pmcid); int pmc_attach(pmc_id_t _pmcid, pid_t _pid); +int pmc_capabilities(pmc_id_t _pmc, uint32_t *_caps); int pmc_configure_logfile(int _fd); int pmc_detach(pmc_id_t _pmcid, pid_t _pid); int pmc_disable(int _cpu, int _pmc); @@ -50,6 +51,7 @@ int pmc_rw(pmc_id_t _pmc, pmc_value_t _newvalue, pmc_value_t *_oldvalue); int pmc_set(pmc_id_t _pmc, pmc_value_t _value); int pmc_start(pmc_id_t _pmc); int pmc_stop(pmc_id_t _pmc); +int pmc_width(pmc_id_t _pmc, uint32_t *_width); int pmc_write(pmc_id_t _pmc, pmc_value_t _value); int pmc_ncpu(void); |