>Number:         150095
>Category:       kern
>Synopsis:       [patch] Account for reserved itimers which shouldn't count 
>against _SC_TIMER_MAX
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Aug 29 22:00:04 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Garrett Cooper
>Release:        9-CURRENT
>Organization:
Cisco Systems, Inc.
>Environment:
FreeBSD orangebox.local 9.0-CURRENT FreeBSD 9.0-CURRENT #10 r211794M: Sun Aug 
29 21:21:29 UTC 2010     gcoo...@orangebox.local:/usr/obj/usr/src/sys/ORANGEBOX 
 amd64
>Description:
Currently 3 reserve itimers are allocated purely for kernel use, but 
unfortunately this breaks the SUSv4 requirement which states:

{TIMER_MAX}
    Maximum number of timers per process supported by the implementation.
    Minimum Acceptable Value: {_POSIX_TIMER_MAX}

..

{_POSIX_TIMER_MAX}
    The per-process number of timers.
    Value: 32

Example (from testcases/open_posix_testsuite/conformance/behavior/timers in the 
LTP package):

$ ./1-1.run-test 
[29] timer_create() did not return success: Resource temporarily unavailable

After applying this patch, things function as expected:

$ ./1-1.run-test 
Test PASSED
>How-To-Repeat:
1. Grab LTP: the package needs to be July or later as I didn't apply many fixes 
to the branch until post that date -- this may require grabbing the source from 
git. See the sourceforge page for more info (http://sf.net/projects/ltp). Use 
ltp/ltp-dev instead of ltp/ltp in the directions, if ltp-dev.git still exists 
(I'm working on fixing that, because the directions on the webpage are 
incorrect).
2. Go to the open_posix_testsuite directory: cd 
$LTP_DIR/testcases/open_posix_testsuite
3. Generate the Makefiles: make generate-makefiles
4. Build the test: cd conformance/behavior/timers; make
5. Execute the test like: ./1-1.run-test
>Fix:


Patch attached with submission follows:

Index: sys/kern/kern_time.c
===================================================================
--- sys/kern/kern_time.c        (revision 211794)
+++ sys/kern/kern_time.c        (working copy)
@@ -356,9 +356,9 @@
        struct timeval tv;
        int error;
 
-       if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
+       if (rqt->tv_sec < 0 || (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000))
                return (EINVAL);
-       if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
+       if (rqt->tv_sec == 0 && rqt->tv_nsec == 0)
                return (0);
        getnanouptime(&ts);
        timespecadd(&ts, rqt);
@@ -995,7 +995,8 @@
 
        PROC_LOCK(p);
        if (preset_id != -1) {
-               KASSERT(preset_id >= 0 && preset_id < 3, ("invalid preset_id"));
+               KASSERT(preset_id >= 0 && preset_id < TIMER_RESERVED,
+                   ("invalid preset_id"));
                id = preset_id;
                if (p->p_itimers->its_timers[id] != NULL) {
                        PROC_UNLOCK(p);
@@ -1007,10 +1008,11 @@
                 * Find a free timer slot, skipping those reserved
                 * for setitimer().
                 */
-               for (id = 3; id < TIMER_MAX; id++)
+               for (id = TIMER_RESERVED; id < (TIMER_RESERVED + TIMER_MAX);
+                   id++)
                        if (p->p_itimers->its_timers[id] == NULL)
                                break;
-               if (id == TIMER_MAX) {
+               if (id == (TIMER_RESERVED + TIMER_MAX)) {
                        PROC_UNLOCK(p);
                        error = EAGAIN;
                        goto out;
@@ -1144,7 +1146,7 @@
                ovalp = NULL;
 
        PROC_LOCK(p);
-       if (uap->timerid < 3 ||
+       if (uap->timerid < TIMER_RESERVED ||
            (it = itimer_find(p, uap->timerid)) == NULL) {
                PROC_UNLOCK(p);
                error = EINVAL;
@@ -1176,7 +1178,7 @@
        int error;
 
        PROC_LOCK(p);
-       if (uap->timerid < 3 ||
+       if (uap->timerid < TIMER_RESERVED ||
           (it = itimer_find(p, uap->timerid)) == NULL) {
                PROC_UNLOCK(p);
                error = EINVAL;
@@ -1206,7 +1208,7 @@
        int error ;
 
        PROC_LOCK(p);
-       if (uap->timerid < 3 ||
+       if (uap->timerid < TIMER_RESERVED ||
            (it = itimer_find(p, uap->timerid)) == NULL) {
                PROC_UNLOCK(p);
                error = EINVAL;
@@ -1483,7 +1485,7 @@
                 * by new image.
                 */
                if (event == ITIMER_EV_EXEC)
-                       i = 3;
+                       i = TIMER_RESERVED;
                else if (event == ITIMER_EV_EXIT)
                        i = 0;
                else
Index: sys/sys/timers.h
===================================================================
--- sys/sys/timers.h    (revision 211794)
+++ sys/sys/timers.h    (working copy)
@@ -83,6 +83,8 @@
 
 #define        ITCF_ONWORKLIST 0x01
 
+/* Clocks reserved by setitimer */
+#define TIMER_RESERVED 3
 #define        TIMER_MAX       32
 
 #define        ITIMER_LOCK(it)         mtx_lock(&(it)->it_mtx)
@@ -94,7 +96,7 @@
        struct itimerlist       its_virtual;
        struct itimerlist       its_prof;
        TAILQ_HEAD(, itimer)    its_worklist;
-       struct itimer           *its_timers[TIMER_MAX];
+       struct itimer           *its_timers[TIMER_RESERVED + TIMER_MAX];
 };
 
 struct kclock {


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to