我有一个关于在linux内核中使用net_device模块的具体问题 让我们解决这个code example。
当我启动我的设备时,我调用alloc_netdev并为其提供私有数据大小,因此它将正确分配它。
现在,当我希望停止使用此设备时,当我调用snull_cleanup时会发生什么。我认为它基本上是免费的结构(包括私人数据) 问题是,如果当前运行的代码是我的设备模块中的内部函数,该函数使用由cally netdev_priv()获取的私有数据,对私有数据的引用,以及所有突然我在内核中获得上下文切换-space to snull_cleanup函数 - 释放私有数据。
然后,当将上下文切换回保存对私有数据的引用的函数时,我不会获得对释放结构的引用吗?
如果你能为我解决这个问题,我会很高兴,谢谢
答案 0 :(得分:1)
我最初的想法是它没有意义:它是你的私人数据所以自己处理 - 你已经分配了它,所以你必须释放它。这是私人数据的常见模式 - 例如,您可以在struct bio
中看到它。但我所看到的是一个非常肮脏的黑客。
所以,我查看了alloc_netdev代码以及我发现的内容。
您没有分配私有结构,您可以将大小传递给alloc_netdev
。如果将私有数据的大小传递给alloc_netdev
(第一个参数),那么它将分配大小:
ALIGN_OF_32( sizeof(struct net_device) + sizeof(struct snull_private) )
所以你的私人数据是struct net_device的固有部分 - 它附加在它之后
Whole struct net_device
you're working with
+-------------------------------+
| +---------------------------+ |
| | | |
| | | |
| | Actual struct net_device | |
| | | |
| | | |
| +---------------------------+ |
| | --> Your private data <-- | |
| +---------------------------+ |
| | Alignment to 32 | |
| +---------------------------+ |
+-------------------------------+
要获取私有数据,请使用netdev_priv
,只需将struct net_device
的大小添加到指针,从而获取私人数据的起始地址:
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
}
使用free_netdev
释放设备将释放包括私人数据在内的整个结构。虽然不会立即完成,但您可以在某个时间访问您的数据。
这个棘手的事情将使您的struct缓存友好,从而提高您的性能。看起来这个私有数据只在net_device的生命周期中才有意义,所以如果你想在破坏net_device后获得一些数据,你可以将net_device本身嵌入到你的结构中,这样你的结构就会成为一个包装器。