The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c0e70e7b97dcfcbeedfdfbacf1543b756a616a18

commit c0e70e7b97dcfcbeedfdfbacf1543b756a616a18
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2025-08-20 19:06:05 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2025-10-18 05:12:36 +0000

    kern_event.c: support copy for timer events
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
    Differential revision:  https://reviews.freebsd.org/D52045
---
 sys/kern/kern_event.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 1f3030995ec6..4fd495fa1ec8 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -179,6 +179,7 @@ static void filt_timerdetach(struct knote *kn);
 static void    filt_timerstart(struct knote *kn, sbintime_t to);
 static void    filt_timertouch(struct knote *kn, struct kevent *kev,
                    u_long type);
+static int     filt_timercopy(struct knote *kn, struct proc *p1);
 static int     filt_timervalidate(struct knote *kn, sbintime_t *to);
 static int     filt_timer(struct knote *kn, long hint);
 static int     filt_userattach(struct knote *kn);
@@ -215,6 +216,7 @@ static const struct filterops timer_filtops = {
        .f_detach = filt_timerdetach,
        .f_event = filt_timer,
        .f_touch = filt_timertouch,
+       .f_copy =  filt_timercopy,
 };
 static const struct filterops user_filtops = {
        .f_attach = filt_userattach,
@@ -943,6 +945,30 @@ filt_timerattach(struct knote *kn)
        return (0);
 }
 
+static int
+filt_timercopy(struct knote *kn, struct proc *p)
+{
+       struct kq_timer_cb_data *kc_src, *kc;
+
+       if (atomic_fetchadd_int(&kq_ncallouts, 1) + 1 > kq_calloutmax) {
+               atomic_subtract_int(&kq_ncallouts, 1);
+               return (ENOMEM);
+       }
+
+       kn->kn_status &= ~KN_DETACHED;
+       kc_src = kn->kn_ptr.p_v;
+       kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK);
+       kc->kn = kn;
+       kc->p = p;
+       kc->flags = kc_src->flags & ~KQ_TIMER_CB_ENQUEUED;
+       kc->next = kc_src->next;
+       kc->to = kc_src->to;
+       kc->cpuid = PCPU_GET(cpuid);
+       callout_init(&kc->c, 1);
+       kqtimer_sched_callout(kc);
+       return (0);
+}
+
 static void
 filt_timerstart(struct knote *kn, sbintime_t to)
 {

Reply via email to