https://github.com/VirtualBox/virtualbox/commit/efa378dadd192af8fbce331e9ec66fb36d65ad3d https://bugs.gentoo.org/967656 From efa378dadd192af8fbce331e9ec66fb36d65ad3d Mon Sep 17 00:00:00 2001 From: Jack Doherty Date: Mon, 10 Nov 2025 21:28:06 +0000 Subject: [PATCH] Network/NAT: Fix high CPU usage when using NAT. github:gh-356 svn:sync-xref-src-repo-rev: r171190 --- a/src/VBox/Devices/Network/DrvNAT.cpp +++ b/src/VBox/Devices/Network/DrvNAT.cpp @@ -302,7 +302,6 @@ static DECLCALLBACK(void) drvNATRecvWorker(PDRVNAT pThis, void *pBuf, size_t cb) rc = RTCritSectLeave(&pThis->DevAccessLock); AssertRC(rc); ASMAtomicDecU32(&pThis->cPkts); - drvNATNotifyNATThread(pThis, "drvNATRecvWorker"); STAM_PROFILE_STOP(&pThis->StatNATRecv, a); } @@ -562,7 +561,7 @@ static DECLCALLBACK(void) drvNATNetworkUp_EndXmit(PPDMINETWORKUP pInterface) */ static void drvNATNotifyNATThread(PDRVNAT pThis, const char *pszWho) { - RT_NOREF(pszWho); + Log3(("Notifying NAT Thread. Culprit: %s\n", pszWho)); #ifdef RT_OS_WINDOWS int cbWritten = send(pThis->ahWakeupSockPair[0], "", 1, NULL); if (RT_LIKELY(cbWritten != SOCKET_ERROR)) @@ -713,6 +712,7 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr uint32_t cMsTimeout = DRVNAT_DEFAULT_TIMEOUT; slirp_pollfds_fill_socket(pThis->pSlirp, &cMsTimeout, drvNAT_AddPollCb /* SlirpAddPollCb */, pThis /* opaque */); cMsTimeout = drvNATTimersAdjustTimeoutDown(pThis, cMsTimeout); + Log4Func(("Timeout adjust to: %d\n", cMsTimeout)); #ifdef RT_OS_WINDOWS int cChangedFDs = WSAPoll(pThis->aPolls, pThis->cSockets, cMsTimeout); @@ -721,6 +721,7 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr #endif if (RT_LIKELY(!(cChangedFDs >= 0))) { + Log4Func(("Poll error\n")); #ifdef RT_OS_WINDOWS int const iLastErr = WSAGetLastError(); /* (In debug builds LogRel translates to two RTLogLoggerExWeak calls.) */ LogRel(("NAT: RTWinPoll returned error=%Rrc (cChangedFDs=%d)\n", iLastErr, cChangedFDs)); @@ -737,6 +738,7 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr Log4Func(("poll\n")); slirp_pollfds_poll(pThis->pSlirp, cChangedFDs < 0, drvNAT_GetREventsCb, pThis /* opaque */); + Log4Func(("management pipe revents = %d\n", pThis->aPolls[0].revents)); /* * Drain the control pipe if necessary. @@ -747,8 +749,9 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr * control pipe of all the notifications. If there is an error * on reading the pipe, we try again next time around. */ - if (pThis->aPolls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND)) /* POLLPRI won't be seen with WSAPoll. */ + if (pThis->aPolls[0].revents & (POLLIN|POLLRDNORM|POLLPRI|POLLRDBAND)) /* POLLPRI won't be seen with WSAPoll. */ { + Log4(("Draining control pipe.\n")); char achBuf[1024]; size_t cbRead = 0; uint64_t cbWakeupNotifs = ASMAtomicReadU64(&pThis->cbWakeupNotifs); @@ -791,6 +794,7 @@ static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThr */ static DECLCALLBACK(int) drvNATAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) { + LogFlowFuncEnter(); RT_NOREF(pThread); PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); @@ -1387,6 +1391,7 @@ static void drvNAT_TimerModCb(void *pvTimer, int64_t msNewDeadlineTs, void *pvUs */ static void drvNAT_NotifyCb(void *opaque) { + LogFlowFuncEnter(); PDRVNAT pThis = (PDRVNAT)opaque; drvNATNotifyNATThread(pThis, "drvNAT_NotifyCb"); }