diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exec.c | 22 | ||||
-rw-r--r-- | sys/kern/kern_pmc.c | 82 | ||||
-rw-r--r-- | sys/kern/sched_4bsd.c | 23 | ||||
-rw-r--r-- | sys/kern/sched_ule.c | 23 |
4 files changed, 148 insertions, 2 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 7a15f75..9783615 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -72,6 +72,10 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_object.h> #include <vm/vm_pager.h> +#ifdef HWPMC_HOOKS +#include <sys/pmckern.h> +#endif + #include <machine/reg.h> MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); @@ -662,7 +666,25 @@ interpret: p->p_args = newargs; newargs = NULL; } + +#ifdef HWPMC_HOOKS + /* + * Check if the process is using PMCs and if so do exec() time + * processing. This processing needs to happen AFTER the + * P_INEXEC flag is cleared. + * + * The proc lock needs to be released before taking the PMC + * SX. + */ + if (PMC_PROC_IS_USING_PMCS(p)) { + PROC_UNLOCK(p); + PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, + (void *) &credential_changing); + } else + PROC_UNLOCK(p); +#else /* !HWPMC_HOOKS */ PROC_UNLOCK(p); +#endif /* Set values passed into the program in registers. */ if (p->p_sysent->sv_setregs) diff --git a/sys/kern/kern_pmc.c b/sys/kern/kern_pmc.c new file mode 100644 index 0000000..29be9c1 --- /dev/null +++ b/sys/kern/kern_pmc.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2003 Joseph Koshy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#ifdef HWPMC_HOOKS + +#include <sys/pmckern.h> +#include <sys/smp.h> + +struct sx pmc_sx; + +/* Hook variable. */ +int (*pmc_hook)(struct thread *td, int function, void *arg) = NULL; + +/* Interrupt handler */ +int (*pmc_intr)(int cpu, uintptr_t pc) = NULL; + +/* + * Since PMC(4) may not be loaded in the current kernel, the + * convention followed is that a non-NULL value of 'pmc_hook' implies + * the presence of this kernel module. + * + * This requires us to protect 'pmc_hook' with a + * shared (sx) lock -- thus making the process of calling into PMC(4) + * somewhat more expensive than a simple 'if' check and indirect call. + */ + + +SX_SYSINIT(pmc, &pmc_sx, "pmc shared lock"); + +/* + * pmc_cpu_is_disabled + * + * return TRUE if the cpu specified has been disabled. + */ + +int +pmc_cpu_is_disabled(int cpu) +{ +#ifdef SMP + return ((hlt_cpus_mask & (1 << cpu)) != 0); +#else + return 0; +#endif +} + +int +pmc_cpu_is_logical(int cpu) +{ +#ifdef SMP + return ((logical_cpus_mask & (1 << cpu)) != 0); +#else + return 0; +#endif +} + +#endif /* HWPMC_HOOKS */ diff --git a/sys/kern/sched_4bsd.c b/sys/kern/sched_4bsd.c index 552ab56..e56d156 100644 --- a/sys/kern/sched_4bsd.c +++ b/sys/kern/sched_4bsd.c @@ -53,6 +53,10 @@ __FBSDID("$FreeBSD$"); #include <sys/turnstile.h> #include <machine/smp.h> +#ifdef HWPMC_HOOKS +#include <sys/pmckern.h> +#endif + /* * INVERSE_ESTCPU_WEIGHT is only suitable for statclock() frequencies in * the range 100-256 Hz (approximately). @@ -959,8 +963,18 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) newtd = choosethread(); } - if (td != newtd) + if (td != newtd) { +#ifdef HWPMC_HOOKS + if (PMC_PROC_IS_USING_PMCS(td->td_proc)) + PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_OUT); +#endif cpu_switch(td, newtd); +#ifdef HWPMC_HOOKS + if (PMC_PROC_IS_USING_PMCS(td->td_proc)) + PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_IN); +#endif + } + sched_lock.mtx_lock = (uintptr_t)td; td->td_oncpu = PCPU_GET(cpuid); } @@ -1284,6 +1298,13 @@ sched_unbind(struct thread* td) } int +sched_is_bound(struct thread *td) +{ + mtx_assert(&sched_lock, MA_OWNED); + return (td->td_kse->ke_flags & KEF_BOUND); +} + +int sched_load(void) { return (sched_tdcnt); diff --git a/sys/kern/sched_ule.c b/sys/kern/sched_ule.c index 850f07e..19a40ae 100644 --- a/sys/kern/sched_ule.c +++ b/sys/kern/sched_ule.c @@ -53,6 +53,10 @@ __FBSDID("$FreeBSD$"); #include <sys/ktrace.h> #endif +#ifdef HWPMC_HOOKS +#include <sys/pmckern.h> +#endif + #include <machine/cpu.h> #include <machine/smp.h> @@ -1391,8 +1395,18 @@ sched_switch(struct thread *td, struct thread *newtd, int flags) kseq_load_add(KSEQ_SELF(), newtd->td_kse); } else newtd = choosethread(); - if (td != newtd) + if (td != newtd) { +#ifdef HWPMC_HOOKS + if (PMC_PROC_IS_USING_PMCS(td->td_proc)) + PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_OUT); +#endif cpu_switch(td, newtd); +#ifdef HWPMC_HOOKS + if (PMC_PROC_IS_USING_PMCS(td->td_proc)) + PMC_SWITCH_CONTEXT(td, PMC_FN_CSW_IN); +#endif + } + sched_lock.mtx_lock = (uintptr_t)td; td->td_oncpu = PCPU_GET(cpuid); @@ -1952,6 +1966,13 @@ sched_unbind(struct thread *td) } int +sched_is_bound(struct thread *td) +{ + mtx_assert(&sched_lock, MA_OWNED); + return (td->td_kse->ke_flags & KEF_BOUND); +} + +int sched_load(void) { #ifdef SMP |