我在内核中有以下结构
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;
};
我已经定义了一个函数tune()
,如下所示:
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);
}
其他功能定义为:
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
}
当我拨打tune()
时,输出如下:
[ 7.160139] get_current_params: parameters:0xBF396BA0
[ 7.160298] compute_energy: parameters:0xBF396B98
我不明白地址因0x8
而异的原因。
这反过来导致内核中除以0异常,因为struct parameters
似乎具有0
的值而不是get_current_params
初始化的值
为什么current_params
的成员struct state
的地址会在函数调用中发生变化?
更新:
我已经确认这个错误仅发生在PID 0上。
查看include/linux/init_task.h
,我看到PID 0已静态初始化。这是我在PID 0和其他任务之间找到的唯一区别。这可能以某种方式对我遇到的问题负责吗?
答案 0 :(得分:1)
对于我所看到的,你说得对,两个地址都应该是一样的。因此,只能有一个选项:同时内核中的任务信息发生变化。
考虑您的代码片段:
void tune(struct task_struct *task) {
...
struct state *state;
...
state = task->tuning.state;
您正在管理两个您可能无法控制的结构(您应该检查它):
(*task): struct task_struct
和
(*task->tuning.state): struct state
所以当你在tune()
打电话时
get_current_params(&state->current_params);
compute_energy(&stats, state);
两个printk
函数之间可能会发生某些事情,所以我认为你必须把重点放在哪里。
尝试在致电task->tuning.state
之前保存get_current_params()
,这样您就可以在致电compute_energy()
后检查它是否仍然是相同的值。
希望这有帮助。