VirtualBox

Changeset 52134 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Jul 22, 2014 5:39:46 PM (11 years ago)
Author:
vboxsync
Message:

NDIS6: Cumulative commit containing async send, unload race fix (intnet), missing offload fix, basic vboxnetadp6.sys (#7231)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r49480 r52134  
    450450
    451451
     452#ifdef VBOX_WITH_INTNET_DISCONNECT
     453/*******************************************************************************
     454*   Forward Declarations                                                       *
     455*******************************************************************************/
     456static void intnetR0TrunkIfDestroy(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork);
     457
     458
     459/**
     460 * Checks if a pointer belongs to the list of known networks without
     461 * accessing memory it points to.
     462 *
     463 * @returns true, if such network is in the list.
     464 * @param   pIntNet     The pointer to the internal network instance (global).
     465 * @param   pNetwork    The pointer that must be validated.
     466 */
     467DECLINLINE(bool) intnetR0NetworkIsValid(PINTNET pIntNet, PINTNETNETWORK pNetwork)
     468{
     469    for (PINTNETNETWORK pCurr = pIntNet->pNetworks; pCurr; pCurr = pCurr->pNext)
     470        if (pCurr == pNetwork)
     471            return true;
     472    return false;
     473}
     474#endif /* VBOX_WITH_INTNET_DISCONNECT */
     475
    452476
    453477/**
     
    716740DECLINLINE(void) intnetR0BusyDecTrunk(PINTNETTRUNKIF pTrunk)
    717741{
    718     intnetR0BusyDec(pTrunk->pNetwork, &pTrunk->cBusy);
     742    if (pTrunk)
     743        intnetR0BusyDec(pTrunk->pNetwork, &pTrunk->cBusy);
    719744}
    720745
     
    744769DECLINLINE(void) intnetR0BusyIncTrunk(PINTNETTRUNKIF pTrunk)
    745770{
     771    if (!pTrunk) return;
    746772    uint32_t cNewBusy = ASMAtomicIncU32(&pTrunk->cBusy);
    747773    AssertMsg((cNewBusy & ~INTNET_BUSY_WAKEUP_MASK) < INTNET_MAX_IFS * 3, ("%#x\n", cNewBusy));
     
    30973123     * since we modified the MAC in the initial request the guest made.
    30983124     */
     3125    RTSpinlockAcquire(pNetwork->hAddrSpinlock);
     3126    RTMAC MacAddrTrunk;
     3127    if (pNetwork->MacTab.pTrunk)
     3128        MacAddrTrunk = pNetwork->MacTab.pTrunk->MacAddr;
     3129    else
     3130        memset(&MacAddrTrunk, 0, sizeof(MacAddrTrunk));
     3131    RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock);
    30993132    if (    ar_oper == RTNET_ARPOP_REPLY
    3100         &&  !memcmp(&pArpIPv4->ar_tha, &pNetwork->MacTab.pTrunk->MacAddr, sizeof(RTMAC)))
     3133        &&  !memcmp(&pArpIPv4->ar_tha, &MacAddrTrunk, sizeof(RTMAC)))
    31013134    {
    31023135        PINTNETIF pIf = intnetR0NetworkAddrCacheLookupIf(pNetwork, (PCRTNETADDRU)&pArpIPv4->ar_tpa,
     
    31063139            Log6(("fw: ar_tha %.6Rhxs -> %.6Rhxs\n", &pArpIPv4->ar_tha, &pIf->MacAddr));
    31073140            pArpIPv4->ar_tha = pIf->MacAddr;
    3108             if (!memcmp(&pEthHdr->DstMac, &pNetwork->MacTab.pTrunk->MacAddr, sizeof(RTMAC)))
     3141            if (!memcmp(&pEthHdr->DstMac, &MacAddrTrunk, sizeof(RTMAC)))
    31093142            {
    31103143                Log6(("fw: DstMac %.6Rhxs -> %.6Rhxs\n", &pEthHdr->DstMac, &pIf->MacAddr));
     
    32723305    /* ASSUMES: that the trunk won't change its report while we're checking. */
    32733306    PINTNETTRUNKIF  pTrunk = pDstTab->pTrunk;
    3274     if ((fTrunkDst & pTrunk->fNoPreemptDsts) == fTrunkDst)
     3307    if (pTrunk && (fTrunkDst & pTrunk->fNoPreemptDsts) == fTrunkDst)
    32753308        return true;
    32763309
     
    35173550    {
    35183551        PINTNETTRUNKIF pTrunk = pDstTab->pTrunk;
    3519         intnetR0BusyDec(pNetwork, &pTrunk->cBusy);
     3552        if (pTrunk)
     3553            intnetR0BusyDec(pNetwork, &pTrunk->cBusy);
    35203554        pDstTab->pTrunk    = NULL;
    35213555        pDstTab->fTrunkDst = 0;
     
    35743608    {
    35753609        PINTNETTRUNKIF pTrunk = pDstTab->pTrunk;
    3576         if (pIfSender)
    3577             intnetR0TrunkIfSend(pTrunk, pNetwork, pIfSender, pDstTab->fTrunkDst, pSG);
    3578         intnetR0BusyDec(pNetwork, &pTrunk->cBusy);
     3610        if (pTrunk)
     3611        {
     3612            if (pIfSender)
     3613                intnetR0TrunkIfSend(pTrunk, pNetwork, pIfSender, pDstTab->fTrunkDst, pSG);
     3614            intnetR0BusyDec(pNetwork, &pTrunk->cBusy);
     3615        }
    35793616        pDstTab->pTrunk    = NULL;
    35803617        pDstTab->fTrunkDst = 0;
     
    49715008    pThis->fNoPreemptDsts = fNoPreemptDsts;
    49725009}
     5010
     5011
     5012#ifdef VBOX_WITH_INTNET_DISCONNECT
     5013/** @copydoc INTNETTRUNKSWPORT::pfnDisconnect */
     5014static DECLCALLBACK(void) intnetR0TrunkIfPortDisconnect(PINTNETTRUNKSWPORT pSwitchPort)
     5015{
     5016    PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort);
     5017    /*
     5018     * We intentionally do not increase the busy count of the trunk as it will cause a deadlock
     5019     * with a racing intnetR0NetworkDestruct. It is safe to do only due to the fact that our
     5020     * caller must have increased the busy count of the corresponding netflt instance thus
     5021     * preventing intnetR0NetworkDestruct from destroying the trunk.
     5022     */
     5023    PINTNETNETWORK pNetwork = pThis->pNetwork;
     5024    if (pNetwork)
     5025    {
     5026        /*
     5027         * We need to save pIntNet too in case pNetwork becomes invalid while we are waiting
     5028         * on pIntNet->hMtxCreateOpenDestroy.
     5029         */
     5030        PINTNET pIntNet = pNetwork->pIntNet;
     5031        Assert(pNetwork->pIntNet);
     5032        /*
     5033         * We must decrease the busy count of corresponing netflt instance here allowing
     5034         * intnetR0NetworkDestruct to proceed with destruction.
     5035         */
     5036        pThis->pIfPort->pfnRelease(pThis->pIfPort, true);
     5037        /* Take the big create/open/destroy sem. */
     5038        RTSemMutexRequest(pIntNet->hMtxCreateOpenDestroy, RT_INDEFINITE_WAIT);
     5039        /*
     5040         * At this point pNetwork may no longer exist, being destroyed by intnetR0NetworkDestruct
     5041         * so we need to make sure it is still valid by looking it up in pIntNet->pNetworks.
     5042         */
     5043        if (intnetR0NetworkIsValid(pIntNet, pNetwork))
     5044        {
     5045            pThis->pIfPort->pfnSetState(pThis->pIfPort, INTNETTRUNKIFSTATE_DISCONNECTING);
     5046
     5047            RTSpinlockAcquire(pNetwork->hAddrSpinlock);
     5048            pNetwork->MacTab.pTrunk = NULL;
     5049            RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock);
     5050
     5051            intnetR0TrunkIfDestroy(pThis, pNetwork);
     5052        }
     5053
     5054        RTSemMutexRelease(pNetwork->pIntNet->hMtxCreateOpenDestroy);
     5055    }
     5056}
     5057#endif /* VBOX_WITH_INTNET_DISCONNECT */
    49735058
    49745059
     
    53325417        pTrunk->SwitchPort.pfnReportGsoCapabilities   = intnetR0TrunkIfPortReportGsoCapabilities;
    53335418        pTrunk->SwitchPort.pfnReportNoPreemptDsts     = intnetR0TrunkIfPortReportNoPreemptDsts;
     5419#ifdef VBOX_WITH_INTNET_DISCONNECT
     5420        pTrunk->SwitchPort.pfnDisconnect              = intnetR0TrunkIfPortDisconnect;
     5421#endif /* VBOX_WITH_INTNET_DISCONNECT */
    53345422        pTrunk->SwitchPort.u32VersionEnd              = INTNETTRUNKSWPORT_VERSION;
    53355423        //pTrunk->pIfPort                 = NULL;
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