Date: Sun, 29 Aug 2010 21:57:38 GMT From: Garrett Cooper <gcooper@FreeBSD.org> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/150095: [patch] Account for reserved itimers which shouldn't count against _SC_TIMER_MAX Message-ID: <201008292157.o7TLvcDT084628@www.freebsd.org> Resent-Message-ID: <201008292200.o7TM04o3055260@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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 gcooper@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008292157.o7TLvcDT084628>