C kprobe,函数调度-处理器锁定-Linux内核
为了在所有处理器上运行给定的函数,我编写了一个函数。除以下情况外,它在所有情况下都能正常工作: 当我尝试在我注册的kprobe中使用它时 下面是一些代码:C kprobe,函数调度-处理器锁定-Linux内核,c,linux,linux-kernel,C,Linux,Linux Kernel,为了在所有处理器上运行给定的函数,我编写了一个函数。除以下情况外,它在所有情况下都能正常工作: 当我尝试在我注册的kprobe中使用它时 下面是一些代码: static DEFINE_MUTEX(entryMutex); static struct kretprobe my_kprobe = { .entry_handler = (kprobe_opcode_t *) NULL, .handler = (kprobe_opcode_t *) process_entry_callback, .ma
static DEFINE_MUTEX(entryMutex);
static struct kretprobe my_kprobe = {
.entry_handler = (kprobe_opcode_t *) NULL,
.handler = (kprobe_opcode_t *) process_entry_callback,
.maxactive = 1000,
.data_size = 0
};
static int driver_init(void)
{
my_kprobe.kp.addr = (kprobe_opcode_t*)kallsyms_lookup_name("sys_execve");
if ((ret = register_kretprobe(&my_kprobe)) < 0)
return -1;
return 0;
}
void foo(void* nothing)
{
printk("In foo\n");
}
static int process_entry_callback(struct kretprobe_instance* instance, struct pt_regs* regs)
{
mutex_lock(&entryMutex);
for(int i = 0; i < 4; ++i) // assumes there are 4 processors
run_func(foo, NULL, i);
mutex_unlock(&entryMutex);
return 0;
}
void run_func_wrap(struct function_data* data)
{
data->func(data->context);
wake_up_process(data->waiting_task);
*(data->condition) = TRUE;
}
void run_func(SCHEDULED_FUNC func, void *context, int processor)
{
struct function_data data;
struct task_struct* th;
BOOLEAN condition = FALSE;
wait_queue_head_t queue;
init_waitqueue_head(&queue);
data.func = func;
data.waiting_task = current;
data.context = context;
data.condition = &condition;
th = kthread_create(sched_func_wrap, &data, "th");
kthread_bind(th, processor);
wake_up_process(th);
wait_event(queue, condition);
}
可以在smp.c@Linux内核源代码中找到
而不是我的职能:
smp_call_function_single
run_func
process\u entry\u callback()
应该返回0。另外,在所有处理器上运行run_func的代码也很奇怪。对每个cpu()使用,
(中断),或者至少对每个联机的cpu()使用,
,而不是做出假设。@myaut确实如此。我认为不包含return语句将是未定义的行为。函数Ofc的末尾有一个返回0。忘了在这里添加。还有,请留下我的跑步记录。如果不在Kprobe回调中使用它,那么它的工作非常好。“睡眠”线程似乎永远不会醒来(在Kprobe中使用时)。您是否尝试使用SysRq+T?它将转储所有线程的堆栈,包括您的线程。我还认为,您应该在设置数据->条件
(否则,run\u func
可能会检查缓存值)之后添加smp\u mb()
之类的内存屏障,并将数据-/code>条件
赋值放在唤醒过程
之前(或者您可能会得到race)。或者使用比等待队列更简单的完成
。