【发布时间】:2012-04-19 20:25:02
【问题描述】:
sk_buff有两个地方可以存放下一个分片数据:
skb_shinfo(head)->frag_list
skb_shinfo(head)->frags[]
请有人解释一下这两种处理碎片的方法之间的区别。
感谢和最好的问候!
【问题讨论】:
标签: linux linux-kernel linux-device-driver fragmentation
sk_buff有两个地方可以存放下一个分片数据:
skb_shinfo(head)->frag_list
skb_shinfo(head)->frags[]
请有人解释一下这两种处理碎片的方法之间的区别。
感谢和最好的问候!
【问题讨论】:
标签: linux linux-kernel linux-device-driver fragmentation
skb_shinfo(head)->frags[]
如果网卡支持SG I/O__ip_append_data会拷贝用户空间数据到skb_shinfo(head)->frags。 NIC 驱动程序(例如 ixgbe_add_rx_frag)也可以使用这些 frags[] 来承载接收到的网络流量;请注意,frags[] 中的每个内容都是完整数据包的一部分。一个完整的数据包由所有frags[] + (skb->data ~ skb->tail)组成。
skb_shinfo(head)->frag_list
IP 分片不直接使用该成员。 在__ip_make_skb()中,frag_list用于收集来自sk->sk_write_queue的所有skb;一些 NIC 驱动程序也使用这个 frag_list 将数据包传送到上层网络堆栈。 frag_list 中的每个 content/skb 也不是一个 complete 数据包; tcp_v4_send_ack -> ip_send_unicast_reply -> ip_push_pending_frames -> ip_finish_skb ->__ip_make_skb;
【讨论】:
两者用于不同的情况。
碎片[]
如果您的设备支持分散-收集 I/O,并且您希望它进行数据组合等。您可以填充 frags[] 结构,从第 2 个片段开始直到第 n 个片段。第一个片段始终由data 和tail 指针指定。其余的片段填充在frags[] 结构中。如果不使用 scatter gather,则此变量为空。
frag_list
这是 IP 片段列表。这将在ip_push_pending_frames 期间填写。
说你的sk_buffs 在这个安排中
sk_buff0->next = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn
ip_push_pending_frames 被调用后
sk_buff0->frag_list = sk_buff1
sk_buff1->next = sk_buff2
...
sk_buffn-1->next = sk_buffn
简单地说
frags[] 用于分散收集 i/o 缓冲区frag_list 用于 ip 片段【讨论】: