Skip to contentSkip to conversation

Question about QOS

DISCUSSION Applied Nicolas DICHTEL 4 participants 10 messages Apr 26, 2005 – May 3, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

I set CONFIG_NET_SCH_CLK_GETTIMEOFDAY in my kernel. The macro PSCHED_TDIFF_SAFE calculates the difference between two timestamps and uses the function psched_tod_diff() to do this. If the clock is readjusted (due to ntp for example), this function can return a negative number (if bound > 1000000) and then the flow is blocked by the kernel. Am I right ? or I miss something ? Is this a bug ?

Thanks
Nicolas

#1 lore raw

* Nicolas DICHTEL <[email protected]> 2005-04-26 11:16

Quoted 8 lines

I set CONFIG_NET_SCH_CLK_GETTIMEOFDAY in my kernel. The macro PSCHED_TDIFF_SAFE calculates
the difference between two timestamps and uses the function psched_tod_diff() to do this.
If the clock is readjusted (due to ntp for example), this function can return a negative number
(if bound > 1000000) and then the flow is blocked by the kernel. Am I right ?

do_gettimeofday takes care of ntp adjustments so we _should_ be safe, however, it might be wise to enforce a range of 0..bound instead of INT_MIN..bound because qdiscs like red are relying on this. Assuming we have a delta of -4 seconds and return -4e6 red will horribly crash when acccessing the array with idle_time>>cell_log.

#2 lore raw
Quoted 10 lines · Thomas Graf

* Nicolas DICHTEL <[email protected]> 2005-04-26 11:16

Quoted 6 lines

I set CONFIG_NET_SCH_CLK_GETTIMEOFDAY in my kernel. The macro PSCHED_TDIFF_SAFE calculates the difference between two timestamps and uses the function psched_tod_diff() to do this. If the clock is readjusted (due to ntp for example), this function can return a negative number (if bound > 1000000) and then the flow is blocked by the kernel. Am I right ?

Quoted 8 lines

do_gettimeofday takes care of ntp adjustments so we _should_ be safe, however, it might be wise to enforce a range of 0..bound instead of INT_MIN..bound because qdiscs like red are relying on this. Assuming we have a delta of -4 seconds and return -4e6 red will horribly crash when acccessing the array with idle_time>>cell_log.

You can have the same kind of problem with a ingress filter. I propose the following patch to fix the range to 0..bound

[SCHED] Fix range in psched_tod_diff() to 0..bound

include/net/pkt_sched.h +1 -1
diff -Nru linux-2.6-a/include/net/pkt_sched.h linux-2.6-b/include/net/pkt_sched.h
@@ -140,7 +140,7 @@
 	if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
 		return bound;
 	delta = delta_sec * 1000000;
-	if (delta > bound)
+	if (delta > bound || delta < 0)
 		delta = bound;
 	return delta;
 }
#3 lore raw

* Nicolas DICHTEL <[email protected]> 2005-04-26 16:57

Quoted 12 lines

You can have the same kind of problem with a ingress filter. I propose the following patch to fix the range to 0..bound

[SCHED] Fix range in psched_tod_diff() to 0..bound

diff -Nru linux-2.6-a/include/net/pkt_sched.h linux-2.6-b/include/net/pkt_sched.h

include/net/pkt_sched.h line 146

Quoted 8 lines
include/net/pkt_sched.h +1 -1
@@ -140,7 +140,7 @@
 	if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
 		return bound;
 	delta = delta_sec * 1000000;
-	if (delta > bound)
+	if (delta > bound || delta < 0)
 		delta = bound;
 	return delta;
 }

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?

#4 lore raw
Quoted 14 lines

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

You're right. Here is the new patch.

[SCHED] Fix range in PSCHED_TDIFF_SAFE to 0..bound

include/net/pkt_sched.h +3 -2
diff -Nru linux-2.6-a/include/net/pkt_sched.h linux-2.6-b/include/net/pkt_sched.h
@@ -140,7 +140,7 @@
 	if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
 		return bound;
 	delta = delta_sec * 1000000;
-	if (delta > bound)
+	if (delta > bound || delta < 0)
 		delta = bound;
 	return delta;
 }
@@ -156,7 +156,8 @@
 		   __delta += 1000000; \
 	   case 1: \
 		   __delta += 1000000; \
-	   case 0: ; \
+	   case 0: \
+		   __delta = abs(__delta); \
 	   } \
 	   __delta; \
 })
