--- a/src/xenvbd/pdo.c +++ b/src/xenvbd/pdo.c @@ -1113,13 +1113,12 @@ UseIndirect( return MaxIndirectSegs; } -static FORCEINLINE ULONG +static FORCEINLINE VOID PdoQueueRequestList( IN PXENVBD_PDO Pdo, IN PLIST_ENTRY List ) { - ULONG Count = 0; for (;;) { PXENVBD_REQUEST Request; PLIST_ENTRY Entry; @@ -1128,12 +1127,10 @@ PdoQueueRequestList( if (Entry == List) break; - ++Count; Request = CONTAINING_RECORD(Entry, XENVBD_REQUEST, Entry); __PdoIncBlkifOpCount(Pdo, Request); QueueAppend(&Pdo->PreparedReqs, &Request->Entry); } - return Count; } static FORCEINLINE VOID @@ -1167,9 +1164,10 @@ PrepareReadWrite( ULONG SectorsLeft = Cdb_TransferBlock(Srb); LIST_ENTRY List; XENVBD_SG_LIST SGList; + LONG ReqCount = 0; InitializeListHead(&List); - SrbExt->Count = 0; + SrbExt->ReqCount = 0; Srb->SrbStatus = SRB_STATUS_PENDING; RtlZeroMemory(&SGList, sizeof(SGList)); @@ -1184,6 +1182,7 @@ PrepareReadWrite( if (Request == NULL) goto fail1; InsertTailList(&List, &Request->Entry); + ReqCount++; Request->Srb = Srb; MaxSegments = UseIndirect(Pdo, SectorsLeft); @@ -1206,7 +1205,9 @@ PrepareReadWrite( SectorStart += SectorsDone; } - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + SrbExt->ReqCount = ReqCount; + KeMemoryBarrier(); + PdoQueueRequestList(Pdo, &List); return TRUE; fail3: @@ -1234,7 +1235,7 @@ PrepareSyncCache( Operation = BLKIF_OP_WRITE_BARRIER; InitializeListHead(&List); - SrbExt->Count = 0; + SrbExt->ReqCount = 0; Srb->SrbStatus = SRB_STATUS_PENDING; Request = PdoGetRequest(Pdo); @@ -1246,7 +1247,9 @@ PrepareSyncCache( Request->Operation = Operation; Request->FirstSector = Cdb_LogicalBlock(Srb); - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + SrbExt->ReqCount = 1; + KeMemoryBarrier(); + PdoQueueRequestList(Pdo, &List); return TRUE; fail1: @@ -1266,9 +1269,10 @@ PrepareUnmap( ULONG Count = _byteswap_ushort(*(PUSHORT)Unmap->BlockDescrDataLength) / sizeof(UNMAP_BLOCK_DESCRIPTOR); ULONG Index; LIST_ENTRY List; + LONG ReqCount = 0; InitializeListHead(&List); - SrbExt->Count = 0; + SrbExt->ReqCount = 0; Srb->SrbStatus = SRB_STATUS_PENDING; for (Index = 0; Index < Count; ++Index) { @@ -1279,6 +1283,7 @@ PrepareUnmap( if (Request == NULL) goto fail1; InsertTailList(&List, &Request->Entry); + ReqCount++; Request->Srb = Srb; Request->Operation = BLKIF_OP_DISCARD; @@ -1287,7 +1292,9 @@ PrepareUnmap( Request->Flags = 0; } - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + SrbExt->ReqCount = ReqCount; + KeMemoryBarrier(); + PdoQueueRequestList(Pdo, &List); return TRUE; fail1: @@ -1362,7 +1369,7 @@ __PdoPauseDataPath( SrbExt->Srb->SrbStatus = SRB_STATUS_ABORTED; PdoPutRequest(Pdo, Request); - if (InterlockedDecrement(&SrbExt->Count) == 0) { + if (InterlockedDecrement(&SrbExt->ReqCount) == 0) { SrbExt->Srb->ScsiStatus = 0x40; // SCSI_ABORTED FdoCompleteSrb(PdoGetFdo(Pdo), SrbExt->Srb); } @@ -1554,7 +1561,7 @@ PdoCompleteResponse( PdoPutRequest(Pdo, Request); // complete srb - if (InterlockedDecrement(&SrbExt->Count) == 0) { + if (InterlockedDecrement(&SrbExt->ReqCount) == 0) { if (Srb->SrbStatus == SRB_STATUS_PENDING) { // SRB has not hit a failure condition (BLKIF_RSP_ERROR | BLKIF_RSP_EOPNOTSUPP) // from any of its responses. SRB must have succeeded @@ -1590,7 +1597,7 @@ PdoPreResume( PdoPutRequest(Pdo, Request); - if (InterlockedDecrement(&SrbExt->Count) == 0) { + if (InterlockedDecrement(&SrbExt->ReqCount) == 0) { InsertTailList(&List, &SrbExt->Entry); } } @@ -1607,7 +1614,7 @@ PdoPreResume( PdoPutRequest(Pdo, Request); - if (InterlockedDecrement(&SrbExt->Count) == 0) { + if (InterlockedDecrement(&SrbExt->ReqCount) == 0) { InsertTailList(&List, &SrbExt->Entry); } } @@ -2218,7 +2225,7 @@ __PdoCleanupSubmittedReqs( PdoPutRequest(Pdo, Request); - if (InterlockedDecrement(&SrbExt->Count) == 0) { + if (InterlockedDecrement(&SrbExt->ReqCount) == 0) { SrbExt->Srb->SrbStatus = SRB_STATUS_ABORTED; SrbExt->Srb->ScsiStatus = 0x40; // SCSI_ABORTED FdoCompleteSrb(PdoGetFdo(Pdo), SrbExt->Srb); --- a/src/xenvbd/srbext.h +++ b/src/xenvbd/srbext.h @@ -89,7 +89,7 @@ typedef struct _XENVBD_REQUEST { typedef struct _XENVBD_SRBEXT { PSCSI_REQUEST_BLOCK Srb; LIST_ENTRY Entry; - LONG Count; + LONG ReqCount; // number of Xen requests } XENVBD_SRBEXT, *PXENVBD_SRBEXT; FORCEINLINE PXENVBD_SRBEXT