clockintr: support an arbitrary callback function argument
authorcheloha <cheloha@openbsd.org>
Sun, 10 Sep 2023 03:08:05 +0000 (03:08 +0000)
committercheloha <cheloha@openbsd.org>
Sun, 10 Sep 2023 03:08:05 +0000 (03:08 +0000)
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
sys/kern/kern_sched.c
sys/kern/kern_time.c
sys/kern/sched_bsd.c
sys/kern/subr_prof.c
sys/sys/clockintr.h
sys/sys/resourcevar.h
sys/sys/sched.h
sys/sys/time.h

index 6edc5d0..aeeb7ed 100644 (file)
@@ -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 <drahn@openbsd.org>
  * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
@@ -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;
 
index 92b0da6..ea1b874 100644 (file)
@@ -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 <art@openbsd.org>
  *
@@ -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__);
 
index 50e9285..1687ee6 100644 (file)
@@ -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;
index 2f9ef56..a5695cb 100644 (file)
@@ -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();
index 10a9d9e..b630890 100644 (file)
@@ -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;
index ea7c2ea..b4dceef 100644 (file)
@@ -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 <cheloha@openbsd.org>
  *
@@ -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);
index b3fc047..fcbd990 100644 (file)
@@ -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;
index d093e1e..cc2b4dc 100644 (file)
@@ -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);
 
index c7b9abc..cef9583 100644 (file)
@@ -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 *);