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:
parent
85e826dd94
commit
e053ed54ac
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user