mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-18 02:19:39 +00:00
pmcstat: fix duplicate event allocation on CPU 0
Commitb6e28991bf
modified the allocation path for system scope PMCs so that the event was allocated early for CPU 0. The reason is so that the PMC's capabilities could be checked, to determine if pmcstat should allocate the event on every CPU, or just on one CPU in each NUMA domain. In the current scheme, there is no way to determine this information without performing the PMC allocation. This broke the established use-case of log analysis, and so0aa1507751
was committed to fix the assertion. The result was what appeared to be functional, but in normal counter measurement pmcstat was silently allocating two counters for CPU 0. This cuts the total number of counters that can be allocated from a CPU in half. Additionally, depending on the particular hardware/event, we might not be able to allocate the same event twice on a single CPU. The simplest solution is to release the early-allocated PMC once we have obtained its capabilities, and reallocate it later on. This restores the event list logic to behave as it has for many years, and partially reverts commitb6e28991bf
. Reported by: alc, kevans Reviewed by: jkoshy, ray MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D41978
This commit is contained in:
parent
da695970ce
commit
c362fe939f
@ -713,8 +713,16 @@ main(int argc, char **argv)
|
||||
errx(EX_SOFTWARE, "ERROR: Out of memory.");
|
||||
(void) strncpy(ev->ev_name, optarg, c);
|
||||
*(ev->ev_name + c) = '\0';
|
||||
|
||||
libpmc_initialize(&npmc);
|
||||
|
||||
if (args.pa_flags & FLAG_HAS_SYSTEM_PMCS) {
|
||||
/*
|
||||
* We need to check the capabilities of the
|
||||
* desired event to determine if it should be
|
||||
* allocated on every CPU, or only a subset of
|
||||
* them. This requires allocating a PMC now.
|
||||
*/
|
||||
if (pmc_allocate(ev->ev_spec, ev->ev_mode,
|
||||
ev->ev_flags, ev->ev_cpu, &ev->ev_pmcid,
|
||||
ev->ev_count) < 0)
|
||||
@ -726,8 +734,14 @@ main(int argc, char **argv)
|
||||
err(EX_OSERR, "ERROR: Cannot get pmc "
|
||||
"capabilities");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the PMC now that we have caps; we
|
||||
* will reallocate shortly.
|
||||
*/
|
||||
pmc_release(ev->ev_pmcid);
|
||||
ev->ev_pmcid = PMC_ID_INVALID;
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(&args.pa_events, ev, ev_next);
|
||||
|
||||
@ -751,10 +765,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (option == 's' || option == 'S') {
|
||||
CPU_CLR(ev->ev_cpu, &cpumask);
|
||||
pmc_id_t saved_pmcid = ev->ev_pmcid;
|
||||
ev->ev_pmcid = PMC_ID_INVALID;
|
||||
pmcstat_clone_event_descriptor(ev, &cpumask, &args);
|
||||
ev->ev_pmcid = saved_pmcid;
|
||||
CPU_SET(ev->ev_cpu, &cpumask);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user