Author: kib
Date: Sun Jan  1 12:19:58 2017
New Revision: 311010
URL: https://svnweb.freebsd.org/changeset/base/311010

Log:
  MFC r310554:
  Some optimizations for kqueue timers.

Modified:
  stable/10/sys/kern/kern_event.c
  stable/10/sys/sys/event.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kern/kern_event.c
==============================================================================
--- stable/10/sys/kern/kern_event.c     Sun Jan  1 12:03:41 2017        
(r311009)
+++ stable/10/sys/kern/kern_event.c     Sun Jan  1 12:19:58 2017        
(r311010)
@@ -611,23 +611,29 @@ timer2sbintime(intptr_t data, int flags)
        return (-1);
 }
 
+struct kq_timer_cb_data {
+       struct callout c;
+       sbintime_t next;        /* next timer event fires at */
+       sbintime_t to;          /* precalculated timer period */
+};
+
 static void
 filt_timerexpire(void *knx)
 {
-       struct callout *calloutp;
        struct knote *kn;
+       struct kq_timer_cb_data *kc;
 
        kn = knx;
        kn->kn_data++;
        KNOTE_ACTIVATE(kn, 0);  /* XXX - handle locking */
 
-       if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) {
-               calloutp = (struct callout *)kn->kn_hook;
-               *kn->kn_ptr.p_nexttime += timer2sbintime(kn->kn_sdata,
-                   kn->kn_sfflags);
-               callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0,
-                   filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE);
-       }
+       if ((kn->kn_flags & EV_ONESHOT) != 0)
+               return;
+
+       kc = kn->kn_ptr.p_v;
+       kc->next += kc->to;
+       callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kn,
+           PCPU_GET(cpuid), C_ABSOLUTE);
 }
 
 /*
@@ -636,16 +642,16 @@ filt_timerexpire(void *knx)
 static int
 filt_timerattach(struct knote *kn)
 {
-       struct callout *calloutp;
+       struct kq_timer_cb_data *kc;
        sbintime_t to;
        unsigned int ncallouts;
 
-       if ((intptr_t)kn->kn_sdata < 0)
+       if (kn->kn_sdata < 0)
                return (EINVAL);
-       if ((intptr_t)kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0)
+       if (kn->kn_sdata == 0 && (kn->kn_flags & EV_ONESHOT) == 0)
                kn->kn_sdata = 1;
        /* Only precision unit are supported in flags so far */
-       if (kn->kn_sfflags & ~NOTE_TIMER_PRECMASK)
+       if ((kn->kn_sfflags & ~NOTE_TIMER_PRECMASK) != 0)
                return (EINVAL);
 
        to = timer2sbintime(kn->kn_sdata, kn->kn_sfflags);
@@ -660,13 +666,12 @@ filt_timerattach(struct knote *kn)
 
        kn->kn_flags |= EV_CLEAR;               /* automatically set */
        kn->kn_status &= ~KN_DETACHED;          /* knlist_add clears it */
-       kn->kn_ptr.p_nexttime = malloc(sizeof(sbintime_t), M_KQUEUE, M_WAITOK);
-       calloutp = malloc(sizeof(*calloutp), M_KQUEUE, M_WAITOK);
-       callout_init(calloutp, CALLOUT_MPSAFE);
-       kn->kn_hook = calloutp;
-       *kn->kn_ptr.p_nexttime = to + sbinuptime();
-       callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0,
-           filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE);
+       kn->kn_ptr.p_v = kc = malloc(sizeof(*kc), M_KQUEUE, M_WAITOK);
+       callout_init(&kc->c, 1);
+       kc->next = to + sbinuptime();
+       kc->to = to;
+       callout_reset_sbt_on(&kc->c, kc->next, 0, filt_timerexpire, kn,
+           PCPU_GET(cpuid), C_ABSOLUTE);
 
        return (0);
 }
@@ -674,13 +679,12 @@ filt_timerattach(struct knote *kn)
 static void
 filt_timerdetach(struct knote *kn)
 {
-       struct callout *calloutp;
+       struct kq_timer_cb_data *kc;
        unsigned int old;
 
-       calloutp = (struct callout *)kn->kn_hook;
-       callout_drain(calloutp);
-       free(calloutp, M_KQUEUE);
-       free(kn->kn_ptr.p_nexttime, M_KQUEUE);
+       kc = kn->kn_ptr.p_v;
+       callout_drain(&kc->c);
+       free(kc, M_KQUEUE);
        old = atomic_fetchadd_int(&kq_ncallouts, -1);
        KASSERT(old > 0, ("Number of callouts cannot become negative"));
        kn->kn_status |= KN_DETACHED;   /* knlist_remove sets it */

Modified: stable/10/sys/sys/event.h
==============================================================================
--- stable/10/sys/sys/event.h   Sun Jan  1 12:03:41 2017        (r311009)
+++ stable/10/sys/sys/event.h   Sun Jan  1 12:19:58 2017        (r311010)
@@ -228,6 +228,8 @@ struct knote {
                struct          aiocblist *p_aio;       /* AIO job pointer */
                struct          aioliojob *p_lio;       /* LIO job pointer */ 
                sbintime_t      *p_nexttime;    /* next timer event fires at */
+               void            *p_v;           /* generic other pointer */
+
        } kn_ptr;
        struct                  filterops *kn_fop;
        void                    *kn_hook;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to