6

私はWebを精査しましたが、「request_threaded_irq」機能に関して、私が持っているいくつかの関連する質問に対する説得力のある答えを見つけられませんでした。

質問1: 最初に、スレッド化されたIRQに関して、この記事を読んでいました。

http://lwn.net/Articles/302043/

そして、私にははっきりしないこの一行があります:

「割り込みをスレッドに変換することは、ハンドラーコードがtasklet / softirq機能を統合し、ロックを単純化することによって割り込みを利用する場合にのみ意味があります。」

「従来の」上半分/下半分のアプローチを進めていたら、共有データに干渉するためにスピンロックまたはローカルIRQを無効にする必要があったことを理解しています。しかし、私が理解していないのは、スレッド化された割り込みが、tasklet / softirq機能を統合することによって、ロックの必要性をどのように単純化するかということです。

質問2: 次に、request_threaded_handlerアプローチはwork_queueベースの下半分のアプローチよりも優れていますか?どちらの場合も、「作業」は専用のスレッドに延期されているように見えます。それで、違いは何ですか?

質問3: 最後に、次のプロトタイプで:

int request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long irqflags, const char *devname, void *dev_id)

IRQの「ハンドラ」部分が関連するIRQ(たとえばUARTが高速で文字を受信する)によって継続的にトリガーされる可能性はありますか?割り込みハンドラは、以前のウェイクアップからのIRQの処理でビジーですか?それで、ハンドラーはすでに実行中の「thread_fn」を「ウェイクアップ」しようとしているのではないでしょうか。その場合、実行中のirq thread_fnはどのように動作しますか?

誰かが私がこれを理解するのを手伝ってくれるなら、私は本当に感謝します。

ありがとう、vj

4

4 に答える 4

5

質問 2 については、作成時の IRQ スレッドは、ワークキューとは異なり、優先度が高く設定されます。ではkernel/irq/manage.c、スレッド化された IRQ のカーネル スレッドを作成するための次のようなコードが表示されます。

            static const struct sched_param param = {
                    .sched_priority = MAX_USER_RT_PRIO/2,
            };


            t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
                               new->name);
            if (IS_ERR(t)) {
                    ret = PTR_ERR(t);
                    goto out_mput;
            }

            sched_setscheduler_nocheck(t, SCHED_FIFO, &param);

ここでは、カーネル スレッドのスケジューリング ポリシーが RT ( SCHED_FIFO) に設定され、スレッドの優先度がMAX_USER_RT_PRIO/2通常のプロセスよりも高い優先度に設定されていることがわかります。

質問 3 について、ご説明の状況は、通常の割り込みでも発生する可能性があります。通常、カーネルでは、ISR の実行中は割り込みが無効になります。ISR の実行中、文字はデバイスのバッファを満たし続けることができ、デバイスは割り込みが無効になっている間でも割り込みをアサートし続けることができ、またアサートし続ける必要があります。

すべての文字が読み取られ、すべての処理が ISR によって完了するまで、IRQ ラインがアサートされたままになっていることを確認するのは、デバイスの仕事です。割り込みがレベルでトリガーされること、または設計によっては割り込みコントローラーによってラッチされることも重要です。

最後に、デバイス/ペリフェラルには適切なサイズの FIFO が必要であり、高速で配信される文字が低速の ISR によって失われることはありません。また、ISR は、実行時にできるだけ多くの文字を読み取るように設計する必要があります。

一般的に言えば、コントローラーには特定のサイズXの FIFO があり、FIFO がいっぱいX/2になると、ISR が可能な限り多くのデータを取得する割り込みを発生させます。ISR は可能な限り読み取りを行ってから、割り込みをクリアします。一方、FIFO がまだ のX/2場合、デバイスは割り込みラインをアサートしたままにし、ISR を再度実行させます。

于 2014-05-18T02:42:52.790 に答える
2
  1. 以前は、下半分は ではなく、taskまだをブロックできませんでした。唯一の違いは、割り込みが無効になっていることです。taskletまたはsoftirqは、ドライバーのISR スレッドとユーザー API ( ioctl()read()、およびwrite()) の間で異なる相互ロックを許可します。
  2. work queueほぼ同等だと思います。ただし、タスクレット/ksoftirqは優先度が高く、そのプロセッサ上のすべての ISR ベースの機能で使用されます。これにより、より良いスケジューリングの機会が得られる場合があります。また、ドライバーが管理することも少なくなります。すべてがカーネルの ISR ハンドラ コードに組み込まれています。
  3. これを処理する必要があります。通常、ピンポンバッファーを使用するか、kfifo提案するようなものを使用できます。はhandler貪欲であり、戻る前に UART からすべてのデータを取得する必要がありますIRQ_WAKE_THREAD
于 2013-03-20T18:08:48.973 に答える
2

質問 3 については、threadedirq がアクティブ化されると、対応する割り込みラインがマスクまたは無効化されます。threadedirq が実行されて完了すると、終了に向かって有効になります。したがって、それぞれの threadedirq の実行中に割り込みが発生することはありません。

于 2013-10-29T05:42:03.590 に答える
1

「ハード」/「ソフト」ハンドラーをスレッド化ハンドラーに変換する元の作業は、PREEMPT_RT Linux (別名 Linux-as-an-RTOS) プロジェクト (メインラインの一部ではありません) を構築するときに、Thomas Gleixner とチームによって行われました。Linux を真に RTOS として実行するには、割り込みハンドラーが最も重要な rt (アプリ) スレッドに割り込む状況を容認することはできません。しかし、アプリ スレッドが割り込みをオーバーライドするようにするにはどうすればよいでしょうか?? (割り込みを) スレッド化し、スケジュール可能 (SCHED_FIFO) にし、アプリ スレッドより優先度を低くします (割り込みスレッドの rtprio のデフォルトは 50 です)。そのため、rtprio が 60 の「rt」SCHED_FIFO アプリ スレッドは、割り込みスレッドであっても「プリエンプション」を行うことができます (機能するのに十分近い)。それはあなたのQに答えるはずです。2.

Qs 3への書き込み:他の人が言ったように、コードはこの状況を処理する必要があります。そうは言っても、スレッド化されたハンドラーを使用する重要なポイントは、(おそらく) ブロック (スリープ) する作業を実行できるようにすることです。「下半分」の作業が非ブロッキングであることが保証され、高速である必要がある場合は、従来のスタイルの「上半分/bh」ハンドラを使用してください。どうすればそれができますか?シンプル: request_threaded_irq() を使用しないで、request_irq() を呼び出すだけです - コード内のコメントは明確に述べています (3 番目のパラメーターについて):

* @thread_fn: Function called from the irq handler thread
*          If NULL, no irq thread is created"

または、IRQF_NO_THREAD フラグを request_irq に渡すこともできます。

(ちなみに、3.14.23 カーネル ソース ツリーで cscope を使用して簡単に確認すると、request_irq() が 1502 回呼び出され [スレッド化されていない割り込み処理が提供されます]、request_threaded_irq() [スレッド化された割り込み] が明示的に 204 回呼び出されていることがわかります)。

于 2015-03-25T08:10:53.547 に答える