Skip to contentSkip to conversation

: DELAYTIMER_MAX is defined

PATCH In review Eric Piel 3 participants 9 messages May 6, 2003 – May 7, 2003

lore
Share & tools
lore

Eric Piel

author
#0 lore raw

PATCH 1/1 : DELAYTIMER_MAX is defined

Hello,

Playing around with the posix timers I've noticed that DELAYTIMER_MAX is not defined. This constant is specified in the POSIX specifications. It should contain the maximum possible value of overruns on a signal. It is also said that the overrun shouldn't overflow. cf
http://www.opengroup.org/onlinepubs/007904975/functions/timer_getoverrun.html

So here is a patch to add this constant and a check that the overrun variable never overflow. It's for 2.5.67 but should apply flawlessly to 2.5.69 too.
Actually one could wonder if the test on the overflow is really needed has an overrun reaching 2^31 seems very hard to happen. However the constant definition is not hurting anything and looks necessary for closer POSIX compliance.

Eric

include/linux/limits.h +2 -0
diff -ur linux-2.5.67-ia64-hrtcore/include/linux/limits.h linux-2.5.67-ia64-hrtimers/include/linux/limits.h
@@ -17,6 +17,8 @@
 #define XATTR_SIZE_MAX 65536	/* size of an extended attribute value (64k) */
 #define XATTR_LIST_MAX 65536	/* size of extended attribute namelist (64k) */
 
+#define DELAYTIMER_MAX INT_MAX	/* # timer expiration overruns a POSIX.1b timer may have */
+
 #define RTSIG_MAX	  32
 
 #endif
include/linux/posix-timers.h +2 -1
diff -ur linux-2.5.67-ia64-hrtcore/include/linux/posix-timers.h linux-2.5.67-ia64-hrtimers/include/linux/posix-timers.h
@@ -25,6 +59,7 @@
 
 #define posix_bump_timer(timr) do { \
                         (timr)->it_timer.expires += (timr)->it_incr; \
-                        (timr)->it_overrun++;               \
+                        if ((timr)->it_overrun < DELAYTIMER_MAX)\
+                            (timr)->it_overrun++;               \
                        }while (0)
 #endif
#1 lore raw
Quoted 8 lines · Eric Piel

Hello,

Playing around with the posix timers I've noticed that DELAYTIMER_MAX is not defined. This constant is specified in the POSIX specifications. It should contain the maximum possible value of overruns on a signal. It is also said that the overrun shouldn't overflow. cf
http://www.opengroup.org/onlinepubs/007904975/functions/timer_getoverrun.html

Quoted 7 lines

So here is a patch to add this constant and a check that the overrun variable never overflow. It's for 2.5.67 but should apply flawlessly to 2.5.69 too.
Actually one could wonder if the test on the overflow is really needed has an overrun reaching 2^31 seems very hard to happen. However the constant definition is not hurting anything and looks necessary for closer POSIX compliance.

I think this is needed in glibc. I am not sure how that relates to kernel defines.

-g

Quoted 31 lines

Eric

------------------------------------------------------------------------

diff -ur linux-2.5.67-ia64-hrtcore/include/linux/limits.h linux-2.5.67-ia64-hrtimers/include/linux/limits.h

include/linux/limits.h +2 -0
@@ -17,6 +17,8 @@
 #define XATTR_SIZE_MAX 65536	/* size of an extended attribute value (64k) */
 #define XATTR_LIST_MAX 65536	/* size of extended attribute namelist (64k) */
 
+#define DELAYTIMER_MAX INT_MAX	/* # timer expiration overruns a POSIX.1b timer may have */
+
 #define RTSIG_MAX	  32
 
 #endif

diff -ur linux-2.5.67-ia64-hrtcore/include/linux/posix-timers.h linux-2.5.67-ia64-hrtimers/include/linux/posix-timers.h

include/linux/posix-timers.h +2 -1
@@ -25,6 +59,7 @@
 
 #define posix_bump_timer(timr) do { \
                         (timr)->it_timer.expires += (timr)->it_incr; \
-                        (timr)->it_overrun++;               \
+                        if ((timr)->it_overrun < DELAYTIMER_MAX)\
+                            (timr)->it_overrun++;               \
                        }while (0)
 #endif
Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
author
#2 lore raw
Quoted 8 lines · george anzinger
Quoted 6 lines · Eric Piel

