割り込みベクトル 0 ~ 31 は予約されており、合計 224 個の割り込みベクトル 32 ~ 255 が使用可能です。これら 224 個の割り込みベクトルはどのように割り当てられるのでしょうか? Linux の 2.6 バージョン では、 システム コール のメイン入口として使用される 0x80 (SYSCALL_VECTOR) を除き、その他は外部ハードウェア割り込みソースに使用されます。プログラマブル割り込みコントローラ 8259A の 15 irq; 実際、CONFIG_X86_IO_APIC が定義されていない場合、他の 223 (0x80 を除く) 割り込みベクトルは 32 番目から始まる 15 のみを使用し、他の 208 は空のままになります。
# 2.2 割り込み要求
## 2.2.1 割り込み要求の概要
# 外部デバイスがオペレーティング システムに関連する処理を要求すると、対応する割り込みが生成されます。
デバイスは、対応する割り込みラインを介して割り込みコントローラーにハイ レベルを送信して割り込み信号を生成し、オペレーティング システムは割り込みコントローラーのステータス ビットからその割り込みラインを取得します。 . 割り込みが発生しました。そして、デバイスが特定の割り込みラインを制御できる場合にのみ、この割り込みラインに信号を送信できます。また、最近ではペリフェラルがますます増えているため、割り込みラインは非常に貴重なリソースであり、1 対 1 にマッピングすることはできません。したがって、割り込み回線を使用する前に、該当する割り込み回線を申請する必要があります。共有割り込み方法が使用されるか排他的割り込みが使用されるかに関係なく、アプリケーション プロセスは最初にすべての割り込みラインをスキャンして、他の割り込みラインによって占有されていない割り込みラインを見つけ、そのうちの 1 つをデバイスの IRQ として選択します。次に、割り込み適用機能を通じて、対応する IRQ を申請します。最後に、アプリケーションの結果に基づいて割り込みが実行できるかどうかを確認します。
2.2.2 割り込み関連構造
コアはデータを処理します。割り込み構造は irq_desc で割り込み行を完全に記述しており、Linux 2.6.22.6 でのソースコードは以下のとおりです。
irq_desc は include/linux/irq.h/**
* struct irq_desc - interrupt descriptor
*
* @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()]
* @chip: low level interrupt hardware access
* @msi_desc: MSI descriptor
* @handler_data: per-IRQ data for the irq_chip methods
* @chip_data: platform-specific per-chip private data for the chip
* methods, to allow shared chip implementations
* @action: the irq action chain
* @status: status information
* @depth: disable-depth, for nested irq_disable() calls
* @wake_depth: enable depth, for multiple set_irq_wake() callers
* @irq_count: stats field to detect stalled irqs
* @irqs_unhandled: stats field for spurious unhandled interrupts
* @lock: locking for SMP
* @affinity: IRQ affinity on SMP
* @cpu: cpu index useful for balancing
* @pending_mask: pending rebalanced interrupts
* @dir: /proc/irq/ procfs entry
* @affinity_entry: /proc/irq/smp_affinity procfs entry on SMP
* @name: flow handler name for /proc/interrupts output */struct irq_desc {
irq_flow_handler_t handle_irq; struct irq_chip *chip; struct msi_desc *msi_desc; void *handler_data; void *chip_data; struct irqaction *action; /* IRQ action list */
unsigned int status; /* IRQ status */
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
unsigned int irqs_unhandled;
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;#endif#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
cpumask_t pending_mask;#endif#ifdef CONFIG_PROC_FS struct proc_dir_entry *dir;#endif
const char *name;
} ____cacheline_internodealigned_in_smp;
ログイン後にコピー
irq_desc
# で定義されています ## 関連する構造は次のとおりです。
include/linux/interrupt.h で定義された割り込みアクション構造: struct irqaction
struct irqaction {
irq_handler_t handler;
unsigned long flags;
cpumask_t mask; const char *name; void *dev_id; struct irqaction *next; int irq; struct proc_dir_entry *dir;
};
ログイン後にコピー
include/ で定義linux: irq_chip チップ関連処理関数集 /**
* struct irq_chip - hardware interrupt chip descriptor
*
* @name: name for /proc/interrupts
* @startup: start up the interrupt (defaults to ->enable if NULL)
* @shutdown: shut down the interrupt (defaults to ->disable if NULL)
* @enable: enable the interrupt (defaults to chip->unmask if NULL)
* @disable: disable the interrupt (defaults to chip->mask if NULL)
* @ack: start of a new interrupt
* @mask: mask an interrupt source
* @mask_ack: ack and mask an interrupt source
* @unmask: unmask an interrupt source
* @eoi: end of interrupt - chip level
* @end: end of interrupt - flow level
* @set_affinity: set the CPU affinity on SMP machines
* @retrigger: resend an IRQ to the CPU
* @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
* @set_wake: enable/disable power-management wake-on of an IRQ
*
* @release: release function solely used by UML
* @typename: obsoleted by name, kept as migration helper */struct irq_chip { const char *name;
unsigned int (*startup)(unsigned int irq); //中断开始 void (*shutdown)(unsigned int irq); //中断关闭 void (*enable)(unsigned int irq); //中断使能 void (*disable)(unsigned int irq); //中断禁用 void (*ack)(unsigned int irq); void (*mask)(unsigned int irq); void (*mask_ack)(unsigned int irq); void (*unmask)(unsigned int irq); void (*eoi)(unsigned int irq); void (*end)(unsigned int irq); void (*set_affinity)(unsigned int irq, cpumask_t dest); int (*retrigger)(unsigned int irq); int (*set_type)(unsigned int irq, unsigned int flow_type); int (*set_wake)(unsigned int irq, unsigned int on); /* Currently used only by UML, might disappear one day.*/#ifdef CONFIG_IRQ_RELEASE_METHOD void (*release)(unsigned int irq, void *dev_id);#endif
/*
* For compatibility, ->typename is copied into ->name.
* Will disappear. */
const char *typename;
};
ログイン後にコピー
2.2.3 割り込み要求の実装
上半分と下半分 内部機構
割り込みハンドラーを高速に実行することと、大量の作業を完了させることを望みます。これら 2 つの目標は相互に制限します。解決方法 ——
上半分と下半分のメカニズム。 割り込みハンドラーを半分に削減しました。割り込みハンドラーは上部にあり、割り込みを受け入れます
で、すぐに実行を開始しますが、厳密な時間制限のある作業しか実行できません。後で完了できる作業は後半に延期され、適切なタイミングで後半が端末によって実行されます。前半はシンプルかつ高速で、 実行中の一部またはすべての割り込みを無効にします。 後半は後で実行され、実行中のすべての割り込みに応答できます。この設計により、システムの割り込みシールド状態を可能な限り短くすることができ、システムの応答性が向上します。上半分には割り込みハンドラー機構のみがあり、下半分にはソフト割り込みの実装、
タスクレットの実装、およびワークキューの実装があります。 ネットワーク カードを使用して、これら 2 つの部分について説明します。ネットワークカードがデータパケットを受信すると、カーネルに通知して割り込みをトリガーしますが、いわゆる前半は、遅延による損失を防ぐために、時間内にデータパケットをメモリに読み込むことであり、これは非常に緊急なタスクです。メモリの読み取り後、これらのデータの処理は緊急ではなくなり、カーネルは割り込み前に実行されていたプログラムを実行でき、ネットワーク データ パケットの処理は下位半分に任せられます。
上半分と下半分を分割する原則
1) 時間に非常に敏感なタスクの場合は、割り込みハンドラの実装;
2) タスクがハードウェアに関連している場合は、実行のために割り込みハンドラに入れます;
3) If aタスクは、他の割り込みによって割り込まれないようにし、割り込みハンドラー内で実行される必要があります;
4) 他のすべてのタスクについては、タスクを下半分は実行用です。
下半分の実装機構のソフト割り込み
下半分の機構の代表としてソフト割り込みが続きます。 SMP (共有メモリ プロセッサ) が登場し、tasklet (tasklet) の実装の基礎にもなりました。は実際にはソフト割り込みでのみ使用されます。これをベースに特定のメカニズムが追加されています。) Softirq は一般的に "Delayable function" の一般名であり、場合によっては tasklet も含まれます (読者は、# が含まれるかどうかを文脈に基づいて推測するように求められます) ##タスクレット)。これは、上で提案した上半分と下半分の区別を満たす必要があるため、時間に依存しないタスクが遅延されるためです。ソフト割り込みは、割り込みハンドラーによって残された残りのタスクを実行します。複数の CPU で並列実行すると、システム全体の効率が向上します。その機能は次のとおりです。
## a) は生成後すぐに実行できず、実行前にカーネルのスケジューリングを待つ必要があります。ソフト割り込みは単独で割り込むことはできず、ハードウェア割り込み(上部)によってのみ割り込みが可能です。
b) は、複数の CPU (同じタイプであっても) で同時に実行できます。したがって、ソフト割り込みはリエントラント機能 (複数の CPU が同時に動作できるようにする) として設計する必要があるため、データ構造を保護するためにスピン ロックも使用する必要があります。
#下半分の実装メカニズムのタスクレット
Tasklet
はソフト割り込みを通じて実装されるため、それ自体もソフト割り込みです。 #ソフト割り込みはポーリング方式で処理されます。それが最後のタイプの割り込みである場合、対応する処理関数が最終的に実行される前に、すべてのタイプの割り込みをサイクルする必要があります。明らかに、ポーリングの効率を確保するために、開発者は割り込みの数を 32
に制限しました。 割り込み処理の数を増やし、処理効率を向上させるために、タスクレット
という仕組みが生まれました。 タスクレット は、未分化のキュー メカニズムを採用しており、割り込みが発生した場合にのみ実行されるため、循環テーブル検索の煩わしさは解消されます。 タスクレット新しいメカニズムとして、明らかにさらに多くの利点がもたらされます。現時点では、SMP の人気が高まっていたため、SMP メカニズムが tasklet に追加され、同じタイプの割り込みが tasklet でのみ処理できるようになりました。 1 つの cpu で実行します。ソフト割り込みの時代には、明らかにそのような考慮はありませんでした。したがって、同じソフト割り込みが 2 つの cpu で同時に実行される可能性があり、競合が発生する可能性があります。 ################################################ # まとめtasklet の利点: ## (1)型の数に制限なし;
(2)効率が高く、テーブル検索をループする必要はありません。
## (3) SMP 機構をサポート
## その特徴は次のとおりです。 1
) 特定の種類の タスクレットは 1 つの CPU 上でのみ実行でき、並列実行はできませんが、シリアルに実行されます。
2) 異なるタイプの複数の タスクレット
を複数のマシン上で並行して実行できます。 CPU がオンです。 3) ソフト割り込みは静的に割り当てられ、カーネルのコンパイル後に変更することはできません。ただし、tasklet ははるかに柔軟で、実行時 (モジュールの追加時など) に変更できます。
#実装メカニズムの下半分はワークキューです上で紹介した遅延可能関数は割り込みコンテキストで実行されます (ソフト割り込みの 1 つのチェックポイントは do_IRQ が終了するときです)。これにより、ソフト割り込みがスリープまたはブロックできないといういくつかの問題が発生します。割り込みコンテキストはカーネル状態にあり、プロセスの切り替えがないため、ソフト割り込みがスリープまたはブロックされると、この状態から抜け出すことができなくなり、カーネル全体がフリーズします。ただし、ブロック関数は割り込みコンテキストでは実装できず、ディスク データ ブロックにアクセスする関数など、プロセス コンテキストで実行する必要があります。したがって、softirqs を使用してブロック機能を実装することはできません。しかし、多くの場合、それらは延期可能な特性を持っています。
上記で紹介した遅延可能関数は割り込みコンテキストで実行されます。これによりいくつかの問題が発生し、一時停止できないことが示されます。つまり、ソフト割り込みがスリープできないことを意味します。ブロックできません。その理由は、割り込みコンテキストがカーネル状態にあり、プロセスの切り替えがないためです。したがって、ソフト割り込みがスリープまたはブロックされると、この状態から抜け出すことができなくなり、カーネル全体がフリーズします。したがって、softirqs を使用してブロック機能を実装することはできません。しかし、多くの場合、それらは延期可能な特性を持っています。また、シリアルに実行されるため、1回の処理時間が長いと他の割り込みの応答が遅くなります。これらの不可能なタスクを完了するために、異なるプロセスを切り替えて異なるタスクを完了できるワーク キューが登場しました。 延期されたタスクにスリープが必要な場合は、ワーク キューを選択します。スリープが必要ない場合は、ソフト割り込みまたは tasklet を選択します。作業キューはプロセス コンテキストで実行でき、作業をカーネル スレッドに委任できます。簡単に言うと、ワーク キューは、割り込みデーモン スレッドとして使用されるカーネル スレッドのグループです。複数の割り込みを 1 つのスレッドに配置することも、各割り込みにスレッドを割り当てることもできます。構造体 workqueue_struct を使用してワーカー スレッドを表し、カーネル スレッドを使用して実装されます。そして、ワーカー スレッドが延期された作業をどのように実行するか——構造 work_struct で構成されるリンク リストがあり、この work_struct はジョブを記述します。ジョブが実行されると、対応する work_struct オブジェクトがリンク リストから削除され、リンク リストにオブジェクトがなくなると、ワーカー スレッドはスリープ状態を続けます。ワークキューはスレッドであるため、スレッドで使用できるすべてのメソッドを使用できます。 ################################################ #何Linux におけるソフト割り込みとワーク キューの役割#Linux におけるソフト割り込みとワーク キューの役割は、割り込み処理を実装することです。下位割り込みメカニズム 実装メカニズムの下半分。 1.ソフト割り込みは、通常、"Delayable function
"の総称です。スリープやブロックはできません。 . 、割り込みコンテキスト内にあり、プロセス間を切り替えることはできません。ソフト割り込みはそれ自体で割り込むことはできませんが、ハードウェア割り込み (上部) によってのみ割り込むことができます。それらは複数の CPU で同時に実行できます。したがって、ソフト割り込みはリエントラント機能として設計する必要があるため、データ構造を保護するためにスピン ロックも必要です。
2.ワークキュー内の関数はプロセスコンテキスト内にあります。スリープまたはブロックすることができ、異なるタスクを完了するために異なるプロセス間を切り替えることができます。 遅延可能関数もワーク キューもユーザーのプロセス領域にアクセスできません。遅延可能関数の実行時に実行中のプロセスが存在することはできません。ワーク キュー関数には Whileカーネル プロセスが実行中であるため、ユーザー空間アドレスにアクセスできません。 関連する推奨事項: 「Linux ビデオ チュートリアル 」