內核軟中斷的延遲執行
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(¤t->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 }
Live together,or Die alone!