From a3464c933063c2d770977c57373583ee9a16e674 Mon Sep 17 00:00:00 2001 From: cheloha Date: Sun, 10 Sep 2023 03:08:05 +0000 Subject: [PATCH] clockintr: support an arbitrary callback function argument Callers can now provide an argument pointer to clockintr_establish(). The pointer is kept in a new struct clockintr member, cl_arg. The pointer is passed as the third parameter to clockintr.cl_func when it is executed during clockintr_dispatch(). Like the callback function, the callback argument is immutable after the clockintr is established. At present, nothing uses this. All current clockintr_establish() callers pass a NULL arg pointer. However, I am confident that dt(4)'s profile provider will need this in the near future. Requested by dlg@ back in March. --- sys/kern/kern_clockintr.c | 22 +++++++++++++--------- sys/kern/kern_sched.c | 8 ++++---- sys/kern/kern_time.c | 4 ++-- sys/kern/sched_bsd.c | 4 ++-- sys/kern/subr_prof.c | 10 +++++----- sys/sys/clockintr.h | 7 ++++--- sys/sys/resourcevar.h | 4 ++-- sys/sys/sched.h | 4 ++-- sys/sys/time.h | 4 ++-- 9 files changed, 36 insertions(+), 31 deletions(-) diff --git a/sys/kern/kern_clockintr.c b/sys/kern/kern_clockintr.c index 6edc5d09018..aeeb7ed9158 100644 --- a/sys/kern/kern_clockintr.c +++ b/sys/kern/kern_clockintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clockintr.c,v 1.46 2023/09/10 01:41:16 cheloha Exp $ */ +/* $OpenBSD: kern_clockintr.c,v 1.47 2023/09/10 03:08:05 cheloha Exp $ */ /* * Copyright (c) 2003 Dale Rahn * Copyright (c) 2020 Mark Kettenis @@ -43,10 +43,10 @@ uint32_t statclock_min; /* [I] minimum statclock period (ns) */ uint32_t statclock_mask; /* [I] set of allowed offsets */ uint64_t clockintr_advance_random(struct clockintr *, uint64_t, uint32_t); -void clockintr_hardclock(struct clockintr *, void *); +void clockintr_hardclock(struct clockintr *, void *, void *); void clockintr_schedule(struct clockintr *, uint64_t); void clockintr_schedule_locked(struct clockintr *, uint64_t); -void clockintr_statclock(struct clockintr *, void *); +void clockintr_statclock(struct clockintr *, void *, void *); void clockqueue_intrclock_install(struct clockintr_queue *, const struct intrclock *); uint64_t clockqueue_next(const struct clockintr_queue *); @@ -114,12 +114,14 @@ clockintr_cpu_init(const struct intrclock *ic) /* TODO: Remove these from struct clockintr_queue. */ if (cq->cq_hardclock == NULL) { - cq->cq_hardclock = clockintr_establish(ci, clockintr_hardclock); + cq->cq_hardclock = clockintr_establish(ci, clockintr_hardclock, + NULL); if (cq->cq_hardclock == NULL) panic("%s: failed to establish hardclock", __func__); } if (cq->cq_statclock == NULL) { - cq->cq_statclock = clockintr_establish(ci, clockintr_statclock); + cq->cq_statclock = clockintr_establish(ci, clockintr_statclock, + NULL); if (cq->cq_statclock == NULL) panic("%s: failed to establish statclock", __func__); } @@ -265,11 +267,12 @@ clockintr_dispatch(void *frame) clockqueue_pend_delete(cq, cl); shadow = &cq->cq_shadow; shadow->cl_expiration = cl->cl_expiration; + shadow->cl_arg = cl->cl_arg; shadow->cl_func = cl->cl_func; cq->cq_running = cl; mtx_leave(&cq->cq_mtx); - shadow->cl_func(shadow, frame); + shadow->cl_func(shadow, frame, shadow->cl_arg); mtx_enter(&cq->cq_mtx); cq->cq_running = NULL; @@ -389,7 +392,7 @@ clockintr_cancel(struct clockintr *cl) struct clockintr * clockintr_establish(struct cpu_info *ci, - void (*func)(struct clockintr *, void *)) + void (*func)(struct clockintr *, void *, void *), void *arg) { struct clockintr *cl; struct clockintr_queue *cq = &ci->ci_queue; @@ -397,6 +400,7 @@ clockintr_establish(struct cpu_info *ci, cl = malloc(sizeof *cl, M_DEVBUF, M_NOWAIT | M_ZERO); if (cl == NULL) return NULL; + cl->cl_arg = arg; cl->cl_func = func; cl->cl_queue = cq; @@ -457,7 +461,7 @@ clockintr_stagger(struct clockintr *cl, uint64_t period, uint32_t n, } void -clockintr_hardclock(struct clockintr *cl, void *frame) +clockintr_hardclock(struct clockintr *cl, void *frame, void *arg) { uint64_t count, i; @@ -467,7 +471,7 @@ clockintr_hardclock(struct clockintr *cl, void *frame) } void -clockintr_statclock(struct clockintr *cl, void *frame) +clockintr_statclock(struct clockintr *cl, void *frame, void *arg) { uint64_t count, i; diff --git a/sys/kern/kern_sched.c b/sys/kern/kern_sched.c index 92b0da6ffa4..ea1b874a5c5 100644 --- a/sys/kern/kern_sched.c +++ b/sys/kern/kern_sched.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sched.c,v 1.89 2023/09/06 02:09:58 cheloha Exp $ */ +/* $OpenBSD: kern_sched.c,v 1.90 2023/09/10 03:08:05 cheloha Exp $ */ /* * Copyright (c) 2007, 2008 Artur Grabowski * @@ -88,13 +88,13 @@ sched_init_cpu(struct cpu_info *ci) spc->spc_idleproc = NULL; - spc->spc_itimer = clockintr_establish(ci, itimer_update); + spc->spc_itimer = clockintr_establish(ci, itimer_update, NULL); if (spc->spc_itimer == NULL) panic("%s: clockintr_establish itimer_update", __func__); - spc->spc_profclock = clockintr_establish(ci, profclock); + spc->spc_profclock = clockintr_establish(ci, profclock, NULL); if (spc->spc_profclock == NULL) panic("%s: clockintr_establish profclock", __func__); - spc->spc_roundrobin = clockintr_establish(ci, roundrobin); + spc->spc_roundrobin = clockintr_establish(ci, roundrobin, NULL); if (spc->spc_roundrobin == NULL) panic("%s: clockintr_establish roundrobin", __func__); diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 50e9285262e..1687ee61d14 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.165 2023/08/29 16:19:34 claudio Exp $ */ +/* $OpenBSD: kern_time.c,v 1.166 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -755,7 +755,7 @@ itimerdecr(struct itimerspec *itp, const struct timespec *decrement) } void -itimer_update(struct clockintr *cl, void *cf) +itimer_update(struct clockintr *cl, void *cf, void *arg) { struct timespec elapsed; uint64_t nsecs; diff --git a/sys/kern/sched_bsd.c b/sys/kern/sched_bsd.c index 2f9ef56aee1..a5695cb5e78 100644 --- a/sys/kern/sched_bsd.c +++ b/sys/kern/sched_bsd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sched_bsd.c,v 1.85 2023/08/30 09:02:38 claudio Exp $ */ +/* $OpenBSD: sched_bsd.c,v 1.86 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /*- @@ -83,7 +83,7 @@ struct loadavg averunnable; * Force switch among equal priority processes every 100ms. */ void -roundrobin(struct clockintr *cl, void *cf) +roundrobin(struct clockintr *cl, void *cf, void *arg) { uint64_t count; struct cpu_info *ci = curcpu(); diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 10a9d9e2cac..b6308905dd9 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.37 2023/09/06 02:09:58 cheloha Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.38 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -64,7 +64,7 @@ u_int gmon_cpu_count; /* [K] number of CPUs with profiling enabled */ extern char etext[]; -void gmonclock(struct clockintr *, void *); +void gmonclock(struct clockintr *, void *, void *); void prof_init(void) @@ -101,7 +101,7 @@ prof_init(void) /* Allocate and initialize one profiling buffer per CPU. */ CPU_INFO_FOREACH(cii, ci) { - ci->ci_gmonclock = clockintr_establish(ci, gmonclock); + ci->ci_gmonclock = clockintr_establish(ci, gmonclock, NULL); if (ci->ci_gmonclock == NULL) { printf("%s: clockintr_establish gmonclock\n", __func__); return; @@ -236,7 +236,7 @@ sysctl_doprof(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, } void -gmonclock(struct clockintr *cl, void *cf) +gmonclock(struct clockintr *cl, void *cf, void *arg) { uint64_t count; struct clockframe *frame = cf; @@ -307,7 +307,7 @@ sys_profil(struct proc *p, void *v, register_t *retval) } void -profclock(struct clockintr *cl, void *cf) +profclock(struct clockintr *cl, void *cf, void *arg) { uint64_t count; struct clockframe *frame = cf; diff --git a/sys/sys/clockintr.h b/sys/sys/clockintr.h index ea7c2ea0624..b4dceefa59a 100644 --- a/sys/sys/clockintr.h +++ b/sys/sys/clockintr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clockintr.h,v 1.12 2023/09/06 02:33:18 cheloha Exp $ */ +/* $OpenBSD: clockintr.h,v 1.13 2023/09/10 03:08:05 cheloha Exp $ */ /* * Copyright (c) 2020-2022 Scott Cheloha * @@ -70,7 +70,8 @@ struct clockintr { uint64_t cl_expiration; /* [m] dispatch time */ TAILQ_ENTRY(clockintr) cl_elink; /* [m] cq_est glue */ TAILQ_ENTRY(clockintr) cl_plink; /* [m] cq_pend glue */ - void (*cl_func)(struct clockintr *, void *); /* [I] callback */ + void *cl_arg; /* [I] argument */ + void (*cl_func)(struct clockintr *, void *, void *); /* [I] callback */ struct clockintr_queue *cl_queue; /* [I] parent queue */ uint32_t cl_flags; /* [m] CLST_* flags */ }; @@ -129,7 +130,7 @@ void clockintr_trigger(void); uint64_t clockintr_advance(struct clockintr *, uint64_t); void clockintr_cancel(struct clockintr *); struct clockintr *clockintr_establish(struct cpu_info *, - void (*)(struct clockintr *, void *)); + void (*)(struct clockintr *, void *, void *), void *); void clockintr_stagger(struct clockintr *, uint64_t, uint32_t, uint32_t); void clockqueue_init(struct clockintr_queue *); int sysctl_clockintr(int *, u_int, void *, size_t *, void *, size_t); diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index b3fc0476b01..fcbd990fcb3 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resourcevar.h,v 1.28 2023/08/29 16:19:34 claudio Exp $ */ +/* $OpenBSD: resourcevar.h,v 1.29 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: resourcevar.h,v 1.12 1995/11/22 23:01:53 cgd Exp $ */ /* @@ -66,7 +66,7 @@ extern uint32_t profclock_period; void addupc_intr(struct proc *, u_long, u_long); void addupc_task(struct proc *, u_long, u_int); -void profclock(struct clockintr *, void *); +void profclock(struct clockintr *, void *, void *); void tuagg_locked(struct process *, struct proc *, const struct timespec *); void tuagg(struct process *, struct proc *); struct tusage; diff --git a/sys/sys/sched.h b/sys/sys/sched.h index d093e1e636c..cc2b4dc6e2e 100644 --- a/sys/sys/sched.h +++ b/sys/sys/sched.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sched.h,v 1.62 2023/09/09 18:19:03 cheloha Exp $ */ +/* $OpenBSD: sched.h,v 1.63 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */ /*- @@ -149,7 +149,7 @@ extern uint32_t roundrobin_period; struct proc; void schedclock(struct proc *); -void roundrobin(struct clockintr *, void *); +void roundrobin(struct clockintr *, void *, void *); void scheduler_start(void); void userret(struct proc *p); diff --git a/sys/sys/time.h b/sys/sys/time.h index c7b9abc2c2e..cef9583c880 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -1,4 +1,4 @@ -/* $OpenBSD: time.h,v 1.64 2023/08/05 20:07:56 cheloha Exp $ */ +/* $OpenBSD: time.h,v 1.65 2023/09/10 03:08:05 cheloha Exp $ */ /* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */ /* @@ -331,7 +331,7 @@ struct proc; int clock_gettime(struct proc *, clockid_t, struct timespec *); struct clockintr; -void itimer_update(struct clockintr *, void *); +void itimer_update(struct clockintr *, void *, void *); void cancel_all_itimers(void); int settime(const struct timespec *); -- 2.20.1