保留中の文字が256文字を超えると、8250 UARTドライバーがTTYを起動しないのはなぜですか?


8

このif条件の動機は何void serial8250_tx_chars(struct uart_8250_port *up)ですか?

if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
    uart_write_wakeup(port);

Linux 1.1.13(1994年5月)から存在し、ほとんどのUARTドライバーで繰り返されています。

背景:カスタマイズされたLinux 3.4.91、ARMv7の組み込みシステム、UARTポート0は、38400ボー、I / O用の16バイトFIFOに設定されています。これは、セットアップでは変更できません。

UARTを介してコンソールで非常に重いprintfを実行すると、内部の4kBバッファー(UART_XMIT_SIZE)がいっぱいになり、バッファーが空になるまで(38400ボーで1秒かかります)、ユーザー空間プロセスが停止します。その後、この動作が繰り返されます。これはn_tty_write()、バッファがいっぱいになると関数がスリープ状態になり、上記の疑わしい状態のために長時間ウェイクアップされないためです。

このチェックを削除するだけで、より自然で効率的になります。次に、printfsはできるだけ早くバッファーをいっぱいにして、私が観察しているバースト処理ではなく、バッファーが空になる速度で続行します。

私の環境では問題なく動作しますが、確かに何かが足りない、または誤解しています。現在の実装には理由があるはずです。その状態を取り除くと副作用はありますか?

余談ですが、この動作を調整するための構成オプションはありますか。たとえば、printfが常にすぐに戻り、バッファーがいっぱいの場合は出力を破棄するように設定しますか?


これについてあまり知らなくても、私の直感はこれです。これは通常のLinuxシリアルコンソールセットアップです。私はそれらを標準のx86ハードウェアで使用しました。直接シリアル接続では、常にハードウェアフロー制御を使用する必要がありました。アイデアかもしれません。
vasquez 2016

1
おそらく効率の違いがあります。WAKEUP_CHARSをUART_XMIT_SIZE-128のような値に設定しないのはなぜですか?
James Youngman、

@JamesYoungman実際、それも結局私がやったことです。乾杯!
ハンスW.ヘッケル

回答:


2

それは効率の尺度です。CPUはシリアルポートよりもはるかに高速で実行されるため、カーネルにバッファーに少し余裕があるたびにユーザースペースプロセスを実行させると、データの1バイトごとにユーザースペースに移動して戻ることになります。これはCPU時間の浪費です。

$ time dd if=/dev/zero of=/dev/null bs=1 count=10000000
10000000+0 records in
10000000+0 records out
10000000 bytes (10 MB, 9.5 MiB) copied, 5.95145 s, 1.7 MB/s

real    0m5.954s
user    0m1.960s
sys     0m3.992s

$ time dd if=/dev/zero of=/dev/null bs=1000 count=10000
10000+0 records in
10000+0 records out
10000000 bytes (10 MB, 9.5 MiB) copied, 0.011041 s, 906 MB/s

real    0m0.014s
user    0m0.000s
sys     0m0.012s

上記のテストは、実際のデバイスの読み取りと書き込みを行うものではありません。全体の時間差は、システムがユーザー空間とカーネル空間の間でバウンドする頻度です。

ユーザースペースが保持されたくない場合は、非ブロッキングI / Oを使用できます。または、select()呼び出しを使用して、デバイスに書き込むスペースがあるかどうかを確認できます。デバイススペースがない場合は、ダンプしてダンプできます。残りを独自のバッファーに入れ、処理を続行します。確かに、フラッシュする必要のあるバッファーがあるので、それは事態を複雑にします...しかし、stdioを使用している場合、それはとにかく本当です。


これは、上記の効率に関する@Jamesのコメントをサポートします。今では、私にはもっと理にかなっています。数字もありがとう!
ハンスW.ヘッケル2016年

カーネル2.6以降、この質問は下位層のドライバー(UARTドライバーなど)によく現れるコードを参照していることに注意してください。これらのドライバーは、ハードウェアと対話するための手段である上位層、serial_coreを提供します。ユーザー空間と実際にやり取りするのは、シリアルコアです(ハードウェアドライバーが独自のioctlまたは同様のものを実装していない場合)。回答者の回答はまだ保持されていると思います。
Andrew Falanga
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.