天下网吧 >> 网吧天地 >> 网吧技术 >> 网吧系统 >> 正文

Linux操作系统下网络性能优化方法简析

2013-1-24不详佚名

68127">

  Newer newer NAPI

  在最初实现的 NAPI 中,有 2 个字段在结构体 net_device 中,分别为轮询函数 poll() 和权重 weight,而所谓的 Newer newer NAPI,是在 2.6.24 版内核之后,对原有的 NAPI 实现的几次重构,其核心是将 NAPI 相关功能和 net_device 分离,这样减少了耦合,代码更加的灵活,因为 NAPI 的相关信息已经从特定的网络设备剥离了,不再是以前的一对一的关系了。例如有些网络适配器,可能提供了多个 port,但所有的 port 却是共用同一个接受数据包的中断,这时候,分离的 NAPI 信息只用存一份,同时被所有的 port 来共享,这样,代码框架上更好地适应了真实的硬件能力。Newer newer NAPI 的中心结构体是napi_struct:

  清单 5、NAPI 结构体

  /* * Structure for NAPI scheduling similar to tasklet but with weighting */ struct napi_struct { /* The poll_list must only be managed by the entity which * changes the state of the NAPI_STATE_SCHED bit. This means * whoever atomically sets that bit can add this napi_struct * to the per-CPU poll_list, and whoever clears that bit * can remove from the list right before clearing the bit. */ struct list_head poll_list; unsigned long state; int weight; int (*poll)(struct napi_struct *, int); #ifdef CONFIG_NETPOLL spinlock_t poll_lock; int poll_owner; #endif unsigned int gro_count; struct net_device *dev; struct list_head dev_list; struct sk_buff *gro_list; struct sk_buff *skb; };

  熟悉老的 NAPI 接口实现的话,里面的字段 poll_list、state、weight、poll、dev、没什么好说的,gro_count 和 gro_list 会在后面讲述 GRO 时候会讲述。需要注意的是,与之前的 NAPI 实现的最大的区别是该结构体不再是 net_device 的一部分,事实上,现在希望网卡驱动自己单独分配与管理 napi 实例,通常将其放在了网卡驱动的私有信息,这样最主要的好处在于,如果驱动愿意,可以创建多个 napi_struct,因为现在越来越多的硬件已经开始支持多接收队列 (multiple receive queues),这样,多个 napi_struct 的实现使得多队列的使用也更加的有效。

  与最初的 NAPI 相比较,轮询函数的注册有些变化,现在使用的新接口是:

  void netif_napi_add(struct net_device *dev, struct napi_struct *napi, int (*poll)(struct napi_struct *, int), int weight)

  熟悉老的 NAPI 接口的话,这个函数也没什么好说的。

  值得注意的是,前面的轮询 poll() 方法原型也开始需要一些小小的改变:

  int (*poll)(struct napi_struct *napi, int budget);

  大部分 NAPI 相关的函数也需要改变之前的原型,下面是打开轮询功能的 API:

  void netif_rx_schedule(struct net_device *dev, struct napi_struct *napi); /* …or… */ int netif_rx_schedule_prep(struct net_device *dev, struct napi_struct *napi); void __netif_rx_schedule(struct net_device *dev, struct napi_struct *napi);

  轮询功能的关闭则需要使用 :

  void netif_rx_complete(struct net_device *dev, struct napi_struct *napi);

  因为可能存在多个 napi_struct 的实例,要求每个实例能够独立的使能或者禁止,因此,需要驱动作者保证在网卡接口关闭时,禁止所有的 napi_struct 的实例。

  函数 netif_poll_enable() 和 netif_poll_disable() 不再需要,因为轮询管理不再和 net_device 直接管理,取而代之的是下面的两个函数:

  void napi_enable(struct napi *napi); void napi_disable(struct napi *napi);


本文来源:不详 作者:佚名

声明
声明:本站所发表的文章、评论及图片仅代表作者本人观点,与本站立场无关。若文章侵犯了您的相关权益,请及时与我们联系,我们会及时处理,感谢您对本站的支持!联系email:support@txwb.com,系统开号,技术支持,服务联系QQ:1175525021本站所有有注明来源为天下网吧或天下网吧论坛的原创作品,各位转载时请注明来源链接!
天下网吧·网吧天下
  • 本周热门
  • 本月热门
  • 阅读排行