Skip to content

Commit

Permalink
Stop using fuswintr() and suswintr() in the profiler.
Browse files Browse the repository at this point in the history
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


git-svn-id: svn+ssh://svn.freebsd.org/base/head@332650 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
  • Loading branch information
brooks committed Apr 17, 2018
1 parent 59aa162 commit ed3de3f
Showing 1 changed file with 12 additions and 20 deletions.
32 changes: 12 additions & 20 deletions sys/kern/subr_prof.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit ed3de3f

Please sign in to comment.