Playing around with the posix timers I've noticed that DELAYTIMER_MAX is not defined. This constant is specified in the POSIX specifications. It should contain the maximum possible value of overruns on a signal. It is also said that the overrun shouldn't overflow. cf
http://www.opengroup.org/onlinepubs/007904975/functions/timer_getoverrun.html

Quoted 5 lines
Quoted 3 lines

So here is a patch to add this constant and a check that the overrun variable never overflow. It's for 2.5.67 but should apply flawlessly to 2.5.69 too.

I think this is needed in glibc. I am not sure how that relates to kernel defines.

How can the glibc do things like that? :

Quoted 6 lines

include/linux/posix-timers.h line 64

Quoted 6 lines
 #define posix_bump_timer(timr) do { \
                         (timr)->it_timer.expires += (timr)->it_incr; \
include/linux/posix-timers.h +2 -1
-                        (timr)->it_overrun++;               \
+                        if ((timr)->it_overrun < DELAYTIMER_MAX)\
+                            (timr)->it_overrun++;               \
                        }while (0)

In addition knowing that DELAYTIMER_MAX is dependant on the implementation and that the implementation is now in the kernel I think DELAYTIMER_MAX should be defined by the kernel. Then glibc can do its usual trick of stealing all the constant from the kernel...

Eric

#3 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 5 lines · Eric Piel
Quoted 5 lines
Quoted 5 lines

Playing around with the posix timers I've noticed that DELAYTIMER_MAX is not defined. This constant is specified in the POSIX specifications. It should contain the maximum possible value of overruns on a signal. It is also said that the overrun shouldn't overflow. cf
http://www.opengroup.org/onlinepubs/007904975/functions/timer_getoverrun.html

This is not correct. The constant does not have to be defined. Like all the various *_MAX constants they only have to be defined if there is a fixed limit the implementation has. If there is none or it can only be defined dynamically at runtime the the macro must not be defined. Instead sysconf() can provide the value. But not even this is necessary. sysconf() can return -1.

Anyway, in this specific case the implementation should be protected against the ever so improbable overflow of the counter, yes. If you want a fixed value, fine. If you want to use ULONG_MAX (or whatever), good too. Whether we advertise this limit is another thing. Advertising it in the macro means it never can be changed.

- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+uLpr2ijCOnn/RHQRAgiAAKCIj4hn7m/lkOIrLjHjqirTFPfvhQCeLbxB cl9pJ+BTHy7VQzpCDeyjmSs=
=WTUD
-----END PGP SIGNATURE-----

author
#4 lore raw
Quoted 6 lines · Ulrich Drepper

This is not correct. The constant does not have to be defined. Like all the various *_MAX constants they only have to be defined if there is a fixed limit the implementation has. If there is none or it can only be defined dynamically at runtime the the macro must not be defined. Instead sysconf() can provide the value. But not even this is necessary. sysconf() can return -1.

Sorry, I wasn't aware about this POSIX rule, thank you for pointing out this. Knowing that it would obviously be better providing support of the constant _SC_DELAYTIMER_MAX for sysconf() and return a value.

This would imply there is now some job for glibc. However it's still unclear for me how the glibc would know about wich value it should return while this question would be so easy to answer for the kernel! Also AFAIK, right now, only the NPTL supports the new syscalls for the timers (and none supports the clocks syscalls). Does it mean a special __sysconf() is necessary in the NPTL? Well, probably that's why you suggested -1 as a return value I guess :-)

Quoted 7 lines

Anyway, in this specific case the implementation should be protected against the ever so improbable overflow of the counter, yes. If you want a fixed value, fine. If you want to use ULONG_MAX (or whatever), good too. Whether we advertise this limit is another thing. Advertising it in the macro means it never can be changed.

You are right also here, of course with this point of view it's better not putting any constant.
So the patch could become something like that: ?

include/linux/posix-timers.h 2003-05-06 16:07:56.000000000 +0200 renamed from include/linux/posix-timers.h 2003-04-22 11:10:44.000000000 +0200 +2 -1
diff -ur linux-2.5.67-ia64-hrtcore/include/linux/posix-timers.h linux-2.5.67-ia64-hrtimers/include/linux/posix-timers.h
@@ -25,6 +59,7 @@
 
 #define posix_bump_timer(timr) do { \
                         (timr)->it_timer.expires += (timr)->it_incr; \
-                        (timr)->it_overrun++;               \
+                        if ((timr)->it_overrun < INT_MAX)\
+                            (timr)->it_overrun++;               \
                        }while (0)
 #endif

