summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Ignacio Naranjo Hernández <joseignacio.naranjo@gmail.com>2010-01-14 18:10:10 +0100
committerThomas Graf <tgraf@suug.ch>2010-03-10 16:18:54 +0100
commit52d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0 (patch)
tree07e18539be867fe1ed8c09af1c52962d4cd392e1
parentcafdaa4e065a2ee658d7e361158100f4c7abe445 (diff)
downloadandroid_external_libnl-52d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0.tar.gz
android_external_libnl-52d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0.tar.bz2
android_external_libnl-52d6b8b9ee21b4bc112cc8a5d6f440536dd7fde0.zip
Fix a bug when calculating ticks_per_usec
I've noticed a wrong behavior when setting up some delays in a netem qdisc. I will try to make the things easier for the reader describing the calls path. To set up a delay (or jitter...) I use 'rtnl_netem_set_delay' which requires an int parameter that tells the delay in micro seconds. Inside this func, the delay is set up with the help of 'nl_us2ticks', which is just an arithmetic operation (us * ticks_per_usec), where us is the input parameter and ticks_per_usec is a global variable initialized in 'get_psched_settings'. And here is the problem: If this variable is going to be calculated using '/proc/net/psched', I think the file scan is not done properly. I don't understand what the meaning of the asterisk is here: int r = fscanf(fd, "%08x%08x%08x%*08x", &tick, &us, &nom); if (4 == r && nom == 1000000 && !got_tick) ticks_per_usec = (double)tick/(double)us; The execution path never gets in the if statement, because r is always 3, and if the fourth parameter is read (avoiding the asterisk), there is no variable to store it in, so it comes a segv. In my opinion we can get rid of the if statement, because I think the proc psched file has always a fixed format of 4 parameters, and 'nom' is always 1000000 (http://lxr.linux.no/#linux+v2.6.32/net/sched/sch_api.c#L1678). Find attached a patch I did, if I am correct.
-rw-r--r--lib/utils.c35
1 files changed, 16 insertions, 19 deletions
diff --git a/lib/utils.c b/lib/utils.c
index 263eb38..4007bee 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -285,7 +285,7 @@ static void __init get_psched_settings(void)
{
char name[FILENAME_MAX];
FILE *fd;
- int got_hz = 0, got_tick = 0;
+ int got_hz = 0;
if (getenv("HZ")) {
long hz = strtol(getenv("HZ"), NULL, 0);
@@ -301,28 +301,25 @@ static void __init get_psched_settings(void)
if (getenv("TICKS_PER_USEC")) {
double t = strtod(getenv("TICKS_PER_USEC"), NULL);
-
ticks_per_usec = t;
- got_tick = 1;
}
+ else {
+ if (getenv("PROC_NET_PSCHED"))
+ snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED"));
+ else if (getenv("PROC_ROOT"))
+ snprintf(name, sizeof(name), "%s/net/psched",
+ getenv("PROC_ROOT"));
+ else
+ strncpy(name, "/proc/net/psched", sizeof(name) - 1);
-
- if (getenv("PROC_NET_PSCHED"))
- snprintf(name, sizeof(name), "%s", getenv("PROC_NET_PSCHED"));
- else if (getenv("PROC_ROOT"))
- snprintf(name, sizeof(name), "%s/net/psched",
- getenv("PROC_ROOT"));
- else
- strncpy(name, "/proc/net/psched", sizeof(name) - 1);
-
- if ((fd = fopen(name, "r"))) {
- uint32_t tick, us, nom;
- int r = fscanf(fd, "%08x%08x%08x%*08x", &tick, &us, &nom);
-
- if (4 == r && nom == 1000000 && !got_tick)
+ if ((fd = fopen(name, "r"))) {
+ uint32_t tick, us;
+ /* the file contains 4 hexadecimals, but we just use
+ the first two of them */
+ int r = fscanf(fd, "%08x %08x", &tick, &us);
ticks_per_usec = (double)tick/(double)us;
-
- fclose(fd);
+ fclose(fd);
+ }
}
}