Kernel: 4.12.6

每个cpu都有自己的softnet_data结构,用来处理数据包接收,但是当softnet_data所在cpu无法工作时,即CPUHP_NET_DEV_DEAD状态,就需要将工作转交给其他cpu处理;

 static int dev_cpu_dead(unsigned int oldcpu)
{
struct sk_buff **list_skb;
struct sk_buff *skb;
unsigned int cpu;
struct softnet_data *sd, *oldsd, *remsd = NULL; //禁用本地中断
local_irq_disable();
//获取当前cpu
cpu = smp_processor_id();
//找到sd
sd = &per_cpu(softnet_data, cpu);
//原sd
oldsd = &per_cpu(softnet_data, oldcpu); /* Find end of our completion_queue. */
//找到当前cpu完成队列尾部
list_skb = &sd->completion_queue;
while (*list_skb)
list_skb = &(*list_skb)->next;
/* Append completion queue from offline CPU. */
//将旧cpu队列连接到当前cpu队列尾部
*list_skb = oldsd->completion_queue;
oldsd->completion_queue = NULL; /* Append output queue from offline CPU. */
//将旧cpu的outputqueue挂到当前cpu尾部
if (oldsd->output_queue) {
*sd->output_queue_tailp = oldsd->output_queue;
sd->output_queue_tailp = oldsd->output_queue_tailp;
oldsd->output_queue = NULL;
oldsd->output_queue_tailp = &oldsd->output_queue;
}
/* Append NAPI poll list from offline CPU, with one exception :
* process_backlog() must be called by cpu owning percpu backlog.
* We properly handle process_queue & input_pkt_queue later.
*/
//将napi poll list挂到当前cpu poll list尾部
while (!list_empty(&oldsd->poll_list)) {
struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
struct napi_struct,
poll_list); list_del_init(&napi->poll_list);
if (napi->poll == process_backlog)
napi->state = ;
else
____napi_schedule(sd, napi);
} //触发发送软中断
raise_softirq_irqoff(NET_TX_SOFTIRQ); //启用中断
local_irq_enable(); #ifdef CONFIG_RPS
remsd = oldsd->rps_ipi_list;
oldsd->rps_ipi_list = NULL;
#endif
/* send out pending IPI's on offline CPU */
net_rps_send_ipi(remsd); /* Process offline CPU's input_pkt_queue */
//把process_queue和input_queue中的skb添加到当前cpu的backlog中
while ((skb = __skb_dequeue(&oldsd->process_queue))) {
netif_rx_ni(skb);
input_queue_head_incr(oldsd);
}
while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
netif_rx_ni(skb);
input_queue_head_incr(oldsd);
} return ;
}

最新文章

  1. android——自定义listView
  2. IOS系列swift语言之课时六
  3. 一个 11 行 Python 代码实现的神经网络
  4. 【转】Java中如何遍历Map对
  5. MYSQL注入天书之宽字节注入
  6. C++实现网格水印之调试笔记(二)
  7. oracle如何修改字段类型(oracle总体知识2)
  8. db2_errroecode
  9. SQL 中的常用函数及使用
  10. php注册、登录界面的制作
  11. jsp中的四个作用域,九个内置对象分别是什么?
  12. iOS 如果页面 A 跳转到 页面 B,A 的 viewDidDisappear 方法和 B 的 viewDidAppear 方法哪个先调用?
  13. stm32 修改工作频率
  14. 格式化 SQL 来提高效率
  15. CSS3实现背景透明,文字不透明
  16. nvm npm node.js的关系
  17. 用minGW编译ffmpeg(供替换opencv中引用的ffmpeg库)
  18. [转] .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
  19. Dapper扩展
  20. 前端--再遇jQuery

热门文章

  1. hdu 1688 Sightseeing (最短路径)
  2. bzoj2165: 大楼 (矩阵快速幂)
  3. POJ1741:Tree——题解+树分治简要讲解
  4. UOJ117:欧拉回路——题解
  5. AOJ.176 两数组最短距离 (乱搞题)
  6. MyBatis之二级缓存
  7. Java编程MapReduce实现WordCount
  8. HDU4081:Qin Shi Huang's National Road System (任意两点间的最小瓶颈路)
  9. TCP ------ TCP三次握手(建立连接)及其相关内容
  10. Leetcode:52. N-QueensII