linux kernel 工程师
全部博文(99)
分类: LINUX
2014-02-13 17:57:30
有两个时机将会调用__qdisc_run()
1.__dev_xmit_skb(), 这是在进程环境下
2. 软中断NET_TX_SOFTIRQ对应net_tx_action函数里, 软中断上下文
调用__qdisc_run之前需要获得qdisc->q.lock这个spin_lock, 之后释放这个lock
另外调用__qdisc_run之前需要设置__QDISC___STATE_RUNNING标志
void __qdisc_run(struct Qdisc *q)
{
int quota = weight_p;
while (qdisc_restart(q)) {
// qdisc_restart才是真正的核心
// 如果qdisc_restart返回值大于0,表示队列非空;返回0表示队列空了或者发送失败
/*
* Ordered by possible occurrence: Postpone processing if
* 1. we've exceeded packet quota
* 2. another process needs the CPU;
*/
//每次__qidisc_run都会考虑使用一个配额,保证不会占用太多时间
// need_resched判断如果有任务需要调度。need_resched应当是在进程环境运行时才有效吧?
if (--quota <= 0 || need_resched()) {
__netif_schedule(q); // 调度softirq, 下次softirq时继续处理
break;
}
}
qdisc_run_end(q); // 标志qdisk is not running
}