Tasklet 方 式 に よ る Linux の リアルタイム 性 向 上
Tasklet 方 式 に よ る Linux の リアルタイム 性 向 上 Tasklet 方 式 に よ る Linux の リアルタイム 性 向 上
Ethernet ドライバの tasklet 化の実際 +++drivers/net/smc91111.c 従来の割込みハンドラをリネーム static void smc_interrupt (int irq, void * dev_id, struct pt_regs * regs) +static void smc_handle_interrupt + (int irq, void * dev_id) { struct net_device *dev = dev_id; int ioaddr = dev>base_addr; struct smc_local *lp = (struct smc_local *)dev>priv; (・・・省略・・・) /* set a timeout value, so I don't stay here forever */ timeout = 4; PRINTK2(KERN_WARNING "%s: MASK IS %x \n", dev>name, mask); do { +#ifdef CONFIG_NET_TASKLET + if (need_hi_tasklet_sched_net()) + break; +#endif リアルタイムタスク実行中ならば 処理を終了 /* read the status flag, and mask it */ status = inb( ioaddr + INT_REG ) & mask; if (!status ) break; (・・・省略・・・) } Copyright(C) 2004 r2linux developer team +#ifdef CONFIG_NET_TASKLET +static void smc_do_tasklet + (unsigned long dev_id) +{ + struct net_device *dev + = (struct net_device *)dev_id; + struct smc_local *lp + = (struct smc_local *)dev>priv; + int irq = dev>irq; + + if (need_hi_tasklet_sched_net()) { + tasklet_hi_schedule(&lp>smc_tasklet); + return; + } + tasklet 関数を作成 リアルタイムタスク実行中ならば 再スケジューリングして終了 + smc_handle_interrupt(irq, dev); + 従来の割込みハンドラを呼び出す + if (need_hi_tasklet_sched_net()) + tasklet_hi_schedule(&lp>smc_tasklet); + else 再スケジューリング + enable_irq(irq); +} + 割込み許可 新しい割込みハンドラを作成 +static void smc_interrupt(int irq, + void * dev_id, struct pt_regs * regs) +{ + struct net_device *dev = dev_id; + struct smc_local *lp + = (struct smc_local *)dev>priv; + + disable_irq(irq); 割込み禁止 + tasklet_hi_schedule(&lp>smc_tasklet); +} tasklet 実行 18
デバイスドライバの tasklet 化の方法 デバイス毎に tasklet 構造体を作成 デバイス構造体に tasklet 構造体を追加 デバイス構造体の初期化時に tasklet 構造体も初期化 tasklet_init() の第 3 引数にデバイス構造体のアドレスを渡す 従来の割込みハンドラをリネーム xxx_intr()→xxx_handle_intr() 新しい割込みハンドラ xxx_intr() を作成 disable_irq() を呼出し、割込みを禁止 Tasklet 実行のため tasklet_hi_schedule() をコール Tasklet 関数 xxx_do_tasklet() の作成 リアルタイムタスク実行中ならば再スケジューリングし て終了 従来の割込みハンドラを呼び出す enable_irq() を呼出し、割込みを許可 Copyright(C) 2004 r2linux developer team 19
- Page 1 and 2: Linux Conference 2004 Tasklet 方
- Page 3 and 4: なぜ、リアルタイム性向
- Page 5 and 6: リアルタイム性の測定方
- Page 7 and 8: 測定結果(1) リアルタイム
- Page 9 and 10: 測定結果(2) Low Latency Patch +
- Page 11 and 12: イベントログによる遅れ
- Page 13 and 14: イベントログの例( Ftp get )
- Page 15 and 16: IDE ドライバの tasklet 化 問
- Page 17: Ethernet ドライバの tasklet
- Page 21 and 22: Tasklet 化の効果 すべての
- Page 23 and 24: 起動遅れヒストグラム (Tas
- Page 25: まとめ デバイスドライバ
デバイスドライバ<strong>の</strong> tasklet 化<strong>の</strong><strong>方</strong>法<br />
デバイス毎<strong>に</strong> tasklet 構造体を作成<br />
デバイス構造体<strong>に</strong> tasklet 構造体を追加<br />
デバイス構造体<strong>の</strong>初期化時<strong>に</strong> tasklet 構造体も初期化<br />
tasklet_init() <strong>の</strong>第 3 引数<strong>に</strong>デバイス構造体<strong>の</strong>アドレスを渡す<br />
従来<strong>の</strong>割込みハンドラをリネーム<br />
xxx_intr()→xxx_handle_intr()<br />
新しい割込みハンドラ xxx_intr() を作成<br />
disable_irq() を呼出し、割込みを禁止<br />
<strong>Tasklet</strong> 実行<strong>の</strong>ため tasklet_hi_schedule() をコール<br />
<strong>Tasklet</strong> 関数 xxx_do_tasklet() <strong>の</strong>作成<br />
<strong>リアルタイム</strong>タスク実行中ならば再スケジューリングし<br />
て終了<br />
従来<strong>の</strong>割込みハンドラを呼び出す<br />
enable_irq() を呼出し、割込みを許可<br />
Copyright(C) 2004 r2linux developer team<br />
19