Beispiel #1
0
/**
 * Solaris callback function for Mp event notification.
 *
 * @param    CpuState   The current event/state of the CPU.
 * @param    iCpu       Which CPU is this event fore.
 * @param    pvArg      Ignored.
 *
 * @remarks This function assumes index == RTCPUID.
 * @returns Solaris error code.
 */
static int rtMpNotificationCpuEvent(cpu_setup_t CpuState, int iCpu, void *pvArg)
{
    RTMPEVENT enmMpEvent;

    RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER;
    RTThreadPreemptDisable(&PreemptState);

    /*
     * Update our CPU set structures first regardless of whether we've been
     * scheduled on the right CPU or not, this is just atomic accounting.
     */
    if (CpuState == CPU_ON)
    {
        enmMpEvent = RTMPEVENT_ONLINE;
        RTCpuSetAdd(&g_rtMpSolCpuSet, iCpu);
    }
    else if (CpuState == CPU_OFF)
    {
        enmMpEvent = RTMPEVENT_OFFLINE;
        RTCpuSetDel(&g_rtMpSolCpuSet, iCpu);
    }
    else
        return 0;

    /*
     * Since we don't absolutely need to do CPU bound code in any of the CPU offline
     * notification hooks, run it on the current CPU. Scheduling a callback to execute
     * on the CPU going offline at this point is too late and will not work reliably.
     */
    bool fRunningOnTargetCpu = iCpu == RTMpCpuId();
    if (   fRunningOnTargetCpu == true
        || enmMpEvent == RTMPEVENT_OFFLINE)
    {
        rtMpNotificationDoCallbacks(enmMpEvent, iCpu);
    }
    else
    {
        /*
         * We're not on the target CPU, schedule (synchronous) the event notification callback
         * to run on the target CPU i.e. the CPU that was online'd.
         */
        RTMPARGS Args;
        RT_ZERO(Args);
        Args.pvUser1 = &enmMpEvent;
        Args.pvUser2 = NULL;
        Args.idCpu   = iCpu;
        RTMpOnSpecific(iCpu, rtMpNotificationSolOnCurrentCpu, &Args, NULL /* pvIgnored1 */);
    }

    RTThreadPreemptRestore(&PreemptState);

    NOREF(pvArg);
    return 0;
}
int VBOXCALL    supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
{
# ifdef SUPDRV_LINUX_HAS_SAFE_MSR_API
    if (idCpu == NIL_RTCPUID)
    {
        supdrvLnxMsrProberModifyOnCpu(idCpu, pReq, NULL);
        return VINF_SUCCESS;
    }
    return RTMpOnSpecific(idCpu, supdrvLnxMsrProberModifyOnCpu, pReq, NULL);
# else
    return VERR_NOT_SUPPORTED;
# endif
}
Beispiel #3
0
/**
 * The native callback.
 *
 * @returns NOTIFY_DONE.
 * @param   pNotifierBlock  Pointer to g_NotifierBlock.
 * @param   ulNativeEvent   The native event.
 * @param   pvCpu           The cpu id cast into a pointer value.
 * @remarks This can fire with preemption enabled and on any CPU.
 */
static int rtMpNotificationLinuxCallback(struct notifier_block *pNotifierBlock, unsigned long ulNativeEvent, void *pvCpu)
{
    int rc;
    bool fProcessEvent = false;
    RTCPUID idCpu      = (uintptr_t)pvCpu;
    NOREF(pNotifierBlock);

    /*
     * Note that redhat/CentOS ported _some_ of the FROZEN macros
     * back to their 2.6.18-92.1.10.el5 kernel but actually don't
     * use them. Thus we have to test for both CPU_TASKS_FROZEN and
     * the individual event variants.
     */
    switch (ulNativeEvent)
    {
        /*
         * Pick up online events or failures to go offline.
         * Ignore failure events for CPUs we didn't see go offline.
         */
# ifdef CPU_DOWN_FAILED
        case CPU_DOWN_FAILED:
#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_FAILED_FROZEN)
        case CPU_DOWN_FAILED_FROZEN:
#  endif
            if (!RTCpuSetIsMember(&g_MpPendingOfflineSet, idCpu))
                break;      /* fProcessEvents = false */
        /* fall thru */
# endif
        case CPU_ONLINE:
# if defined(CPU_TASKS_FROZEN) && defined(CPU_ONLINE_FROZEN)
        case CPU_ONLINE_FROZEN:
# endif
# ifdef CPU_DOWN_FAILED
            RTCpuSetDel(&g_MpPendingOfflineSet, idCpu);
# endif
            fProcessEvent = true;
            break;

        /*
         * Pick the earliest possible offline event.
         * The only important thing here is that we get the event and that
         * it's exactly one.
         */
# ifdef CPU_DOWN_PREPARE
        case CPU_DOWN_PREPARE:
#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DOWN_PREPARE_FROZEN)
        case CPU_DOWN_PREPARE_FROZEN:
#  endif
            fProcessEvent = true;
# else
        case CPU_DEAD:
#  if defined(CPU_TASKS_FROZEN) && defined(CPU_DEAD_FROZEN)
        case CPU_DEAD_FROZEN:
#  endif
            /* Don't process CPU_DEAD notifications. */
# endif
# ifdef CPU_DOWN_FAILED
            RTCpuSetAdd(&g_MpPendingOfflineSet, idCpu);
# endif
            break;
    }

    if (!fProcessEvent)
        return NOTIFY_DONE;

    /*
     * Reschedule the callbacks to fire on the specific CPU with preemption disabled.
     */
    rc = RTMpOnSpecific(idCpu, rtMpNotificationLinuxOnCurrentCpu, pNotifierBlock, &ulNativeEvent);
    Assert(RT_SUCCESS(rc)); NOREF(rc);
    return NOTIFY_DONE;
}