Linux Kernel 2.6.28,struct net_device结构中添加了needed_headroom/needed_tailroom成员,为此更新了许多地方。
struct net_device
{
/*
* 硬件可能需要额外的headroom与tailroom, 但并不是所有情况下都使用这两个成员,尤其是tailroom.
* 在一些情况下不是通过分配skb,而是使用LL_MAX_HEADER.
*/
unsigned short needed_headroom;
unsigned short needed_tailroom;
}
以下是一些相关内容:
struct hh_cache
{
/* cached hardware header; allow for machine alignment needs. */
#define HH_DATA_MOD 16
#define HH_DATA_OFF(__len) \
(HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1))
#define HH_DATA_ALIGN(__len) \
(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
};
/* 必须保证以下关系成立:HH alignment <= LL alignment.
*
* LL_ALLOCATED_SPACE宏中考虑了device可能需要的tailroom.
*/
#define LL_RESERVED_SPACE(dev) \
((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
#define LL_RESERVED_SPACE_EXTRA(dev,extra) \
((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
#define LL_ALLOCATED_SPACE(dev) \
((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
为此,修改了以下文件:
af_econet.c (net\econet): skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
af_packet.c (net\packet): skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
arp.c (net\ipv4): skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
igmp.c (net\ipv4): skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
igmp.c (net\ipv4): skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
ip6_output.c (net\ipv6): if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
ipconfig.c (net\ipv4): skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
mcast.c (net\ipv6): skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
mcast.c (net\ipv6): skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
ndisc.c (net\ipv6): len + LL_ALLOCATED_SPACE(dev)),
ndisc.c (net\ipv6): len + LL_ALLOCATED_SPACE(dev)),
netdevice.h (include\linux): * LL_ALLOCATED_SPACE also takes into account the tailroom the device
netdevice.h (include\linux):#define LL_ALLOCATED_SPACE(dev) \
netpoll.c (net\core): send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
raw.c (net\ipv4): length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
raw.c (net\ipv6): length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
参考资料:
[1] Johannes Berg, allow netdevices to specify needed head/tailroom, 05 May 2008, [url]http://lwn.net/Articles/280996/[/url]
struct net_device
{
/*
* 硬件可能需要额外的headroom与tailroom, 但并不是所有情况下都使用这两个成员,尤其是tailroom.
* 在一些情况下不是通过分配skb,而是使用LL_MAX_HEADER.
*/
unsigned short needed_headroom;
unsigned short needed_tailroom;
}
以下是一些相关内容:
struct hh_cache
{
/* cached hardware header; allow for machine alignment needs. */
#define HH_DATA_MOD 16
#define HH_DATA_OFF(__len) \
(HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1))
#define HH_DATA_ALIGN(__len) \
(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
};
/* 必须保证以下关系成立:HH alignment <= LL alignment.
*
* LL_ALLOCATED_SPACE宏中考虑了device可能需要的tailroom.
*/
#define LL_RESERVED_SPACE(dev) \
((((dev)->hard_header_len+(dev)->needed_headroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
#define LL_RESERVED_SPACE_EXTRA(dev,extra) \
((((dev)->hard_header_len+(dev)->needed_headroom+(extra))&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
#define LL_ALLOCATED_SPACE(dev) \
((((dev)->hard_header_len+(dev)->needed_headroom+(dev)->needed_tailroom)&~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
为此,修改了以下文件:
af_econet.c (net\econet): skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
af_packet.c (net\packet): skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
arp.c (net\ipv4): skb = alloc_skb(arp_hdr_len(dev) + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
igmp.c (net\ipv4): skb = alloc_skb(size + LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
igmp.c (net\ipv4): skb=alloc_skb(IGMP_SIZE+LL_ALLOCATED_SPACE(dev), GFP_ATOMIC);
ip6_output.c (net\ipv6): if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
ipconfig.c (net\ipv4): skb = alloc_skb(sizeof(struct bootp_pkt) + LL_ALLOCATED_SPACE(dev) + 15,
mcast.c (net\ipv6): skb = sock_alloc_send_skb(sk, size + LL_ALLOCATED_SPACE(dev), 1, &err);
mcast.c (net\ipv6): skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
ndisc.c (net\ipv6): len + LL_ALLOCATED_SPACE(dev)),
ndisc.c (net\ipv6): len + LL_ALLOCATED_SPACE(dev)),
netdevice.h (include\linux): * LL_ALLOCATED_SPACE also takes into account the tailroom the device
netdevice.h (include\linux):#define LL_ALLOCATED_SPACE(dev) \
netpoll.c (net\core): send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev),
raw.c (net\ipv4): length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
raw.c (net\ipv6): length + LL_ALLOCATED_SPACE(rt->u.dst.dev) + 15,
参考资料:
[1] Johannes Berg, allow netdevices to specify needed head/tailroom, 05 May 2008, [url]http://lwn.net/Articles/280996/[/url]
转载于:https://blog.51cto.com/kapok/127606