git: 6fa041d7f125 - main - Measure latency of PMC interruptions

Mateusz Guzik mjguzik at gmail.com
Fri Sep 17 16:44:52 UTC 2021


ping?

On 9/14/21, Wojciech Macek <wma at semihalf.com> wrote:
> 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();
>>
> _______________________________________________
> dev-commits-src-all at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
> To unsubscribe, send any mail to
> "dev-commits-src-all-unsubscribe at freebsd.org"
>


-- 
Mateusz Guzik <mjguzik gmail.com>


More information about the dev-commits-src-all mailing list