VirtualBox

Changeset 29362 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
May 11, 2010 2:40:17 PM (15 years ago)
Author:
vboxsync
Message:

SrvIntNetR0.cpp: Don't call RTMemAllocZ when in interrupt or atomic context. Fixed intnetR0IfAddrCacheAddIt regression which prevent the cache from containing more than one valid entry.

File:
1 edited

Legend:

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

    r29160 r29362  
    11811181    RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
    11821182
    1183     if (!pCache->cEntriesAlloc)
    1184     {
    1185         /* Allocate the table - 64 entries. */
     1183    if (RT_UNLIKELY(!pCache->cEntriesAlloc))
     1184    {
     1185        /* This shouldn't happen*/
    11861186        RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock, &Tmp);
    1187         uint8_t *pbEntries = (uint8_t *)RTMemAllocZ(pCache->cbEntry * 64);
    1188         if (!pbEntries)
    1189             return;
    1190         RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
    1191         if (!pCache->cEntriesAlloc)
    1192         {
    1193             pCache->pbEntries     = pbEntries;
    1194             pCache->cEntriesAlloc = 64;
    1195         }
    1196         else
    1197         {
    1198             RTSpinlockReleaseNoInts(pNetwork->hAddrSpinlock, &Tmp);
    1199             RTMemFree(pbEntries);
    1200             RTSpinlockAcquireNoInts(pNetwork->hAddrSpinlock, &Tmp);
    1201         }
    1202     }
    1203     else
    1204     {
    1205         /* simple FIFO, might consider usage/ageing here... */
     1187        return;
     1188    }
     1189
     1190    /* When the table is full, drop the older entry (FIFO). Do proper ageing? */
     1191    if (pCache->cEntries >= pCache->cEntriesAlloc)
     1192    {
    12061193        Log(("intnetR0IfAddrCacheAddIt: type=%d replacing %.*Rhxs\n",
    12071194             (int)(uintptr_t)(pCache - &pIf->aAddrCache[0]), pCache->cbAddress, pCache->pbEntries));
    12081195        memmove(pCache->pbEntries, pCache->pbEntries + pCache->cbEntry, pCache->cbEntry * (pCache->cEntries - 1));
    12091196        pCache->cEntries--;
     1197        Assert(pCache->cEntries < pCache->cEntriesAlloc);
    12101198    }
    12111199
     
    12951283        return;
    12961284    intnetR0IfAddrCacheAddSlow(pIf, pCache, pAddr, cbAddr, pszMsg);
     1285}
     1286
     1287
     1288/**
     1289 * Destroys the specified address cache.
     1290 * @param   pCache              The address cache.
     1291 */
     1292static void intnetR0IfAddrCacheDestroy(PINTNETADDRCACHE pCache)
     1293{
     1294    void *pvFree = pCache->pbEntries;
     1295    pCache->pbEntries     = NULL;
     1296    pCache->cEntries      = 0;
     1297    pCache->cEntriesAlloc = 0;
     1298    RTMemFree(pvFree);
     1299}
     1300
     1301
     1302/**
     1303 * Initialize the address cache for the specified address type.
     1304 *
     1305 * The cache storage is preallocated and fixed size so that we can handle
     1306 * inserts from problematic contexts.
     1307 *
     1308 * @returns VINF_SUCCESS or VERR_NO_MEMORY.
     1309 * @param   pCache              The cache to initialize.
     1310 * @param   enmAddrType         The address type.
     1311 * @param   fEnabled            Whether the address cache is enabled or not.
     1312 */
     1313static int intnetR0IfAddrCacheInit(PINTNETADDRCACHE pCache, INTNETADDRTYPE enmAddrType, bool fEnabled)
     1314{
     1315    pCache->cEntries  = 0;
     1316    pCache->cbAddress = intnetR0AddrSize(enmAddrType);
     1317    pCache->cbEntry   = RT_ALIGN(pCache->cbAddress, 4);
     1318    if (fEnabled)
     1319    {
     1320        pCache->cEntriesAlloc = 32;
     1321        pCache->pbEntries     = (uint8_t *)RTMemAllocZ(pCache->cEntriesAlloc * pCache->cbEntry);
     1322        if (!pCache->pbEntries)
     1323            return VERR_NO_MEMORY;
     1324    }
     1325    else
     1326    {
     1327        pCache->cEntriesAlloc = 0;
     1328        pCache->pbEntries     = NULL;
     1329    }
     1330    return VINF_SUCCESS;
    12971331}
    12981332
     
    40424076    pIf->pDstTab = NULL;
    40434077
    4044     for (unsigned i = 0; i < RT_ELEMENTS(pIf->aAddrCache); i++)
    4045         if (pIf->aAddrCache[i].pbEntries)
    4046         {
    4047             RTMemFree(pIf->aAddrCache[i].pbEntries);
    4048             pIf->aAddrCache[i].pbEntries = NULL;
    4049         }
    4050 
    4051     pIf->pvObj = NULL;
     4078    for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++)
     4079        intnetR0IfAddrCacheDestroy(&pIf->aAddrCache[i]);
     4080
     4081     pIf->pvObj = NULL;
    40524082    RTMemFree(pIf);
    40534083}
     
    41114141    pIf->pSession           = pSession;
    41124142    //pIf->pvObj            = NULL;
    4113     //pIf->aAddrCache[kIntNetAddrType_Invalid]            = {0};
    4114     //pIf->aAddrCache[kIntNetAddrType_IPv4].pbEntries     = NULL;
    4115     //pIf->aAddrCache[kIntNetAddrType_IPv4].cEntries      = 0;
    4116     //pIf->aAddrCache[kIntNetAddrType_IPv4].cEntriesAlloc = 0;
    4117     pIf->aAddrCache[kIntNetAddrType_IPv4].cbAddress       = intnetR0AddrSize(kIntNetAddrType_IPv4);
    4118     pIf->aAddrCache[kIntNetAddrType_IPv4].cbEntry         = intnetR0AddrSize(kIntNetAddrType_IPv4);
    4119     //pIf->aAddrCache[kIntNetAddrType_IPv6].pbEntries     = NULL;
    4120     //pIf->aAddrCache[kIntNetAddrType_IPv6].cEntries      = 0;
    4121     //pIf->aAddrCache[kIntNetAddrType_IPv6].cEntriesAlloc = 0;
    4122     pIf->aAddrCache[kIntNetAddrType_IPv6].cbAddress       = intnetR0AddrSize(kIntNetAddrType_IPv6);
    4123     pIf->aAddrCache[kIntNetAddrType_IPv6].cbEntry         = intnetR0AddrSize(kIntNetAddrType_IPv6);
    4124     //pIf->aAddrCache[kIntNetAddrType_IPX].pbEntries      = NULL;
    4125     //pIf->aAddrCache[kIntNetAddrType_IPX].cEntries       = 0;
    4126     //pIf->aAddrCache[kIntNetAddrType_IPX].cEntriesAlloc  = 0;
    4127     pIf->aAddrCache[kIntNetAddrType_IPX].cbAddress        = intnetR0AddrSize(kIntNetAddrType_IPX);
    4128     pIf->aAddrCache[kIntNetAddrType_IPX].cbEntry          = RT_ALIGN_32(intnetR0AddrSize(kIntNetAddrType_IPX), 16);
     4143    //pIf->aAddrCache       = {0};
    41294144    pIf->hRecvInSpinlock    = NIL_RTSPINLOCK;
    41304145    pIf->cBusy              = 0;
    41314146    //pIf->pDstTab          = NULL;
    41324147
    4133     rc = intnetR0AllocDstTab(pNetwork->MacTab.cEntriesAllocated, (PINTNETDSTTAB *)&pIf->pDstTab);
     4148    for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End && RT_SUCCESS(rc); i++)
     4149        rc = intnetR0IfAddrCacheInit(&pIf->aAddrCache[i], (INTNETADDRTYPE)i,
     4150                                     !!(pNetwork->fFlags & INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE));
     4151    if (RT_SUCCESS(rc))
     4152        rc = intnetR0AllocDstTab(pNetwork->MacTab.cEntriesAllocated, (PINTNETDSTTAB *)&pIf->pDstTab);
    41344153    if (RT_SUCCESS(rc))
    41354154        rc = RTSemEventCreate((PRTSEMEVENT)&pIf->hRecvEvent);
     
    42074226    pIf->hRecvEvent = NIL_RTSEMEVENT;
    42084227    RTMemFree(pIf->pDstTab);
     4228    for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++)
     4229        intnetR0IfAddrCacheDestroy(&pIf->aAddrCache[i]);
    42094230    RTMemFree(pIf);
    42104231    LogFlow(("intnetR0NetworkCreateIf: returns %Rrc\n", rc));
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