Page MenuHomeFreeBSD

D50546.diff
No OneTemporary

D50546.diff

diff --git a/FreeBSD/sys/dev/hwpmc/hwpmc_logging.c b/FreeBSD/sys/dev/hwpmc/hwpmc_logging.c
--- a/FreeBSD/sys/dev/hwpmc/hwpmc_logging.c
+++ b/FreeBSD/sys/dev/hwpmc/hwpmc_logging.c
@@ -718,7 +718,10 @@
/* create a log initialization entry */
PMCLOG_RESERVE_WITH_ERROR(po, PMCLOG_TYPE_INITIALIZE,
sizeof(struct pmclog_initialize));
- PMCLOG_EMIT32(PMC_VERSION);
+ if ((po->po_flags & PMC_PO_LEGACY) != 0)
+ PMCLOG_EMIT32(pmc_compat_version);
+ else
+ PMCLOG_EMIT32(PMC_VERSION);
PMCLOG_EMIT32(md->pmd_cputype);
#if defined(__i386__) || defined(__amd64__)
PMCLOG_EMIT64(tsc_freq);
@@ -1098,19 +1101,26 @@
void
pmclog_process_procexec(struct pmc_owner *po, pmc_id_t pmid, pid_t pid,
- uintptr_t baseaddr, uintptr_t dynaddr, char *path)
+ uintptr_t baseaddr, uintptr_t dynaddr, uintptr_t entryaddr, char *path)
{
- int pathlen, recordlen;
+ int pathlen, recordlen, legacy;
PMCDBG3(LOG,EXC,1,"po=%p pid=%d path=\"%s\"", po, pid, path);
pathlen = strlen(path) + 1; /* #bytes for the path */
recordlen = offsetof(struct pmclog_procexec, pl_pathname) + pathlen;
+ legacy = !!(po->po_flags & PMC_PO_LEGACY);
+ if (legacy)
+ recordlen -= sizeof (uintptr_t);
PMCLOG_RESERVE(po, PMCLOG_TYPE_PROCEXEC, recordlen);
PMCLOG_EMIT32(pid);
PMCLOG_EMIT32(pmid);
- PMCLOG_EMITADDR(baseaddr);
- PMCLOG_EMITADDR(dynaddr);
+ if (legacy) {
+ PMCLOG_EMITADDR(entryaddr);
+ } else {
+ PMCLOG_EMITADDR(baseaddr);
+ PMCLOG_EMITADDR(dynaddr);
+ }
PMCLOG_EMITSTRING(path,pathlen);
PMCLOG_DESPATCH_SYNC(po);
}
diff --git a/FreeBSD/sys/dev/hwpmc/hwpmc_mod.c b/FreeBSD/sys/dev/hwpmc/hwpmc_mod.c
--- a/FreeBSD/sys/dev/hwpmc/hwpmc_mod.c
+++ b/FreeBSD/sys/dev/hwpmc/hwpmc_mod.c
@@ -392,6 +392,15 @@
&pmc_unprivileged_syspmcs, 0,
"allow unprivileged process to allocate system PMCs");
+/*
+ * Enable support for legacy profilers, like AMDuProf, that are
+ * built for older version of FreeBSD and use an older ABI.
+ */
+int pmc_compat_version = 0;
+SYSCTL_INT(_kern_hwpmc, OID_AUTO, compat_verson, CTLFLAG_RWTUN,
+ &pmc_compat_version, 0,
+ "Emulate ABI from this older version when an older binary is run");
+
/*
* Hash function. Discard the lower 2 bits of the pointer since
* these are always zero for our uses. The hash multiplier is
@@ -1345,7 +1354,8 @@
CK_LIST_FOREACH(po, &pmc_ss_owners, po_ssnext) {
if ((po->po_flags & PMC_PO_OWNS_LOGFILE) != 0) {
pmclog_process_procexec(po, PMC_ID_INVALID, p->p_pid,
- pk->pm_baseaddr, pk->pm_dynaddr, fullpath);
+ pk->pm_baseaddr, pk->pm_dynaddr, pk->pm_entryaddr,
+ fullpath);
}
}
PMC_EPOCH_EXIT();
@@ -1392,7 +1402,8 @@
if (po->po_sscount == 0 &&
(po->po_flags & PMC_PO_OWNS_LOGFILE) != 0) {
pmclog_process_procexec(po, pm->pm_id, p->p_pid,
- pk->pm_baseaddr, pk->pm_dynaddr, fullpath);
+ pk->pm_baseaddr, pk->pm_dynaddr,
+ pk->pm_entryaddr, fullpath);
}
}
@@ -2306,6 +2317,8 @@
/* Allocate space for N pointers and one descriptor struct. */
po = malloc(sizeof(struct pmc_owner), M_PMC, M_WAITOK | M_ZERO);
po->po_owner = p;
+ if (pmc_compat_version != 0 && p->p_osrel == 1200500)
+ po->po_flags |= PMC_PO_LEGACY;
LIST_INSERT_HEAD(poh, po, po_next); /* insert into hash table */
TAILQ_INIT(&po->po_logbuffers);
@@ -3418,6 +3431,8 @@
(pmc_pcpu[(cpu)]->pc_hwpmcs[(n)]->phw_pmc == NULL)
if (PMC_IS_SYSTEM_MODE(mode)) {
+ if (pmc_compat_version != 0 && curproc->p_osrel == 1200500)
+ pa->pm_flags |= PMC_F_EV_PMU;
pmc_select_cpu(cpu);
for (n = pcd->pcd_ri; n < md->pmd_npmc; n++) {
pcd = pmc_ri_to_classdep(md, n, &adjri);
@@ -3819,6 +3834,10 @@
break;
}
+ /* zero out flags on legacy apps */
+ if (pmc_compat_version != 0 && curproc->p_osrel == 1200500)
+ cl.pm_flags = 0;
+
/* No flags currently implemented */
if (cl.pm_flags != 0) {
pmclog_proc_ignite(pmclog_proc_handle, NULL);
@@ -4011,6 +4030,13 @@
break;
/* don't service clients newer than our driver */
modv = PMC_VERSION;
+ if (cv == 0 && pmc_compat_version != 0 &&
+ curproc->p_osrel == 1200500) {
+ /* work around AMDuProf support ending at FreeBSD 13 */
+ printf("%s %d: overriding hwpmc version to 0x%x\n",
+ curproc->p_comm, curproc->p_osrel, pmc_compat_version);
+ modv = pmc_compat_version;
+ }
if ((cv & 0xFFFF0000) > (modv & 0xFFFF0000)) {
error = EPROGMISMATCH;
break;
diff --git a/FreeBSD/sys/kern/kern_exec.c b/FreeBSD/sys/kern/kern_exec.c
--- a/FreeBSD/sys/kern/kern_exec.c
+++ b/FreeBSD/sys/kern/kern_exec.c
@@ -932,6 +932,7 @@
pe.pm_credentialschanged = credential_changing;
pe.pm_baseaddr = imgp->reloc_base;
pe.pm_dynaddr = imgp->et_dyn_addr;
+ pe.pm_entryaddr = imgp->entry_addr;
PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe);
vn_lock(imgp->vp, LK_SHARED | LK_RETRY);
diff --git a/FreeBSD/sys/sys/pmc.h b/FreeBSD/sys/sys/pmc.h
--- a/FreeBSD/sys/sys/pmc.h
+++ b/FreeBSD/sys/sys/pmc.h
@@ -874,6 +874,7 @@
#define PMC_PO_OWNS_LOGFILE 0x00000001 /* has a log file */
#define PMC_PO_SHUTDOWN 0x00000010 /* in the process of shutdown */
#define PMC_PO_INITIAL_MAPPINGS_DONE 0x00000020
+#define PMC_PO_LEGACY 0x00000040
/*
* struct pmc_hw -- describe the state of the PMC hardware
@@ -1072,6 +1073,9 @@
/* driver statistics */
extern struct pmc_driverstats pmc_stats;
+/* compat version */
+extern int pmc_compat_version;
+
#if defined(HWPMC_DEBUG)
/* HWPMC_DEBUG without KTR will compile but is a no-op. */
diff --git a/FreeBSD/sys/sys/pmckern.h b/FreeBSD/sys/sys/pmckern.h
--- a/FreeBSD/sys/sys/pmckern.h
+++ b/FreeBSD/sys/sys/pmckern.h
@@ -76,6 +76,7 @@
int pm_credentialschanged;
uintptr_t pm_baseaddr;
uintptr_t pm_dynaddr;
+ uintptr_t pm_entryaddr;
};
struct pmckern_map_in {
diff --git a/FreeBSD/sys/sys/pmclog.h b/FreeBSD/sys/sys/pmclog.h
--- a/FreeBSD/sys/sys/pmclog.h
+++ b/FreeBSD/sys/sys/pmclog.h
@@ -315,7 +315,7 @@
void pmclog_process_proccsw(struct pmc *_pm, struct pmc_process *_pp,
pmc_value_t _v, struct thread *);
void pmclog_process_procexec(struct pmc_owner *_po, pmc_id_t _pmid, pid_t _pid,
- uintfptr_t _baseaddr, uintptr_t _dynaddr, char *_path);
+ uintfptr_t _baseaddr, uintptr_t _dynaddr, uintptr_t _entryaddr, char *_path);
void pmclog_process_procexit(struct pmc *_pm, struct pmc_process *_pp);
void pmclog_process_procfork(struct pmc_owner *_po, pid_t _oldpid, pid_t _newpid);
void pmclog_process_sysexit(struct pmc_owner *_po, pid_t _pid);

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 5, 7:29 PM (1 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40214456
Default Alt Text
D50546.diff (6 KB)

Event Timeline