kern/150095: [patch] Account for reserved itimers which shouldn't count against _SC_TIMER_MAX

Garrett Cooper gcooper at FreeBSD.org
Sun Aug 29 22:00:05 UTC 2010


>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 at 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:


More information about the freebsd-bugs mailing list