Chinaunix首页 | 论坛 | 博客
  • 博客访问: 688382
  • 博文数量: 207
  • 博客积分: 1743
  • 博客等级: 上尉
  • 技术积分: 2044
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-20 14:36
文章分类

全部博文(207)

文章存档

2016年(24)

2015年(10)

2014年(50)

2013年(45)

2012年(78)

分类: LINUX

2014-06-24 14:45:00

/*

 * CPUs often take a performance hit when accessing unaligned memory

 * locations. The actual performance hit varies, it can be small if the

 * hardware handles it or large if we have to take an exception and fix it

 * in software.

 *

 * Since an ethernet header is 14 bytes network drivers often end up with

 * the IP header at an unaligned offset. The IP header can be aligned by

 * shifting the start of the packet by 2 bytes. Drivers should do this

 * with:

 *

 * skb_reserve(skb, NET_IP_ALIGN);

 *

 * The downside to this alignment of the IP header is that the DMA is now

 * unaligned. On some architectures the cost of an unaligned DMA is high

 * and this cost outweighs the gains made by aligning the IP header.

 *

 * Since this trade off varies between architectures, we allow NET_IP_ALIGN

 * to be overridden.

 */

#ifndef 

#define  2

#endif

 

以上是NET_IP_ALIGN的内核注释,位于kernel/include/linux/skbuff.h中。大意如下:

    在访问未对齐的内存时,CPU常常会有一个性能冲击,这种能冲击在硬件能处理这种不对齐时能减小到很小;而如果这种不对齐的异常只能通过软件来处理,则会对性能产生较大冲击。由于一个以太网头部为14个字节,因而网络驱动经常在一个不对齐的偏移处结束这个网络头部。为了使这个头部能字对齐,可以将网络数据包的头部前移2字节。使用如下方法:

    skb_reserve(skb, NET_IP_ALIGN);

这种偏移带来的不利在于DMA地址不对齐了。在某些架构上,这种DMA不对齐所带来的性能上的开销代价是很大的,这种代价带来的弊端远大于IP头对齐所带来的性能改善。这个是我们需要权衡的,因此我们使用一个宏来控制。

 

    我们的代码集中讨论drivers/net/usb/usbnet.c文件和drivers/net/usb/sr9700.c文件。

usbnet.c在sr9700.c上层,sr9700.c是最底层与硬件交互的代码。

 

             NET_IP_ALIGN在这里的作用是:要不使除去ip头部的14字节后的数据包4字节对齐,减轻后续软件的工作量,要不使包含头部的数据包首部4字节对齐,以利于DMA传输。

             DMA传输一般都需要目的地址为4字节对齐,而skb = alloc_skb (size + NET_IP_ALIGN, flags)所分配的内存首地址是4字节对齐的。如果不进行skb_reserve(skb, NET_IP_ALIGN);即不保留前NET_IP_ALIGN字节无效,那么skb->data指针刚好是4字节对齐,利于USB的DMA传输。如果保留前NET_IP_ALIGN字节无效,那USB的DMA的首地址就不是4字节对齐了,但是由于IP头是14字节的(6+6+2)所以,IP头后面的数据包就刚好4字节对齐了。所以这需要一个取舍。

      而我们的芯片中的USB使用的DMA现在使用的目的首地址必须是4字节边界对齐,在实现上的策略是无论传入什么地址,只是屏蔽最低2bit,后的地址作为目的地址,这就造成传入0xc80be002作为接收缓冲区的首地址,结果有效数据的头两个字节却出现在0xc80be000和0xc80be001处的原因

阅读(2443) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~