Changeset 92873 in vbox for trunk/src/VBox/Runtime/r0drv
- Timestamp:
- Dec 11, 2021 1:38:33 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 148821
- Location:
- trunk/src/VBox/Runtime/r0drv/nt
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp
r92871 r92873 1350 1350 * 1351 1351 * @returns IPRT status code (errors are asserted). 1352 * @retval VERR_CPU_NOT_FOUND if impossible CPU. Not asserted. 1352 1353 * @param pDpc The DPC. 1353 1354 * @param idCpu The ID of the new target CPU. 1355 * @note Callable at any IRQL. 1354 1356 */ 1355 1357 DECLHIDDEN(int) rtMpNtSetTargetProcessorDpc(KDPC *pDpc, RTCPUID idCpu) … … 1361 1363 PROCESSOR_NUMBER ProcNum; 1362 1364 NTSTATUS rcNt = g_pfnrtKeGetProcessorNumberFromIndex(RTMpCpuIdToSetIndex(idCpu), &ProcNum); 1363 AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("KeGetProcessorNumberFromIndex(%u) -> %#x\n", idCpu, rcNt), 1364 RTErrConvertFromNtStatus(rcNt)); 1365 1366 rcNt = g_pfnrtKeSetTargetProcessorDpcEx(pDpc, &ProcNum); 1367 AssertLogRelMsgReturn(NT_SUCCESS(rcNt), 1368 ("KeSetTargetProcessorDpcEx(,%u(%u/%u)) -> %#x\n", idCpu, ProcNum.Group, ProcNum.Number, rcNt), 1369 RTErrConvertFromNtStatus(rcNt)); 1365 if (NT_SUCCESS(rcNt)) 1366 { 1367 rcNt = g_pfnrtKeSetTargetProcessorDpcEx(pDpc, &ProcNum); 1368 AssertLogRelMsgReturn(NT_SUCCESS(rcNt), 1369 ("KeSetTargetProcessorDpcEx(,%u(%u/%u)) -> %#x\n", idCpu, ProcNum.Group, ProcNum.Number, rcNt), 1370 RTErrConvertFromNtStatus(rcNt)); 1371 } 1372 else if (rcNt == STATUS_INVALID_PARAMETER) 1373 return VERR_CPU_NOT_FOUND; 1374 else 1375 AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("KeGetProcessorNumberFromIndex(%u) -> %#x\n", idCpu, rcNt), 1376 RTErrConvertFromNtStatus(rcNt)); 1377 1370 1378 } 1371 1379 else if (g_pfnrtKeSetTargetProcessorDpc) … … 1936 1944 g_pfnrtKeSetImportanceDpc(&s_aPokeDpcs[i], HighImportance); 1937 1945 int rc = rtMpNtSetTargetProcessorDpc(&s_aPokeDpcs[i], idCpu); 1938 if (RT_FAILURE(rc) )1946 if (RT_FAILURE(rc) && rc != VERR_CPU_NOT_FOUND) 1939 1947 return rc; 1940 1948 } -
trunk/src/VBox/Runtime/r0drv/nt/timer-r0drv-nt.cpp
r92872 r92873 74 74 /** The NT DPC object. */ 75 75 KDPC NtDpc; 76 /** Whether we failed to set the target CPU for the DPC and that this needs 77 * to be done at RTTimerStart (simple timers) or during timer callback (omni). */ 78 bool fDpcNeedTargetCpuSet; 76 79 } RTTIMERNTSUBTIMER; 77 80 /** Pointer to a NT sub-timer structure. */ … … 426 429 427 430 /** 431 * Called when we have an impcomplete DPC object. 432 * 433 * @returns KeInsertQueueDpc return value. 434 * @param pSubTimer The sub-timer to queue an DPC for. 435 * @param iCpu The CPU set index corresponding to that sub-timer. 436 */ 437 DECL_NO_INLINE(static, BOOLEAN) rtTimerNtOmniQueueDpcSlow(PRTTIMERNTSUBTIMER pSubTimer, int iCpu) 438 { 439 int rc = rtMpNtSetTargetProcessorDpc(&pSubTimer->NtDpc, RTMpCpuIdFromSetIndex(iCpu)); 440 if (RT_SUCCESS(rc)) 441 { 442 pSubTimer->fDpcNeedTargetCpuSet = false; 443 return KeInsertQueueDpc(&pSubTimer->NtDpc, 0, 0); 444 } 445 return FALSE; 446 } 447 448 449 /** 450 * Wrapper around KeInsertQueueDpc that makes sure the target CPU has been set. 451 * 452 * This is for handling deferred rtMpNtSetTargetProcessorDpc failures during 453 * creation. These errors happens for offline CPUs which probably never every 454 * will come online, as very few systems do CPU hotplugging. 455 * 456 * @returns KeInsertQueueDpc return value. 457 * @param pSubTimer The sub-timer to queue an DPC for. 458 * @param iCpu The CPU set index corresponding to that sub-timer. 459 */ 460 DECLINLINE(BOOLEAN) rtTimerNtOmniQueueDpc(PRTTIMERNTSUBTIMER pSubTimer, int iCpu) 461 { 462 if (RT_LIKELY(!pSubTimer->fDpcNeedTargetCpuSet)) 463 return KeInsertQueueDpc(&pSubTimer->NtDpc, 0, 0); 464 return rtTimerNtOmniQueueDpcSlow(pSubTimer, iCpu); 465 } 466 467 468 /** 428 469 * Common timer callback worker for omni-timers. 429 470 * … … 457 498 if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) 458 499 && iCpuSelf != iCpu) 459 KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0);500 rtTimerNtOmniQueueDpc(&pTimer->aSubTimers[iCpu], iCpu); 460 501 461 502 pTimer->pfnTimer(pTimer, pTimer->pvUser, ++pSubTimer->iTick); … … 475 516 if (RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)) 476 517 cCpus++; 477 ASMAtomicAddS32(&pTimer->cOmniSuspendCountDown, cCpus); 518 ASMAtomicAddS32(&pTimer->cOmniSuspendCountDown, cCpus); /** @todo this is bogus bogus bogus. The counter is only used here. */ 478 519 479 520 for (int iCpu = 0; iCpu < RTCPUSET_MAX_CPUS; iCpu++) 480 521 if ( RTCpuSetIsMemberByIndex(&OnlineSet, iCpu) 481 522 && iCpuSelf != iCpu) 482 if (! KeInsertQueueDpc(&pTimer->aSubTimers[iCpu].NtDpc, 0, 0))523 if (!rtTimerNtOmniQueueDpc(&pTimer->aSubTimers[iCpu], iCpu)) 483 524 ASMAtomicDecS32(&pTimer->cOmniSuspendCountDown); /* already queued and counted. */ 484 525 … … 584 625 KeReleaseSpinLock(&pTimer->Spinlock, bSavedIrql); 585 626 return VERR_CPU_OFFLINE; 627 } 628 629 /* 630 * Lazy set the DPC target CPU if needed. 631 */ 632 if ( !pTimer->fSpecificCpu 633 || !pTimer->aSubTimers[0].fDpcNeedTargetCpuSet) 634 { /* likely */ } 635 else 636 { 637 int rc = rtMpNtSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, pTimer->idCpu); 638 if (RT_FAILURE(rc)) 639 { 640 KeReleaseSpinLock(&pTimer->Spinlock, bSavedIrql); 641 return rc; 642 } 586 643 } 587 644 … … 902 959 if (RT_SUCCESS(rc)) 903 960 { 961 RTCPUSET OnlineSet; 962 RTMpGetOnlineSet(&OnlineSet); 963 904 964 if (pTimer->fOmniTimer) 905 965 { … … 915 975 pTimer->iMasterTick = 0; 916 976 pTimer->idCpu = NIL_RTCPUID; 917 for (unsigned iCpu = 0; iCpu < cSubTimers && RT_SUCCESS(rc); iCpu++)977 for (unsigned iCpu = 0; iCpu < cSubTimers; iCpu++) 918 978 { 919 979 pTimer->aSubTimers[iCpu].iTick = 0; 920 980 pTimer->aSubTimers[iCpu].pParent = pTimer; 921 981 922 if ( 923 && RTMpIsCpuOnline(RTMpCpuIdFromSetIndex(iCpu)))982 if ( pTimer->idCpu == NIL_RTCPUID 983 && RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)) 924 984 { 925 985 pTimer->idCpu = RTMpCpuIdFromSetIndex(iCpu); … … 935 995 if (g_pfnrtKeSetImportanceDpc) 936 996 g_pfnrtKeSetImportanceDpc(&pTimer->aSubTimers[iCpu].NtDpc, HighImportance); 937 rc = rtMpNtSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, iCpu); 997 998 /* This does not necessarily work for offline CPUs that could potentially be onlined 999 at runtime, so postpone it. (See troubles on testboxmem1 after r148799.) */ 1000 int rc2 = rtMpNtSetTargetProcessorDpc(&pTimer->aSubTimers[iCpu].NtDpc, iCpu); 1001 if (RT_SUCCESS(rc2)) 1002 pTimer->aSubTimers[0].fDpcNeedTargetCpuSet = false; 1003 else if (!RTCpuSetIsMemberByIndex(&OnlineSet, iCpu)) 1004 pTimer->aSubTimers[0].fDpcNeedTargetCpuSet = true; 1005 else 1006 { 1007 rc = rc2; 1008 break; 1009 } 938 1010 } 939 1011 Assert(pTimer->idCpu != NIL_RTCPUID); … … 953 1025 g_pfnrtKeSetImportanceDpc(&pTimer->aSubTimers[0].NtDpc, HighImportance); 954 1026 if (pTimer->fSpecificCpu) 955 rc = rtMpNtSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, fFlags & RTTIMER_FLAGS_CPU_MASK); 1027 { 1028 /* This does not necessarily work for offline CPUs that could potentially be onlined 1029 at runtime, so postpone it. (See troubles on testboxmem1 after r148799.) */ 1030 int rc2 = rtMpNtSetTargetProcessorDpc(&pTimer->aSubTimers[0].NtDpc, pTimer->idCpu); 1031 if (RT_SUCCESS(rc2)) 1032 pTimer->aSubTimers[0].fDpcNeedTargetCpuSet = false; 1033 else if (!RTCpuSetIsMember(&OnlineSet, pTimer->idCpu)) 1034 pTimer->aSubTimers[0].fDpcNeedTargetCpuSet = true; 1035 else 1036 rc = rc2; 1037 } 956 1038 } 957 1039 if (RT_SUCCESS(rc))
Note:
See TracChangeset
for help on using the changeset viewer.