- 论坛徽章:
- 0
|
本帖最后由 junnyg 于 2013-04-13 18:25 编辑
回复 2# chishanmingshen
以前看过一点RPS和RFS的资料,实现是在netif_receive_skb函数中增加目标CPU的筛选代码,并唤起目标CPU的软中断处理
netif_receive_skb(struct sk_buff *skb)
cpu = get_rps_cpu(skb->dev, skb, &rflow);根据数据包选择一个CPU
enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
sd = &per_cpu(softnet_data, cpu);得到每CPU变量softnet_data
__skb_queue_tail(&sd->input_pkt_queue, skb);将数据包加入接收队列
____napi_schedule(sd, &sd->backlog);启动backlog,结构是napi_struct- if (unlikely(tcpu != next_cpu) && /*old_cpu 与 期望cpu不一致*/
- 2371 (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || /*判断old_cpu的合法性,是否已被下线等*/
- 2372 ((int)(per_cpu(softnet_data, tcpu).input_queue_head -
- 2373 rflow->last_qtail)) >= 0)) { /* 在这里判断old_cpu上是不是已经处理该流的历史包了 */
- 2374 tcpu = rflow->cpu = next_cpu; /*如果条件都满足,则使用期望cpu,并更新rflow上的历史cpu值 */
- 2375 if (tcpu != RPS_NO_CPU)
- 2376 rflow->last_qtail = per_cpu(softnet_data, /*更新rflow上记录的历史包在目标cpu上的包处理链表上的位置 */
- 2377 tcpu).input_queue_head;
- 2378 }
- 2379 if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) {
- 2380 *rflowp = rflow;
- 2381 cpu = tcpu;
- 2382 goto done;
- 2383 }
复制代码 个人对你问题的理解:
我的疑问:
这样,只是一个软中断的包都传给同一个cpu,但是多个软中断之间的cpu是不同的?假设每个软中断都会把本轮的queue里的包处理完。
不太明白你的意思,谈下自己的理解:
1. 每个流的包都会计算出一个期望CPU
2. 由于多线程模型等因素,当前流包上一次处理的包的cpu和当前计算的期望CPU可能不一致
3. 如果一致则直接将包挂到期望CPU的软中断包处理链表上,并唤起期望CPU的软中断服务
4. 如果不一致则需要检查当前流的包在old_cpu上处理的状态,通过检查(int)(per_cpu(softnet_data, tcpu).input_queue_head - rflow->last_qtail)) 是否>= 0,意思是old_cpu链表上当前正在处理的节点位置已经超过保存的上次挂上的包的位置了,那么可以直接使用期望CPU来处理当前包了
5. 如果old_cpu还没处理到上次挂的包,那就只能把包挂到old_cpu上了,这样才能保证包的保序
|
|