Date: Sun, 25 Dec 2016 19:49:35 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r310554 - in head/sys: kern sys Message-ID: <201612251949.uBPJnZnv081411@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Dec 25 19:49:35 2016 New Revision: 310554 URL: https://svnweb.freebsd.org/changeset/base/310554 Log: Some optimizations for kqueue timers. There is no need to do two allocations per kqueue timer. Gather all data needed by the timer callout into the structure and allocate it at once. Use the structure to preserve the result of timer2sbintime(), to not perform repeated 64bit calculations in callout. Remove tautological casts. Remove now unused p_nexttime [1]. Noted by: markj [1] Reviewed by: markj (previous version) Sponsored by: The FreeBSD Foundation MFC after: 1 week X-MFC note: do not remove p_nexttime Differential revision: https://reviews.freebsd.org/D8901 Modified: head/sys/kern/kern_event.c head/sys/sys/event.h Modified: head/sys/kern/kern_event.c ============================================================================== --- head/sys/kern/kern_event.c Sun Dec 25 19:49:09 2016 (r310553) +++ head/sys/kern/kern_event.c Sun Dec 25 19:49:35 2016 (r310554) @@ -631,23 +631,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); } /* @@ -656,16 +662,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); @@ -680,13 +686,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, 1); - 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); } @@ -694,13 +699,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: head/sys/sys/event.h ============================================================================== --- head/sys/sys/event.h Sun Dec 25 19:49:09 2016 (r310553) +++ head/sys/sys/event.h Sun Dec 25 19:49:35 2016 (r310554) @@ -231,7 +231,6 @@ struct knote { struct proc *p_proc; /* proc pointer */ struct kaiocb *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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612251949.uBPJnZnv081411>