VirtualBox

Ignore:
Timestamp:
Apr 2, 2007 11:12:09 PM (18 years ago)
Author:
vboxsync
Message:

Fixed wrong u64LastMonotime usage (the cause of all the trouble). Disable interrupts while updating GIP like on NT.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r1850 r1869  
    13211321    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
    13221322    {
     1323        pDevExt->aCPUs[i].u64LastMonotime = pDevExt->u64LastMonotime;
     1324        pDevExt->aCPUs[i].ulLastJiffies   = pDevExt->ulLastJiffies;
     1325        pDevExt->aCPUs[i].iSmpProcessorId = -512;
    13231326        init_timer(&pDevExt->aCPUs[i].Timer);
    1324         pDevExt->aCPUs[i].Timer.data = (unsigned long)pDevExt;
    1325         pDevExt->aCPUs[i].Timer.function = VBoxSupGipTimerPerCpu;
    1326         pDevExt->aCPUs[i].Timer.expires = jiffies;
     1327        pDevExt->aCPUs[i].Timer.data      = i;
     1328        pDevExt->aCPUs[i].Timer.function  = VBoxSupGipTimerPerCpu;
     1329        pDevExt->aCPUs[i].Timer.expires   = jiffies;
    13271330    }
    13281331#endif
     
    13901393static void     VBoxSupGipTimer(unsigned long ulUser)
    13911394{
    1392     PSUPDRVDEVEXT pDevExt  = (PSUPDRVDEVEXT)ulUser;
    1393     PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
    1394     unsigned long ulNow    = jiffies;
    1395     unsigned long ulDiff   = ulNow - pDevExt->ulLastJiffies;
    1396     uint64_t u64Monotime;
     1395    PSUPDRVDEVEXT       pDevExt;
     1396    PSUPGLOBALINFOPAGE  pGip;
     1397    unsigned long       ulNow;
     1398    unsigned long       ulDiff;
     1399    uint64_t            u64Monotime;
     1400    unsigned long       SavedFlags;
     1401
     1402    local_irq_save(SavedFlags);
     1403
     1404    pDevExt = (PSUPDRVDEVEXT)ulUser;
     1405    pGip    = pDevExt->pGip;
     1406    ulNow   = jiffies;
     1407    ulDiff  = ulNow - pDevExt->ulLastJiffies;
     1408
    13971409    pDevExt->ulLastJiffies = ulNow;
    13981410#ifdef TICK_NSEC
     
    14051417        supdrvGipUpdate(pDevExt->pGip, u64Monotime);
    14061418    mod_timer(&g_GipTimer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
     1419
     1420    local_irq_restore(SavedFlags);
    14071421}
    14081422
     
    14121426 * Timer callback function for the other CPUs.
    14131427 *
    1414  * @param   ulUser  The device extension pointer.
    1415  */
    1416 static void VBoxSupGipTimerPerCpu(unsigned long ulUser)
    1417 {
    1418     PSUPDRVDEVEXT       pDevExt = (PSUPDRVDEVEXT)ulUser;
    1419     PSUPGLOBALINFOPAGE  pGip    = pDevExt->pGip;
    1420     unsigned long       ulNow   = jiffies;
    1421     unsigned long       ulDiff  = ulNow - pDevExt->ulLastJiffies;
     1428 * @param   iLnxCPU     The APIC ID of this timer.
     1429 */
     1430static void VBoxSupGipTimerPerCpu(unsigned long iLnxCPU)
     1431{
     1432    PSUPDRVDEVEXT       pDevExt;
     1433    PSUPGLOBALINFOPAGE  pGip;
     1434    uint8_t             iCPU;
    14221435    uint64_t            u64Monotime;
    1423     uint8_t             iCPU = ASMGetApicId();
    1424 
    1425     if (RT_UNLIKELY(iCPU >= RT_ELEMENTS(pGip->aCPUs)))
    1426     {
    1427         printk("vboxdrv: error: apicid=%d max=%d cpuid=%d\n",
     1436    unsigned long       SavedFlags;
     1437
     1438    local_irq_save(SavedFlags);
     1439
     1440    pDevExt = &g_DevExt;
     1441    pGip    = pDevExt->pGip;
     1442    iCPU    = ASMGetApicId();
     1443   
     1444    if (RT_LIKELY(iCPU < RT_ELEMENTS(pGip->aCPUs)))
     1445    {
     1446        if (RT_LIKELY(iCPU == iLnxCPU))
     1447        {
     1448            unsigned long   ulNow  = jiffies;
     1449            unsigned long   ulDiff = ulNow - pDevExt->aCPUs[iLnxCPU].ulLastJiffies;
     1450
     1451            pDevExt->aCPUs[iLnxCPU].ulLastJiffies = ulNow;
     1452#ifdef TICK_NSEC
     1453            u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * TICK_NSEC;
     1454#else
     1455            u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * (1000000 / HZ);
     1456#endif
     1457            ASMAtomicXchgU64(&pDevExt->aCPUs[iCPU].u64LastMonotime, u64Monotime);
     1458            if (RT_LIKELY(pGip))
     1459                supdrvGipUpdatePerCpu(pGip, u64Monotime, iCPU);
     1460            mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
     1461        }
     1462        else
     1463            printk("vboxdrv: error: GIP CPU update timer executing on the wrong CPU: apicid=%d != timer-apicid=%ld (cpuid=%d != timer-cpuid=%d)\n",
     1464                   iCPU, iLnxCPU, smp_processor_id(), pDevExt->aCPUs[iLnxCPU].iSmpProcessorId);
     1465    }
     1466    else
     1467        printk("vboxdrv: error: APIC ID is bogus (GIP CPU update): apicid=%d max=%d cpuid=%d\n",
    14281468               iCPU, RT_ELEMENTS(pGip->aCPUs), smp_processor_id());
    1429         return;
    1430     }
    1431 
    1432     pDevExt->aCPUs[iCPU].ulLastJiffies = ulNow;
    1433 #ifdef TICK_NSEC
    1434     u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * TICK_NSEC;
    1435 #else
    1436     u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * (1000000 / HZ);
    1437 #endif
    1438     ASMAtomicXchgU64(&pDevExt->aCPUs[iCPU].u64LastMonotime, u64Monotime);
    1439     if (RT_LIKELY(pGip))
    1440         supdrvGipUpdatePerCpu(pGip, pDevExt->aCPUs[iCPU].u64LastMonotime, iCPU);
    1441     mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
     1469
     1470    local_irq_restore(SavedFlags);
    14421471}
    14431472#endif  /* CONFIG_SMP */
     
    15761605    uint8_t iCPU = ASMGetApicId();
    15771606
    1578 
    15791607    if (RT_UNLIKELY(iCPU >= RT_ELEMENTS(pDevExt->pGip->aCPUs)))
    15801608    {
     
    15841612    }
    15851613
     1614    pDevExt->aCPUs[iCPU].iSmpProcessorId = smp_processor_id();
    15861615    mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies);
    15871616}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette