VirtualBox

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


Ignore:
Timestamp:
Oct 31, 2022 8:15:38 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154336
Message:

NetworkServices/IntNetSwitch,Devices/Network/DrvIntNet,Devices/Network/SrvIntNetR0: Don't require a dedicated waiting thread to get notified when there is something to receive but make it possible to register a callback which is called and sends an IPC message instead, bugref:10297

Location:
trunk/src/VBox/Devices/Network
Files:
3 edited

Legend:

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

    r97089 r97338  
    249249        xpc_dictionary_set_data(hObj, "req", pvArg, cbArg);
    250250        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
    251         int rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
    252 
    253         size_t cbReply = 0;
    254         const void *pvData = xpc_dictionary_get_data(hObjReply, "reply", &cbReply);
    255         AssertRelease(cbReply == cbArg);
    256         memcpy(pvArg, pvData, cbArg);
     251        uint64_t u64Rc = xpc_dictionary_get_uint64(hObjReply, "rc");
     252        if (INTNET_R3_SVC_IS_VALID_RC(u64Rc))
     253        {
     254            size_t cbReply = 0;
     255            const void *pvData = xpc_dictionary_get_data(hObjReply, "reply", &cbReply);
     256            AssertRelease(cbReply == cbArg);
     257            memcpy(pvArg, pvData, cbArg);
     258            xpc_release(hObjReply);
     259
     260            return INTNET_R3_SVC_GET_RC(u64Rc);
     261        }
     262
    257263        xpc_release(hObjReply);
    258 
    259         return rc;
     264        return VERR_INVALID_STATE;
    260265    }
    261266    else
     
    316321        xpc_dictionary_set_data(hObj, "req", &GetBufferPtrsReq, sizeof(GetBufferPtrsReq));
    317322        xpc_object_t hObjReply = xpc_connection_send_message_with_reply_sync(pThis->hXpcCon, hObj);
    318         rc = (int)xpc_dictionary_get_int64(hObjReply, "rc");
     323        uint64_t u64Rc = xpc_dictionary_get_uint64(hObjReply, "rc");
     324        if (INTNET_R3_SVC_IS_VALID_RC(u64Rc))
     325            rc = INTNET_R3_SVC_GET_RC(u64Rc);
     326        else
     327            rc = VERR_INVALID_STATE;
     328
    319329        if (RT_SUCCESS(rc))
    320330        {
     
    327337                pThis->cbBuf = cbMem;
    328338        }
     339
    329340        xpc_release(hObjReply);
    330341    }
  • trunk/src/VBox/Devices/Network/SrvIntNetR0.cpp

    r96407 r97338  
    245245    /** Pointer to ring-3 mapping of the default exchange buffer. */
    246246    R3PTRTYPE(PINTNETBUF)   pIntBufDefaultR3;
     247#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    247248    /** Event semaphore which a receiver/consumer thread will sleep on while
    248249     * waiting for data to arrive. */
     
    250251    /** Number of threads sleeping on the event semaphore. */
    251252    uint32_t volatile       cSleepers;
     253#else
     254    /** The callback to call when there is something to receive/consume. */
     255    PFNINTNETIFRECVAVAIL    pfnRecvAvail;
     256    /** Opaque user data to pass to the receive avail callback (pfnRecvAvail). */
     257    void                   *pvUserRecvAvail;
     258#endif
    252259    /** The interface handle.
    253260     * When this is INTNET_HANDLE_INVALID a sleeper which is waking up
     
    28332840
    28342841
     2842/**
     2843 * Notifies consumers of incoming data from @a pIf that data is available.
     2844 */
     2845DECL_FORCE_INLINE(void) intnetR0IfNotifyRecv(PINTNETIF pIf)
     2846{
     2847#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
     2848    RTSemEventSignal(pIf->hRecvEvent);
     2849#else
     2850    pIf->pfnRecvAvail(pIf->hIf, pIf->pvUserRecvAvail);
     2851#endif
     2852}
     2853
     2854
    28352855/**
    28362856 * Sends a frame to a specific interface.
     
    28522872    {
    28532873        pIf->cYields = 0;
    2854         RTSemEventSignal(pIf->hRecvEvent);
     2874        intnetR0IfNotifyRecv(pIf);
    28552875        return;
    28562876    }
     
    28702890        while (--cYields > 0)
    28712891        {
    2872             RTSemEventSignal(pIf->hRecvEvent);
     2892            intnetR0IfNotifyRecv(pIf);
    28732893            RTThreadYield();
    28742894
     
    28792899            {
    28802900                STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatYieldsOk);
    2881                 RTSemEventSignal(pIf->hRecvEvent);
     2901                intnetR0IfNotifyRecv(pIf);
    28822902                return;
    28832903            }
     
    28892909    /* ok, the frame is lost. */
    28902910    STAM_REL_COUNTER_INC(&pIf->pIntBuf->cStatLost);
    2891     RTSemEventSignal(pIf->hRecvEvent);
     2911    intnetR0IfNotifyRecv(pIf);
    28922912}
    28932913
     
    46674687    }
    46684688
    4669     const RTSEMEVENT hRecvEvent   = pIf->hRecvEvent;
     4689#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     4690    AssertReleaseFailed(); /* Should never be called. */
     4691    return VERR_NOT_SUPPORTED;
     4692#else
     4693    const RTSEMEVENT hRecvEvent  = pIf->hRecvEvent;
    46704694    const bool       fNoMoreWaits = ASMAtomicUoReadBool(&pIf->fNoMoreWaits);
    46714695    RTNATIVETHREAD   hDtorThrd;
     
    47214745    Log4(("IntNetR0IfWait: returns %Rrc\n", rc));
    47224746    return rc;
     4747#endif
    47234748}
    47244749
     
    47654790    }
    47664791
     4792#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     4793    AssertReleaseFailed();
     4794    return VERR_NOT_SUPPORTED;
     4795#else
    47674796    const RTSEMEVENT hRecvEvent  = pIf->hRecvEvent;
    47684797    RTNATIVETHREAD   hDtorThrd;
     
    48074836    Log4(("IntNetR0IfWait: returns %Rrc\n", VINF_SUCCESS));
    48084837    return VINF_SUCCESS;
     4838#endif
    48094839}
    48104840
     
    48514881    ASMAtomicWriteU32(&pIf->hIf, INTNET_HANDLE_INVALID);
    48524882
     4883#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    48534884    /*
    48544885     * Signal the event semaphore to wake up any threads in IntNetR0IfWait
     
    48624893    }
    48634894    RTSemEventSignal(pIf->hRecvEvent);
     4895#endif
    48644896
    48654897    /*
     
    50005032    RTSemMutexRelease(pIntNet->hMtxCreateOpenDestroy);
    50015033
     5034#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    50025035    /*
    50035036     * Wakeup anyone waiting on this interface. (Kind of unlikely, but perhaps
     
    50315064        pIf->hRecvEvent = NIL_RTSEMEVENT;
    50325065    }
     5066#endif
    50335067
    50345068    /*
     
    50805114 *
    50815115 * @returns VBox status code.
    5082  * @param   pNetwork    The network, referenced.  The reference is consumed on
    5083  *                      success.
    5084  * @param   pSession    The session handle.
    5085  * @param   cbSend      The size of the send buffer.
    5086  * @param   cbRecv      The size of the receive buffer.
    5087  * @param   fFlags      The open network flags.
    5088  * @param   phIf        Where to store the interface handle.
    5089  */
    5090 static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession,
    5091                                    unsigned cbSend, unsigned cbRecv, uint32_t fFlags,
    5092                                    PINTNETIFHANDLE phIf)
     5116 * @param   pNetwork        The network, referenced.  The reference is consumed
     5117 *                          on success.
     5118 * @param   pSession        The session handle.
     5119 * @param   cbSend          The size of the send buffer.
     5120 * @param   cbRecv          The size of the receive buffer.
     5121 * @param   fFlags          The open network flags.
     5122 * @param   pfnRecvAvail    The receive available callback to call instead of
     5123 *                          signalling the semaphore (R3 service only).
     5124 * @param   pvUser          The opaque user data to pass to the callback.
     5125 * @param   phIf            Where to store the interface handle.
     5126 */
     5127static int intnetR0NetworkCreateIf(PINTNETNETWORK pNetwork, PSUPDRVSESSION pSession, unsigned cbSend, unsigned cbRecv,
     5128                                   uint32_t fFlags, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser, PINTNETIFHANDLE phIf)
    50935129{
    50945130    LogFlow(("intnetR0NetworkCreateIf: pNetwork=%p pSession=%p cbSend=%u cbRecv=%u fFlags=%#x phIf=%p\n",
     
    51005136    AssertPtr(pNetwork);
    51015137    AssertPtr(phIf);
     5138#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
     5139    Assert(pfnRecvAvail == NULL);
     5140    Assert(pvUser == NULL);
     5141    RT_NOREF(pfnRecvAvail, pvUser);
     5142#endif
    51025143
    51035144    /*
     
    51365177    //pIf->pIntBufDefault   = 0;
    51375178    //pIf->pIntBufDefaultR3 = NIL_RTR3PTR;
     5179#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    51385180    pIf->hRecvEvent         = NIL_RTSEMEVENT;
     5181#else
     5182    pIf->pfnRecvAvail       = pfnRecvAvail;
     5183    pIf->pvUserRecvAvail    = pvUser;
     5184#endif
    51395185    //pIf->cSleepers        = 0;
    51405186    pIf->hIf                = INTNET_HANDLE_INVALID;
     
    51545200    if (RT_SUCCESS(rc))
    51555201        rc = intnetR0AllocDstTab(pNetwork->MacTab.cEntriesAllocated, (PINTNETDSTTAB *)&pIf->pDstTab);
     5202#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    51565203    if (RT_SUCCESS(rc))
    51575204        rc = RTSemEventCreate((PRTSEMEVENT)&pIf->hRecvEvent);
     5205#endif
    51585206    if (RT_SUCCESS(rc))
    51595207        rc = RTSpinlockCreate(&pIf->hRecvInSpinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "hRecvInSpinlock");
     
    52485296    RTSpinlockDestroy(pIf->hRecvInSpinlock);
    52495297    pIf->hRecvInSpinlock = NIL_RTSPINLOCK;
     5298#if !defined(VBOX_WITH_INTNET_SERVICE_IN_R3) || !defined(IN_RING3)
    52505299    RTSemEventDestroy(pIf->hRecvEvent);
    52515300    pIf->hRecvEvent = NIL_RTSEMEVENT;
     5301#else
     5302    pIf->pfnRecvAvail    = NULL;
     5303    pIf->pvUserRecvAvail = NULL;
     5304#endif
    52525305    RTMemFree(pIf->pDstTab);
    52535306    for (int i = kIntNetAddrType_Invalid + 1; i < kIntNetAddrType_End; i++)
     
    65946647 * @param   pszTrunk        The trunk name. Its meaning is specific to the type.
    65956648 * @param   fFlags          Flags, see INTNET_OPEN_FLAGS_*.
    6596  * @param   fRestrictAccess Whether new participants should be subjected to access check or not.
     6649 * @param   fRestrictAccess Whether new participants should be subjected to
     6650 *                          access check or not.
    65976651 * @param   cbSend          The send buffer size.
    65986652 * @param   cbRecv          The receive buffer size.
     6653 * @param   pfnRecvAvail    The receive available callback to call instead of
     6654 *                          signalling the semaphore (R3 service only).
     6655 * @param   pvUser          The opaque user data to pass to the callback.
    65996656 * @param   phIf            Where to store the handle to the network interface.
    66006657 */
    66016658INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork,
    66026659                               INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
    6603                                uint32_t cbSend, uint32_t cbRecv, PINTNETIFHANDLE phIf)
     6660                               uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser,
     6661                               PINTNETIFHANDLE phIf)
    66046662{
    66056663    LogFlow(("IntNetR0Open: pSession=%p pszNetwork=%p:{%s} enmTrunkType=%d pszTrunk=%p:{%s} fFlags=%#x cbSend=%u cbRecv=%u phIf=%p\n",
     
    66756733    if (RT_SUCCESS(rc))
    66766734    {
    6677         rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
     6735        rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf);
    66786736        if (RT_SUCCESS(rc))
    66796737        {
     
    66896747        if (RT_SUCCESS(rc))
    66906748        {
    6691             rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, phIf);
     6749            rc = intnetR0NetworkCreateIf(pNetwork, pSession, cbSend, cbRecv, fFlags, pfnRecvAvail, pvUser, phIf);
    66926750            if (RT_FAILURE(rc))
    66936751                SUPR0ObjRelease(pNetwork->pvObj, pSession);
     
    67136771        return VERR_INVALID_PARAMETER;
    67146772    return IntNetR0Open(pSession, &pReq->szNetwork[0], pReq->enmTrunkType, pReq->szTrunk,
    6715                         pReq->fFlags, pReq->cbSend, pReq->cbRecv, &pReq->hIf);
    6716 }
     6773                        pReq->fFlags, pReq->cbSend, pReq->cbRecv, NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pReq->hIf);
     6774}
     6775
     6776
     6777#if defined(VBOX_WITH_INTNET_SERVICE_IN_R3) && defined(IN_RING3)
     6778INTNETR3DECL(int) IntNetR3Open(PSUPDRVSESSION pSession, const char *pszNetwork,
     6779                               INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
     6780                               uint32_t cbSend, uint32_t cbRecv, PFNINTNETIFRECVAVAIL pfnRecvAvail, void *pvUser,
     6781                               PINTNETIFHANDLE phIf)
     6782{
     6783    return IntNetR0Open(pSession, pszNetwork, enmTrunkType, pszTrunk, fFlags, cbSend, cbRecv, pfnRecvAvail, pvUser, phIf);
     6784}
     6785#endif
    67176786
    67186787
  • trunk/src/VBox/Devices/Network/testcase/tstIntNetR0.cpp

    r97300 r97338  
    447447{
    448448    pThis->hIf0 = INTNET_HANDLE_INVALID;
    449     RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "",
    450                                          0/*fFlags*/, cbSend, cbRecv, &pThis->hIf0), rcCheck);
     449    RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "", 0/*fFlags*/, cbSend, cbRecv,
     450                                         NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pThis->hIf0), rcCheck);
    451451    RTTESTI_CHECK_RET(pThis->hIf0 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR);
    452452    RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf0, g_pSession, &pThis->pBuf0, NULL), VINF_SUCCESS, rcCheck);
     
    455455
    456456    pThis->hIf1 = INTNET_HANDLE_INVALID;
    457     RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "",
    458                                          0/*fFlags*/, cbSend, cbRecv, &pThis->hIf1), rcCheck);
     457    RTTESTI_CHECK_RC_OK_RET(IntNetR0Open(g_pSession, pszNetwork, kIntNetTrunkType_None, "", 0/*fFlags*/, cbSend, cbRecv,
     458                                         NULL /*pfnRecvAvail*/, NULL /*pvUser*/, &pThis->hIf1), rcCheck);
    459459    RTTESTI_CHECK_RET(pThis->hIf1 != INTNET_HANDLE_INVALID, VERR_INTERNAL_ERROR);
    460460    RTTESTI_CHECK_RC_RET(IntNetR0IfGetBufferPtrs(pThis->hIf1, g_pSession, &pThis->pBuf1, NULL), VINF_SUCCESS, rcCheck);
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