>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"