6410 linux DM9000收包机制
来源:互联网 发布:win7系统无法安装软件 编辑:程序博客网 时间:2024/06/05 15:35
- 中断接收
DM9000网卡注册的中断函数为dm9000_interrupt(),该中断函数调用dm9000_rx()从网卡的buffer中读取接收到的数据,将数据接收到skb中之后,调用netif_rx()处理该数据包,最后的结果是将数据包传递给上层处理。
我们看看netif_rx()函数代码主要部分:
int netif_rx(struct sk_buff *skb){ int ret; ......#ifdef CONFIG_RPS ......#else { unsigned int qtail; ret = enqueue_to_backlog(skb, get_cpu(), &qtail); put_cpu(); }#endif return ret;}
在enqueue_to_backlog()中,通过__skb_queue_tail(&sd->input_pkt_queue, skb)将skb接入per cpu 变量softnet_data的链中。接着在enqueue_to_backlog()中调用____napi_schedule()。
if (!__test_and_set_bit(NAPI_STATE_SCHED, &sd->backlog.state)) { if (!rps_ipi_queued(sd)) { printk(KERN_INFO "skedu napi\r\n"); ____napi_schedule(sd, &sd->backlog); }}
我们进入____napi_schedule()函数看看做了什么
static inline void ____napi_schedule(struct softnet_data *sd, struct napi_struct *napi){ list_add_tail(&napi->poll_list, &sd->poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ);}
该函数将napi->poll_list加入sd->poll_list中,并置位了系统注册的软中断的第NET_RX_SOFTIRQ位。最后函数从DM9000的中断函数中返回退出。Linux中负责将skb传递给上层的函数是__netif_receive_skb(),那么该函数是怎么被调用的呢?
- 软中断处理函数net_rx_action()
当软中断被调度执行后,net_rx_action()函数会被调用。
static void net_rx_action(struct softirq_action *h){ ...... while (!list_empty(&sd->poll_list)) { ...... n = list_first_entry(&sd->poll_list, struct napi_struct, poll_list); ...... if (test_bit(NAPI_STATE_SCHED, &n->state)) { work = n->poll(n, weight); trace_napi_poll(n); } ...... if (unlikely(work == weight)) { if (unlikely(napi_disable_pending(n))) { local_irq_enable(); napi_complete(n); local_irq_disable(); } else list_move_tail(&n->poll_list, &sd->poll_list); } ......}
简化之后,该函数首先从poll_list中取出一个napi_struct ,即____napi_schedule()函数中加入到poll_list中的napi_struct,然后调用该napi_struct的poll函数。查找代码,找出poll函数指针指向的函数原型process_backlog(),在process_backlog()函数中执行__netif_receive_skb(skb)将skb传递给上层。
- 软中断什么时候被调用?
这个问题,我在网上搜了好一会儿工夫,最后发现,每次cpu执行完中断函数后,例如dm9000_interrupt()函数,在cpu退出中断asm_do_IRQ()前调用irq_exit(),在irq_exit()中执行软中断。在软中断中唤醒软中断处理任务,然后,cpu中断彻底退出,等到系统调度任务的时候,软终端所唤醒的任务得以被调度执行。具体来说,就是net_rx_action()函数。
- 6410 linux DM9000收包机制
- linux HyperV 网卡驱动收包机制
- dm9000 linux driver 问题
- linux 网络设备驱动-DM9000
- linux Dm9000 驱动分析
- linux网卡DM9000讲解
- Linux内核网卡收包机制历史变革
- S3C2416支持DM9000驱动(Linux)
- S3C2416支持DM9000驱动(Linux)
- linux设备驱动-DM9000移植
- DM9000
- DM9000
- dm9000
- DM9000
- dm9000
- dm9000
- DM9000
- DM9000
- C++对象的内存分析(6)
- ubuntu移植crypto++到Android平台
- hdu 1001 解析
- UFLDL sparse coding ICA RICA[待更]
- ubuntu下搭建android开发环境(三)ubuntu安装搜狗输入法(by 星空武哥)
- 6410 linux DM9000收包机制
- 线程的几个主要概念
- ubuntu移植libcurl到Android平台
- Android开发-Looper类介绍
- 网易内推笔试题--数字游戏
- AsyncTask对照 Thread加Handler
- Linux中sort,uniq,cut,wc命令详解
- 虚幻4 OnlineSubsystem 平台相关的支付登陆等功能
- Android基础:内存溢出和内存泄漏的区别