为什么linux内核的kref doc在kthread_运行失败时忽略kref_put
linux内核中的最新kref文档可以找到: 本文件中的第一个示例重复如下:为什么linux内核的kref doc在kthread_运行失败时忽略kref_put,linux,linux-kernel,kernel,reference-counting,Linux,Linux Kernel,Kernel,Reference Counting,linux内核中的最新kref文档可以找到: 本文件中的第一个示例重复如下: void data_release(struct kref *ref) { struct my_data *data = container_of(ref, struct my_data, refcount); kfree(data); } void more_data_handling(void *cb_data) { struct my_data *data = cb_data;
void data_release(struct kref *ref)
{
struct my_data *data = container_of(ref, struct my_data, refcount);
kfree(data);
}
void more_data_handling(void *cb_data)
{
struct my_data *data = cb_data;
.
. do stuff with data here
.
kref_put(&data->refcount, data_release);
}
int my_data_handler(void)
{
int rv = 0;
struct my_data *data;
struct task_struct *task;
data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
kref_init(&data->refcount);
kref_get(&data->refcount);
task = kthread_run(more_data_handling, data, "more_data_handling");
if (task == ERR_PTR(-ENOMEM)) {
rv = -ENOMEM;
goto out;
}
.
. do stuff with data here
.
out:
kref_put(&data->refcount, data_release);
return rv;
}
在my_data\u handler
中,kref_init()
已经将1放入refcount
,然后kref_get()
进行refcount
2。但是,如果kthread\u run
失败,则只会发生一次kref\u put
(就在out
标记之后),它会使refcount
最后变为1,并且永远不会释放数据
我还注意到,在2009年之前的文档中,有一个kref_put
在goto out
之前,但是它被一个补丁()删除了,该补丁声称这个kref_put
是重复的。你是100%正确的。
kref_init以refcount 1开始,由my_data_处理程序线程决定kref_put()的大小。
kref_get()将refcount增加到2,以便在“更多数据处理”线程中保持数据的活动状态。这是kref_put()的“更多数据处理”线程责任
在边缘情况下,线程无法打开,因此无法承担其责任,则my_data_handler()将对失败的“more_data_handling”线程和自身负责一次kref_put()
我敦促您向原始作者、删除所需kref_put的人以及内核邮件列表发送电子邮件。似乎是一个错误,我认为您可以发送一个补丁。它曾经在那里,但通过一个补丁提交明确删除,该补丁提交也是由Linus本人签署的。所以我想也许我错过了什么。看起来真的很奇怪。但就代码本身而言,如果
more\u data\u handling()
中的kref\u put
从未运行,它将泄漏。