#5 lore raw

* Nicolas DICHTEL <[email protected]> 2005-04-27 09:44

Quoted 9 lines
Quoted 9 lines

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?

Quoted 5 lines

You're right. Here is the new patch.

[SCHED] Fix range in PSCHED_TDIFF_SAFE to 0..bound

Quoted 22 lines

diff -Nru linux-2.6-a/include/net/pkt_sched.h linux-2.6-b/include/net/pkt_sched.h

include/net/pkt_sched.h +3 -2
@@ -140,7 +140,7 @@
 	if (bound <= 1000000 || delta_sec > (0x7FFFFFFF/1000000)-1)
 		return bound;
 	delta = delta_sec * 1000000;
-	if (delta > bound)
+	if (delta > bound || delta < 0)
 		delta = bound;
 	return delta;
 }
@@ -156,7 +156,8 @@
 		   __delta += 1000000; \
 	   case 1: \
 		   __delta += 1000000; \
-	   case 0: ; \
+	   case 0: \
+		   __delta = abs(__delta); \
 	   } \
 	   __delta; \
 })
maintainer Applied
#6 lore raw
Quoted 10 lines · On Wed, 27 Apr 2005 13:42:16 +0200 Thomas Graf <[email protected]> wrote:

* Nicolas DICHTEL <[email protected]> 2005-04-27 09:44

Quoted 9 lines
Quoted 9 lines

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?

Quoted 7 lines
Quoted 5 lines

You're right. Here is the new patch.

[SCHED] Fix range in PSCHED_TDIFF_SAFE to 0..bound

Applied, thanks everyone.

#7 lore raw
In reply to Thomas Graf
Quoted 9 lines · Thomas Graf

* Nicolas DICHTEL <[email protected]> 2005-04-27 09:44

Quoted 7 lines
Quoted 7 lines

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?

Why abs(delta)? It could be above bound, in fact all cases besides delta_sec > 2 doesn't take care to stay inside [0..bound] at all.

[PKT_SCHED]: Fix range in PSCHED_TDIFF_SAFE to 0..bound

---
commit d5f65671be760f33c1c7667f793ed75ad6e6a710 tree 4af3018396f125b0c2601882d924e63a0d74bef4 parent 980207c270e72e2cc6ae7b0de6ea6cd38a726e5b author Patrick McHardy <[email protected]> 1114776755 +0200 committer Patrick McHardy <[email protected]> 1114776755 +0200

include/net/pkt_sched.h (mode:100644 sha1:fcb05a387dbee560d6a0f20b6e8c3c4f1b2d93f1) renamed from include/net/pkt_sched.h (mode:100644 sha1:7352e455053cc857e70f0cb1e008eb7adabbe011) +2 -1
Index: include/net/pkt_sched.h
===================================================================
@@ -157,7 +157,8 @@
 	   case 1: \
 		   __delta += 1000000; \
 	   case 0: \
-		   __delta = abs(__delta); \
+ 		   if (__delta > bound || __delta < 0) \
+ 			__delta = bound; \
 	   } \
 	   __delta; \
 })
#8 lore raw

* Patrick McHardy <[email protected]> 2005-04-29 14:16

Quoted 2 lines

Why abs(delta)? It could be above bound, in fact all cases besides delta_sec > 2 doesn't take care to stay inside [0..bound] at all.

Doh, of course. Absolutely correct.

maintainer Applied
#9 lore raw
In reply to Patrick McHardy
Quoted 11 lines · On Fri, 29 Apr 2005 14:16:50 +0200 Patrick McHardy <[email protected]> wrote:
Quoted 9 lines · Thomas Graf

* Nicolas DICHTEL <[email protected]> 2005-04-27 09:44

Quoted 7 lines
Quoted 7 lines

Yes I agree, it doesn't really matter what value we return and `bound' is most likely to be correct. I think we should also fix the unlikely but still possible case when tv1.tv_usec is slightly smaller than tv2.tv_usec. I know it is very unlikely but do_gettimeofday really is not that reliable and we have users which rely on a positive delta. Can you extend your patch to return abs(delta) for case 0 in PSCHED_TDIFF_SAFE?

Quoted 2 lines

Why abs(delta)? It could be above bound, in fact all cases besides delta_sec > 2 doesn't take care to stay inside [0..bound] at all.

Applied, thanks Patrick.