From: Carsten Schmidt Carsten on 4 Sep 2009 12:14 Hi, Sometimes I experience strange behavior when writing to the irp->MdlAddress buffer of a disk filter driver I am writing. In my IRP_MJ_READ routine I need to return the contents of an internal buffer in stead of passing the request on to the disk driver. If I enter the code below in the IRP_MJ_READ dispatch routine the assertion occasionally fails, i.e., the RtlCopyMemory command did not copy correctly. if (irp->MdlAddress) { void* mdlBuffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); ULONG length = IoGetCurrentIrpStackLocation(irp)->Parameters.Read.Length; RtlCopyMemory(mdlBuffer, buffer, length); ASSERT(RtlEqualMemory(mdlBuffer, buffer, length )); // <- This assertion occasionally fails } Typically irp->MdlAddress->MdlFlags is (MDL_IO_PAGE_READ | MDL_PAGES_LOCKED) before the MmGetSystemAddressForMdlSafe() call and (MDL_IO_PAGE_READ | MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA) afterwards. What really puzzles me is that after one ore more attempts the test code below succeeds. It looks like the MDL is not fully ready yet on the first attempt and that a separate thread is building it simultaneously. do { differs = FALSE; RtlFillMemory(mdlBuffer, length, 'X'); for (i = 0; i < length; ++i) { if (buffer[i] != 'X') { differs = TRUE; KdPrint( ("Byte %d of %d differs.\n", i, length) ); } } } while (differs); Can anybody please tell me what is going on. Thanks
From: Alexander Grigoriev on 4 Sep 2009 23:37 This is essentially the same memory that your application gives. If the application is modifying the memory while you're copying there, you'll get a mismatch. "Carsten Schmidt" <Carsten Schmidt(a)discussions.microsoft.com> wrote in message news:378D665B-1166-4C38-9362-B4927F395E51(a)microsoft.com... > Hi, > > Sometimes I experience strange behavior when writing to the > irp->MdlAddress > buffer of a disk filter driver I am writing. > > In my IRP_MJ_READ routine I need to return the contents of an internal > buffer in stead of passing the request on to the disk driver. > > If I enter the code below in the IRP_MJ_READ dispatch routine the > assertion > occasionally fails, i.e., the RtlCopyMemory command did not copy > correctly. > > > if (irp->MdlAddress) { > void* mdlBuffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, > NormalPagePriority); > ULONG length = > IoGetCurrentIrpStackLocation(irp)->Parameters.Read.Length; > RtlCopyMemory(mdlBuffer, buffer, length); > ASSERT(RtlEqualMemory(mdlBuffer, buffer, length )); // <- This > assertion > occasionally fails > } > > > Typically irp->MdlAddress->MdlFlags is (MDL_IO_PAGE_READ | > MDL_PAGES_LOCKED) > before the MmGetSystemAddressForMdlSafe() call and (MDL_IO_PAGE_READ | > MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA) afterwards. > > What really puzzles me is that after one ore more attempts the test code > below succeeds. It looks like the MDL is not fully ready yet on the first > attempt and that a separate thread is building it simultaneously. > > > do { > differs = FALSE; > RtlFillMemory(mdlBuffer, length, 'X'); > for (i = 0; i < length; ++i) { > if (buffer[i] != 'X') { > differs = TRUE; > KdPrint( ("Byte %d of %d differs.\n", i, length) ); > } > } > } while (differs); > > > Can anybody please tell me what is going on. > > Thanks >
From: Carsten Schmidt on 5 Sep 2009 05:26 Thanks for your reply. It was much appreciated, but I'm afraid it didn't help me much. Since I am in an IRP_MJ_READ request I am expected to write to the buffer. Furthermore, the MDL_MAPPED_TO_SYSTEM_VA flag is not set, i.e., the memory is not mapped to virtual memory yet, so no other thread can write to the memory simultaneously. However, after I posted this question I think I have come across a explanation to what is happening. The memory manager has mapped some MDL pages to a dummy page (http://www.microsoft.com/whdc/driver/tips/mdl.mspx). "Carsten Schmidt" wrote: > Hi, > > Sometimes I experience strange behavior when writing to the irp->MdlAddress > buffer of a disk filter driver I am writing. > > In my IRP_MJ_READ routine I need to return the contents of an internal > buffer in stead of passing the request on to the disk driver. > > If I enter the code below in the IRP_MJ_READ dispatch routine the assertion > occasionally fails, i.e., the RtlCopyMemory command did not copy correctly. > > > if (irp->MdlAddress) { > void* mdlBuffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, > NormalPagePriority); > ULONG length = IoGetCurrentIrpStackLocation(irp)->Parameters.Read.Length; > RtlCopyMemory(mdlBuffer, buffer, length); > ASSERT(RtlEqualMemory(mdlBuffer, buffer, length )); // <- This assertion > occasionally fails > } > > > Typically irp->MdlAddress->MdlFlags is (MDL_IO_PAGE_READ | MDL_PAGES_LOCKED) > before the MmGetSystemAddressForMdlSafe() call and (MDL_IO_PAGE_READ | > MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA) afterwards. > > What really puzzles me is that after one ore more attempts the test code > below succeeds. It looks like the MDL is not fully ready yet on the first > attempt and that a separate thread is building it simultaneously. > > > do { > differs = FALSE; > RtlFillMemory(mdlBuffer, length, 'X'); > for (i = 0; i < length; ++i) { > if (buffer[i] != 'X') { > differs = TRUE; > KdPrint( ("Byte %d of %d differs.\n", i, length) ); > } > } > } while (differs); > > > Can anybody please tell me what is going on. > > Thanks >
From: Alexander Grigoriev on 5 Sep 2009 11:22 No, the dummy page is not relevant to this. Again, mapping to the system space doesn't make the memory protected from other writers. It's just mapping (aliasing), not copying. If your application is modifying the buffer at this time (by writing to the user-mode address), you'll see the modifications at the system-mapped address, and the other way around. If your application accidentally passed the same buffer to two different read requests from another threads at the same time, you may also see such corruption. "Carsten Schmidt" <CarstenSchmidt(a)discussions.microsoft.com> wrote in message news:50E4B253-D482-4675-905A-9A884C8DD50B(a)microsoft.com... > Thanks for your reply. It was much appreciated, but I'm afraid it didn't > help > me much. Since I am in an IRP_MJ_READ request I am expected to write to > the > buffer. Furthermore, the MDL_MAPPED_TO_SYSTEM_VA flag is not set, i.e., > the > memory is not mapped to virtual memory yet, so no other thread can write > to > the memory simultaneously. > > However, after I posted this question I think I have come across a > explanation to what is happening. The memory manager has mapped some MDL > pages to a dummy page > (http://www.microsoft.com/whdc/driver/tips/mdl.mspx). > > "Carsten Schmidt" wrote: > >> Hi, >> >> Sometimes I experience strange behavior when writing to the >> irp->MdlAddress >> buffer of a disk filter driver I am writing. >> >> In my IRP_MJ_READ routine I need to return the contents of an internal >> buffer in stead of passing the request on to the disk driver. >> >> If I enter the code below in the IRP_MJ_READ dispatch routine the >> assertion >> occasionally fails, i.e., the RtlCopyMemory command did not copy >> correctly. >> >> >> if (irp->MdlAddress) { >> void* mdlBuffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, >> NormalPagePriority); >> ULONG length = >> IoGetCurrentIrpStackLocation(irp)->Parameters.Read.Length; >> RtlCopyMemory(mdlBuffer, buffer, length); >> ASSERT(RtlEqualMemory(mdlBuffer, buffer, length )); // <- This >> assertion >> occasionally fails >> } >> >> >> Typically irp->MdlAddress->MdlFlags is (MDL_IO_PAGE_READ | >> MDL_PAGES_LOCKED) >> before the MmGetSystemAddressForMdlSafe() call and (MDL_IO_PAGE_READ | >> MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA) afterwards. >> >> What really puzzles me is that after one ore more attempts the test code >> below succeeds. It looks like the MDL is not fully ready yet on the first >> attempt and that a separate thread is building it simultaneously. >> >> >> do { >> differs = FALSE; >> RtlFillMemory(mdlBuffer, length, 'X'); >> for (i = 0; i < length; ++i) { >> if (buffer[i] != 'X') { >> differs = TRUE; >> KdPrint( ("Byte %d of %d differs.\n", i, length) ); >> } >> } >> } while (differs); >> >> >> Can anybody please tell me what is going on. >> >> Thanks >>
|
Pages: 1 Prev: data stored on CDs in raw mode Next: How to Communicate with chips on the ISA bus/SMBus? |