私は、ファッションの後、動作しているブロックデバイスドライバーを持っています。これは 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
した場合に呼び出します。-EIO
0
リクエスト キューは次のように設定されます。
#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);