i2c子系统的一个bug,大家鉴定下

yuanlulu 2011-06-21 04:46:58
问题是内核中用i2c_unregister_device清除i2c_new_device的影响,但是没有释放内存,会造成内存泄漏。
源码在/driver/i2c/i2c-core.c中,这两个函数的代码如下:

/**
* i2c_new_device - instantiate an i2c device
* @adap: the adapter managing the device
* @info: describes one I2C device; bus_num is ignored
* Context: can sleep
*
* Create an i2c device. Binding is handled through driver model
* probe()/remove() methods. A driver may be bound to this device when we
* return from this function, or any later moment (e.g. maybe hotplugging will
* load the driver module). This call is not appropriate for use by mainboard
* initialization logic, which usually runs during an arch_initcall() long
* before any i2c_adapter could exist.
*
* This returns the new i2c client, which may be saved for later use with
* i2c_unregister_device(); or NULL to indicate an error.
*/
struct i2c_client *
i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
struct i2c_client *client;
int status;

client = kzalloc(sizeof *client, GFP_KERNEL);
if (!client)
return NULL;

client->adapter = adap;

client->dev.platform_data = info->platform_data;

if (info->archdata)
client->dev.archdata = *info->archdata;

client->flags = info->flags;
client->addr = info->addr;
client->irq = info->irq;

strlcpy(client->name, info->type, sizeof(client->name));

/* Check for address business */
status = i2c_check_addr(adap, client->addr);
if (status)
goto out_err;

client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
client->dev.type = &i2c_client_type;

dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
client->addr);
status = device_register(&client->dev);
if (status)
goto out_err;

dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
client->name, dev_name(&client->dev));

return client;

out_err:
dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "
"(%d)\n", client->name, client->addr, status);
kfree(client);
return NULL;
}
EXPORT_SYMBOL_GPL(i2c_new_device);


/**
* i2c_unregister_device - reverse effect of i2c_new_device()
* @client: value returned from i2c_new_device()
* Context: can sleep
*/
void i2c_unregister_device(struct i2c_client *client)
{
device_unregister(&client->dev);
}
EXPORT_SYMBOL_GPL(i2c_unregister_device);


i2c_new_device主要做了两件事,一件是用kzalloc申请内存,然后初始化一通之后用device_register注册。
所以i2c_unregister_device要想消除i2c_new_device的影响必须先device_unregister,然后释放内存。可是它只做了第一步,没有释放内存。后果就是内存泄漏。
我认为是一个BUG,大家觉得呢?
PS:我的内核是2.6.34,我看了一下,2.6.39也是如此。
...全文
287 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuanlulu 2011-06-21
  • 打赏
  • 举报
回复
这应该不是一个BUG,属于自己学艺不精。 i2c_client_type->i2c_client_dev_release里释放了内存。
看来是sysfs模型没学好啊
yuanlulu 2011-06-21
  • 打赏
  • 举报
回复
大家别讨论为什么用这个函数好不好。大家就这两个函数本身说说有没有问题。
yuanlulu 2011-06-21
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 laojing123 的回复:]

引用 2 楼 yuanlulu 的回复:
引用 1 楼 cailang06 的回复:

我们通常挂IIC设备用i2c_register_driver,好像没有用到i2c_new_device,而i2c_unregister_device对应于i2c_register_driver,i2c_register_driver里面是没有申请内存的

如果你追踪i2c_register_driv……
[/Quote]
如果自己定义了i2c_driver的address_list成员,i2c-core就会调用i2c_new_device创建i2c_client.还有就是,使用i2c_register_board_info注册的设备信息也会通过i2c_new_device来创建i2c_client。
井朝天 2011-06-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yuanlulu 的回复:]
引用 1 楼 cailang06 的回复:

我们通常挂IIC设备用i2c_register_driver,好像没有用到i2c_new_device,而i2c_unregister_device对应于i2c_register_driver,i2c_register_driver里面是没有申请内存的

如果你追踪i2c_register_driver就会知道它调用了i2c_new_devic……
[/Quote]
注册一个驱动,怎么会去创建一个device呢?
yuanlulu 2011-06-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cailang06 的回复:]

我们通常挂IIC设备用i2c_register_driver,好像没有用到i2c_new_device,而i2c_unregister_device对应于i2c_register_driver,i2c_register_driver里面是没有申请内存的
[/Quote]
如果你追踪i2c_register_driver就会知道它调用了i2c_new_device,是间接调用的
cailang06 2011-06-21
  • 打赏
  • 举报
回复
我们通常挂IIC设备用i2c_register_driver,好像没有用到i2c_new_device,而i2c_unregister_device对应于i2c_register_driver,i2c_register_driver里面是没有申请内存的

4,469

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