Changeset 10681 in vbox for trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
- Timestamp:
- Jul 15, 2008 8:00:27 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp
r10677 r10681 36 36 #include <iprt/assert.h> 37 37 #include <iprt/string.h> 38 #include <iprt/time.h> 38 39 39 40 … … 97 98 { 98 99 /** The port interface we present to the component. */ 99 INTNETTRUNKSWPORT SwitchPort;100 INTNETTRUNKSWPORT SwitchPort; 100 101 /** The port interface we get from the component. */ 101 PINTNETTRUNKIFPORT pIfPort;102 PINTNETTRUNKIFPORT pIfPort; 102 103 /** The trunk mutex that serializes all calls <b>to</b> the component. */ 103 RTSEMFASTMUTEX FastMutex; 104 RTSEMFASTMUTEX FastMutex; 105 /** Pointer to the network we're connect to. 106 * This may be NULL if we're orphaned? */ 107 struct INTNETNETWORK *pNetwork; 108 /** Whether to supply physical addresses with the outbound SGs. */ 109 bool volatile fPhysSG; 104 110 } INTNETTRUNKIF; 105 111 /** Pointer to a trunk interface. */ 106 112 typedef INTNETTRUNKIF *PINTNETTRUNKIF; 113 114 /** Converts a pointer to INTNETTRUNKIF::SwitchPort to a PINTNETTRUNKIF. */ 115 #define INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort) ((PINTNETTRUNKIF)(pSwitchPort)) 107 116 108 117 … … 118 127 * This is protected by the INTNET::FastMutex. */ 119 128 PINTNETIF pIFs; 129 /** Pointer to the trunk interface. 130 * Can be NULL if there is no trunk connection. */ 131 PINTNETTRUNKIF pTrunkIF; 120 132 /** The network mutex. 121 133 * It protects everything dealing with this network. */ … … 191 203 INTNETHT IfHandles; 192 204 } INTNET; 205 206 207 /******************************************************************************* 208 * Internal Functions * 209 *******************************************************************************/ 210 static PINTNETTRUNKIF intnetTrunkIfRetain(PINTNETTRUNKIF pThis); 211 static void intnetTrunkIfRelease(PINTNETTRUNKIF pThis); 212 static bool intnetTrunkIfOutLock(PINTNETTRUNKIF pThis); 213 static void intnetTrunkIfOutUnlock(PINTNETTRUNKIF pThis); 193 214 194 215 … … 1253 1274 1254 1275 1255 #ifdef IN_RING0 1276 1277 1256 1278 1257 1279 /** @copydoc INTNETTRUNKSWPORT::pfnSetSGPhys */ 1258 static DECLCALLBACK(bool) intnetTrunkIfPortSetSGPhys(PINTNETTRUNKSWPORT pIfPort, bool fEnable) 1259 { 1280 static DECLCALLBACK(bool) intnetTrunkIfPortSetSGPhys(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable) 1281 { 1282 PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 1260 1283 AssertMsgFailed(("Not implemented because it wasn't required on Darwin\n")); 1284 return ASMAtomicXchgBool(&pThis->fPhysSG, fEnable); 1285 } 1286 1287 1288 /** @copydoc INTNETTRUNKSWPORT::pfnRecv */ 1289 static DECLCALLBACK(bool) intnetTrunkIfPortRecv(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG, uint32_t fSrc) 1290 { 1291 PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 1292 PINTNETNETWORK pNetwork = pThis->pNetwork; 1293 1294 /* assert some sanity */ 1295 AssertPtrReturn(pNetwork, false); 1296 AssertReturn(pNetwork->FastMutex != NIL_RTSEMFASTMUTEX, false); 1297 AssertPtr(pSG); 1298 Assert(fSrc); 1299 1300 /* 1301 * 1302 */ 1303 1304 1261 1305 return false; 1262 1306 } 1263 1307 1264 1308 1265 /** @copydoc INTNETTRUNKSWPORT::pfnRecv */ 1266 static DECLCALLBACK(bool) intnetTrunkIfPortRecv(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG, uint32_t fSrc) 1267 { 1309 /** @copydoc INTNETTRUNKSWPORT::pfnSGRetain */ 1310 static DECLCALLBACK(void) intnetTrunkIfPortSGRetain(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG) 1311 { 1312 PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 1313 PINTNETNETWORK pNetwork = pThis->pNetwork; 1314 1315 /* assert some sanity */ 1316 AssertPtrReturnVoid(pNetwork); 1317 AssertReturnVoid(pNetwork->FastMutex != NIL_RTSEMFASTMUTEX); 1318 AssertPtr(pSG); 1319 Assert(pSG->cUsers > 0); 1320 1321 /* do it. */ 1322 ++pSG->cUsers; 1323 } 1324 1325 1326 /** @copydoc INTNETTRUNKSWPORT::pfnSGRelease */ 1327 static DECLCALLBACK(void) intnetTrunkIfPortSGRelease(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG) 1328 { 1329 PINTNETTRUNKIF pThis = INTNET_SWITCHPORT_2_TRUNKIF(pSwitchPort); 1330 PINTNETNETWORK pNetwork = pThis->pNetwork; 1331 1332 /* assert some sanity */ 1333 AssertPtrReturnVoid(pNetwork); 1334 AssertReturnVoid(pNetwork->FastMutex != NIL_RTSEMFASTMUTEX); 1335 AssertPtr(pSG); 1336 Assert(pSG->cUsers > 0); 1337 1338 /* 1339 * Free it? 1340 */ 1341 if (!--pSG->cUsers) 1342 { 1343 /** @todo later */ 1344 } 1345 } 1346 1347 1348 /** 1349 * Retain the trunk interface. 1350 * 1351 * @returns pThis. 1352 * 1353 * @param pThis The trunk. 1354 * 1355 * @remarks Any locks. 1356 */ 1357 static PINTNETTRUNKIF intnetTrunkIfRetain(PINTNETTRUNKIF pThis) 1358 { 1359 if (pThis && pThis->pIfPort) 1360 pThis->pIfPort->pfnRetain(pThis->pIfPort); 1361 return pThis; 1362 } 1363 1364 1365 /** 1366 * Release the trunk interface. 1367 * 1368 * @param pThis The trunk. 1369 */ 1370 static void intnetTrunkIfRelease(PINTNETTRUNKIF pThis) 1371 { 1372 if (pThis && pThis->pIfPort) 1373 pThis->pIfPort->pfnRelease(pThis->pIfPort); 1374 } 1375 1376 1377 /** 1378 * Takes the out-bound trunk lock. 1379 * 1380 * This will ensure that pIfPort is valid. 1381 * 1382 * @returns success indicator. 1383 * @param pThis The trunk. 1384 * 1385 * @remarks No locks other than the create/destroy one. 1386 */ 1387 static bool intnetTrunkIfOutLock(PINTNETTRUNKIF pThis) 1388 { 1389 AssertPtrReturn(pThis, false); 1390 int rc = RTSemFastMutexRequest(pThis->FastMutex); 1391 if (RT_SUCCESS(rc)) 1392 { 1393 if (RT_LIKELY(pThis->pIfPort)) 1394 return true; 1395 RTSemFastMutexRelease(pThis->FastMutex); 1396 } 1397 else 1398 AssertMsg(rc == VERR_SEM_DESTROYED, ("%Rrc\n", rc)); 1268 1399 return false; 1269 1400 } 1270 1401 1271 1402 1272 /** @copydoc INTNETTRUNKSWPORT::pfnSGRetain */ 1273 static DECLCALLBACK(void) intnetTrunkIfPortSGRetain(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG) 1274 { 1275 1276 } 1277 1278 1279 /** @copydoc INTNETTRUNKSWPORT::pfnSGRelease */ 1280 static DECLCALLBACK(void) intnetTrunkIfPortSGRelease(PINTNETTRUNKSWPORT pIfPort, PINTNETSG pSG) 1281 { 1282 1403 /** 1404 * Releases the out-bound trunk lock. 1405 * 1406 * @param pThis The trunk. 1407 */ 1408 static void intnetTrunkIfOutUnlock(PINTNETTRUNKIF pThis) 1409 { 1410 if (pThis) 1411 { 1412 int rc = RTSemFastMutexRelease(pThis->FastMutex); 1413 AssertRC(rc); 1414 } 1415 } 1416 1417 1418 /** 1419 * Activates the trunk interface. 1420 * 1421 * @param pThis The trunk. 1422 * @param fActive What to do with it. 1423 * 1424 * @remarks Caller may only own the create/destroy lock. 1425 */ 1426 static void intnetTrunkIfActivate(PINTNETTRUNKIF pThis, bool fActive) 1427 { 1428 if (intnetTrunkIfOutLock(pThis)) 1429 { 1430 pThis->pIfPort->pfnSetActive(pThis->pIfPort, fActive); 1431 intnetTrunkIfOutUnlock(pThis); 1432 } 1433 } 1434 1435 1436 /** 1437 * Shutdown the trunk interface. 1438 * 1439 * @param pThis The trunk. 1440 * @param pNetworks The network. 1441 * 1442 * @remarks The caller must *NOT* hold the network lock. The global 1443 * create/destroy lock is fine though. 1444 */ 1445 static void intnetTrunkIfDestroy(PINTNETTRUNKIF pThis, PINTNETNETWORK pNetwork) 1446 { 1447 /* assert sanity */ 1448 if (!pThis) 1449 return; 1450 AssertPtr(pThis); 1451 Assert(pThis->pNetwork == pNetwork); 1452 AssertPtrNull(pThis->pIfPort); 1453 1454 /* 1455 * The interface has already been deactivated, we just to wait for 1456 * it to become idle before we can disconnect and release it. 1457 */ 1458 PINTNETTRUNKIFPORT pIfPort = pThis->pIfPort; 1459 if (pIfPort) 1460 { 1461 intnetTrunkIfOutLock(pThis); 1462 1463 /* unset it */ 1464 pThis->pIfPort = NULL; 1465 1466 /* wait in portions so we can complain ever now an then. */ 1467 uint64_t StartTS = RTTimeSystemNanoTS(); 1468 int rc = pIfPort->pfnWaitForIdle(pIfPort, 10*1000); 1469 if (RT_FAILURE(rc)) 1470 { 1471 LogRel(("intnet: '%s' did't become idle in %RU64 ns (%Rrc).\n", 1472 pNetwork->szName, RTTimeSystemNanoTS() - StartTS, rc)); 1473 Assert(rc == VERR_TIMEOUT); 1474 while ( RT_FAILURE(rc) 1475 && RTTimeSystemNanoTS() - StartTS < UINT64_C(30000000000)) /* 30 sec */ 1476 rc = pIfPort->pfnWaitForIdle(pIfPort, 10*1000); 1477 if (rc == VERR_TIMEOUT) 1478 { 1479 LogRel(("intnet: '%s' did't become idle in %RU64 ns (%Rrc).\n", 1480 pNetwork->szName, RTTimeSystemNanoTS() - StartTS, rc)); 1481 while ( rc == VERR_TIMEOUT 1482 && RTTimeSystemNanoTS() - StartTS < UINT64_C(360000000000)) /* 360 sec */ 1483 rc = pIfPort->pfnWaitForIdle(pIfPort, 30*1000); 1484 if (RT_FAILURE(rc)) 1485 { 1486 LogRel(("intnet: '%s' did't become idle in %RU64 ns (%Rrc), giving up.\n", 1487 pNetwork->szName, RTTimeSystemNanoTS() - StartTS, rc)); 1488 AssertRC(rc); 1489 } 1490 } 1491 } 1492 1493 /* disconnect & release it. */ 1494 pIfPort->pfnDisconnectAndRelease(pIfPort); 1495 } 1496 1497 /* 1498 * Free up the resources. 1499 */ 1500 RTSEMFASTMUTEX FastMutex = pThis->FastMutex; 1501 pThis->FastMutex = NIL_RTSEMFASTMUTEX; 1502 pThis->pNetwork = NULL; 1503 RTSemFastMutexRelease(FastMutex); 1504 RTSemFastMutexDestroy(FastMutex); 1505 RTMemFree(pThis); 1283 1506 } 1284 1507 … … 1335 1558 pTrunkIF->SwitchPort.u32VersionEnd = INTNETTRUNKSWPORT_VERSION; 1336 1559 //pTrunkIF->pIfPort = NULL; 1560 pTrunkIF->pNetwork = pNetwork; 1561 //pTrunkIF->fPhysSG = false; 1337 1562 int rc = RTSemFastMutexCreate(&pTrunkIF->FastMutex); 1338 1563 if (RT_SUCCESS(rc)) 1339 1564 { 1565 #ifdef IN_RING0 /* (testcase is ring-3) */ 1340 1566 /* 1341 1567 * Query the factory we want, then use it create and connect the trunk. … … 1350 1576 { 1351 1577 Assert(pTrunkIF->pIfPort); 1578 pNetwork->pTrunkIF = pTrunkIF; 1352 1579 LogFlow(("intnetNetworkCreateTrunkConnection: VINF_SUCCESS - pszName=%s szTrunk=%s Network=%s\n", 1353 1580 rc, pszName, pNetwork->szTrunk, pNetwork->szName)); … … 1355 1582 } 1356 1583 } 1357 1358 RTMemFree(pTrunkIF); 1359 } 1584 #endif /* IN_RING0 */ 1585 RTSemFastMutexDestroy(pTrunkIF->FastMutex); 1586 } 1587 RTMemFree(pTrunkIF); 1360 1588 LogFlow(("intnetNetworkCreateTrunkConnection: %Rrc - pszName=%s szTrunk=%s Network=%s\n", 1361 1589 rc, pszName, pNetwork->szTrunk, pNetwork->szName)); … … 1363 1591 } 1364 1592 1365 #endif /* IN_RING0 */1366 1593 1367 1594 … … 1399 1626 Assert(pNetwork->pIntNet == pIntNet); 1400 1627 1628 /* take the create/destroy sem. */ 1401 1629 RTSemFastMutexRequest(pIntNet->FastMutex); 1402 1630 1631 /* 1632 * Deactivate the trunk connection first (if any). 1633 */ 1634 if (pNetwork->pTrunkIF) 1635 intnetTrunkIfActivate(pNetwork->pTrunkIF, false /* fActive */); 1403 1636 1404 1637 /* … … 1421 1654 pNetwork->pvObj = NULL; 1422 1655 1423 RTSemFastMutexRequest(pNetwork->FastMutex);1424 1425 1656 /* 1426 1657 * Because of the undefined order of the per session object dereferencing when closing a session, … … 1428 1659 * deal with this by simply orphaning the interfaces. 1429 1660 */ 1661 RTSemFastMutexRequest(pNetwork->FastMutex); 1662 1430 1663 PINTNETIF pCur = pNetwork->pIFs; 1431 1664 while (pCur) … … 1437 1670 } 1438 1671 1672 /* Grab and zap the trunk pointer before leaving the mutex. */ 1673 PINTNETTRUNKIF pTrunkIF = pNetwork->pTrunkIF; 1674 pNetwork->pTrunkIF = NULL; 1675 1439 1676 RTSemFastMutexRelease(pNetwork->FastMutex); 1677 1678 /* 1679 * If there is a trunk, delete it. 1680 * Note that this may tak a while if we're unlucky... 1681 */ 1682 if (pTrunkIF) 1683 intnetTrunkIfDestroy(pTrunkIF, pNetwork); 1440 1684 1441 1685 /* … … 1446 1690 RTMemFree(pNetwork); 1447 1691 1692 /* release the create/destroy sem. (can be done before trunk destruction.) */ 1448 1693 RTSemFastMutexRelease(pIntNet->FastMutex); 1449 1694 }
Note:
See TracChangeset
for help on using the changeset viewer.