Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329492
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: LINUX

2013-08-06 14:55:07

kernel:linux-2.6.18

net_rx接收处理函数触发软中断,负责下半部处理的软中断函数net_rx_action函数将会被执行。


点击(此处)折叠或打开

  1. static int __init net_dev_init(void)
  2. {
  3. .
  4.        open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
  5.        open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
  6. .
  7. }


net_rx_action负责从当前CPU中获取softnet_data,处理poll_list上的dev,调用dev->poll()对网络数据进行真正处理。

点击(此处)折叠或打开

  1. # define jiffies raid6_jiffies()

  2. static inline uint32_t raid6_jiffies(void)
  3. {
  4. struct timeval tv;
  5. gettimeofday(&tv, NULL);
  6. return tv.tv_sec*1000 + tv.tv_usec/1000;
  7. }

  8. static void net_rx_action(struct softirq_action *h)
  9. {
  10. struct softnet_data *queue = &__get_cpu_var(softnet_data);
  11. unsigned long start_time = jiffies;
  12. int budget = netdev_budget;
  13. void *have;


  14. local_irq_disable();


  15. /*
  16. * __netif_rx_schedule函数中进行的挂链操作
  17. * list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
  18. */
  19. while (!list_empty(&queue->poll_list)) {
  20. struct net_device *dev;

  21. /*
  22. (jiffies - start_time>1)保证执行当前的 POLL 过程的时间不超过一个时间片,
  23. 不被软中断占用太多的时间,这样在一次调度的时间内执行完毕当前的 POLL 过程。
  24. budget 表示一个时间片内最大数据传输的"块数",
  25. 块的意思为每个 POLL 所完成sk_buff数量,
  26. 每块中间的 sk_buff 数量为 dev->quota 决定,
  27. 在 8139CP 驱动中,budget 为 300,
  28. 而 quota 为 16 表示每给时间片最多可以接收到 4.8K 的 sk_buff 数量
  29. */
  30. if (budget <= 0 || jiffies - start_time > 1)
  31. goto softnet_break;


  32. local_irq_enable();


  33. /*
  34. * 取出设备
  35. * 比如在netif_rx_schedule(&queue->backlog_dev)中,dev就是backlog_dev,
  36. */
  37. dev = list_entry(queue->poll_list.next,
  38. struct net_device, poll_list);
  39. have = netpoll_poll_lock(dev);
  40. /*
  41. * 调用dev->poll()进行数据真正处理
  42. * poll 指针在net_dev_init默认指向process_backlog()
  43. *
  44. */
  45. if (dev->quota <= 0 || dev->poll(dev, &budget)){
  46. netpoll_poll_unlock(have);
  47. local_irq_disable();
  48. list_move_tail(&dev->poll_list, &queue->poll_list);
  49. /*完成一次POLL过程的数据的接收,重新定义设备接收数据的"配额"(事实上就是sk_buff缓冲区的数量,每次调用POLL方法的时候可以创建并且最多可以向上层提交的sk_buff缓冲区数目,这个参数很重要在高速处理的时候有需要慎重优化这个数值,在有大量数据接收的情况下,需要增加该数值)*/
  50. if (dev->quota < 0)
  51. dev->quota += dev->weight;
  52. else
  53. dev->quota = dev->weight;
  54. } else {
  55. netpoll_poll_unlock(have);
  56. dev_put(dev);
  57. local_irq_disable();
  58. }
  59. }
  60. out:
  61. local_irq_enable();
  62. return;


  63. softnet_break:
  64. __get_cpu_var(netdev_rx_stat).time_squeeze++;
  65. __raise_softirq_irqoff(NET_RX_SOFTIRQ);
  66. goto out;
  67. }

参考文档:
http://www.ibm.com/developerworks/cn/linux/l-napi/index.html?ca=dwcn-newsletter-linux
阅读(4875) | 评论(0) | 转发(2) |
0

上一篇:netif_rx函数

下一篇:process_backlog函数

给主人留下些什么吧!~~