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.
This commit is contained in:
parent
cafdaa4e06
commit
52d6b8b9ee
1 changed files with 16 additions and 19 deletions
35
lib/utils.c
35
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue