Re: git: eff9ee7c0c8e - main - hwpmc: Increase thread priority while iterating CPUs.
- In reply to: Alexander Motin : "git: eff9ee7c0c8e - main - hwpmc: Increase thread priority while iterating CPUs."
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 07 Jun 2022 14:52:30 UTC
On 6/7/22, Alexander Motin <mav@freebsd.org> wrote: > The branch main has been updated by mav: > > URL: > https://cgit.FreeBSD.org/src/commit/?id=eff9ee7c0c8e1fe782d6c01a29bb23224b02a847 > > commit eff9ee7c0c8e1fe782d6c01a29bb23224b02a847 > Author: Alexander Motin <mav@FreeBSD.org> > AuthorDate: 2022-06-07 02:36:16 +0000 > Commit: Alexander Motin <mav@FreeBSD.org> > CommitDate: 2022-06-07 02:51:01 +0000 > > hwpmc: Increase thread priority while iterating CPUs. > > This allows to profile already running high-priority threads, that > otherwise by blocking thread migration to respective CPUs blocked PMC > management, i.e. profiling could start only when workload completed. > > While there, return the thread to its original CPU after iterating > the list. Otherwise all threads using PMC end up on the last CPU. > the iteration is a bogus scheme and needs to be replaced with something similar to what rms locks are doing right now, see rms_rlock and rms_wlock. Maybe I'll hack it up this month. > MFC after: 1 month > --- > sys/dev/hwpmc/hwpmc_logging.c | 21 +++++++++------------ > sys/dev/hwpmc/hwpmc_mod.c | 17 ++++++++--------- > sys/sys/pmc.h | 4 ++++ > 3 files changed, 21 insertions(+), 21 deletions(-) > > diff --git a/sys/dev/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c > index c16adff8c842..8d9015af78e9 100644 > --- a/sys/dev/hwpmc/hwpmc_logging.c > +++ b/sys/dev/hwpmc/hwpmc_logging.c > @@ -764,6 +764,7 @@ pmclog_deconfigure_log(struct pmc_owner *po) > { > int error; > struct pmclog_buffer *lb; > + struct pmc_binding pb; > > PMCDBG1(LOG,CFG,1, "de-config po=%p", po); > > @@ -787,19 +788,16 @@ pmclog_deconfigure_log(struct pmc_owner *po) > PMCLOG_RESET_BUFFER_DESCRIPTOR(lb); > pmc_plb_rele(lb); > } > + pmc_save_cpu_binding(&pb); > for (int i = 0; i < mp_ncpus; i++) { > - thread_lock(curthread); > - sched_bind(curthread, i); > - thread_unlock(curthread); > + pmc_select_cpu(i); > /* return the 'current' buffer to the global pool */ > if ((lb = po->po_curbuf[curcpu]) != NULL) { > PMCLOG_RESET_BUFFER_DESCRIPTOR(lb); > pmc_plb_rele(lb); > } > } > - thread_lock(curthread); > - sched_unbind(curthread); > - thread_unlock(curthread); > + pmc_restore_cpu_binding(&pb); > > /* drop a reference to the fd */ > if (po->po_file != NULL) { > @@ -869,18 +867,17 @@ pmclog_schedule_one_cond(struct pmc_owner *po) > static void > pmclog_schedule_all(struct pmc_owner *po) > { > + struct pmc_binding pb; > + > /* > * Schedule the current buffer if any and not empty. > */ > + pmc_save_cpu_binding(&pb); > for (int i = 0; i < mp_ncpus; i++) { > - thread_lock(curthread); > - sched_bind(curthread, i); > - thread_unlock(curthread); > + pmc_select_cpu(i); > pmclog_schedule_one_cond(po); > } > - thread_lock(curthread); > - sched_unbind(curthread); > - thread_unlock(curthread); > + pmc_restore_cpu_binding(&pb); > } > > int > diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c > index e94527041af8..18b8bb1674a3 100644 > --- a/sys/dev/hwpmc/hwpmc_mod.c > +++ b/sys/dev/hwpmc/hwpmc_mod.c > @@ -249,9 +249,6 @@ static void pmc_process_thread_delete(struct thread > *td); > static void pmc_process_thread_userret(struct thread *td); > static void pmc_remove_owner(struct pmc_owner *po); > static void pmc_remove_process_descriptor(struct pmc_process *pp); > -static void pmc_restore_cpu_binding(struct pmc_binding *pb); > -static void pmc_save_cpu_binding(struct pmc_binding *pb); > -static void pmc_select_cpu(int cpu); > static int pmc_start(struct pmc *pm); > static int pmc_stop(struct pmc *pm); > static int pmc_syscall_handler(struct thread *td, void *syscall_args); > @@ -739,13 +736,14 @@ pmc_ri_to_classdep(struct pmc_mdep *md, int ri, int > *adjri) > * save the cpu binding of the current kthread > */ > > -static void > +void > pmc_save_cpu_binding(struct pmc_binding *pb) > { > PMCDBG0(CPU,BND,2, "save-cpu"); > thread_lock(curthread); > pb->pb_bound = sched_is_bound(curthread); > pb->pb_cpu = curthread->td_oncpu; > + pb->pb_priority = curthread->td_priority; > thread_unlock(curthread); > PMCDBG1(CPU,BND,2, "save-cpu cpu=%d", pb->pb_cpu); > } > @@ -754,16 +752,16 @@ pmc_save_cpu_binding(struct pmc_binding *pb) > * restore the cpu binding of the current thread > */ > > -static void > +void > pmc_restore_cpu_binding(struct pmc_binding *pb) > { > PMCDBG2(CPU,BND,2, "restore-cpu curcpu=%d restore=%d", > curthread->td_oncpu, pb->pb_cpu); > thread_lock(curthread); > - if (pb->pb_bound) > - sched_bind(curthread, pb->pb_cpu); > - else > + sched_bind(curthread, pb->pb_cpu); > + if (!pb->pb_bound) > sched_unbind(curthread); > + sched_prio(curthread, pb->pb_priority); > thread_unlock(curthread); > PMCDBG0(CPU,BND,2, "restore-cpu done"); > } > @@ -772,7 +770,7 @@ pmc_restore_cpu_binding(struct pmc_binding *pb) > * move execution over the specified cpu and bind it there. > */ > > -static void > +void > pmc_select_cpu(int cpu) > { > KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), > @@ -784,6 +782,7 @@ pmc_select_cpu(int cpu) > > PMCDBG1(CPU,SEL,2, "select-cpu cpu=%d", cpu); > thread_lock(curthread); > + sched_prio(curthread, PRI_MIN); > sched_bind(curthread, cpu); > thread_unlock(curthread); > > diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h > index 372e77ecdee7..18c38ca36659 100644 > --- a/sys/sys/pmc.h > +++ b/sys/sys/pmc.h > @@ -997,6 +997,7 @@ struct pmc_cpu { > struct pmc_binding { > int pb_bound; /* is bound? */ > int pb_cpu; /* if so, to which CPU */ > + u_char pb_priority; /* Thread active priority. */ > }; > > struct pmc_mdep; > @@ -1225,6 +1226,9 @@ int pmc_save_kernel_callchain(uintptr_t *_cc, int > _maxsamples, > struct trapframe *_tf); > int pmc_save_user_callchain(uintptr_t *_cc, int _maxsamples, > struct trapframe *_tf); > +void pmc_restore_cpu_binding(struct pmc_binding *pb); > +void pmc_save_cpu_binding(struct pmc_binding *pb); > +void pmc_select_cpu(int cpu); > struct pmc_mdep *pmc_mdep_alloc(int nclasses); > void pmc_mdep_free(struct pmc_mdep *md); > uint64_t pmc_rdtsc(void); > -- Mateusz Guzik <mjguzik gmail.com>