VirtualBox

Changeset 54395 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Feb 23, 2015 5:34:01 PM (10 years ago)
Author:
vboxsync
Message:

IPRT, HostDriver, VMMR0: MP notifications fixes for TSC-delta measurements, scheduling of notification callback taken care by the API consumer instead of IPRT.

Location:
trunk/src/VBox/Runtime/r0drv
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/linux/mpnotification-r0drv-linux.c

    r44529 r54395  
    55
    66/*
    7  * Copyright (C) 2008-2011 Oracle Corporation
     7 * Copyright (C) 2008-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3232#include "internal/iprt.h"
    3333
    34 #include <iprt/mp.h>
    3534#include <iprt/asm-amd64-x86.h>
    3635#include <iprt/err.h>
     
    7069
    7170/**
    72  * Notification wrapper that updates CPU states and invokes our notification
    73  * callbacks.
    74  *
    75  * @param idCpu             The CPU Id.
    76  * @param pvUser1           Pointer to the notifier_block (unused).
    77  * @param pvUser2           The notification event.
    78  * @remarks This can be invoked in interrupt context.
    79  */
    80 static DECLCALLBACK(void) rtMpNotificationLinuxOnCurrentCpu(RTCPUID idCpu, void *pvUser1, void *pvUser2)
    81 {
    82     unsigned long ulNativeEvent = *(unsigned long *)pvUser2;
    83     NOREF(pvUser1);
    84 
    85     AssertRelease(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    86     AssertReleaseMsg(idCpu == RTMpCpuId(),  /* ASSUMES iCpu == RTCPUID */
    87                      ("idCpu=%u RTMpCpuId=%d ApicId=%d\n", idCpu, RTMpCpuId(), ASMGetApicId() ));
    88 
    89     switch (ulNativeEvent)
    90     {
    91 # ifdef CPU_DOWN_FAILED
    92         case CPU_DOWN_FAILED:
    93 #  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
    94         case CPU_DOWN_FAILED_FROZEN:
    95 #  endif
    96 # endif
    97         case CPU_ONLINE:
    98 # if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
    99         case CPU_ONLINE_FROZEN:
    100 # endif
    101             rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
    102             break;
    103 
    104 # ifdef CPU_DOWN_PREPARE
    105         case CPU_DOWN_PREPARE:
    106 #  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
    107         case CPU_DOWN_PREPARE_FROZEN:
    108 #  endif
    109             rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
    110             break;
    111 # endif
    112     }
    113 }
    114 
    115 
    116 /**
    11771 * The native callback.
    11872 *
     
    12175 * @param   ulNativeEvent   The native event.
    12276 * @param   pvCpu           The cpu id cast into a pointer value.
     77 *
    12378 * @remarks This can fire with preemption enabled and on any CPU.
    12479 */
    12580static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock, unsigned long ulNativeEvent, void *pvCpu)
    12681{
    127     int rc;
    12882    bool fProcessEvent = false;
    12983    RTCPUID idCpu      = (uintptr_t)pvCpu;
     
    188142        return NOTIFY_DONE;
    189143
    190     /*
    191      * Reschedule the callbacks to fire on the specific CPU with preemption disabled.
    192      */
    193     rc = RTMpOnSpecific(idCpu, rtMpNotificationLinuxOnCurrentCpu, pNotifierBlock, &ulNativeEvent);
    194     Assert(RT_SUCCESS(rc)); NOREF(rc);
     144    switch (ulNativeEvent)
     145    {
     146# ifdef CPU_DOWN_FAILED
     147        case CPU_DOWN_FAILED:
     148#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
     149        case CPU_DOWN_FAILED_FROZEN:
     150#  endif
     151# endif
     152        case CPU_ONLINE:
     153# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
     154        case CPU_ONLINE_FROZEN:
     155# endif
     156            rtMpNotificationDoCallbacks(RTMPEVENT_ONLINE, idCpu);
     157            break;
     158
     159# ifdef CPU_DOWN_PREPARE
     160        case CPU_DOWN_PREPARE:
     161#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
     162        case CPU_DOWN_PREPARE_FROZEN:
     163#  endif
     164            rtMpNotificationDoCallbacks(RTMPEVENT_OFFLINE, idCpu);
     165            break;
     166# endif
     167    }
     168
    195169    return NOTIFY_DONE;
    196170}
  • trunk/src/VBox/Runtime/r0drv/solaris/mpnotification-r0drv-solaris.c

    r54294 r54395  
    55
    66/*
    7  * Copyright (C) 2008-2012 Oracle Corporation
     7 * Copyright (C) 2008-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    6464
    6565/**
    66  * PFNRTMPWORKER worker for executing Mp events on the target CPU.
    67  *
    68  * @param    idCpu          The current CPU Id.
    69  * @param    pvArg          Opaque pointer to event type (online/offline).
    70  * @param    pvIgnored1     Ignored.
    71  */
    72 static void rtMpNotificationSolOnCurrentCpu(RTCPUID idCpu, void *pvArg, void *pvIgnored1)
    73 {
    74     NOREF(pvIgnored1);
    75     NOREF(idCpu);
    76 
    77     PRTMPARGS pArgs = (PRTMPARGS)pvArg;
    78     AssertRelease(pArgs && pArgs->idCpu == RTMpCpuId());
    79     Assert(pArgs->pvUser1);
    80     Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD));
    81 
    82     RTMPEVENT enmMpEvent = *(RTMPEVENT *)pArgs->pvUser1;
    83     rtMpNotificationDoCallbacks(enmMpEvent, pArgs->idCpu);
    84 }
    85 
    86 
    87 /**
    8866 * Solaris callback function for Mp event notification.
    8967 *
     68 * @returns Solaris error code.
    9069 * @param    CpuState   The current event/state of the CPU.
    91  * @param    iCpu       Which CPU is this event fore.
     70 * @param    iCpu       Which CPU is this event for.
    9271 * @param    pvArg      Ignored.
    9372 *
    9473 * @remarks This function assumes index == RTCPUID.
    95  * @returns Solaris error code.
     74 *          We may -not- be firing on the CPU going online/offline and called
     75 *          with preemption enabled.
    9676 */
    9777static int rtMpNotificationCpuEvent(cpu_setup_t CpuState, int iCpu, void *pvArg)
    9878{
    9979    RTMPEVENT enmMpEvent;
    100 
    101     RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
    102     RTThreadPreemptDisable(&PreemptState);
    10380
    10481    /*
     
    11996        return 0;
    12097
    121     /*
    122      * Since we don't absolutely need to do CPU bound code in any of the CPU offline
    123      * notification hooks, run it on the current CPU. Scheduling a callback to execute
    124      * on the CPU going offline at this point is too late and will not work reliably.
    125      */
    126     bool fRunningOnTargetCpu = iCpu == RTMpCpuId();
    127     if (   fRunningOnTargetCpu == true
    128         || enmMpEvent == RTMPEVENT_OFFLINE)
    129     {
    130         rtMpNotificationDoCallbacks(enmMpEvent, iCpu);
    131     }
    132     else
    133     {
    134         /** @todo We should probably be using thread_affinity_set() here, see
    135          *        cpu_online() code. */
    136         /*
    137          * We're not on the target CPU, schedule (synchronous) the event notification callback
    138          * to run on the target CPU i.e. the CPU that was online'd.
    139          */
    140         RTMPARGS Args;
    141         RT_ZERO(Args);
    142         Args.pvUser1 = &enmMpEvent;
    143         Args.pvUser2 = NULL;
    144         Args.idCpu   = iCpu;
    145         RTMpOnSpecific(iCpu, rtMpNotificationSolOnCurrentCpu, &Args, NULL /* pvIgnored1 */);
    146     }
    147 
    148     RTThreadPreemptRestore(&PreemptState);
    149 
     98    rtMpNotificationDoCallbacks(enmMpEvent, iCpu);
    15099    NOREF(pvArg);
    151100    return 0;
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