中断处理过程:
reg value–>irq(int) —> struct irq_desc
1 | ==> 中断时的有一个寄存器会保存中断源的vector值. |
注:这里的handle_irq不是真正的中断处理函数,而是几大类中断控制器处理函数.
如82599, msi等.
`do_IRQ(struct pt_regs *regs)
File: arch/x86/kernel/irq.c
arch/x86/kernel/entry_64.S
will call do_IRQ
reg value–>irq(int) —> struct irq_desc
1 | ==> 中断时的有一个寄存器会保存中断源的vector值. |
注:这里的handle_irq不是真正的中断处理函数,而是几大类中断控制器处理函数.
如82599, msi等.
File: arch/x86/kernel/irq.c
arch/x86/kernel/entry_64.S
will call do_IRQ
A delayed work will first start a timer,
and when timeout, the delayed work will be put a worker_pool‘sworklist or a pool_workqueue‘s delayed_works
1 | 113 struct delayed_work { |
###Summary
The struct worker is the really scheudle unit in workqueue.
Each struct worker has a corresponding thread(task) by worker->task.
A struct worker is linked to struct worker_pool->idle_list when work is idle.
and moved to struct worker_pool->busy_hash.
worker_threadworker from pool->idle_list and clear worker ‘s WORKER_IDLE flag.pool and manage the workers(create/destory)Iterate all the `struct work_struct *work` in the `struct worker_pool->worklist`,
and run them in sequence with process_one_work(worker, work);.worker into idle list again.garbage collection is a common method used in kernel.
When a object(struct,memeory) become invalid, we need
free them, but the object maybe reference by others.
such as a dst_entry is not invalid, and it is still
referenced(used) by others.
then __dst_free will be called for this case.
It will first set dst to dirty(dead),
and then put it into dst_garbage.list by dst->next.
Then a workqueue task will check the dst‘s reference,
and free(destory) it when no reference on it.
Two key struct struct dst_garbage and dst_gc_work
We think it as a ideal and simple case:
1 | > dev_queue_xmit |
In struct Qdisc, there are two similar fileds.
running flag is stored in __state of struct Qdisc, NOT state.
Every time, when we send a packet from qdisc, the running flag is
set by qdisc_run_begin, and after that, it is removed by qdisc_run_end.
1 | 84 unsigned long state; |
why need busylock?
In this part, only the framework is prepared for qdisc,
and the noop_qdisc is set as default.
netdev_queues.for example: intel igb hardware has 8 hardware tx queue,
and nic driver create 8 corresponding struct netdev_queue
in the _tx of struct net_device.
mq_qdiscThe mq_qdisc is attached to the corresponding device.
In mq_qdisc private field, a default qdisc will be
create for each NIC’s hardware queue.
This is done in mq_init.
The default qdisc is pfifo_fast_ops.
mq_qdisc to netdev_queue.In mq_attach, these qdiscs are attatched to correspondingstruct netdev_queue.
Here only trace with the case mq_qdisc.
When dev is up, dev_open is called, which will call dev_activate.
###Qdisc_ops is the core of a Qdisc.
All kinds of the Qdisc_ops are linked in a list by qdisc_base.
The key item of different Qdisc_ops is id[IFNAMSIZ].
Note: the list is a Singly-linked list, not a common list of kernel.
1 | 158 struct Qdisc_ops { |
qdisc_base1 | 134 /* The list of all installed queueing disciplines. */ |