VirtualBox

Changeset 6340 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Jan 11, 2008 2:26:32 PM (17 years ago)
Author:
vboxsync
Message:

vboxdrv: added support for Linux high-res timers (disabled), added module parameter for forcing async TSC mode, show some more information on module initialization

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

Legend:

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

    r5999 r6340  
    9696#   include <linux/timer.h>
    9797
     98#   if 0
     99#    include <linux/hrtimer.h>
     100#    define VBOX_HRTIMER
     101#   endif
     102
    98103#elif defined(RT_OS_DARWIN)
    99104#   include <libkern/libkern.h>
     
    259264/** Pointer to the device extension. */
    260265typedef struct SUPDRVDEVEXT *PSUPDRVDEVEXT;
     266
     267#ifdef RT_OS_LINUX
     268# ifdef VBOX_HRTIMER
     269typedef struct hrtimer    VBOXKTIMER;
     270# else
     271typedef struct timer_list VBOXKTIMER;
     272# endif
     273#endif
    261274
    262275#ifdef VBOX_WITH_IDT_PATCHING
     
    710723        unsigned            iSmpProcessorId;
    711724        /** The per cpu timer. */
    712         struct timer_list   Timer;
     725        VBOXKTIMER          Timer;
    713726    }                       aCPUs[256];
    714727# endif
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r6046 r6340  
    4141
    4242#include <linux/module.h>
     43#include <linux/moduleparam.h>
    4344#include <linux/kernel.h>
    4445#include <linux/init.h>
     
    261262
    262263/** Timer structure for the GIP update. */
    263 static struct timer_list    g_GipTimer;
     264static VBOXKTIMER           g_GipTimer;
    264265/** Pointer to the page structure for the GIP. */
    265266struct page                *g_pGipPage;
     
    280281static int                  g_iModuleMajor;
    281282#endif /* !CONFIG_VBOXDRV_AS_MISC */
     283
     284/** Module parameter */
     285static int force_async_tsc = 0;
    282286
    283287/** The module name. */
     
    303307*   Internal Functions                                                         *
    304308*******************************************************************************/
     309#ifdef VBOX_HRTIMER
     310typedef enum hrtimer_restart (*VBOXTIMERFN)(struct hrtimer *);
     311#else
     312typedef void (*VBOXTIMERFN)(unsigned long);
     313#endif
     314
    305315static int      VBoxDrvLinuxInit(void);
    306316static void     VBoxDrvLinuxUnload(void);
     
    315325static int      VBoxDrvLinuxInitGip(PSUPDRVDEVEXT pDevExt);
    316326static int      VBoxDrvLinuxTermGip(PSUPDRVDEVEXT pDevExt);
     327#ifdef VBOX_HRTIMER
     328static enum hrtimer_restart VBoxDrvLinuxGipTimer(struct hrtimer *timer);
     329#else
    317330static void     VBoxDrvLinuxGipTimer(unsigned long ulUser);
     331#endif
    318332#ifdef CONFIG_SMP
     333# ifdef VBOX_HRTIMER
     334static enum hrtimer_restart VBoxDrvLinuxGipTimerPerCpu(struct hrtimer *timer);
     335# else
    319336static void     VBoxDrvLinuxGipTimerPerCpu(unsigned long ulUser);
     337# endif
    320338static void     VBoxDrvLinuxGipResumePerCpu(void *pvUser);
    321339#endif
     
    349367};
    350368#endif
     369
     370static inline void vbox_ktimer_init(VBOXKTIMER *timer, VBOXTIMERFN function, unsigned long data)
     371{
     372#ifdef VBOX_HRTIMER
     373   hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
     374    timer->function = function;
     375#else
     376    init_timer(timer);
     377    timer->data     = data;
     378    timer->function = function;
     379    timer->expires  = jiffies;
     380#endif
     381}
     382
     383static inline void vbox_ktimer_start(VBOXKTIMER *timer)
     384{
     385#ifdef VBOX_HRTIMER
     386    hrtimer_start(timer, ktime_add_ns(ktime_get(), 1000000), HRTIMER_MODE_ABS);
     387#else
     388    mod_timer(timer, jiffies);
     389#endif
     390}
     391
     392static inline void vbox_ktimer_stop(VBOXKTIMER *timer)
     393{
     394#ifdef VBOX_HRTIMER
     395    hrtimer_cancel(timer);
     396#else
     397    if (timer_pending(timer))
     398        del_timer_sync(timer);
     399#endif
     400}
    351401
    352402#ifdef CONFIG_X86_LOCAL_APIC
     
    647697                if (!rc)
    648698                {
     699                    printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is "
     700#ifdef VBOX_HRTIMER
     701                            "'high-res'"
     702#else
     703                            "'normal'"
     704#endif
     705                            ".\n",
     706                            g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'");
    649707                    dprintf(("VBoxDrv::ModuleInit returning %#x\n", rc));
    650708                    printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "
     
    9771035     * Initialize the timer.
    9781036     */
    979     init_timer(&g_GipTimer);
    980     g_GipTimer.data = (unsigned long)pDevExt;
    981     g_GipTimer.function = VBoxDrvLinuxGipTimer;
    982     g_GipTimer.expires = jiffies;
     1037    vbox_ktimer_init(&g_GipTimer, VBoxDrvLinuxGipTimer, (unsigned long)pDevExt);
    9831038#ifdef CONFIG_SMP
    9841039    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
     
    9871042        pDevExt->aCPUs[i].ulLastJiffies   = pDevExt->ulLastJiffies;
    9881043        pDevExt->aCPUs[i].iSmpProcessorId = -512;
    989         init_timer(&pDevExt->aCPUs[i].Timer);
    990         pDevExt->aCPUs[i].Timer.data      = i;
    991         pDevExt->aCPUs[i].Timer.function  = VBoxDrvLinuxGipTimerPerCpu;
    992         pDevExt->aCPUs[i].Timer.expires   = jiffies;
     1044        vbox_ktimer_init(&pDevExt->aCPUs[i].Timer, VBoxDrvLinuxGipTimerPerCpu, i);
    9931045    }
    9941046#endif
     
    10161068     * Delete the timer if it's pending.
    10171069     */
    1018     if (timer_pending(&g_GipTimer))
    1019         del_timer_sync(&g_GipTimer);
     1070    vbox_ktimer_stop(&g_GipTimer);
    10201071#ifdef CONFIG_SMP
    10211072    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
    1022         if (timer_pending(&pDevExt->aCPUs[i].Timer))
    1023             del_timer_sync(&pDevExt->aCPUs[i].Timer);
     1073        vbox_ktimer_stop(&pDevExt->aCPUs[i].Timer);
    10241074#endif
    10251075
     
    10541104 * @param   ulUser  The device extension pointer.
    10551105 */
     1106#ifdef VBOX_HRTIMER
     1107static enum hrtimer_restart VBoxDrvLinuxGipTimer(struct hrtimer* timer)
     1108#else
    10561109static void VBoxDrvLinuxGipTimer(unsigned long ulUser)
     1110#endif
    10571111{
    10581112    PSUPDRVDEVEXT       pDevExt;
     
    10621116    uint64_t            u64Monotime;
    10631117    unsigned long       SavedFlags;
     1118#ifdef VBOX_HRTIMER
     1119    ktime_t             kNow;
     1120#endif
    10641121
    10651122    local_irq_save(SavedFlags);
    10661123
    10671124    ulNow   = jiffies;
     1125#ifdef VBOX_HRTIMER
     1126    kNow    = ktime_get();
     1127    pDevExt = &g_DevExt;
     1128#else
    10681129    pDevExt = (PSUPDRVDEVEXT)ulUser;
     1130#endif
    10691131    pGip    = pDevExt->pGip;
    10701132
     
    10891151        supdrvGipUpdate(pDevExt->pGip, u64Monotime);
    10901152    if (RT_LIKELY(!pDevExt->fGIPSuspended))
     1153    {
     1154#ifdef VBOX_HRTIMER
     1155        hrtimer_forward(&g_GipTimer, kNow, ktime_set(0, 1000000));
     1156#else
    10911157        mod_timer(&g_GipTimer, ulNow + ONE_MSEC_IN_JIFFIES);
     1158#endif
     1159    }
    10921160
    10931161    local_irq_restore(SavedFlags);
     1162
     1163#ifdef VBOX_HRTIMER
     1164    return pDevExt->fGIPSuspended ? HRTIMER_NORESTART : HRTIMER_RESTART;
     1165#endif
    10941166}
    10951167
     
    11011173 * @param   iTimerCPU     The APIC ID of this timer.
    11021174 */
     1175#ifdef VBOX_HRTIMER
     1176static enum hrtimer_restart VBoxDrvLinuxGipTimerPerCpu(struct hrtimer *timer)
     1177#else
    11031178static void VBoxDrvLinuxGipTimerPerCpu(unsigned long iTimerCPU)
     1179#endif
    11041180{
    11051181    PSUPDRVDEVEXT       pDevExt;
     
    11091185    unsigned long       SavedFlags;
    11101186    unsigned long       ulNow;
     1187# ifdef VBOX_HRTIMER
     1188    unsigned long       iTimerCPU;
     1189    ktime_t             kNow;
     1190# endif
    11111191
    11121192    local_irq_save(SavedFlags);
     
    11161196    pGip    = pDevExt->pGip;
    11171197    iCPU    = ASMGetApicId();
     1198# ifdef VBOX_HRTIMER
     1199    iTimerCPU = iCPU; /* XXX hrtimer does not support a 'data' field */
     1200    kNow    = ktime_get();
     1201# endif
    11181202
    11191203    if (RT_LIKELY(iCPU < RT_ELEMENTS(pGip->aCPUs)))
     
    11281212                supdrvGipUpdatePerCpu(pGip, u64Monotime, iCPU);
    11291213            if (RT_LIKELY(!pDevExt->fGIPSuspended))
     1214            {
     1215# ifdef VBOX_HRTIMER
     1216                hrtimer_forward(&pDevExt->aCPUs[iCPU].Timer, kNow, ktime_set(0, 1000000));
     1217# else
    11301218                mod_timer(&pDevExt->aCPUs[iCPU].Timer, ulNow + ONE_MSEC_IN_JIFFIES);
     1219# endif
     1220            }
    11311221        }
    11321222        else
     
    11391229
    11401230    local_irq_restore(SavedFlags);
     1231
     1232# ifdef VBOX_HRTIMER
     1233    return pDevExt->fGIPSuspended ? HRTIMER_NORESTART : HRTIMER_RESTART;
     1234# endif
    11411235}
    11421236#endif  /* CONFIG_SMP */
     
    12531347    {
    12541348#endif
    1255         mod_timer(&g_GipTimer, jiffies);
     1349        vbox_ktimer_start(&g_GipTimer);
    12561350#ifdef CONFIG_SMP
    12571351    }
    12581352    else
    12591353    {
    1260         mod_timer(&g_GipTimer, jiffies);
     1354        vbox_ktimer_start(&g_GipTimer);
    12611355        smp_call_function(VBoxDrvLinuxGipResumePerCpu, pDevExt, 0 /* retry */, 1 /* wait */);
    12621356    }
     
    12861380
    12871381    pDevExt->aCPUs[iCPU].iSmpProcessorId = smp_processor_id();
    1288     mod_timer(&pDevExt->aCPUs[iCPU].Timer, jiffies);
     1382    vbox_ktimer_start(&pDevExt->aCPUs[iCPU].Timer);
    12891383}
    12901384#endif /* CONFIG_SMP */
     
    13041398    ASMAtomicXchgU8(&pDevExt->fGIPSuspended, true);
    13051399
    1306     if (timer_pending(&g_GipTimer))
    1307         del_timer_sync(&g_GipTimer);
     1400    vbox_ktimer_stop(&g_GipTimer);
    13081401#ifdef CONFIG_SMP
    13091402    for (i = 0; i < RT_ELEMENTS(pDevExt->aCPUs); i++)
    1310         if (timer_pending(&pDevExt->aCPUs[i].Timer))
    1311             del_timer_sync(&pDevExt->aCPUs[i].Timer);
     1403        vbox_ktimer_stop(&pDevExt->aCPUs[i].Timer);
    13121404#endif
    13131405}
     
    13391431bool VBOXCALL  supdrvOSGetForcedAsyncTscMode(void)
    13401432{
    1341     return false;
     1433    return force_async_tsc != 0;
    13421434}
    13431435
     
    14361528MODULE_VERSION(VBOX_VERSION_STRING " (" xstr(SUPDRVIOC_VERSION) ")");
    14371529#endif
     1530
     1531module_param(force_async_tsc, int, 0444);
     1532MODULE_PARM_DESC(force_async_tsc, "force the asynchronous TSC mode");
     1533
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