- Timestamp:
- Oct 2, 2020 5:58:42 AM (4 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 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 /* -
trunk/src/VBox/Devices/VirtIO/VirtioCore.h
r85415 r86405 35 35 # define VIRTIO_HEX_DUMP(logLevel, pv, cb, base, title) do { } while (0) 36 36 #endif 37 38 #ifdef IN_RING3 39 # define VIRTIOLOG(format...) LogFunc((format)) 40 # define VIRTIOLOGREL(format...) LogRelFunc((format)) 41 #else 42 # define VIRTIOLOG(format...) SUPR0Printf(format) 43 # define VIRTIOLOGREL(format...) SUPR0Printf(format) 44 #endif 45 46 #define VIRTIOLOGLEVEL2(format...) virtioLogLevel(2, format) 47 #define VIRTIOLOGLEVEL3(format...) virtioLogLevel(3, format) 48 #define VIRTIOLOGLEVEL4(format...) virtioLogLevel(4, format) 49 #define VIRTIOLOGLEVEL5(format...) virtioLogLevel(5, format) 50 #define VIRTIOLOGLEVEL6(format...) virtioLogLevel(6, format) 51 #define VIRTIOLOGLEVEL7(format...) virtioLogLevel(7, format) 52 #define VIRTIOLOGLEVEL8(format...) virtioLogLevel(8, format) 53 #define VIRTIOLOGLEVEL9(format...) virtioLogLevel(9, format) 54 #define VIRTIOLOGLEVEL10(format...) virtioLogLevel(10, format) 55 #define VIRTIOLOGLEVEL11(format...) virtioLogLevel(11, format) 56 #define VIRTIOLOGLEVEL12(format...) virtioLogLevel(12, format) 57 58 DECLINLINE(void) virtioLogLevel(int logLevel, const char *format...) 59 { 60 va_list arglist; 61 va_start(arglist, format); 62 if (LogIsItEnabled(logLevel, LOG_GROUP)) 63 VIRTIOLOG(format); 64 va_end(arglist); 65 } 37 66 38 67 /** Pointer to the shared VirtIO state. */ … … 362 391 R3PTRTYPE(PVIRTIO_PCI_CAP_T) pDeviceCap; /**< Pointer to struct in PCI config area. */ 363 392 364 uint32_t cbDevSpecificCfg;/**< Size of client's dev-specific config data */365 R3PTRTYPE(uint8_t *) pbDevSpecificCfg;/**< Pointer to client's struct */366 R3PTRTYPE(uint8_t *) pbPrevDevSpecificCfg;/**< Previous read dev-specific cfg of client */367 bool fGenUpdatePending;/**< If set, update cfg gen after driver reads */368 char pcszMmioName[MAX_NAME];/**< MMIO mapping name */393 uint32_t cbDevSpecificCfg; /**< Size of client's dev-specific config data */ 394 R3PTRTYPE(uint8_t *) pbDevSpecificCfg; /**< Pointer to client's struct */ 395 R3PTRTYPE(uint8_t *) pbPrevDevSpecificCfg; /**< Previous read dev-specific cfg of client */ 396 bool fGenUpdatePending; /**< If set, update cfg gen after driver reads */ 397 char pcszMmioName[MAX_NAME]; /**< MMIO mapping name */ 369 398 } VIRTIOCORER3; 370 399
Note:
See TracChangeset
for help on using the changeset viewer.