VirtualBox

Changeset 1563 in vbox


Ignore:
Timestamp:
Mar 20, 2007 12:17:24 AM (18 years ago)
Author:
vboxsync
Message:

Rewrote it to use per-cpu timers instead of smp_call_function.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDRV.h

    r1480 r1563  
    8585#   include <linux/slab.h>
    8686#   include <asm/semaphore.h>
     87#   include <linux/timer.h>
    8788
    8889#elif defined(__DARWIN__)
     
    648649    /** The last mono time stamp. */
    649650    uint64_t volatile       u64LastMonotime;
     651# ifdef CONFIG_SMP
     652    /** Array of per CPU data for SUPGIPMODE_ASYNC_TSC. */
     653    struct LINUXCPU
     654    {
     655        /** The last jiffies. */
     656        unsigned long       ulLastJiffies;
     657        /** The last mono time stamp. */
     658        uint64_t volatile   u64LastMonotime;
     659        /** The per cpu timer. */
     660        struct timer_list   Timer;
     661    }                       aCPUs[256];
     662# endif
    650663#endif
    651664} SUPDRVDEVEXT;
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r1480 r1563  
    251251static void     VBoxSupGipTimer(unsigned long ulUser);
    252252#ifdef CONFIG_SMP
    253 static void     VBoxSupDrvGipPerCpu(void *pvUser);
     253static void     VBoxSupGipTimerPerCpu(unsigned long ulUser);
     254static void     VBoxSupGipResumePerCpu(void *pvUser);
    254255#endif
    255256static int      VBoxSupDrvOrder(unsigned long size);
     
    12691270    dma_addr_t  HCPhys;
    12701271    PSUPGLOBALINFOPAGE pGip;
     1272#ifdef CONFIG_SMP
     1273    unsigned i;
     1274#endif
    12711275    dprintf(("VBoxSupDrvInitGip:\n"));
    12721276
     
    13121316    g_GipTimer.function = VBoxSupGipTimer;
    13131317    g_GipTimer.expires = jiffies;
     1318#ifdef CONFIG_SMP
     1319    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
     1320    {
     1321        init_timer(&pDevExt->aCPUs[i].Timer);
     1322        pDevExt->aCPUs[i].Timer.data = (unsigned long)pDevExt;
     1323        pDevExt->aCPUs[i].Timer.function = VBoxSupGipTimerPerCpu;
     1324        pDevExt->aCPUs[i].Timer.expires = jiffies;
     1325    }
     1326#endif
    13141327
    13151328    return 0;
     
    13271340    struct page *pPage;
    13281341    PSUPGLOBALINFOPAGE pGip;
     1342#ifdef CONFIG_SMP
     1343    unsigned i;
     1344#endif
    13291345    dprintf(("VBoxSupDrvTermGip:\n"));
    13301346
     
    13331349     */
    13341350    if (timer_pending(&g_GipTimer))
    1335         del_timer(&g_GipTimer);
     1351        del_timer_sync(&g_GipTimer);
     1352#ifdef CONFIG_SMP
     1353    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
     1354        if (timer_pending(&pDevExt->aCPUs[i].Timer))
     1355            del_timer_sync(&pDevExt->aCPUs[i].Timer);
     1356#endif
    13361357
    13371358    /*
     
    13591380/**
    13601381 * Timer callback function.
    1361  * The ulUser parameter is the device extension pointer.
     1382 *
     1383 * In ASYNC TSC mode this is called on the primary CPU, and we're
     1384 * assuming that the CPU remains online.
     1385 *
     1386 * @param   ulUser  The device extension pointer.
    13621387 */
    13631388static void     VBoxSupGipTimer(unsigned long ulUser)
     
    13761401    ASMAtomicXchgU64(&pDevExt->u64LastMonotime, u64Monotime);
    13771402    if (RT_LIKELY(pGip))
    1378     {
     1403        supdrvGipUpdate(pDevExt->pGip, u64Monotime);
     1404    mod_timer(&g_GipTimer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
     1405}
     1406
     1407
    13791408#ifdef CONFIG_SMP
    1380         if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
    1381 #endif
    1382             supdrvGipUpdate(pDevExt->pGip, u64Monotime);
    1383 #ifdef CONFIG_SMP
    1384         else
    1385         {
    1386             smp_call_function(VBoxSupDrvGipPerCpu, pDevExt, 0 /* don't retry? */, 0 /* don't wait */);
    1387             supdrvGipUpdate(pDevExt->pGip, u64Monotime);
    1388         }
    1389 #endif
    1390     }
    1391     mod_timer(&g_GipTimer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
    1392 }
    1393 
    1394 
    1395 #ifdef CONFIG_SMP
    1396 /**
    1397  * smp_call_function callback.
    1398  * This is invoked on all the other CPUs.
     1409/**
     1410 * Timer callback function for the other CPUs.
    13991411 *
    1400  * @param   pvUser  Pointer to the device extension.
    1401  */
    1402 static void VBoxSupDrvGipPerCpu(void *pvUser)
    1403 {
    1404     PSUPDRVDEVEXT pDevExt  = (PSUPDRVDEVEXT)pvUser;
    1405     PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
    1406     supdrvGipUpdatePerCpu(pGip, pDevExt->u64LastMonotime, ASMGetApicId());
     1412 * @param   ulUser  The device extension pointer.
     1413 */
     1414static void VBoxSupGipTimerPerCpu(unsigned long ulUser)
     1415{
     1416    PSUPDRVDEVEXT       pDevExt = (PSUPDRVDEVEXT)ulUser;
     1417    PSUPGLOBALINFOPAGE  pGip    = pDevExt->pGip;
     1418    unsigned long       ulNow   = jiffies;
     1419    unsigned long       ulDiff  = ulNow - pDevExt->ulLastJiffies;
     1420    uint64_t            u64Monotime;
     1421    uint8_t             iCPU = ASMGetApicId();
     1422
     1423    if (RT_UNLIKELY(iCPU >= RT_ELEMENTS(pGip->aCPUs)))
     1424    {
     1425        printk("vboxdrv: error: apicid=%d max=%d cpuid=%d\n",
     1426               iCPU, RT_ELEMENTS(pGip->aCPUs), smp_processor_id());
     1427        return;
     1428    }
     1429
     1430    pDevExt->aCPUs[iCPU].ulLastJiffies = ulNow;
     1431#ifdef TICK_NSEC
     1432    u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * TICK_NSEC;
     1433#else
     1434    u64Monotime = pDevExt->aCPUs[iCPU].u64LastMonotime + ulDiff * (1000000 / HZ);
     1435#endif
     1436    ASMAtomicXchgU64(&pDevExt->aCPUs[iCPU].u64LastMonotime, u64Monotime);
     1437    if (RT_LIKELY(pGip))
     1438        supdrvGipUpdatePerCpu(pGip, pDevExt->aCPUs[iCPU].u64LastMonotime, iCPU);
     1439    mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies + (HZ <= 1000 ? 0 : ONE_MSEC_IN_JIFFIES));
    14071440}
    14081441#endif  /* CONFIG_SMP */
     
    15141547{
    15151548    dprintf2(("supdrvOSGipResume:\n"));
    1516     mod_timer(&g_GipTimer, jiffies);
    1517 }
     1549#ifdef CONFIG_SMP
     1550    if (pDevExt->pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
     1551#endif
     1552        mod_timer(&g_GipTimer, jiffies);
     1553#ifdef CONFIG_SMP
     1554    else
     1555    {
     1556        mod_timer(&g_GipTimer, jiffies);
     1557        smp_call_function(VBoxSupGipResumePerCpu, pDevExt, 0 /* retry */, 1 /* wait */);
     1558    }
     1559#endif
     1560}
     1561
     1562
     1563#ifdef CONFIG_SMP
     1564/**
     1565 * Callback for resuming GIP updating on the other CPUs.
     1566 *
     1567 * This is only used when the GIP is in async tsc mode.
     1568 *
     1569 * @param   pvUser  Pointer to the device instance.
     1570 */
     1571static void VBoxSupGipResumePerCpu(void *pvUser)
     1572{
     1573    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
     1574    uint8_t iCPU = ASMGetApicId();
     1575
     1576
     1577    if (RT_UNLIKELY(iCPU >= RT_ELEMENTS(pDevExt->pGip->aCPUs)))
     1578    {
     1579        printk("vboxdrv: error: apicid=%d max=%d cpuid=%d\n",
     1580               iCPU, RT_ELEMENTS(pDevExt->pGip->aCPUs), smp_processor_id());
     1581        return;
     1582    }
     1583
     1584    mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies);
     1585}
     1586#endif /* CONFIG_SMP */
    15181587
    15191588
     
    15251594void  VBOXCALL  supdrvOSGipSuspend(PSUPDRVDEVEXT pDevExt)
    15261595{
     1596#ifdef CONFIG_SMP
     1597    unsigned i;
     1598#endif
    15271599    dprintf2(("supdrvOSGipSuspend:\n"));
     1600
    15281601    if (timer_pending(&g_GipTimer))
    1529         del_timer(&g_GipTimer);
     1602        del_timer_sync(&g_GipTimer);
     1603#ifdef CONFIG_SMP
     1604    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
     1605        if (timer_pending(&pDevExt->aCPUs[i].Timer))
     1606            del_timer_sync(&pDevExt->aCPUs[i].Timer);
     1607#endif
    15301608}
    15311609
     
    16311709MODULE_DESCRIPTION("VirtualBox Support Driver");
    16321710MODULE_LICENSE("GPL");
     1711
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