Eric

#5 lore raw

I would like to give some thought to setting this value rather low, say 1000 or so. The issue is that the update to the expire time is done by adding the timer increment repeatedly until a time that has not yet passed is found. THIS TAKES TIME and it is done under an irq spin_lock! I do think we should limit the time in this loop and, also, possibly finding a way to do it with out holding the spin_lock, so that other tasks could at least preempt the caller. (As it is, it already done in the callers task and not in an interrupt context.)

This, of course, also says that we should not only limit the value of overrun, but also do something different when it happens.

-g

Quoted 47 lines · Eric Piel
Quoted 6 lines · Ulrich Drepper

This is not correct. The constant does not have to be defined. Like all the various *_MAX constants they only have to be defined if there is a fixed limit the implementation has. If there is none or it can only be defined dynamically at runtime the the macro must not be defined. Instead sysconf() can provide the value. But not even this is necessary. sysconf() can return -1.

Sorry, I wasn't aware about this POSIX rule, thank you for pointing out this. Knowing that it would obviously be better providing support of the constant _SC_DELAYTIMER_MAX for sysconf() and return a value.

This would imply there is now some job for glibc. However it's still
unclear for me how the glibc would know about wich value it should return while this question would be so easy to answer for the kernel! Also AFAIK, right now, only the NPTL supports the new syscalls for the
timers (and none supports the clocks syscalls). Does it mean a special
__sysconf() is necessary in the NPTL? Well, probably that's why you suggested -1 as a return value I guess :-)

Quoted 6 lines

Anyway, in this specific case the implementation should be protected against the ever so improbable overflow of the counter, yes. If you want a fixed value, fine. If you want to use ULONG_MAX (or whatever), good too. Whether we advertise this limit is another thing. Advertising it in the macro means it never can be changed.

You are right also here, of course with this point of view it's better not putting any constant.
So the patch could become something like that: ?

diff -ur linux-2.5.67-ia64-hrtcore/include/linux/posix-timers.h linux-2.5.67-ia64-hrtimers/include/linux/posix-timers.h

include/linux/posix-timers.h 2003-05-06 16:07:56.000000000 +0200 renamed from include/linux/posix-timers.h 2003-04-22 11:10:44.000000000 +0200 +2 -1
@@ -25,6 +59,7 @@
 
 #define posix_bump_timer(timr) do { \
                         (timr)->it_timer.expires += (timr)->it_incr; \
-                        (timr)->it_overrun++;               \
+                        if ((timr)->it_overrun < INT_MAX)\
+                            (timr)->it_overrun++;               \
                        }while (0)
 #endif

Eric

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#6 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 2 lines · george anzinger

This, of course, also says that we should not only limit the value of overrun, but also do something different when it happens.

That's legitimate and in this case we perhaps should publish this lower value since it can be limiting. Since real work is involved in having higher values this constiutes another possible DoS in the code and has to be resolved.

- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+uU6P2ijCOnn/RHQRAralAJ43h7EBj8sqm2QmmdTGXwBiAL9LUQCgignS Lu4ITL+4lDmZXoK0BR8UFLU=
=DKUl
-----END PGP SIGNATURE-----

#7 lore raw
Quoted 6 lines · Ulrich Drepper

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

george anzinger wrote:

Quoted 8 lines
Quoted 2 lines

This, of course, also says that we should not only limit the value of overrun, but also do something different when it happens.

That's legitimate and in this case we perhaps should publish this lower value since it can be limiting. Since real work is involved in having higher values this constitutes another possible DoS in the code and has to be resolved.

As soon as I get a few other fires under control, I will be working on this and the limit on number of timers issue. Andrew Morton suggested an rlimit for that. Perhaps that is what should be used here also.

Seem reasonable?

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#8 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 4 lines · george anzinger

Andrew Morton suggested
an rlimit for that. Perhaps that is what should be used here also.

Seem reasonable?

For this as well? We are getting an awful lot of these it seems.

The DELAYTIMER_MAX thing probably can be hardcoded. I can see no harm in limiting it to 1000 or so. The number of timers can be handled via rlimit.

- --
- --------------. ,-. 444 Castro Street
Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA
Red Hat --' drepper at redhat.com ---------------------------
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+uViH2ijCOnn/RHQRApl3AKC6l4zZMsn7SaiGSw6hb9KZpc5cQACgm1NW 09sC2WWGZsw1QAUxcTjo8rI=
=Nafv
-----END PGP SIGNATURE-----