可能使用net_device取消引用私有数据

时间:2014-06-24 07:32:16

标签: linux linux-kernel kernel linux-device-driver

我有一个关于在linux内核中使用net_device模块的具体问题 让我们解决这个code example

当我启动我的设备时,我调用alloc_netdev并为其提供私有数据大小,因此它将正确分配它。

现在,当我希望停止使用此设备时,当我调用snull_cleanup时会发生什么。我认为它基本上是免费的结构(包括私人数据) 问题是,如果当前运行的代码是我的设备模块中的内部函数,该函数使用由cally netdev_priv()获取的私有数据,对私有数据的引用,以及所有突然我在内核中获得上下文切换-space to snull_cleanup函数 - 释放私有数据。

然后,当将上下文切换回保存对私有数据的引用的函数时,我不会获得对释放结构的引用吗?

如果你能为我解决这个问题,我会很高兴,谢谢

1 个答案:

答案 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本身嵌入到你的结构中,这样你的结构就会成为一个包装器。