Changeset 86405 in vbox for trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
- Timestamp:
- Oct 2, 2020 5:58:42 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r85608 r86405 304 304 typedef struct VIRTIONETVIRTQ 305 305 { 306 struct VIRTIONETWORKER *pWorker; /**< Pointer to R0 worker struct */307 struct VIRTIONETWORKERR3 *pWorkerR3; /**< Pointer to R3 worker struct */308 306 uint16_t uIdx; /**< Index of this queue */ 309 307 uint16_t align; … … 321 319 { 322 320 SUPSEMEVENT hEvtProcess; /**< handle of associated sleep/wake-up semaphore */ 323 PVIRTIONETVIRTQ pVirtq; /**< pointer to queue */324 321 uint16_t uIdx; /**< Index of this worker */ 325 322 bool volatile fSleeping; /**< Flags whether worker thread is sleeping or not */ … … 337 334 { 338 335 R3PTRTYPE(PPDMTHREAD) pThread; /**< pointer to worker thread's handle */ 339 PVIRTIONETVIRTQ pVirtq; /**< pointer to queue */340 336 uint16_t uIdx; /**< Index of this worker */ 341 337 uint16_t pad; … … 603 599 } 604 600 601 602 605 603 /** 606 604 * @callback_method_impl{VIRTIOCORER0,pfnVirtqNotified} … … 612 610 613 611 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr]; 614 PVIRTIONETWORKER pWorker = pVirtq->pWorker;612 PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr]; 615 613 616 614 #if defined (IN_RING3) && defined (LOG_ENABLED) 615 617 616 RTLogFlush(NULL); 617 618 618 #endif 619 619 … … 624 624 if (cBufsAvailable) 625 625 { 626 Log10Func(("%s %u empty bufs added to %s by guest (notifying leaf device)\n",627 pThis->szInst, cBufsAvailable, pVirtq->szName) );626 VIRTIOLOGLEVEL10("%s %u empty bufs added to %s by guest (notifying leaf device)\n", 627 pThis->szInst, cBufsAvailable, pVirtq->szName); 628 628 virtioNetWakeupRxBufWaiter(pDevIns); 629 629 } 630 630 else 631 LogRel(("%s \n\n***WARNING: %s notified but no empty bufs added by guest! (skip notifying of leaf device)\n\n",632 pThis->szInst, pVirtq->szName) );631 VIRTIOLOGLEVEL10("%s \n\n***WARNING: %s notified but no empty bufs added by guest! (skip notifying of leaf device)\n\n", 632 pThis->szInst, pVirtq->szName); 633 633 } 634 634 else if (IS_TX_VIRTQ(uVirtqNbr) || IS_CTRL_VIRTQ(uVirtqNbr)) … … 639 639 if (ASMAtomicReadBool(&pWorker->fSleeping)) 640 640 { 641 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName)); 641 VIRTIOLOGLEVEL10("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName); 642 642 643 int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess); 643 644 AssertRC(rc); … … 645 646 else 646 647 { 647 Log10Func(("%s %s has available buffers - worker already awake\n", pThis->szInst, pVirtq->szName));648 VIRTIOLOGLEVEL10("%s %s has available buffers - worker already awake\n", pThis->szInst, pVirtq->szName); 648 649 } 649 650 } 650 651 else 651 652 { 652 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName));653 VIRTIOLOGLEVEL10("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName); 653 654 } 654 655 } … … 838 839 if (pVirtq->fHasWorker) 839 840 { 840 PVIRTIONETWORKER pWorker = pVirtq->pWorker; 841 PVIRTIONETWORKERR3 pWorkerR3 = pVirtq->pWorkerR3; 841 PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr]; 842 PVIRTIONETWORKERR3 pWorkerR3 = &pThisCC->aWorkers[uVirtqNbr]; 843 844 Assert((pWorker->uIdx == pVirtq->uIdx)); 845 Assert((pWorkerR3->uIdx == pVirtq->uIdx)); 842 846 843 847 if (pWorker->fAssigned) … … 1134 1138 { 1135 1139 PVIRTIONETWORKER pWorker = &pThis->aWorkers[uIdxWorker]; 1136 PVIRTIONETVIRTQ pVirtq = pWorker->pVirtq;1140 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uIdxWorker]; 1137 1141 if (pVirtq->fAttachedToVirtioCore) 1138 1142 { … … 2589 2593 } 2590 2594 2591 static int virtioNetR3CreateOneWorkerThread(PPDMDEVINS pDevIns, PVIRTIONET pThis, uint16_t uIdxWorker,2595 static int virtioNetR3CreateOneWorkerThread(PPDMDEVINS pDevIns, PVIRTIONET pThis, 2592 2596 PVIRTIONETWORKER pWorker, PVIRTIONETWORKERR3 pWorkerR3, 2593 2597 PVIRTIONETVIRTQ pVirtq) … … 2597 2601 2598 2602 int rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pWorker->hEvtProcess); 2603 LogFunc(("PDMDevHlpSUPSemEventCreate(pDevIns, &pWorker->hEvtProcess=%p)", &pWorker->hEvtProcess)); 2604 LogFunc(("pWorker->hEvtProcess = %x\n", pWorker->hEvtProcess)); 2599 2605 2600 2606 if (RT_FAILURE(rc)) … … 2611 2617 N_("Error creating thread for Virtual Virtq %s\n"), pVirtq->uIdx); 2612 2618 2613 pWorker->pVirtq = pWorkerR3->pVirtq = pVirtq;2614 pWorker->uIdx = pWorkerR3->uIdx = uIdxWorker;2615 pVirtq->pWorker = pWorker;2616 pVirtq->pWorkerR3 = pWorkerR3;2617 2619 pWorker->fAssigned = true; /* Because worker's state held in fixed-size array w/empty slots */ 2618 2620 … … 2625 2627 { 2626 2628 2627 #define CTRLWIDX 0 /* First worker is for the control queue */2628 2629 2629 2630 Log10Func(("%s\n", pThis->szInst)); 2630 2631 2631 2632 PVIRTIONETVIRTQ pCtlVirtq = &pThis->aVirtqs[CTRLQIDX]; 2632 int rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, CTRLQIDX /* uIdxWorker */,2633 &pThis->aWorkers[CTRL WIDX], &pThisCC->aWorkers[CTRLWIDX], pCtlVirtq);2633 int rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, 2634 &pThis->aWorkers[CTRLQIDX], &pThisCC->aWorkers[CTRLQIDX], pCtlVirtq); 2634 2635 AssertRCReturn(rc, rc); 2635 2636 2636 2637 pCtlVirtq->fHasWorker = true; 2637 2638 2638 uint16_t uIdxWorker = CTRLWIDX + 1; 2639 for (uint16_t uVirtqPair = pThis->cInitializedVirtqPairs; uVirtqPair < pThis->cVirtqPairs; uVirtqPair++, uIdxWorker++) 2639 for (uint16_t uVirtqPair = pThis->cInitializedVirtqPairs; uVirtqPair < pThis->cVirtqPairs; uVirtqPair++) 2640 2640 { 2641 2641 PVIRTIONETVIRTQ pTxVirtq = &pThis->aVirtqs[TXQIDX(uVirtqPair)]; 2642 2642 PVIRTIONETVIRTQ pRxVirtq = &pThis->aVirtqs[RXQIDX(uVirtqPair)]; 2643 2643 2644 rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, uIdxWorker, &pThis->aWorkers[uIdxWorker],2645 &pThisCC->aWorkers[uIdxWorker], pTxVirtq);2644 rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, &pThis->aWorkers[TXQIDX(uVirtqPair)], 2645 &pThisCC->aWorkers[TXQIDX(uVirtqPair)], pTxVirtq); 2646 2646 AssertRCReturn(rc, rc); 2647 2647 … … 2665 2665 PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC); 2666 2666 PVIRTIONETWORKER pWorker = (PVIRTIONETWORKER)pThread->pvUser; 2667 PVIRTIONETVIRTQ pVirtq = pWorker->pVirtq; 2667 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[pWorker->uIdx]; 2668 uint16_t uIdx = pWorker->uIdx; 2669 2670 ASMAtomicWriteBool(&pWorker->fSleeping, false); 2671 2672 Assert(pWorker->uIdx == pVirtq->uIdx); 2668 2673 2669 2674 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 2670 2675 return VINF_SUCCESS; 2671 2676 2672 LogFunc(("%s worker thread started for %s\n", pThis->szInst, pVirtq->szName));2677 LogFunc(("%s worker thread idx=%d started for %s (virtq idx=%d)\n", pThis->szInst, pWorker->uIdx, pVirtq->szName, pVirtq->uIdx)); 2673 2678 2674 2679 /** @todo Race w/guest enabling/disabling guest notifications cyclically. 2675 2680 See BugRef #8651, Comment #82 */ 2676 virtioCoreVirtqEnableNotify(&pThis->Virtio, pVirtq->uIdx, true /* fEnable */);2681 virtioCoreVirtqEnableNotify(&pThis->Virtio, uIdx, true /* fEnable */); 2677 2682 2678 2683 while ( pThread->enmState != PDMTHREADSTATE_TERMINATING 2679 2684 && pThread->enmState != PDMTHREADSTATE_TERMINATED) 2680 2685 { 2681 if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pVirtq->uIdx))2686 if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pVirtq->uIdx)) 2682 2687 { 2683 2688 /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */ 2684 2689 ASMAtomicWriteBool(&pWorker->fSleeping, true); 2690 2685 2691 bool fNotificationSent = ASMAtomicXchgBool(&pWorker->fNotified, false); 2686 2692 if (!fNotificationSent) … … 2688 2694 Log10Func(("%s %s worker sleeping...\n\n", pThis->szInst, pVirtq->szName)); 2689 2695 Assert(ASMAtomicReadBool(&pWorker->fSleeping)); 2696 2690 2697 int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT); 2691 2698 STAM_COUNTER_INC(&pThis->StatTransmitByThread); … … 2698 2705 } 2699 2706 ASMAtomicWriteBool(&pWorker->fSleeping, false); 2707 2700 2708 } 2701 2709 … … 2760 2768 { 2761 2769 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr]; 2762 pVirtq->uIdx = uVirtqNbr; 2770 PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr]; 2771 2772 Assert(pWorker->uIdx == uVirtqNbr); 2773 Assert(pVirtq->uIdx == pWorker->uIdx); 2774 2763 2775 (void) virtioCoreR3VirtqAttach(&pThis->Virtio, pVirtq->uIdx, pVirtq->szName); 2764 2776 pVirtq->fAttachedToVirtioCore = true; … … 3032 3044 virtioNetR3SetVirtqNames(pThis); 3033 3045 pThis->aVirtqs[CTRLQIDX].fCtlVirtq = true; 3046 for (unsigned uVirtqNbr = 0; uVirtqNbr < pThis->cVirtVirtqs; uVirtqNbr++) 3047 { 3048 PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr]; 3049 PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr]; 3050 PVIRTIONETWORKERR3 pWorkerR3 = &pThisCC->aWorkers[uVirtqNbr]; 3051 pVirtq->uIdx = uVirtqNbr; 3052 pWorker->uIdx = uVirtqNbr; 3053 pWorkerR3->uIdx = uVirtqNbr; 3054 } 3034 3055 3035 3056 /* … … 3039 3060 if (RT_FAILURE(rc)) 3040 3061 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to create worker threads")); 3062 3041 3063 3042 3064 /*
Note:
See TracChangeset
for help on using the changeset viewer.