Changeset 54446 in vbox
- Timestamp:
- Feb 24, 2015 1:02:31 PM (10 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/linux/Makefile
r54419 r54446 144 144 generic/RTMpGetArraySize-generic.o \ 145 145 generic/RTMpGetCoreCount-generic.o \ 146 generic/RTMpOnPair-generic.o \147 146 generic/RTSemEventWait-2-ex-generic.o \ 148 147 generic/RTSemEventWaitNoResume-2-ex-generic.o \ -
trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv
r54419 r54446 156 156 ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \ 157 157 ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetCoreCount-generic.cpp=>generic/RTMpGetCoreCount-generic.c \ 158 ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpOnPair-generic.cpp=>generic/RTMpOnPair-generic.c \159 158 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWait-2-ex-generic.cpp=>generic/RTSemEventWait-2-ex-generic.c \ 160 159 ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventWaitNoResume-2-ex-generic.c \ -
trunk/src/VBox/Runtime/Makefile.kmk
r54410 r54446 1870 1870 generic/RTMpGetCoreCount-generic.cpp \ 1871 1871 generic/mppresent-generic.cpp \ 1872 generic/RTMpOnPair-generic.cpp \1873 1872 r0drv/linux/alloc-r0drv-linux.c \ 1874 1873 r0drv/linux/assert-r0drv-linux.c \ -
trunk/src/VBox/Runtime/r0drv/linux/mp-r0drv-linux.c
r54415 r54446 214 214 215 215 /** 216 * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER, does hit 217 * increment after calling the worker. 218 * 219 * @param pvInfo Pointer to the RTMPARGS package. 220 */ 221 static void rtmpLinuxWrapperPostInc(void *pvInfo) 222 { 223 PRTMPARGS pArgs = (PRTMPARGS)pvInfo; 224 pArgs->pfnWorker(RTMpCpuId(), pArgs->pvUser1, pArgs->pvUser2); 225 ASMAtomicIncU32(&pArgs->cHits); 226 } 227 228 229 /** 216 230 * Wrapper between the native linux all-cpu callbacks and PFNRTWORKER. 217 231 * … … 318 332 319 333 334 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) 335 /** 336 * Wrapper between the native linux per-cpu callbacks and PFNRTWORKER 337 * employed by RTMpOnPair on older kernels that lacks smp_call_function_many. 338 * 339 * @param pvInfo Pointer to the RTMPARGS package. 340 */ 341 static void rtMpLinuxOnPairWrapper(void *pvInfo) 342 { 343 PRTMPARGS pArgs = (PRTMPARGS)pvInfo; 344 RTCPUID idCpu = RTMpCpuId(); 345 346 if ( idCpu == pArgs->idCpu 347 || idCpu == pArgs->idCpu2) 348 { 349 pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2); 350 ASMAtomicIncU32(&pArgs->cHits); 351 } 352 } 353 #endif 354 355 356 RTDECL(int) RTMpOnPair(RTCPUID idCpu1, RTCPUID idCpu2, uint32_t fFlags, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2) 357 { 358 int rc; 359 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; 360 361 AssertReturn(idCpu1 != idCpu2, VERR_INVALID_PARAMETER); 362 AssertReturn(!(fFlags & RTMPON_F_VALID_MASK), VERR_INVALID_FLAGS); 363 364 /* 365 * Check that both CPUs are online before doing the broadcast call. 366 */ 367 RTThreadPreemptDisable(&PreemptState); 368 if ( RTMpIsCpuOnline(idCpu1) 369 && RTMpIsCpuOnline(idCpu2)) 370 { 371 /* 372 * Use the smp_call_function variant taking a cpu mask where available, 373 * falling back on broadcast with filter. Slight snag if one of the 374 * CPUs is the one we're running on, we must do the call and the post 375 * call wait ourselves. 376 */ 377 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) 378 cpumask_t DstCpuMask; 379 RTCPUID idCpuSelf = RTMpCpuId(); 380 bool const fCallSelf = idCpuSelf == idCpu1 || idCpuSelf == idCpu2; 381 #endif 382 RTMPARGS Args; 383 Args.pfnWorker = pfnWorker; 384 Args.pvUser1 = pvUser1; 385 Args.pvUser2 = pvUser2; 386 Args.idCpu = idCpu1; 387 Args.idCpu2 = idCpu2; 388 Args.cHits = 0; 389 390 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) 391 cpumask_clear(&DstCpuMask); 392 cpumask_set_cpu(idCpu1, &DstCpuMask); 393 cpumask_set_cpu(idCpu2, &DstCpuMask); 394 #endif 395 396 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) 397 smp_call_function_many(&DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */); 398 rc = 0; 399 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28) 400 rc = smp_call_function_many(&DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */); 401 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) 402 rc = smp_call_function_mask(&DstCpuMask, rtmpLinuxWrapperPostInc, &Args, !fCallSelf /* wait */); 403 #else /* older kernels */ 404 rc = smp_call_function(rtMpLinuxOnPairWrapper, &Args, 0 /* retry */, 0 /* wait */); 405 #endif /* older kernels */ 406 Assert(rc == 0); 407 408 409 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) 410 /* Call ourselves if necessary and wait for the other party to be done. */ 411 if (fCallSelf) 412 { 413 uint32_t cLoops = 0; 414 rtmpLinuxWrapper(&Args); 415 while (ASMAtomicReadU32(&Args.cHits) < 2) 416 { 417 if ((cLoops & 0x1ff) == 0 && !RTMpIsCpuOnline(idCpuSelf == idCpu1 ? idCpu2 : idCpu2)) 418 break; 419 cLoops++; 420 ASMNopPause(); 421 } 422 } 423 #endif 424 425 Assert(Args.cHits <= 2); 426 if (Args.cHits == 2) 427 rc = VINF_SUCCESS; 428 else if (Args.cHits == 1) 429 rc = VERR_NOT_ALL_CPUS_SHOWED; 430 else if (Args.cHits == 0) 431 rc = VERR_CPU_OFFLINE; 432 else 433 rc = VERR_CPU_IPE_1; 434 } 435 /* 436 * A CPU must be present to be considered just offline. 437 */ 438 else if ( RTMpIsCpuPresent(idCpu1) 439 && RTMpIsCpuPresent(idCpu2)) 440 rc = VERR_CPU_OFFLINE; 441 else 442 rc = VERR_CPU_NOT_FOUND; 443 RTThreadPreemptRestore(&PreemptState);; 444 return rc; 445 } 446 RT_EXPORT_SYMBOL(RTMpOnPair); 447 448 449 RTDECL(bool) RTMpOnPairIsConcurrentExecSupported(void) 450 { 451 return true; 452 } 453 RT_EXPORT_SYMBOL(RTMpOnPairIsConcurrentExecSupported); 320 454 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) 321 455 /**
Note:
See TracChangeset
for help on using the changeset viewer.