スキップしてメイン コンテンツへ

 none
IoGetDmaAdapterで4GB超のバッファを取得したい RRS feed

  • 質問

  • 64ビット版のwindows7で動作するWDMドライバを開発しています。PCI-Expカード上のDMAコアでシステムメモリとDMAを行う際にDMAバッファを大量に確保します。IoGetDmaAdapterからのAllocateCommonBufferを使っていますが、実験的に数MB程度のバッファ取得を何度も繰り返し、どの程度確保できるか試したところ、3.5GBあたりに壁があり、それ以上のトータル確保ができません。(マシンはamd64タイプで12GBのメモリを実装・認識しています)

    IoGetDmaAdapterの指定は以下のパラメータで行っています。

        RtlZeroMemory(&DeviceDescription,sizeof(DeviceDescription));
        DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
        DeviceDescription.Master = TRUE;
        DeviceDescription.ScatterGather = FALSE;
        DeviceDescription.DemandMode = FALSE;
        DeviceDescription.AutoInitialize = FALSE;
        DeviceDescription.Dma32BitAddresses = FALSE;
        DeviceDescription.Dma64BitAddresses = TRUE;
        DeviceDescription.InterfaceType = PCIBus;
        DeviceDescription.MaximumLength = (ULONG) -1;

    また、このとき、書き戻される物理アドレスは4GB空間内のアドレスで、4GBを超えるアドレスは見たことがありません。

    どうしたら4GB以上のバッファを取得できますか?

    何卒よろしくお願いします。

    2013年11月5日 7:02

回答

  • I am not sure, ... but "Performing DMA in 64-Bit Windows" said followings:

    ----------------------------------
    Performing DMA in 64-Bit Windows

    3. Use the high-performance scatter/gather routines (GetScatterGatherList and PutScatterGatherList) that were added in Windows 2000.
    ----------------------------------

    > DeviceDescription.ScatterGather = FALSE;

    Why do you set "FALSE" in ScatterGather member of the DEVICE_DESCRIPTION structure?

    2013年11月6日 8:25

