Stop using fuswintr() and suswintr() in the profiler.

Always take the AST path rather than calling MD functions which are
often implemented as always failing. The is the case on amd64, arm,
i386, and powerpc. This optimization (inherited from 4.4 Lite) is a
pessimization on those architectures and is the sole use of these
functions. They will be removed in a seperate commit.

Reviewed by:	kib
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D15101
This commit is contained in:
brooks 2018-04-17 16:36:53 +00:00
parent 85e826dd94
commit e053ed54ac

View File

@ -447,10 +447,9 @@ sys_profil(struct thread *td, struct profil_args *uap)
/*
* Collect user-level profiling statistics; called on a profiling tick,
* when a process is running in user-mode. This routine may be called
* from an interrupt context. We try to update the user profiling buffers
* cheaply with fuswintr() and suswintr(). If that fails, we revert to
* an AST that will vector us to trap() with a context in which copyin
* and copyout will work. Trap will then call addupc_task().
* from an interrupt context. We perform the update with an AST
* that will vector us to trap() with a context in which copyin and
* copyout will work. Trap will then call addupc_task().
*
* Note that we may (rarely) not get around to the AST soon enough, and
* lose profile ticks when the next tick overwrites this one, but in this
@ -461,35 +460,28 @@ void
addupc_intr(struct thread *td, uintfptr_t pc, u_int ticks)
{
struct uprof *prof;
caddr_t addr;
u_int i;
int v;
if (ticks == 0)
return;
prof = &td->td_proc->p_stats->p_prof;
PROC_PROFLOCK(td->td_proc);
if (pc < prof->pr_off ||
(i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) {
if (pc < prof->pr_off || PC_TO_INDEX(pc, prof) >= prof->pr_size) {
PROC_PROFUNLOCK(td->td_proc);
return; /* out of range; ignore */
}
addr = prof->pr_base + i;
PROC_PROFUNLOCK(td->td_proc);
if ((v = fuswintr(addr)) == -1 || suswintr(addr, v + ticks) == -1) {
td->td_profil_addr = pc;
td->td_profil_ticks = ticks;
td->td_pflags |= TDP_OWEUPC;
thread_lock(td);
td->td_flags |= TDF_ASTPENDING;
thread_unlock(td);
}
td->td_profil_addr = pc;
td->td_profil_ticks = ticks;
td->td_pflags |= TDP_OWEUPC;
thread_lock(td);
td->td_flags |= TDF_ASTPENDING;
thread_unlock(td);
}
/*
* Much like before, but we can afford to take faults here. If the
* update fails, we simply turn off profiling.
* Actually update the profiling statistics. If the update fails, we
* simply turn off profiling.
*/
void
addupc_task(struct thread *td, uintfptr_t pc, u_int ticks)