Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
$B3d$j9~$_$N8eH>It!"(BSoftirq$B!"(BTasklet$B!"(BWork Queue
[go: Go Back, main page]

$B3d$j9~$_$N8eH>It!"(BSoftirq$B!"(BTasklet$B!"(BWork Queue

					2013$BG/(B02$B7n(B05$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II

                                       $BC^GHBg3X(B $B%7%9%F%`>pJs9)3X8&5f2J(B 
                                       $B%3%s%T%e!<%?%5%$%(%s%9@l96(B, $BEE;R!&>pJs9)3X7O(B
                                       $B?7>k(B $BLw(B
                                       <yas@cs.tsukuba.ac.jp>

$B$3$N%Z!<%8$O!" http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2012/2013-02-05
$B$"$k$$$O!" http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/

$B"#:#F|$NBg;v$JOC(B

$B"#3d$j9~$_!"8eH>It(B

$B3d$j9~$_$NLdBjE@(B $B3d$j9~$_%O%s%I%i$O!":9$7Gw$C$?$3$H$@$1$r$7$F!"$=$l0J30$N$3$H$O!"8e$G!"(B $B$+$D!"3d$j9~$_$r5v2D$7$?>uBV$G

$B%G%P%$%9!

$B?^(B? $B3d$j9~$_=hM}$NA0H>ItJ,$H8eH>ItJ,(B

$BA02s!"(B request_irq() $B$G<($7$?$N$O!"A0H>$NOC!#:#F|$O!"8eH>$NOC!#(B

$B"!(Bgfp_t gfp_mask

kmalloc() $BEy$G;H$o$l$k(B gfp_t gfp_mask (1$B7n(B8$BF|$N;qNA(B) $B$N%9%j!<%W$N2DH]$KCeL\!#(B

$B"!8eH>It(B(bottom half$B!"(Bbotom halves)

$B8eH>It$N;E;v$O!"3d$j9~$_4XO"$N;E;v$N$&$A!"3d$j9~$_%O%s%I%i$G$O9T$o$J$$(B $BItJ,$r9T$&!#3d$j9~$_%O%s%I%i!JA0H>It!K$r7Z$/$9$k$H!"<+A3$K8eH>It$N;E;v(B $B$OB?$/$J$k!#(B

$B3d$j9~$_%O%s%I%i(B($BA0H>It(B)$B$H8eH>It$NLr3dJ,C4$NL\0B!#(B

Linux $B$G$O!"8eH>It$N;EAH$_$H$7$F!"Nr;KE*;v>p$+$iMM!9$J
  • BH (Botom Half,$B8GM-L>;lE*$J0UL#(B)$B!#:G8E!#%7%9%F%`A4BN(B $B$G(B32 $B8D$N%j%9%H!#%^%k%A%W%m%;%C%5$G$bC` Task Queue$B!#%?%9%/$NCY1d Softirq$B!#F1$8 Tasklet$B!#F1$8e(B $B$K Work Queue$B!#(Btask queue $B$N?7$7$$$b$N!#(B $BIaDL$O!"(BTasklet $B$+(B Work Queue $B$r;H$($P$h$$!#(B

    $BCm0U(B1: Tasklet $B$O!"(Btask $B9=B$BN$H$O$^$C$?$/4X78$J$$!#L>A0$,$h$/$J$$!#(B

    $BCm0U(B2: Softirq $B$H$$$&MQ8l$r!"3d$j9~$_=hM}$N8eH>It$H$$$&0UL#$G;H$&?M$b$$(B $B$k!#(B

    $BCm0U(B3: $BEAE}E*$J(BUnix$B$G$O!"(Btop half $B$O!"%7%9%F%`!&%3!<%k$+$iGI@8$9$k>e0L(B $BAX$N=hM}!"(Bbottom half $B$O!"3d$j9~$_$+$iGI@8$9$k2<0LAX$N=hM}$N0UL#$G;H$o(B $B$l$k$3$H$,$"$k!#(BLinux $B$G$O!"(Btop half, bottom half $B$O!"3d$j9~$_=hM}$NA0(B $BH>ItJ,$H8eH>ItJ,$N0UL#$K;H$&!#(B

    $B"#(BSoftirq

    $B%O!<%I%&%'%"$N(B IRQ $B$H$NBPHf(B

    $B%G%P%$%9!

    $B?^(B? $B%O!<%I%&%'%"$N3d$j9~$_$K$*$1$k%O%s%I%i$N

    $B%G%P%$%9!

    $B?^(B? Softirq$B$G$N%O%s%I%i$N

    $B%O!<%I%&%'%"$N3d$j9~$_(B
    • $B%G%P%$%9$O!"<+J,$N3d$j9~$_?.9f@~$r(B 1 $B$K$9$k!#(B
    • $B3d$j9~$_%3%s%H%m!<%i$O!"(BCPU $B$N3d$j9~$_?.9f@~$r(B 1 $B$K$9$k!#(B
    • CPU $B$O!"E,Ev$J;~(B($B3d$j9~$_6X;_$G$J$$;~(B)$B$K!"3d$j9~$_=hM}$r3+;O$9$k!#(B
    • CPU $B$O!"%P%9$+$i3d$j9~$_%Y%/%?$rFI$_=P$7!"$=$l$,(B n $B$J$i$=$l$KBP1~(B $B$7$?(B $B3d$j9~$_5-=R;R%F!<%V%k(B $B$N(B n $BHVL\$N%(%s%H%j$r ($B3d$j9~$_A0$N%W%m%0%i%`%+%&%s%?Ey$N>uBV$rJ]B8$7$F(B) $B3d$j9~$_%O%s%I%i$NHVCO$X%8%c%s%W$9$k!#(B
    Softirq
    • $B3d$j9~$_$r5/$3$7$?$$4X?t$O!"(Braise_softirq(n) $B$r8F$S=P$9!#(B
    • raise_softirq() $B$O!"JQ?t(B softirq_pending $B$N(Bn$B%S%C%HL\$r(B 1 $B$K$9$k!#(B
    • Softirq $B$N%7%9%F%`$O!"!VE,Ev$J;~!W$K!"4X?t(B do_softirq() $B$r8F$S=P$9!#(B
    • do_softirq() $B$O!"JQ?t(B softirq_pending $B$N%S%C%H$r=g$KD4$Y$F!"(B n $BHVL\$N%S%C%H$,(B 1 $B$J$i$P(B $BG[Ns(B softirq_vec[n] $B$r;2>H$7$F!"(B Softirq $B$N%O%s%I%i$NHVCO$r do_softirq() $B$O!"(BSoftirq $B$N%O%s%I%i$r8F$S=P$9!#(B

    $B"!(Bdo_softirq() $B$N

    $B4X?t(B do_softirq() $B$r8F$S=P$7!"
  • $B%O!<%I%&%'%"$K$h$k3d$j9~$_%O%s%I%i$N=hM}$,A4$F=*$o$C$F!"3d$j9~$_A0(B $B$N=hM}$KLa$kA0(B
  • ksoftirqd $B%+!<%M%k%9%l%C%I(B $B$,5/>2$7$?;~(B
  • $BL@<(E*$K%A%'%C%/$9$k;~!#%M%C%H%o!<%/=hM}Ey$GMxMQ!#(B

    $B"!(BSoftirq$B$G$N3d$j9~$_%O%s%I%i$NJ];}(B($BG[Ns(B softirq_vec[])

    Softirq$B$N linux-3.6.8/include/linux/interrupt.h 442: struct softirq_action 443: { 444: void (*action)(struct softirq_action *); 445: }; linux-3.6.8/kernel/softirq.c 55: static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;

    $B"!(BSoftirq$B$G$N3d$j9~$_%O%s%I%i(B

    softirq $B$N%O%s%I%i$O!" void softirq_handler(struct softirq_action *a) { ... }
    • Softirq $B$N%O%s%I%i$O!"3d$j9~$_$O5v2D$5$l$?>uBV$GF0$/!#(B $B%O!<%I%&%'%"$N3d$j9~$_$K$h$k3d$j9~$_%O%s%I%i(B($BA0H>It(B)$B$O!"(BSoftirq $B$N(B $B%O%s%I%i$N $BJ#?t$N(B Softirq $B$N%O%s%I%i$,J#?t$N(BCPU$B$GF1;~$K 1$B$D$N(B CPU $B$G!"(BSoftirq $B$N%O%s%I%i$O!"B>$N(B Softirq $B$N%O%s%I%i$r3d$j(B $B9~$`$3$H$O$J$$!#(B
    • Softirq $B$N%O%s%I%i$O!"(Bsleep $B$G$-$J$$!#(B

    $B"!(Bsoftirq_pending$B$H(Braise_softirq()

    $BJQ?t(Bsoftirq_pending$B$O!"%S%C%H$NG[Ns!#%S%C%H(Bn$B$,(B1$B$J$i$P!"(Bsoftirq_vec[n] $B$r

    $B$3$NJQ?t$N%S%C%H(Bn$B$r(B1$B$K$9$k(B(raise)$B$K$O!" void raise_softirq(unsigned int n) $B$^$:!"3d$j9~$_$,6X;_$7!"(B n $B$G;XDj$5$l$?(B Softirq $B$r $B35G0E*$K$O!" unsigned int softirq_pending; raise_softirq(int n) { softirq_pending |= (1 << n); } $B

  • local_softirq_pending(): $BCM$r set_softirq_pending(x): $BCM$rBeF~$9$k!#(B

    $B"!(Bdo_softirq()

    do_softirq()$B!!$O!"(Braise $B$5$l$?(B Softirq $B$,$"$l$P linux-3.6.8/kernel/softirq.c 207: asmlinkage void __do_softirq(void) 208: { 209: struct softirq_action *h; 210: __u32 pending; ... 222: pending = local_softirq_pending(); ... 232: set_softirq_pending(0); 233: 234: local_irq_enable(); 235: 236: h = softirq_vec; 237: 238: do { 239: if (pending & 1) { ... 246: h->action(h); ... 258: } 259: h++; 260: pending >>= 1; 261: } while (pending); ... 277: }

    $B"!(BSoftirq$B$NMxMQ>l=j(B

    Softirq $B$N linux-3.6.8/include/linux/interrupt.h 417: enum 418: { 419: HI_SOFTIRQ=0, 420: TIMER_SOFTIRQ, 421: NET_TX_SOFTIRQ, 422: NET_RX_SOFTIRQ, 423: BLOCK_SOFTIRQ, 424: BLOCK_IOPOLL_SOFTIRQ, 425: TASKLET_SOFTIRQ, 426: SCHED_SOFTIRQ, 427: HRTIMER_SOFTIRQ, 428: RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ 429: 430: NR_SOFTIRQS 431: }; Softirq $B$Nl=j(B
    • $B%M%C%H%o!<%/=hM}(B
    • $B%V%m%C%/!&%G%P%$%9(B
    • $B%+!<%M%k!&%?%$%^(B
    • Tasklets $B$N $BIaDL$O!"(Btasklets $B$r;H$($P==J,$G!"<+J,$GFH<+$N(B softirqs $B$rDI2C$9$kI,MW$O(B $B$"$^$j$J$$!#?7$7$$(B Softirq $B$rDI2C$7$?$$;~$K$O!"
    • $B>e$N(B enum $B$K%$%s%G%C%/%9$H$J$kDj?t$rDI2C$9$k!#(B
    • Softirq $B%O%s%I%i$H$J$k4X?t$rDj5A$9$k!#(B
    • open_softirq() $B$G!"(BSoftirq $B%O%s%I%i$rEPO?$9$k!#(B

    $B"!%M%C%H%o!<%/=hM}$G$N(B Softirq $B$NMxMQNc(B

    $B%M%C%H%o!<%/=hM}$G$O!"Aw?.(B(TX, Transmit) $B$H linux-3.6.8/net/core/dev.c 6579: static int __init net_dev_init(void) 6580: { ... 6642: open_softirq(NET_TX_SOFTIRQ, net_tx_action); 6643: open_softirq(NET_RX_SOFTIRQ, net_rx_action); ... 6651: } 3005: static void net_tx_action(struct softirq_action *h) 3006: { ... 3061: } 3903: static void net_rx_action(struct softirq_action *h) 3904: { ... 3987: }

    $B"!(Bksoftirqd(kernel soft IRQ daemon)

    ksoftirqd $B$O!"(BSoftirq $B$d(B Tasklet $B$r $ ps alx [$B F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND ... 1 0 3 2 20 0 0 0 run_ks S ? 0:00 [ksoftirqd/0] $ []

    $BLdBj(B: Softirq $B$rM%@h$9$Y$-$+!"IaDL$N%f!<%6!&%W%m%;%9$rM%@h$9$Y$-$+!#(B

    • Softirq ($B$d(B Tasklet)$B$rM%@h$7$F=hM}$7$?$i!"(BSoftirq $B$,9bIQEY$G:n$i$l(B $B$?;~$K!"%f!<%6%W%m%;%9$,$^$C$?$/uBV(B)$B!#(B
    • $B%f!<%6%W%m%;%9$rM%@h$7$F=hM}$7$?$i!"(BSoftirq $B$d(B Tasklet $B$r $B2r7h:v(B: ksoftirqd
      • ksoftirqd $B$O!"IaCJ$O(B sleep $B$7$F$$$k!#(B $B ksoftirqd $B$O!"DcM%@hEY(B(nice $BCM(B 19)$B$G(B Softirq (Tasklet$B$r4^$`(B)$B$r=hM}$9$k!#(B
      $BCm0U(B: do_softirq() $B$O!"(B ksoftirqd$B0J30(B $B$G$B"#(BTasklet Tasklets $B$O!"(BSoftirqs $B$N>e$K9=C[$5$l$F$$$k!#(B $B$h$j4JC1$J%$%s%?%U%'!<%9$G!"%m%C%/$K4X$9$k@)Ls$,4K$$!#(B

      Tasklet $B$G#1$D$N;E;v$O linux-3.6.8/include/linux/interrupt.h 503: struct tasklet_struct 504: { 505: struct tasklet_struct *next; 506: unsigned long state; 507: atomic_t count; 508: void (*func)(unsigned long); 509: unsigned long data; 510: };

      • func: Tasklet $B%O%s%I%i!#0z?t$O!"(Bdata$B!#(B
      • state: Tasklet $B$N>uBV!#(BTASKLET_STATE_SCHED ($B%9%1%8%e!<%k$5$l$F$$$k!"(B $Be$,$C$F$$$k(B) $B$+(BTASKLET_STATE_RUN ($B count: 0 $B$J$iM-8z!#(B0$B0J30$J$iL58z!#(B $B0l;~E*$KL58z2=$7$?$$$J$i!"(Bcount $B$rA}$d$9!#(B
      • next: $B%j%9%H$r:n$k%]%$%s%?!#(B
      $BA4BN$H$7$F!"

      tasklet_vec$B!

      $B?^(B? Tasklet$B$K$*$1$k;E;v$N%-%e!<(B

      $B"!(BTasklet$B$N9=B$BN$N@k8@(B

      $B@EE*$K(B struct tasklet_struct $B$r@k8@$9$k$K$O!" DECLARE_TASKLET(name, func, data) $BM-8z$J(B(count==0) $B$N(B struct tasklet_struct $B$r@k8@$9$k(B DECLARE_TASKLET_DISABLED(name, func, data) $BL58z$J(B(count==1) $B$N(B struct tasklet_struct $B$r@k8@$9$k(B
      • name: struct tasklet $B9=B$BN$NJQ?tL>(B
      • func: $B%O%s%I%i$H$J$k4X?t(B
      • data: $B%O%s%I%i$KEO$9%G!<%?(B
      kmalloc()$BEy$GF0E*$K3NJ]$7$?>l9g$K$O!" void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); $B$=$NB>$K!"@8@.>CLGM-8zL58z$K4X$7$F
    • tasklet_disable(): $BL58z2=$9$k!J%-%e!<$K$"$k$,$"$k$, tasklet_disable_nosync(): $BL58z2=$7!" tasklet_enable(): $BM-8z$K$9$k(B
    • tasklet_kill(): $B$G%-%e!<$+$i:o=|$9$k(B

    $B"!(BTasklet$B$N%O%s%I%i(B

    Tasklet $B$N%O%s%I%i$O!" void tasklet_handler(unsigned long data) { .... }
    • Tasklet $B$N%O%s%I%i$O!"3d$j9~$_$O5v2D$5$l$?>uBV$GF0$/!#%O!<%I%&%'%"(B $B$N3d$j9~$_$K$h$k3d$j9~$_%O%s%I%i(B($BA0H>It(B)$B$O!"(BTasklet $B$N%O%s%I%i$N $B0[$J$k(B Tasklet $B$O!"J#?t$N(B CPU $B$GF1;~$K $BF1$8(B Tasklet $B$O!"(B1$BEY$K(B1$B$D$7$+F0$+$J$$!#(B
    • Tasklet $B$N%O%s%I%i$O!"(Bsleep $B$G$-$J$$!#(B

    $B"!(BTasklet$B$N

    Tasklet $B$N%O%s%I%i$r void tasklet_schedule(struct tasklet_struct *t) Tasklet t $B$rDL>o$NM%@hEY$G%9%1%8%e!<%k$9$k(B void tasklet_hi_schedule(struct tasklet_struct *t) Tasklet t $B$r9bM%@hEY$G%9%1%8%e!<%k$9$k(B $B$9$k$H!"$=$l$O!V$=$N$&$A$K!W(B1$BEY$@$1$B"!(BTasklet$B$NMxMQNc(B Atheros Communications Inc$B$NL5@~(BLAN$B$N%I%i%$%P$G$NMxMQNc!#(B
    linux-3.6.8/drivers/net/wireless/ath/ath9k/ath9k.h
    
     657:	struct ath_softc {
    ...
     664:	        struct tasklet_struct intr_tq;
     665:	        struct tasklet_struct bcon_tasklet;
    ...
     734:	};
    
    linux-3.6.8/drivers/net/wireless/ath/ath9k/init.c
     561:	        tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
     562:	        tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
     563:	                     (unsigned long)sc);
    
    
    • struct ath_softc $B$O!"$3$N%I%i%$%P$G;H$&9=B$BN!#(B
    • 2$B$D$N(B Tasklet $B$N9=B$BN$,$"$k!#(B
      • intr_tq: $B4X?t(B ath9k_tasklet() $BMQ!#(B
      • bcon_tasklet: $B4X?t(B ath_beacon_tasklet() $BMQ!#(B
    • $B=i4|2=;~$K!"$3$l$i$N9=B$BN$r(B tasklet_init() $B$G=i4|2=$7$F$$$k!#(B
    linux-3.6.8/drivers/net/wireless/ath/ath9k/main.c
    
     429:	irqreturn_t ath_isr(int irq, void *dev)
     430:	{
    ...
     476:	        ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
    ...
     489:	        if (status & SCHED_INTR)
     490:	                sched = true;
    ...
     522:	        if (status & ATH9K_INT_SWBA)
     523:	                tasklet_schedule(&sc->bcon_tasklet);
    ...
     550:	        if (sched) {
    ...
     553:	                tasklet_schedule(&sc->intr_tq);
     554:	        }
     555:	
     556:	        return IRQ_HANDLED;
    ...
     559:	}
    
     361:	void ath9k_tasklet(unsigned long data)
     362:	{
    ...
     427:	}
    
    linux-3.6.8/drivers/net/wireless/ath/ath9k/beacon.c
     310:	void ath9k_beacon_tasklet(unsigned long data)
     311:	{
    ...
     408:	}
    
    • ath_isr() $B$O!"(B $B%O!<%I%&%'%"$N3d$j9~$_%O%s%I%i(B($BA0H>It$N3d$j9~$_%O%s%I%i(B)$B!#(B
    • $B$^$:!"%O!<%I%&%'%"$N%l%8%9%?$r%"%/%;%9$7$F!"(Bstatus $B$rF@$k!#(B
    • status $B$N$"$k%S%C%H(B( ATH9K_INT_SWBA )$B$,%*%s$N;~$K$O(B $B8e$G(B YHM_Esape(&sc->bcon_tasklet) $B$N(B Tasklet $B$r $B$"$k>r7o(B(sched$B$,(Btrue$B!"(Bstatus $B$N!!(BSCHED_INTR $B%S%C%H$,%*%s(B) $B$,@.$jN)(B $B$F$P!"8e$G(BYHM_Esape(&sc->intr_tq) $B$N(BTasklet $B$r $B:G8e$K%O!<%I%&%'%"$N3d$j9~$_%O%s%I%i$O!"(BIRQ_HANDLED $B$r(B return$B$9$k!#(B
    • $B$=$N$&$A$K!"(Bath9k_tasklet() $B4X?t$d(B ath_beacon_tasklet() $B4X?t(B $B$,8F$P$l$k!#(B

    $B"#(BWork Queue

    $B3d$j9~$_$K4XO"$7$?=hM}$G!"l9g(B(Tasklet$B$d(BSoftirq $B$G$OIT2DG=$J(B $B>l9g(B)$B$K(BWork Queue$B;H$&!#(B
    • sleep $B$9$kI,MW$,$"$k!#(B
    • $B3d$j9~$_%3%s%F%-%9%H$G$O$J$/!"%W%m%;%9%3%s%F%-%9%H$G4X?t$r8F$S=P$7$?$$(B
    • ($BBgNL$N(B)$B%a%b%j$r3NJ]$7$?$$(B($B%Z!<%8%"%&%H$N$?$a$K(Bsleep$B$9$k2DG=@-$,$"$k(B)
    • $B%;%^%U%)Ey$NF14|=hM}$r9T$&(B

    $B"!(BWork Queue$B$N%o!<%+!&%9%l%C%I(B

    Work Queue $B$N%o!<%+!&%9%l%C%I$O!"%+!<%M%k!&%l%Y%k$N%9%l%C%I$G!"(B $B3d$j9~$_=hM}$N8eH>ItJ,$N=hM}$r9T$&$3$H$,$G$-$k!#(B ($B3d$j9~$_=hM}0J30$G;H$C$F$b$h$$!#(B)

    workqueue_struct$B!

    $B?^(B? Work Queue$B$K$*$1$k;E;v$N%-%e!<(B

    $B%-%e!<$K$D$J$,$l$k;E;v$O!"(BTasklet $B$N;E;v$H$[$H$s$IF1$8$G!"4X?t$X$N%]%$(B $B%s%?(B func $B$H(B data $B$+$i$J$k!#=hM}$N

    $ ps alx [$B
    F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
    ...
    1     0     5     2   0 -20      0     0 worker S<   ?          0:00 [kworker/0:0H]
    1     0     6     2  20   0      0     0 worker S    ?          0:00 [kworker/u:0]
    1     0     7     2   0 -20      0     0 worker S<   ?          0:00 [kworker/u:0H]
    1     0    27     2  20   0      0     0 worker S    ?          0:00 [kworker/u:1]
    1     0   367     2   0 -20      0     0 worker S<   ?          0:00 [kworker/0:1H]
    1     0   650     2   0 -20      0     0 worker S<   ?          0:00 [kworker/u:1H]
    ...
    1     0 29461     2  20   0      0     0 worker S    ?          0:00 [kworker/0:1]
    1     0 29482     2  20   0      0     0 worker S    ?          0:00 [kworker/0:2]
    1     0 29503     2  20   0      0     0 worker S    ?          0:00 [kworker/0:0]
    1     0 29601     2  20   0      0     0 worker S    ?          0:00 [kworker/0:3]
    $ []
    
    $BHFMQ$N(B Work Queue $B$N%o!<%+!&%9%l%C%I$NB>$K!"@lMQ$N%o!<%+!&%9%l%C%I$r:n(B $B$k$3$H$b$G$-$k!#(B

    $B"!(Bwork_struct$B9=B$BN(B

    $B%o!<%/!&%-%e!<$GMQ$$$k(B 1 $B$D$N;E;v$O!"9=B$BN(B struct work_struct $B$GI=8=$5(B $B$l$k!#(B
    linux-3.6.8/include/linux/workqueue.h
    
      18:	typedef void (*work_func_t)(struct work_struct *work);
    
      79:	struct work_struct {
      80:	        atomic_long_t data;
      81:	        struct list_head entry;
      82:	        work_func_t func;
    ...
      86:	};
    
    • entry: $B%-%e! func: $B%O%s%I%i(B
    $B struct work_struct my_work; ... INIT_WORK(&my_work,my_work_handler);

    $B"!(BWork Queue $B%O%s%I%i(B

    Work Queue $B%O%s%I%i$O!" void my_work_handler(struct work_struct *work) { ... }

    $B"!(BWork $B$N

    $B%O%s%I%i$r8F$S=P$7$?$$;~$K$O!" schedule_work(&work); $B$3$N7k2L!"(BINIT_WORK() $B$G@_Dj$7$?%O%s%I%i$,%o!<%+!&%9%l%C%I$K$h$j!V$=$N(B $B$&$A!W$K8F$S=P$5$l$k!#(B

    schedule_work() $B$G$O!"B(:B$K/$78e$K schedule_delayed_work(&work,ticks); ticks $B$O!"$I$N$/$i$$4V$r$H$k$+!#C10L$O!"(Bjiffies ($B:#8e$Ne$2$k(B)$B!#(B $BB?$/$N%7%9%F%`$G(B10$B%_%jIC(B-1$B%_%jIC$G!"@_Dj$K$h$C$F0[$J$k!#(B

    $B"!(Bflush_scheduled_work()

    schedule_work() $B$GMW5a$7$?;E;v$,40N;$7$?$3$H$rBT$C$F!"$B"!(Balloc_workqueue() $B@lMQ$N%o!<%+!&%9%l%C%I$r:n$j$?$$;~$K$O!"
  • alloc_workqueue(): $B%o!<%+!&%9%l%C%I$r:n$k!#(B
  • queue_work(), queue_delayed_work():: $B%-%e!<$K;E;v$r2C$($k!#(B

    $B"#3d$j9~$_$N8eH>It$NA*Br(B

    • sleep $B$9$kI,MW$,$"$k!J2DG=@-$,$"$k!K$J$i!"(BWork Queue$B!#;H$$J}$b4JC1!#(B
    • $B$=$NB>$N>l9g$O!"(BTasklet$B!#F1$8(B Tasklet $B$O!"(B1$BEY$K(B1$B$D$7$+F0$+$J$$!#(B
    • $B$,$s$P$C$FJBNs@-$r=P$7$?$$$J$i!"(BSoftirq

    $B"#2]Bj(B8 $B3d$j9~$_$N8eH>It!"(BSoftirq$B!"(BTasklet$B!"(BWork Queue

    $B!zLdBj(B(801) $B3d$j9~$_8eH>$N=hM}(B

    $B3d$j9~$_=hM}$r!"A0H>(B(top half)$B$H8eH>(B(bottom half)$B$KJ,$1$kM}M3$r4JC1$K@b(B $BL@$7$J$5$$!#(B

    $B!zLdBj(B(802) Tasklet$B$N=i4|2=(B

    Tasklet $B$r;H$C$F$G8F$S=P$7$?$$!#(B
    void f(int arg1, int arg2) {
       $B>JN,(B;
    }
    
    $B$3$l$r void tasklet_handler(unsigned long data) { /* Tasklet $B%O%s%I%i(B */ int arg1, arg2; arg1 = $B>JN,(B; arg2 = $B>JN,(B; /*$B6uMs(B(a)*/ $B$=$NB>$N;E;v(B; } DECLARE_TASKLET(/*$B6uMs(B(b)*/, /*$B6uMs(B(c)*/, 0); /* $B9=B$BN$N=i4|2=(B */ $BCm0U(B: $B9=B$BN$NL>A0$O!"$B!zLdBj(B(803) $B%O%s%I%i$N $BItJ,(B($B%O!<%I%&%'%"$N3d$j9~$_(B)$B$N0lIt$G$"$k!#(B $B3d$j9~$_=hM}$N8eH>$G!"(B$BLdBj(B(802) $B$GDj5A$7$?(B Tasklet $B$N%O%s%I%i$r8F$V$h$&$K!"6uMs$rKd$a$J$5$$!#(B
    irqreturn_t irq_handler(int irq, void *dev) {
        /*$B6uMs(B(d)*/
        return IRQ_HANDLED;
    }
    

    Last updated: 2013/02/11 14:10:20
    Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>