內核軟中斷的延遲執行

 1  static int ksoftirqd(void * __bind_cpu)
 2 362 {
 3 363         int bind_cpu = (int) (long) __bind_cpu;
 4 364         int cpu = cpu_logical_map(bind_cpu);
 5 365 
 6 366         daemonize();
 7 367         current->nice = 19;
 8 368         sigfillset(&current->blocked);
 9 369 
10 370         /* Migrate to the right CPU */
11 371         current->cpus_allowed = 1UL << cpu;
12 372         while (smp_processor_id() != cpu)
13 373                 schedule();
14 374 
15 375         sprintf(current->comm, "ksoftirqd_CPU%d", bind_cpu);
16 376 
17 377         __set_current_state(TASK_INTERRUPTIBLE);
18 378         mb();
19 379 
20 380         ksoftirqd_task(cpu) = current;
21 381 
22 382         for (;;) {
23 383                 if (!softirq_pending(cpu))
24 384                         schedule();
25 385 
26 386                 __set_current_state(TASK_RUNNING);
27 387 
28 388                 while (softirq_pending(cpu)) {
29 389                         do_softirq();
30 390                         if (current->need_resched) /*進行調度,以防長期佔用CPU*/
31 391                                 schedule();
32 392                 }
33 393 
34 394                 __set_current_state(TASK_INTERRUPTIBLE);
35 395         }
36 396 }
 61 asmlinkage void do_softirq()
 62 {
 63         int cpu = smp_processor_id();
 64         __u32 pending;
 65         unsigned long flags;
 66         __u32 mask;
 67 
 68         if (in_interrupt())
 69                 return;
 70 
 71         local_irq_save(flags);
 72 
 73         pending = softirq_pending(cpu);
 74 
 75         if (pending) {
 76                 struct softirq_action *h;
 77 
 78                 mask = ~pending;
 79                 local_bh_disable();
 80 restart:
 81                 /* Reset the pending bitmask before enabling irqs */
 82                 softirq_pending(cpu) = 0;
 83 
 84                 local_irq_enable();
 85 
 86                 h = softirq_vec;
 87 
 88                 do {
 89                         if (pending & 1)
 90                                 h->action(h); /* 執行註冊的handler */
 91                         h++;
 92                         pending >>= 1;
 93                 } while (pending);
 94 
 95                 local_irq_disable();
 96 
 97                 pending = softirq_pending(cpu);
 98                 if (pending & mask) {
 99                         mask &= ~pending;
100                         goto restart;
101                 }
102                 __local_bh_enable();
103 
104                 if (pending)
105                         wakeup_softirqd(cpu);
106         }
107 
108         local_irq_restore(flags);
109 }

 

posted @ 2015-07-08 02:14  苍术厚朴  阅读(413)  评论(0编辑  收藏  举报