git: 6fa041d7f125 - main - Measure latency of PMC interruptions
Wojciech Macek
wma at semihalf.com
Tue Sep 14 03:39:27 UTC 2021
Hi,
Thanks for comments, I'll handle all of them as well as docs.
Wojtek
pon., 13 wrz 2021 o 22:06 Mitchell Horne <mhorne at freebsd.org> napisał(a):
> On Mon, Sep 13, 2021 at 1:11 AM Wojciech Macek <wma at freebsd.org> wrote:
> >
> > The branch main has been updated by wma:
> >
> > URL:
> https://cgit.FreeBSD.org/src/commit/?id=6fa041d7f125db65f400af7f520a41ff78d19cd7
> >
> > commit 6fa041d7f125db65f400af7f520a41ff78d19cd7
> > Author: Wojciech Macek <wma at FreeBSD.org>
> > AuthorDate: 2021-09-13 04:08:32 +0000
> > Commit: Wojciech Macek <wma at FreeBSD.org>
> > CommitDate: 2021-09-13 04:08:32 +0000
> >
> > Measure latency of PMC interruptions
> >
> > Add HWPMC events to measure latency.
> > Provide sysctl to choose the number of outstanding events which
> > trigger HWPMC event.
> >
> > Obtained from: Semihalf
> > Sponsored by: Stormshield
> > Differential revision: https://reviews.freebsd.org/D31283
> > ---
> > sys/kern/kern_intr.c | 58
> ++++++++++++++++++++++++++++++++++++++++++++++------
> > 1 file changed, 52 insertions(+), 6 deletions(-)
> >
> > diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
> > index 1660414a50ef..19401877dfbd 100644
> > --- a/sys/kern/kern_intr.c
> > +++ b/sys/kern/kern_intr.c
> > @@ -30,6 +30,7 @@
> > __FBSDID("$FreeBSD$");
> >
> > #include "opt_ddb.h"
> > +#include "opt_hwpmc_hooks.h"
> > #include "opt_kstack_usage_prof.h"
> >
> > #include <sys/param.h>
> > @@ -75,6 +76,7 @@ struct intr_thread {
> > struct thread *it_thread; /* Kernel thread. */
> > int it_flags; /* (j) IT_* flags. */
> > int it_need; /* Needs service. */
> > + int it_waiting; /* Waiting in the runq. */
> > };
> >
> > /* Interrupt thread flags kept in it_flags */
> > @@ -100,13 +102,19 @@ SYSCTL_INT(_hw, OID_AUTO, intr_storm_threshold,
> CTLFLAG_RWTUN,
> > static int intr_epoch_batch = 1000;
> > SYSCTL_INT(_hw, OID_AUTO, intr_epoch_batch, CTLFLAG_RWTUN,
> &intr_epoch_batch,
> > 0, "Maximum interrupt handler executions without re-entering
> epoch(9)");
> > +#ifdef HWPMC_HOOKS
> > +static int intr_hwpmc_waiting_report_threshold = 1;
> > +SYSCTL_INT(_hw, OID_AUTO, intr_hwpmc_waiting_report_threshold,
> CTLFLAG_RWTUN,
> > + &intr_hwpmc_waiting_report_threshold, 1,
> > + "Threshold for reporting number of events in a workq");
> > +#endif
> > static TAILQ_HEAD(, intr_event) event_list =
> > TAILQ_HEAD_INITIALIZER(event_list);
> > static struct mtx event_lock;
> > MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF);
> >
> > static void intr_event_update(struct intr_event *ie);
> > -static int intr_event_schedule_thread(struct intr_event *ie);
> > +static int intr_event_schedule_thread(struct intr_event *ie, struct
> trapframe *frame);
> > static struct intr_thread *ithread_create(const char *name);
> > static void ithread_destroy(struct intr_thread *ithread);
> > static void ithread_execute_handlers(struct proc *p,
> > @@ -115,6 +123,16 @@ static void ithread_loop(void *);
> > static void ithread_update(struct intr_thread *ithd);
> > static void start_softintr(void *);
> >
> > +#ifdef HWPMC_HOOKS
> > +#include <sys/pmckern.h>
> > +PMC_SOFT_DEFINE( , , intr, all);
> > +PMC_SOFT_DEFINE( , , intr, ithread);
> > +PMC_SOFT_DEFINE( , , intr, filter);
> > +PMC_SOFT_DEFINE( , , intr, stray);
> > +PMC_SOFT_DEFINE( , , intr, schedule);
> > +PMC_SOFT_DEFINE( , , intr, waiting);
> > +#endif
> > +
>
> Hi Wojciech,
>
> Do you plan to document these new events in the pmc.soft(3) man page?
>
> Cheers,
> Mitchell
>
>
> > /* Map an interrupt type to an ithread priority. */
> > u_char
> > intr_priority(enum intr_type flags)
> > @@ -773,7 +791,7 @@ intr_handler_barrier(struct intr_handler *handler)
> > }
> > if ((handler->ih_flags & IH_CHANGED) == 0) {
> > handler->ih_flags |= IH_CHANGED;
> > - intr_event_schedule_thread(ie);
> > + intr_event_schedule_thread(ie, NULL);
> > }
> > while ((handler->ih_flags & IH_CHANGED) != 0)
> > msleep(handler, &ie->ie_lock, 0, "ih_barr", 0);
> > @@ -872,7 +890,7 @@ intr_event_remove_handler(void *cookie)
> > KASSERT((handler->ih_flags & IH_DEAD) == 0,
> > ("duplicate handle remove"));
> > handler->ih_flags |= IH_DEAD;
> > - intr_event_schedule_thread(ie);
> > + intr_event_schedule_thread(ie, NULL);
> > while (handler->ih_flags & IH_DEAD)
> > msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0);
> > intr_event_update(ie);
> > @@ -944,7 +962,7 @@ intr_event_resume_handler(void *cookie)
> > }
> >
> > static int
> > -intr_event_schedule_thread(struct intr_event *ie)
> > +intr_event_schedule_thread(struct intr_event *ie, struct trapframe
> *frame)
> > {
> > struct intr_entropy entropy;
> > struct intr_thread *it;
> > @@ -986,11 +1004,28 @@ intr_event_schedule_thread(struct intr_event *ie)
> > atomic_store_rel_int(&it->it_need, 1);
> > thread_lock(td);
> > if (TD_AWAITING_INTR(td)) {
> > +#ifdef HWPMC_HOOKS
> > + atomic_set_int(&it->it_waiting, 0);
> > + if (frame != NULL)
> > + PMC_SOFT_CALL_TF( , , intr, schedule, frame);
> > + else
> > + PMC_SOFT_CALL( , , intr, schedule);
> > +#endif
> > CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__,
> td->td_proc->p_pid,
> > td->td_name);
> > TD_CLR_IWAIT(td);
> > sched_add(td, SRQ_INTR);
> > } else {
> > +#ifdef HWPMC_HOOKS
> > + atomic_add_int(&it->it_waiting, 1);
> > +
> > + if (atomic_load_int(&it->it_waiting) >=
> intr_hwpmc_waiting_report_threshold) {
> > + if (frame != NULL)
> > + PMC_SOFT_CALL_TF( , , intr, waiting,
> frame);
> > + else
> > + PMC_SOFT_CALL( , , intr, waiting);
> > + }
> > +#endif
> > CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d",
> > __func__, td->td_proc->p_pid, td->td_name,
> it->it_need, TD_GET_STATE(td));
> > thread_unlock(td);
> > @@ -1083,7 +1118,7 @@ swi_sched(void *cookie, int flags)
> > #endif
> > } else {
> > VM_CNT_INC(v_soft);
> > - error = intr_event_schedule_thread(ie);
> > + error = intr_event_schedule_thread(ie, NULL);
> > KASSERT(error == 0, ("stray software interrupt"));
> > }
> > }
> > @@ -1374,12 +1409,23 @@ intr_event_handle(struct intr_event *ie, struct
> trapframe *frame)
> > ret = ih->ih_filter(frame);
> > else
> > ret = ih->ih_filter(ih->ih_argument);
> > +#ifdef HWPMC_HOOKS
> > + PMC_SOFT_CALL_TF( , , intr, all, frame);
> > +#endif
> > KASSERT(ret == FILTER_STRAY ||
> > ((ret & (FILTER_SCHEDULE_THREAD | FILTER_HANDLED))
> != 0 &&
> > (ret & ~(FILTER_SCHEDULE_THREAD | FILTER_HANDLED))
> == 0),
> > ("%s: incorrect return value %#x from %s", __func__,
> ret,
> > ih->ih_name));
> > filter = filter || ret == FILTER_HANDLED;
> > +#ifdef HWPMC_HOOKS
> > + if (ret & FILTER_SCHEDULE_THREAD)
> > + PMC_SOFT_CALL_TF( , , intr, ithread, frame);
> > + else if (ret & FILTER_HANDLED)
> > + PMC_SOFT_CALL_TF( , , intr, filter, frame);
> > + else if (ret == FILTER_STRAY)
> > + PMC_SOFT_CALL_TF( , , intr, stray, frame);
> > +#endif
> >
> > /*
> > * Wrapper handler special handling:
> > @@ -1416,7 +1462,7 @@ intr_event_handle(struct intr_event *ie, struct
> trapframe *frame)
> > if (thread) {
> > int error __unused;
> >
> > - error = intr_event_schedule_thread(ie);
> > + error = intr_event_schedule_thread(ie, frame);
> > KASSERT(error == 0, ("bad stray interrupt"));
> > }
> > critical_exit();
>
More information about the dev-commits-src-all
mailing list