5

大きな SCSI 書き込みを生成するユーザー空間アプリケーションがあります (詳細は後述)。しかし、SCSI ターゲット (つまり、FC によって接続されたストレージ) に到達する SCSI コマンドを見ると、これらの書き込みが 512K のチャンクに分割されています。

アプリケーションは基本的に、デバイスに直接 1M サイズの直接書き込みを行います。

fd = open("/dev/sdab", ..|O_DIRECT);
write(fd, ..., 1024 * 1024);

このコードにより、それぞれ 512K の 2 つの SCSI WRITE が送信されます。

ただし、ブロック層なしで直接 SCSI コマンドを発行すると、書き込みは分割されません。コマンドラインから次のコマンドを発行します。

sg_dd bs=1M count=1 blk_sgio=1 if=/dev/urandom of=/dev/sdab oflag=direct

1M サイズの SCSI WRITE が 1 つ確認できます。

問題は、何が書き込みを分割しているのか、さらに重要なことに、それは構成可能かということです。Linux のブロック層は (SG_IO が通過しないため) 有罪のようであり、512K はあまりにも恣意的な数値であり、何らかの構成可能なパラメーターではないようです。

4

5 に答える 5

3

「IO 要求のサイズが約 512K に制限されているのはなぜですか」に対する回答で説明されているように、 Unix & Linux Stack Exchange の質問と、「 2MB が 512KB に変わるとき」ドキュメントの「デバイスの制限」セクション (カーネル ブロック レイヤーによる)メンテナの Jens Axboe さん、これは、デバイスとカーネルにサイズ制限があるためである可能性があります ( に表示/sys/block/<disk>/queue/):

  • max_hw_sectors_kbハードウェアが受け入れることができる単一の I/O の最大サイズ
  • max_sectors_kbブロックレイヤーが送信する最大サイズ
  • max_segment_sizeスキャッター ギャザー (SG) I/Oのmax_segmentsDMA エンジンの制限 (各セグメントの最大サイズと単一の I/O の最大セグメント数)

セグメントの制限は、I/O の送信元のバッファーが連続していない場合に非常に重要であり、最悪の場合、各セグメントがページ (x86 プラットフォームでは 4096 バイト) と同じくらい小さい場合があります。これは、1 つの I/O の SG I/O を 4096 * のサイズに制限できることを意味しますmax_segments

問題は、何が書き込みを分割しているのかということです

ご想像のとおり、Linux ブロック層です。

さらに重要なことに、それは構成可能ですか?

いじることはできますmax_sectors_kbが、残りは修正されており、デバイス/ドライバーの制限から来ています(したがって、おそらくそうではないと推測しますが、メモリの断片化が少ないため、再起動直後により大きなI / Oが表示される場合があります)。

512K は恣意的な数値であり、何らかの構成可能なパラメーターにはなりません。

この値は、フラグメント SG バッファーに関連している可能性があります。x86 プラットフォームを使用していて、次max_segments128ようになっているとします。

4096 * 128 / 1024 = 512

それが 512K の由来です。

おまけのおしゃべり: https://twitter.com/axboe/status/1207509190907846657によると、お使いのデバイスが DMA エンジンではなく IOMMU を使用している場合、セグメントが制限されるべきではありません...

于 2019-12-19T04:26:27.720 に答える
1

責任は確かにブロック層にあり、SCSI層自体はサイズにほとんど関係がありません。ただし、特にdirect ioに関しては、基盤となるレイヤーが実際にリクエストを渡すことができることを確認する必要があります。これは、多くの小さなページに分割される可能性があり、ハードウェアでサポートできるものよりも長いスキャッターギャザーリストが必要になるためです。ドライバーだけでも(libataは多少制限されていました)。

/ sys / class / block / $ DEV / queueを調べて調整する必要があります。そこにはさまざまなファイルがあり、必要なものと一致する可能性が最も高いのはmax_sectors_kbですが、試してみて、何が効果的かを確認できます。また、パーティション変数も調整する必要がある場合があります。

于 2012-07-14T20:59:04.853 に答える
1

ブロック ドライバーの要求属性ごとに最大セクターがあります。変更方法を確認する必要があります。以前は blockdev --getmaxsect を介してこの値を取得できましたが、マシンの blockdev に --getmaxsect オプションが表示されません。

于 2012-06-10T19:24:58.643 に答える
0

次のファイルを見ると、論理ブロック サイズが異なるかどうかがわかります。この場合はおそらく 512 です。ただし、これらのファイルに書き込んでこれらの値を変更できるかどうかはわかりません。(論理ブロックサイズ)

/sys/block/<disk>/queue/physical_block_size 
/sys/block/<disk>/queue/logical_block_size
于 2012-05-14T17:47:59.300 に答える
0

ioctl(fd, BLKSECTSET, &blocks) を試す

于 2013-02-16T02:56:33.107 に答える