[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 2/2] Fix race calculating SrbExt->Count
From: Owen Smith <owen.smith@xxxxxxxxxx> It is possible under heavy loads for the backend to start completing sub-requests of a Srb before the SrbExt Count is set. This would leave the count unable to reach 0 (as 1 or more requests are skipped by count being overridden) Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/xenvbd/pdo.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c index dd5b6ea..ee2a3cc 100644 --- a/src/xenvbd/pdo.c +++ b/src/xenvbd/pdo.c @@ -1169,6 +1169,7 @@ PrepareReadWrite( ULONG SectorsLeft = Cdb_TransferBlock(Srb); LIST_ENTRY List; XENVBD_SG_LIST SGList; + ULONG DebugCount; InitializeListHead(&List); SrbExt->Count = 0; @@ -1185,6 +1186,7 @@ PrepareReadWrite( if (Request == NULL) goto fail1; InsertTailList(&List, &Request->Entry); + InterlockedIncrement(&SrbExt->Count); Request->Srb = Srb; MaxSegments = UseIndirect(Pdo, SectorsLeft); @@ -1207,7 +1209,10 @@ PrepareReadWrite( SectorStart += SectorsDone; } - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + DebugCount = PdoQueueRequestList(Pdo, &List); + if (DebugCount != (ULONG)SrbExt->Count) { + Trace("[%u] %d != %u\n", PdoGetTargetId(Pdo), SrbExt->Count, DebugCount); + } Srb->SrbStatus = SRB_STATUS_PENDING; return TRUE; @@ -1215,6 +1220,7 @@ fail3: fail2: fail1: PdoCancelRequestList(Pdo, &List); + SrbExt->Count = 0; Srb->SrbStatus = SRB_STATUS_ERROR; return FALSE; } @@ -1230,6 +1236,7 @@ PrepareSyncCache( PXENVBD_REQUEST Request; LIST_ENTRY List; UCHAR Operation; + ULONG DebugCount; if (FrontendGetDiskInfo(Pdo->Frontend)->FlushCache) Operation = BLKIF_OP_FLUSH_DISKCACHE; @@ -1243,17 +1250,22 @@ PrepareSyncCache( if (Request == NULL) goto fail1; InsertTailList(&List, &Request->Entry); + InterlockedIncrement(&SrbExt->Count); Request->Srb = Srb; Request->Operation = Operation; Request->FirstSector = Cdb_LogicalBlock(Srb); - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + DebugCount = PdoQueueRequestList(Pdo, &List); + if (DebugCount != (ULONG)SrbExt->Count) { + Trace("[%u] %d != %u\n", PdoGetTargetId(Pdo), SrbExt->Count, DebugCount); + } Srb->SrbStatus = SRB_STATUS_PENDING; return TRUE; fail1: PdoCancelRequestList(Pdo, &List); + SrbExt->Count = 0; Srb->SrbStatus = SRB_STATUS_ERROR; return FALSE; } @@ -1270,6 +1282,7 @@ PrepareUnmap( ULONG Count = _byteswap_ushort(*(PUSHORT)Unmap->BlockDescrDataLength) / sizeof(UNMAP_BLOCK_DESCRIPTOR); ULONG Index; LIST_ENTRY List; + ULONG DebugCount; InitializeListHead(&List); SrbExt->Count = 0; @@ -1282,6 +1295,7 @@ PrepareUnmap( if (Request == NULL) goto fail1; InsertTailList(&List, &Request->Entry); + InterlockedIncrement(&SrbExt->Count); Request->Srb = Srb; Request->Operation = BLKIF_OP_DISCARD; @@ -1290,12 +1304,16 @@ PrepareUnmap( Request->Flags = 0; } - SrbExt->Count = PdoQueueRequestList(Pdo, &List); + DebugCount = PdoQueueRequestList(Pdo, &List); + if (DebugCount != (ULONG)SrbExt->Count) { + Trace("[%u] %d != %u\n", PdoGetTargetId(Pdo), SrbExt->Count, DebugCount); + } Srb->SrbStatus = SRB_STATUS_PENDING; return TRUE; fail1: PdoCancelRequestList(Pdo, &List); + SrbExt->Count = 0; Srb->SrbStatus = SRB_STATUS_ERROR; return FALSE; } @@ -1429,6 +1447,13 @@ PdoSubmitPrepared( ) { PXENVBD_BLOCKRING BlockRing = FrontendGetBlockRing(Pdo->Frontend); + if (PdoIsPaused(Pdo)) { + if (QueueCount(&Pdo->PreparedReqs)) + Warning("Target[%d] : Paused, not submitting new requests (%u)\n", + PdoGetTargetId(Pdo), + QueueCount(&Pdo->PreparedReqs)); + return FALSE; + } for (;;) { PXENVBD_REQUEST Request; -- 2.8.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |