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