すべての返信

  • F.Y.I.
    ----------------------------------
    Performing DMA in 64-Bit Windows
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff558795(v=vs.85).aspx
    ----------------------------------

    2013年11月6日 3:03
  • A log is displayed on below.

    ---------------------------------------------

    sizeof(Mm64BitPhysicalAddress)=8
    *Mm64BitPhysicalAddress=1
    Mm64BitPhysicalAddress is TRUE

    Alloc. Init size=0x40000000
    [   0] AllocateCommonBuffer(Len:40000000) Failure
    [   0] AllocateCommonBuffer(Len:20000000) Failure
    [   0] AllocateCommonBuffer(Len:10000000) Failure
    [   0] AllocateCommonBuffer(Len:08000000,Phy:962a0000,Ptr:fffff88010800000) OK
    [   1] AllocateCommonBuffer(Len:08000000,Phy:71199000,Ptr:fffff88018800000) OK
    [   2] AllocateCommonBuffer(Len:08000000,Phy:5e1aa000,Ptr:fffff88020800000) OK
    [   3] AllocateCommonBuffer(Len:08000000,Phy:420af000,Ptr:fffff88028800000) OK
    [   4] AllocateCommonBuffer(Len:08000000,Phy:3341b000,Ptr:fffff88030800000) OK
    [   5] AllocateCommonBuffer(Len:08000000,Phy:116a7000,Ptr:fffff88038800000) OK
    [   6] AllocateCommonBuffer(Len:08000000) Failure
    [   6] AllocateCommonBuffer(Len:04000000,Phy:c839f000,Ptr:fffff88040800000) OK
    [   7] AllocateCommonBuffer(Len:04000000,Phy:b29f8000,Ptr:fffff88044800000) OK
        :
    [  17] AllocateCommonBuffer(Len:04000000,Phy:2511c000,Ptr:fffff8806c800000) OK
    [  18] AllocateCommonBuffer(Len:04000000) Failure
    [  18] AllocateCommonBuffer(Len:02000000,Phy:d2d1b000,Ptr:fffff88070800000) OK
    [  19] AllocateCommonBuffer(Len:02000000,Phy:cfe0f000,Ptr:fffff88072800000) OK
        :
    [  44] AllocateCommonBuffer(Len:02000000,Phy:0649d000,Ptr:fffff880a4800000) OK
    [  45] AllocateCommonBuffer(Len:02000000) Failure
    [  45] AllocateCommonBuffer(Len:01000000,Phy:cea9d000,Ptr:fffff880a6800000) OK
    [  46] AllocateCommonBuffer(Len:01000000,Phy:c6991000,Ptr:fffff880a7800000) OK
        :
    [  67] AllocateCommonBuffer(Len:01000000,Phy:0549d000,Ptr:fffff880bc800000) OK
    [  68] AllocateCommonBuffer(Len:01000000) Failure
    [  68] AllocateCommonBuffer(Len:00800000,Phy:d4ddf000,Ptr:fffff88006000000) OK
    [  69] AllocateCommonBuffer(Len:00800000,Phy:d251b000,Ptr:fffff88006e00000) OK
        :
    [  99] AllocateCommonBuffer(Len:00800000,Phy:0b53d000,Ptr:fffff880c7000000) OK
    [ 100] AllocateCommonBuffer(Len:00800000) Failure
    [ 100] AllocateCommonBuffer(Len:00400000,Phy:d66ff000,Ptr:fffff88006800000) OK
    [ 101] AllocateCommonBuffer(Len:00400000,Phy:d211b000,Ptr:fffff88007600000) OK
        :
    [ 129] AllocateCommonBuffer(Len:00400000,Phy:00c00000,Ptr:fffff880cbc00000) OK
    [ 130] AllocateCommonBuffer(Len:00400000) Failure
    [ 130] AllocateCommonBuffer(Len:00200000,Phy:d6c65000,Ptr:fffff88005c00000) OK
    [ 131] AllocateCommonBuffer(Len:00200000,Phy:d1f1b000,Ptr:fffff880cc000000) OK
        :
    [ 180] AllocateCommonBuffer(Len:00200000,Phy:00600000,Ptr:fffff880d2200000) OK
    [ 181] AllocateCommonBuffer(Len:00200000) Failure
    [ 181] AllocateCommonBuffer(Len:00100000,Phy:d6b65000,Ptr:fffff88005900000) OK
    [ 182] AllocateCommonBuffer(Len:00100000,Phy:cfb0f000,Ptr:fffff880d2400000) OK
        :
    [ 226] AllocateCommonBuffer(Len:00100000,Phy:0447e000,Ptr:fffff880d5000000) OK
    [ 227] AllocateCommonBuffer(Len:00100000) Failure
    Total allocated size=cdc00000
    -------------------------------------------

    It will be why?

    2013年11月6日 7:50
  • I am not sure, ... but "Performing DMA in 64-Bit Windows" said followings:

    ----------------------------------
    Performing DMA in 64-Bit Windows

    3. Use the high-performance scatter/gather routines (GetScatterGatherList and PutScatterGatherList) that were added in Windows 2000.
    ----------------------------------

    > DeviceDescription.ScatterGather = FALSE;

    Why do you set "FALSE" in ScatterGather member of the DEVICE_DESCRIPTION structure?

    2013年11月6日 8:25
  • I was surprised.
    When setting the ScatterGather member to TRUE, 4 GB of wall was exceeded frankly.
    Was this member a key?
    no, - it went.
    It is solution frankly.

    Result is following with successfully.

    (8GByte Memory)

    SubdrvGetDmaBufOk() sizeof(Mm64BitPhysicalAddress)=8
    SubdrvGetDmaBufOk() *Mm64BitPhysicalAddress=1
    Mm64BitPhysicalAddress is TRUE

    Alloc. Init size=40000000
    [   0] AllocateCommonBuffer(Len:40000000) Failure
    [   0] AllocateCommonBuffer(Len:20000000) Failure
    [   0] AllocateCommonBuffer(Len:10000000) Failure
    [   0] AllocateCommonBuffer(Len:08000000,Phy:1e2e85000,Ptr:fffff88010800000) OK
    [   1] AllocateCommonBuffer(Len:08000000,Phy:1da387000,Ptr:fffff88018800000) OK
    [   2] AllocateCommonBuffer(Len:08000000,Phy:1c4308000,Ptr:fffff88020800000) OK
    [   3] AllocateCommonBuffer(Len:08000000,Phy:1b9c07000,Ptr:fffff88028800000) OK
    [   4] AllocateCommonBuffer(Len:08000000,Phy:1a3486000,Ptr:fffff88030800000) OK
    [   5] AllocateCommonBuffer(Len:08000000,Phy:183430000,Ptr:fffff88038800000) OK
    [   6] AllocateCommonBuffer(Len:08000000,Phy:11f48f000,Ptr:fffff88040800000) OK
    [   7] AllocateCommonBuffer(Len:08000000,Phy:114894000,Ptr:fffff88048800000) OK
    [   8] AllocateCommonBuffer(Len:08000000,Phy:b020f000,Ptr:fffff88050800000) OK
    [   9] AllocateCommonBuffer(Len:08000000) Failure
    [   9] AllocateCommonBuffer(Len:04000000,Phy:200a03000,Ptr:fffff88058800000) OK
    [  10] AllocateCommonBuffer(Len:04000000,Phy:1f2a80000,Ptr:fffff8805c800000) OK
        :
    [  43] AllocateCommonBuffer(Len:04000000,Phy:14520000,Ptr:fffff880e0800000) OK
    [  44] AllocateCommonBuffer(Len:04000000) Failure
    [  44] AllocateCommonBuffer(Len:02000000,Phy:1fce80000,Ptr:fffff880e4800000) OK
    [  45] AllocateCommonBuffer(Len:02000000,Phy:1f9a04000,Ptr:fffff880e6800000) OK
        :
    [  99] AllocateCommonBuffer(Len:02000000,Phy:06343000,Ptr:fffff88152800000) OK
    [ 100] AllocateCommonBuffer(Len:02000000) Failure
    [ 100] AllocateCommonBuffer(Len:01000000,Phy:1fbe80000,Ptr:fffff88154800000) OK
    [ 101] AllocateCommonBuffer(Len:01000000,Phy:1f8a04000,Ptr:fffff88155800000) OK
        :
    [ 164] AllocateCommonBuffer(Len:01000000,Phy:05343000,Ptr:fffff88194800000) OK
    [ 165] AllocateCommonBuffer(Len:01000000) Failure
    [ 165] AllocateCommonBuffer(Len:00800000,Phy:1f8204000,Ptr:fffff88006000000) OK
    [ 166] AllocateCommonBuffer(Len:00800000,Phy:1f2280000,Ptr:fffff88006e00000) OK
        :
    [ 233] AllocateCommonBuffer(Len:00800000,Phy:08a23000,Ptr:fffff881b1800000) OK
    [ 234] AllocateCommonBuffer(Len:00800000) Failure
    [ 234] AllocateCommonBuffer(Len:00400000,Phy:1fba80000,Ptr:fffff88005a00000) OK
    [ 235] AllocateCommonBuffer(Len:00400000,Phy:1f7e04000,Ptr:fffff88006800000) OK
        :
    [ 298] AllocateCommonBuffer(Len:00400000,Phy:00c00000,Ptr:fffff881bec00000) OK
    [ 299] AllocateCommonBuffer(Len:00400000) Failure
    [ 299] AllocateCommonBuffer(Len:00200000,Phy:21cc00000,Ptr:fffffa8008600000) OK
    [ 300] AllocateCommonBuffer(Len:00200000,Phy:21ca00000,Ptr:fffffa8008800000) OK
        :
    [ 474] AllocateCommonBuffer(Len:00200000,Phy:00600000,Ptr:fffff881c7e00000) OK
    [ 475] AllocateCommonBuffer(Len:00200000) Failure
    [ 475] AllocateCommonBuffer(Len:00100000,Phy:21d0a8000,Ptr:fffffa80082a8000) OK
    [ 476] AllocateCommonBuffer(Len:00100000,Phy:20e8ef000,Ptr:fffff88005900000) OK
        :
    [ 566] AllocateCommonBuffer(Len:00100000,Phy:04461000,Ptr:fffff881cd900000) OK
    [ 567] AllocateCommonBuffer(Len:00100000) Failure
    Total allocated size=1d3800000

    Thank you.
    2013年11月6日 11:04
  • > When setting the ScatterGather member to TRUE, 4 GB of wall was exceeded frankly.
    > Was this member a key?


    The "Scatter/Gather" mechanism is very important in Windows system.
    I recommend that you understand this mechanism.

    --------------------------------------------------------------------------
    スキャッタ・ギャザー(Scatter/Gather)
    http://pc.watch.impress.co.jp/docs/article/990428/key75.htm

    Using Scatter/Gather DMA
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff565510(v=vs.85).aspx
    --------------------------------------------------------------------------

    // なぜ英語??

    2013年11月8日 2:36