NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/45618: kqueue EVFILT_TIMER with smaller timeout value makes kernel busy or panic



>Number:         45618
>Category:       kern
>Synopsis:       kqueue EVFILT_TIMER with smaller timeout value makes kernel 
>busy or panic
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Nov 16 13:10:01 +0000 2011
>Originator:     Motoyuki OHMORI
>Release:        NetBSD current 5.99.22 (2010/04/26) and 5.1-RELEASE
>Organization:
Chikushi Jogakuen University
>Environment:
NetBSD xxx 5.1 NetBSD 5.1 (GENERIC) #0: Sat Nov  6 13:19:33 UTC 2010  
builds%b6.netbsd.org@localhost:/home/builds/ab/netbsd-5-1-RELEASE/amd64/201011061943Z-obj/home/builds/ab/netbsd-5-1-RELEASE/src/sys/arch/amd64/compile/GENERIC
 amd64

>Description:
When EVFILT_TIMER with smaller interval value kernel gets busy or sometimes 
panic.

The kernel seems to be alive because it answers for ping from remote
host.  However, kernel seems to be too busy after the EVFILT_TIMER is 
added and expires once.  While a similar problem is reported by #42685, 
I here do not use pthread.

Even though my environment is a little bit old, I suspect that a function,
filt_timerexpire, in kern_event.c even in current seems to have same 
issue.  The problem seems that filt_timerexpire() does not consider the 
case where tticks is equal to zero after a timer expires at least once.
>How-To-Repeat:
Execute kevent like below:

    EV_SET(&ev, ident, EVFILT_TIMER, EV_ADD, 0, 1, 0);
    kevent(kqueue, &ev, 1, NULL, 0, NULL);

We then get kernel busy or panic.
>Fix:
At this moment, I cannot examine a patch.  However, I hope that a below
patch would be effective. 

Index: sys/kern/kern_event.c
===================================================================
--- sys/kern/kern_event.c       (revision 147)
+++ sys/kern/kern_event.c       (working copy)
@@ -598,6 +598,8 @@
        knote_activate(kn);
        if ((kn->kn_flags & EV_ONESHOT) == 0) {
                tticks = mstohz(kn->kn_sdata);
+               if (tticks == 0)
+                       tticks = 1;
                callout_schedule((callout_t *)kn->kn_hook, tticks);
        }
        mutex_exit(&kqueue_misc_lock);



Home | Main Index | Thread Index | Old Index