I have the following structures in the kernel
struct state {
/* Current algorithm iteration */
int tune_id;
/* Thread id */
pid_t tid;
#ifndef __KERNEL__
/* Paths */
char *stats_path;
char *budget_path;
char *controller_path;
#endif /* __KERNEL__ */
int budget;
/* Stats */
struct statistics prev_stats;
struct parameters current_params;
u64 cur_time;
/* Algorithm specific data */
void *data;
};
struct tuning {
struct algorithm *algorithm;
struct state *state;
struct energy energy;
};
I've defined a function tune()
as follows:
void tune(struct task_struct *task) {
struct statistics stats;
struct state *state;
get_current_stats(&stats);
state = task->tuning.state;
get_current_params(&state->current_params);
compute_energy(&stats, state);
}
The other functions are defined as:
void get_current_params(struct parameters *params)
{
printk(KERN_DEBUG "get_current_params: parameters:0x%X\n", (unsigned int) params);
params->cpu_frequency_MHZ = (cpufreq_get(0) + 500) / 1000;
params->mem_frequency_MHZ = (memfreq_get() + 500) / 1000;
}
void compute_energy(struct statistics *stats, struct state *state)
{
struct statistics *diffs;
struct frontier *frontier;
u64 energy_budget;
int threshold;
int i,j;
struct configuration s;
struct configuration emin;
#ifdef TIMING
u64 ns;
ns = get_thread_time();
#endif
#ifdef DEBUG
#ifdef __KERNEL__
printk(KERN_DEBUG "compute_energy: parameters:0x%X\n", (unsigned int) &state->current_params);
#endif /* __KERNEL__ */
#endif
}
When I call tune()
, the output is as follows:
[ 7.160139] get_current_params: parameters:0xBF396BA0
[ 7.160298] compute_energy: parameters:0xBF396B98
I don't understand why the addresses differ by 0x8
. This in turn causes a divide by 0 exception in the kernel since the struct parameters
seems to have values of 0
instead of what was initialized by get_current_params
Why is it that the address of the member current_params
of struct state
changes across function calls?
Update :
I've verified that this bug only occurs for PID 0.
Looking at include/linux/init_task.h
, I see that PID 0 is statically initialized. This is the only difference I could find between PID 0 and the other tasks. Could this somehow be responsible for the issue I'm having?
For what I can see, you are right in that both addresses should be the same. So there can only be one option: task information changes in the kernel in the meanwhile.
Considering this snippet of your code:
void tune(struct task_struct *task) {
...
struct state *state;
...
state = task->tuning.state;
You are managing two structs over which you may have no control (you should check that):
(*task): struct task_struct
and
(*task->tuning.state): struct state
So when in tune()
you call
get_current_params(&state->current_params);
compute_energy(&stats, state);
something could happen between both printk
functions, so there is where I think you have to put your focus in. Try saving task->tuning.state
before the call to get_current_params()
so you could check that it continues to be the same value after call to compute_energy()
.
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.