dev_cpu_dead
2024-08-25 22:30:33
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 ;
}
最新文章
- android——自定义listView
- IOS系列swift语言之课时六
- 一个 11 行 Python 代码实现的神经网络
- 【转】Java中如何遍历Map对
- MYSQL注入天书之宽字节注入
- C++实现网格水印之调试笔记(二)
- oracle如何修改字段类型(oracle总体知识2)
- db2_errroecode
- SQL 中的常用函数及使用
- php注册、登录界面的制作
- jsp中的四个作用域,九个内置对象分别是什么?
- iOS 如果页面 A 跳转到 页面 B,A 的 viewDidDisappear 方法和 B 的 viewDidAppear 方法哪个先调用?
- stm32 修改工作频率
- 格式化 SQL 来提高效率
- CSS3实现背景透明,文字不透明
- nvm npm node.js的关系
- 用minGW编译ffmpeg(供替换opencv中引用的ffmpeg库)
- [转] .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
- Dapper扩展
- 前端--再遇jQuery
热门文章
- hdu 1688 Sightseeing (最短路径)
- bzoj2165: 大楼 (矩阵快速幂)
- POJ1741:Tree——题解+树分治简要讲解
- UOJ117:欧拉回路——题解
- AOJ.176 两数组最短距离 (乱搞题)
- MyBatis之二级缓存
- Java编程MapReduce实现WordCount
- HDU4081:Qin Shi Huang's National Road System (任意两点间的最小瓶颈路)
- TCP ------ TCP三次握手(建立连接)及其相关内容
- Leetcode:52. N-QueensII