Changeset 7869 in vbox
- Timestamp:
- Apr 10, 2008 12:39:02 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r7521 r7869 41 41 #include <iprt/mem.h> 42 42 #include <iprt/log.h> 43 #include <iprt/mp.h> 43 44 44 45 #include <linux/sched.h> … … 462 463 # endif /* DO_DISABLE_NMI */ 463 464 #endif /* CONFIG_X86_LOCAL_APIC */ 465 466 467 /** 468 * Determine if the time stamp counters of the CPU cores are asynchronous. 469 */ 470 static uint64_t g_aTsc[8][8]; 471 472 static DECLCALLBACK(void) Worker(RTCPUID idCpu, void *pvUser1, void *pvUser2) 473 { 474 int iSlot = *(int*)pvUser1; 475 int iCpu = *(int*)pvUser2; 476 g_aTsc[iSlot][iCpu] = ASMReadTSC(); 477 } 478 479 /* 480 * When using the default/normal timer code it is essential that the time stamp counter 481 * (TSC) runs never backwards, that is, a read operation to the counter should return 482 * a bigger value than any previous read operation. This is guaranteed by the latest 483 * AMD CPUs and by newer Intel CPUs which never enter the C2 state (P4). In any other 484 * case we have to choose the asynchronous timer mode. 485 */ 486 static void VBoxDetermineAsyncTsc(void) 487 { 488 uint64_t u64Diff, u64DiffMin, u64DiffMax, u64TscLast; 489 int iSlot, iCpu; 490 bool fBackwards = false; 491 int cCpu = RTMpGetOnlineCount(); 492 493 printk(KERN_DEBUG DEVICE_NAME ": Found %u cores.\n", cCpu); 494 if (cCpu < 2) 495 return; 496 497 if (cCpu > RT_ELEMENTS(g_aTsc)) 498 cCpu = RT_ELEMENTS(g_aTsc); 499 500 for (iSlot = 0; iSlot < RT_ELEMENTS(g_aTsc); iSlot++) 501 { 502 for (iCpu = 0; iCpu < cCpu; iCpu++) 503 RTMpOnSpecific(iCpu, Worker, &iSlot, &iCpu); 504 } 505 506 u64DiffMin = (uint64_t)~0; 507 u64TscLast = 0; 508 for (iSlot = 0; iSlot < RT_ELEMENTS(g_aTsc); iSlot++) 509 { 510 uint64_t u64Tsc0 = g_aTsc[iSlot][0]; 511 u64DiffMax = 0; 512 if (u64Tsc0 <= u64TscLast) 513 fBackwards = true; 514 u64TscLast = u64Tsc0; 515 for (iCpu = 1; iCpu < cCpu; iCpu++) 516 { 517 uint64_t u64TscN = g_aTsc[iSlot][iCpu]; 518 if (u64TscN <= u64TscLast) 519 fBackwards = true; 520 u64TscLast = u64TscN; 521 u64Diff = u64TscN > u64Tsc0 ? u64TscN - u64Tsc0 : u64Tsc0 - u64TscN; 522 if (u64DiffMax < u64Diff) 523 u64DiffMax = u64Diff; 524 } 525 if (u64DiffMin > u64DiffMax) 526 u64DiffMin = u64DiffMax; 527 } 528 /* Don't depend on 64-bit arithmetics in the printk code. We assume that the difference between both 529 * cores is smaller than 2^32. */ 530 printk(KERN_DEBUG DEVICE_NAME ": fBackwards=%d u64DiffMin=%u.\n", fBackwards, (uint32_t)u64DiffMin); 531 if (fBackwards) 532 force_async_tsc = 1; 533 } 464 534 465 535 /** … … 590 660 #endif /* CONFIG_X86_LOCAL_APIC */ 591 661 662 /* 663 * Check for synchronous/asynchronous TSC mode. 664 */ 665 VBoxDetermineAsyncTsc(); 666 592 667 #ifdef CONFIG_VBOXDRV_AS_MISC 593 668 rc = misc_register(&gMiscDevice);
Note:
See TracChangeset
for help on using the changeset viewer.