4

私は、ファッションの後、動作しているブロックデバイスドライバーを持っています。これは PCIe デバイス用であり、デバイスにはシーク時間がないため、要求キューを使用するのではなく、make_request_fn を使用して BIOS を直接処理しています。ただし、まだトランザクション オーバーヘッドがあります。

デバイスから連続して読み取ると、多くのセグメント (通常は最大 32) を持つ BIOS が取得され、それぞれが 2 つのハードウェア セクター (つまり 2 * 2k) で構成され、これがデバイスへの 1 つのスキャッター ギャザー トランザクションとして処理され、保存されます。多くのシグナリング オーバーヘッド。ただし、書き込みでは、BIOS にはそれぞれ 2 セクターのセグメントが 1 つしかないため、合計で操作にかなりの時間がかかります。私がやりたいことは、入ってくる BIOS を何らかの方法で多くのセグメントで構成するか、または自分で BIOS を適切にマージすることです。ここで正しいアプローチは何ですか?

の現在の内容は、次のmake_request_fnようなものです。

  • バイオの読み取り/書き込みを決定する
  • 略歴の各セグメントについて、scatterlist*with でエントリを作成しますsg_set_page
  • このスキャッタリストを PCI にマッピングするにはpci_map_sg
  • scatterlist 内のすべてのセグメントについて、複数セグメントの DMA スキャッター ギャザー操作を定義するデバイス固有の構造に追加します。
  • その構造をDMAにマップする
  • 取引を行う
  • 構造と SG DMA のマップ解除
  • 失敗した場合と成功bio_endioした場合に呼び出します。-EIO0

リクエスト キューは次のように設定されます。

#define MYDEV_BLOCK_MAX_SEGS 32
#define MYDEV_SECTOR_SIZE 2048

blk_queue_make_request(mydev->queue, mydev_make_req);

set_bit(QUEUE_FLAG_NONROT, &mydev->queue->queue_flags);
blk_queue_max_segments(mydev->queue, MYDEV_BLOCK_MAX_SEGS);
blk_queue_physical_block_size(mydev->queue, MYDEV_SECTOR_SIZE);
blk_queue_logical_block_size(mydev->queue, MYDEV_SECTOR_SIZE);

blk_queue_flush(mydev->queue, 0);

blk_queue_segment_boundary(mydev->queue, -1UL);
blk_queue_max_segments(mydev->queue, MYDEV_BLOCK_MAX_SEGS);
blk_queue_dma_alignment(mydev->queue, 0x7);
4

0 に答える 0