【发布时间】:2013-11-14 01:07:29
【问题描述】:
当Linux内核分配像skbuff这样的结构时,分配的数据区域(skbuff->tail - skbuff->head)是否总是一个连续的内存块,还是可以不连续?
【问题讨论】:
标签: linux networking memory memory-management kernel
当Linux内核分配像skbuff这样的结构时,分配的数据区域(skbuff->tail - skbuff->head)是否总是一个连续的内存块,还是可以不连续?
【问题讨论】:
标签: linux networking memory memory-management kernel
简答:
是的。内存范围 [skbuff->end - skbuff->head] 始终是一个连续的内存块。
长答案:
仍然可以,但是如果您的 skbuff 是碎片化的(稍后我将解释如何检查它是否是碎片化的),那么您的数据将不会位于一个连续的内存块上。请注意,[skbuff->end - skbuff->head] 范围内的数据仍然在一个连续的内存块中,但碎片化的 skbuff 并非所有数据都在[skbuff->end - skbuff->head] 范围内。
如果您想更深入地了解如何使用fragmented skbuff,那么我建议您阅读this(并从该标题开始阅读When SKB is Non Linear)。我认为那里的解释很清楚,也很形象化。
如何判断我的 skbuff 是碎片化的?
如果您不是分配 skbuff 的人,并且您想了解您正在使用的 skbuff 的数据是否碎片,您可以查看skb->data_len 的值:
skb->len。skb->len 仍然是
全帧和skb->data_len 是所有数据片段的总长度不是
计算第一个片段。您也可以只调用skb_is_nonlinear(),如果它返回true,则skbuff 是碎片化的(位于物理非连续内存上)。
奖励:
如果你收到了一个碎片化的 skbuff 并且你不能使用碎片化的 skbuff(因为你的硬件不支持它或其他一些原因),那么你可以使用函数 @ 将这个碎片化的 skbuff 重塑为一个新的 skbuff 线性 skbuff(不是碎片化的) 987654322@。但请记住,此功能将创建原始 skbuff 的副本,因此此操作将花费您...
嗯..别忘了释放原始的skbuff。
【讨论】: