dev_cpu_dead

Kernel: 4.12.6

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

 1 static int dev_cpu_dead(unsigned int oldcpu)
 2 {
 3     struct sk_buff **list_skb;
 4     struct sk_buff *skb;
 5     unsigned int cpu;
 6     struct softnet_data *sd, *oldsd, *remsd = NULL;
 7
 8     //禁用本地中断
 9     local_irq_disable();
10     //获取当前cpu
11     cpu = smp_processor_id();
12     //找到sd
13     sd = &per_cpu(softnet_data, cpu);
14     //原sd
15     oldsd = &per_cpu(softnet_data, oldcpu);
16
17     /* Find end of our completion_queue. */
18     //找到当前cpu完成队列尾部
19     list_skb = &sd->completion_queue;
20     while (*list_skb)
21         list_skb = &(*list_skb)->next;
22     /* Append completion queue from offline CPU. */
23     //将旧cpu队列连接到当前cpu队列尾部
24     *list_skb = oldsd->completion_queue;
25     oldsd->completion_queue = NULL;
26
27     /* Append output queue from offline CPU. */
28     //将旧cpu的outputqueue挂到当前cpu尾部
29     if (oldsd->output_queue) {
30         *sd->output_queue_tailp = oldsd->output_queue;
31         sd->output_queue_tailp = oldsd->output_queue_tailp;
32         oldsd->output_queue = NULL;
33         oldsd->output_queue_tailp = &oldsd->output_queue;
34     }
35     /* Append NAPI poll list from offline CPU, with one exception :
36      * process_backlog() must be called by cpu owning percpu backlog.
37      * We properly handle process_queue & input_pkt_queue later.
38      */
39     //将napi poll list挂到当前cpu poll list尾部
40     while (!list_empty(&oldsd->poll_list)) {
41         struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
42                                 struct napi_struct,
43                                 poll_list);
44
45         list_del_init(&napi->poll_list);
46         if (napi->poll == process_backlog)
47             napi->state = 0;
48         else
49             ____napi_schedule(sd, napi);
50     }
51
52     //触发发送软中断
53     raise_softirq_irqoff(NET_TX_SOFTIRQ);
54
55     //启用中断
56     local_irq_enable();
57
58 #ifdef CONFIG_RPS
59     remsd = oldsd->rps_ipi_list;
60     oldsd->rps_ipi_list = NULL;
61 #endif
62     /* send out pending IPI‘s on offline CPU */
63     net_rps_send_ipi(remsd);
64
65     /* Process offline CPU‘s input_pkt_queue */
66     //把process_queue和input_queue中的skb添加到当前cpu的backlog中
67     while ((skb = __skb_dequeue(&oldsd->process_queue))) {
68         netif_rx_ni(skb);
69         input_queue_head_incr(oldsd);
70     }
71     while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
72         netif_rx_ni(skb);
73         input_queue_head_incr(oldsd);
74     }
75
76     return 0;
77 }
时间: 2024-10-17 21:39:49

dev_cpu_dead的相关文章

__init net_dev_init

Kernel: 4.12.6 网络设备初始化,主要包括初始化softnet_data,注册收发包软中断等: 1 static int __init net_dev_init(void) 2 { 3 int i, rc = -ENOMEM; 4 5 BUG_ON(!dev_boot_phase); 6 7 //初始化统计信息的proc文件 8 if (dev_proc_init()) 9 goto out; 10 11 //初始化kobject 12 if (netdev_kobject_init