Changeset 32710 in vbox for trunk/src/VBox/HostDrivers/VBoxNetFlt
- Timestamp:
- Sep 23, 2010 11:44:42 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/VBoxNetFlt/solaris/VBoxNetFlt-solaris.c
r31847 r32710 216 216 ddi_prop_op, /* property ops */ 217 217 &g_VBoxNetFltSolarisStreamTab, 218 D_NEW | D_MP | D_MTQPAIR ,/* compat. flag */218 D_NEW | D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL, /* compat. flag */ 219 219 CB_REV /* revision */ 220 220 }; … … 255 255 DEVICE_NAME, 256 256 &g_VBoxNetFltSolarisStreamTab, 257 D_NEW | D_MP | D_MTQPAIR 257 D_NEW | D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL 258 258 }; 259 259 … … 344 344 #endif 345 345 size_t cLoopback; /* loopback queue size list */ 346 timeout_id_t TimeoutId;/* timeout id of promisc. req */346 timeout_id_t volatile TimeoutId; /* timeout id of promisc. req */ 347 347 PVBOXNETFLTPACKETID pHead; /* loopback packet identifier head */ 348 348 PVBOXNETFLTPACKETID pTail; /* loopback packet identifier tail */ … … 897 897 if (pStream->Type == kPromiscStream) 898 898 { 899 /* 900 * If there are any timeout scheduled, we need to make sure they are cancelled. 901 */ 902 vboxnetflt_promisc_stream_t *pPromiscStream = (vboxnetflt_promisc_stream_t *)pStream; 903 timeout_id_t TimeoutId = ASMAtomicReadPtr(&pPromiscStream->TimeoutId); 904 if (TimeoutId) 905 { 906 quntimeout(WR(pPromiscStream->Stream.pReadQueue), TimeoutId); 907 ASMAtomicWritePtr(&pPromiscStream->TimeoutId, NULL); 908 } 909 899 910 flushq(pQueue, FLUSHALL); 900 911 flushq(WR(pQueue), FLUSHALL); … … 1299 1310 1300 1311 /** 1301 * Send fake promiscous mode requests downstream.1302 * 1303 * @param pQueue Pointer to the read queue.1304 * @param fPromisc Whether to enable promiscous mode or not.1305 * @param PromiscLevel Promiscous level; DL_PROMISC_PHYS/SAP/MULTI.1312 * Callback function for qwriter to send promiscuous request messages 1313 * downstream. 1314 * 1315 * @param pQueue Pointer to the write queue. 1316 * @param fPromisc Whether to send promiscuous ON or OFF requests. 1306 1317 * 1307 1318 * @returns VBox status code. … … 1346 1357 } 1347 1358 1348 qreply(pQueue, pPromiscPhysMsg);1349 qreply(pQueue, pPromiscSapMsg);1359 putnext(pQueue, pPromiscPhysMsg); 1360 putnext(pQueue, pPromiscSapMsg); 1350 1361 1351 1362 return VINF_SUCCESS; … … 1353 1364 1354 1365 1355 /* 1356 * Callback wrapper for qtimeout to safely send promiscuous off request. 1357 * 1358 * @param pvData Pointer to a vboxnetflt_promisc_params_t structure, will be freed by us. 1366 /** 1367 * Callback wrapper for qwriter() to safely send promiscuous requests. This is 1368 * called at the outer perimeter with exclusive lock held. 1369 * 1370 * @param pQueue Pointer to the write queue. 1371 * @param pMsg A one byte message indicates a Promisc ON, otherwise 1372 * a promiscuous OFF request. See 1373 * vboxNetFltSolarisPromiscReqWrap(). 1374 */ 1375 static void vboxNetFltSolarisPromiscReqWrapExcl(queue_t *pQueue, mblk_t *pMsg) 1376 { 1377 /* 1378 * Paranoia. 1379 */ 1380 AssertReturnVoid(pQueue); 1381 if (RT_UNLIKELY(!pMsg)) 1382 LogRel((DEVICE_NAME ":VBoxNetFltSolarisPromiscReqWrapExcl pQueue=%p missing message!\n", pQueue)); 1383 1384 bool fPromisc = (MBLKL(pMsg) == 1); 1385 freemsg(pMsg); 1386 pMsg = NULL; 1387 int rc = vboxNetFltSolarisPromiscReq(pQueue, fPromisc); 1388 if (RT_FAILURE(rc)) 1389 LogRel((DEVICE_NAME ":VBoxNetFltSolarisPromiscReqWrapExcl vboxNetFltSolarisPromiscReq failed. rc=%d\n", rc)); 1390 else 1391 LogRel((DEVICE_NAME ":VBoxNetFltSolarisPromiscReqWrapExcl success fPromisc=%d\n", fPromisc)); 1392 } 1393 1394 1395 /** 1396 * Callback wrapper for qtimeout() to safely send promiscuous requests. This is 1397 * called at the inner perimenter with shared lock. 1398 * 1399 * @param pvData Pointer to vboxnetflt_promisc_params_t. See 1400 * vboxNetFltPortOsSetActive(). 1359 1401 */ 1360 1402 static void vboxNetFltSolarisPromiscReqWrap(void *pvData) … … 1368 1410 && pPromiscStream->Stream.pReadQueue) 1369 1411 { 1370 pPromiscStream->TimeoutId = 0; 1371 vboxNetFltSolarisPromiscReq(pPromiscStream->Stream.pReadQueue, pParams->fPromiscOn); 1412 /* 1413 * Use size of message to indicate to qwriter callback whether it must send 1414 * promiscuous On or Off messages. This is ugly but easier and more efficient than 1415 * scheduling two separate qwriter callbacks with prepared messages to putnext. 1416 */ 1417 size_t cbMsg = pParams->fPromiscOn ? 1 : 2; 1418 mblk_t *pMsg = allocb(cbMsg, BPRI_HI); 1419 if (RT_UNLIKELY(!pMsg)) 1420 { 1421 LogRel((DEVICE_NAME ":Failed to alloc message of %u bytes\n", cbMsg)); 1422 return; 1423 } 1424 1425 /* 1426 * Move the data pointer so we can use MBLKL, as MBLKSIZE gets the db_lim which is 1427 * always aligned. 1428 */ 1429 pMsg->b_wptr += cbMsg; 1430 1431 /* 1432 * Upgrade inner perimeter lock to exclusive outer perimeter lock and 1433 * then call putnext while we are at the outer perimeter. 1434 */ 1435 qwriter(WR(pPromiscStream->Stream.pReadQueue), pMsg, vboxNetFltSolarisPromiscReqWrapExcl, PERIM_OUTER); 1436 ASMAtomicWritePtr(&pPromiscStream->TimeoutId, NULL); 1372 1437 } 1373 1438 RTMemFree(pParams); … … 2022 2087 if (pThis->u.s.hIface) 2023 2088 { 2024 /*2025 * If there are any timeout scheduled, we need to make sure they are cancelled.2026 */2027 vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtrT(&pThis->u.s.pPromiscStream, vboxnetflt_promisc_stream_t *);2028 if ( pPromiscStream2029 && pPromiscStream->TimeoutId)2030 {2031 quntimeout(WR(pPromiscStream->Stream.pReadQueue), pPromiscStream->TimeoutId);2032 }2033 2034 2089 ldi_close(pThis->u.s.hIface, FREAD | FWRITE, kcred); 2035 2090 pThis->u.s.hIface = NULL; … … 3623 3678 if (RT_LIKELY(pData)) 3624 3679 { 3680 /* 3681 * See #5262 as to why we need to do all this qtimeout/qwriter tricks. 3682 */ 3625 3683 vboxnetflt_promisc_stream_t *pPromiscStream = ASMAtomicUoReadPtrT(&pThis->u.s.pPromiscStream, vboxnetflt_promisc_stream_t *); 3626 3684 if ( pPromiscStream … … 3629 3687 pData->pThis = pThis; 3630 3688 pData->fPromiscOn = fActive; 3631 if ( pPromiscStream->TimeoutId != 0)3689 if (ASMAtomicReadPtr(&pPromiscStream->TimeoutId)) 3632 3690 quntimeout(WR(pPromiscStream->Stream.pReadQueue), pPromiscStream->TimeoutId); 3633 pPromiscStream->TimeoutId = qtimeout(WR(pPromiscStream->Stream.pReadQueue), vboxNetFltSolarisPromiscReqWrap, pData, 1 /* ticks */); 3634 return; 3635 } 3691 timeout_id_t TimeoutId = qtimeout(WR(pPromiscStream->Stream.pReadQueue), vboxNetFltSolarisPromiscReqWrap, pData, 1 /* ticks */); 3692 ASMAtomicWritePtr(&pPromiscStream->TimeoutId, TimeoutId); 3693 return; /* pData will be freed by vboxNetFltSolarisPromiscReqWrap() */ 3694 } 3695 else 3696 LogRel((DEVICE_NAME ":vboxNetFltPortOsSetActive pThis=%p fActive=%d missing stream!\n", pThis, fActive)); 3636 3697 RTMemFree(pData); 3637 3698 }
Note:
See TracChangeset
for help on using the changeset viewer.