VirtualBox

Changeset 90461 in vbox


Ignore:
Timestamp:
Aug 1, 2021 8:56:10 PM (3 years ago)
Author:
vboxsync
Message:

VMMDev: New port for lock contention testing. bugref:6695

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/VMMDevTesting.h

    r82968 r90461  
    9090/** The go-to-ring-3-NOP I/O port - 1,2,4 RW. */
    9191#define VMMDEV_TESTING_IOPORT_NOP_R3    (VMMDEV_TESTING_IOPORT_BASE + 5)
     92/** Take the VMMDev lock in arrival context and return - 1,2,4 RW.
     93 * Writing configures counter action by a thread taking the lock to trigger
     94 * contention:
     95 *  - Bits 19-0 is the lock hold time in microseconds. Zero disables it.
     96 *  - Bit 31 make the thread poke the EMT(s) prior to releasing the lock.
     97 *  - Bits 30-20 are reserved and must be zero. */
     98#define VMMDEV_TESTING_IOPORT_LOCKED    (VMMDEV_TESTING_IOPORT_BASE + 6)
    9299
    93100/** @name Commands.
     
    153160/** @}  */
    154161
     162/** What the NOP accesses returns. */
     163#define VMMDEV_TESTING_NOP_RET                  UINT32_C(0x64726962) /* bird */
    155164
    156 /** What the NOP accesses returns. */
    157 #define VMMDEV_TESTING_NOP_RET          UINT32_C(0x64726962) /* bird */
     165/** @name Locked Control dword
     166 * @{ */
     167/** Locked Control: Lock hold interval in microseconds. */
     168#define VMMDEV_TESTING_LOCKED_HOLD_MASK         UINT32_C(0x00003fff)
     169/** Locked Control: Wait time in microseconds between locking attempts. */
     170#define VMMDEV_TESTING_LOCKED_WAIT_MASK         UINT32_C(0x0fffc000)
     171/** Locked Control: Wait time shift count. */
     172#define VMMDEV_TESTING_LOCKED_WAIT_SHIFT        14
     173/** Locked Control: Must be zero. */
     174#define VMMDEV_TESTING_LOCKED_MBZ_MASK          UINT32_C(0x70000000)
     175/** Locked Control: Poke EMT(s) flag.   */
     176#define VMMDEV_TESTING_LOCKED_POKE              UINT32_C(0x80000000)
     177/** @} */
    158178
    159179/** @} */
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r90447 r90461  
    44824482    pThis->hIoPortTesting       = NIL_IOMIOPORTHANDLE;
    44834483    pThis->hMmioTesting         = NIL_IOMMMIOHANDLE;
     4484    pThis->hTestingLockEvt      = NIL_SUPSEMEVENT;
    44844485#endif
    44854486
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r90266 r90461  
    2727#include <VBox/vmm/pdmifs.h>
    2828#ifndef VBOX_WITHOUT_TESTING_FEATURES
     29# include <VBox/vmm/pdmthread.h>
    2930# include <iprt/test.h>
    3031# include <VBox/VMMDevTesting.h>
     
    260261    uint32_t            StatMemBalloonChunks;
    261262
     263    /** @name Testing
     264     * @{ */
    262265    /** Set if testing is enabled. */
    263266    bool                fTestingEnabled;
     
    266269    /** Alignment padding. */
    267270    bool                afPadding9[HC_ARCH_BITS == 32 ? 2 : 6];
    268 #ifndef VBOX_WITHOUT_TESTING_FEATURES
     271#if !defined(VBOX_WITHOUT_TESTING_FEATURES) || defined(DOXYGEN_RUNNING)
    269272    /** The high timestamp value. */
    270273    uint32_t            u32TestingHighTimestamp;
     
    303306        uint8_t         abReadBack[VMMDEV_TESTING_READBACK_SIZE];
    304307    } TestingData;
    305 
     308    /** The locking testing control dword. */
     309    union
     310    {
     311        /** Plain view. */
     312        uint32_t        u32;
     313        struct
     314        {
     315            /** Number of microseconds to hold the lock. Zero means disabled. */
     316            uint32_t    cUsHold : 14;
     317            /** Number of microseconds to wait before retaking the lock again. */
     318            uint32_t    cUsBetween : 14;
     319            /** Reserved MBZ. */
     320            uint32_t    uReserved : 3;
     321            /** Whether to poke EMTs before releasing it. */
     322            uint32_t    fPokeBeforeRelease : 1;
     323        } s;
     324    } TestingLockControl;
     325    /** Alignment padding.  */
     326    uint32_t            uPadding10;
     327    /** Event semaphore that the locking thread blocks. */
     328    SUPSEMEVENT         hTestingLockEvt;
    306329    /** Handle for the I/O ports used by the testing component. */
    307330    IOMIOPORTHANDLE     hIoPortTesting;
    308331    /** Handle for the MMIO region used by the testing component. */
    309332    IOMMMIOHANDLE       hMmioTesting;
    310 #endif /* !VBOX_WITHOUT_TESTING_FEATURES */
     333#endif /* !VBOX_WITHOUT_TESTING_FEATURES || DOXYGEN_RUNNING */
     334    /** @} */
    311335
    312336    /** @name Heartbeat
     
    453477    /** Testing instance for dealing with the output. */
    454478    RTTEST                          hTestingTest;
     479    /** The locking test thread (). */
     480    PPDMTHREAD                      pTestingLockThread;
    455481#endif
    456482} VMMDEVR3;
  • trunk/src/VBox/Devices/VMMDev/VMMDevTesting.cpp

    r82968 r90461  
    3333#include <iprt/time.h>
    3434#include <iprt/test.h>
     35
     36#ifdef IN_RING3
     37# define USING_VMM_COMMON_DEFS /* HACK ALERT! We ONLY want the EMT thread handles, so the common defs doesn't matter. */
     38# include <VBox/vmm/vmcc.h>
     39#endif
    3540
    3641#include "VMMDevState.h"
     
    577582                }
    578583
     584                /*
     585                 * Configure the locking contention test.
     586                 */
     587                case VMMDEV_TESTING_IOPORT_LOCKED - VMMDEV_TESTING_IOPORT_BASE:
     588                    switch (cb)
     589                    {
     590                        case 4:
     591                        case 2:
     592                        case 1:
     593                        {
     594                            int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VINF_SUCCESS);
     595                            AssertRCReturn(rc, rc);
     596
     597                            u32 &= ~VMMDEV_TESTING_LOCKED_MBZ_MASK;
     598                            if (pThis->TestingLockControl.u32 != u32)
     599                            {
     600                                pThis->TestingLockControl.u32 = u32;
     601                                PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hTestingLockEvt);
     602                            }
     603
     604                            PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect);
     605                            return VINF_SUCCESS;
     606                        }
     607
     608                        default:
     609                            AssertFailed();
     610                            return VERR_INTERNAL_ERROR_2;
     611                    }
     612
    579613                default:
    580614                    break;
     
    676710}
    677711
    678 
    679712#ifdef IN_RING3
     713
     714/**
     715 * @callback_method_impl{FNPDMTHREADDEV}
     716 */
     717static DECLCALLBACK(int)  vmmdevR3TestingLockingThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
     718{
     719    PVMMDEV pThis = PDMDEVINS_2_DATA(pDevIns, PVMMDEV);
     720    PVM     pVM   = PDMDevHlpGetVM(pDevIns);
     721    AssertPtr(pVM);
     722
     723    while (RT_LIKELY(pThread->enmState == PDMTHREADSTATE_RUNNING))
     724    {
     725        /*
     726         * Enter the critical section and
     727         */
     728        int rc = PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VINF_SUCCESS);
     729        AssertLogRelRCReturn(rc, rc);
     730
     731        uint32_t cNsNextWait;
     732        if (pThis->TestingLockControl.s.cUsHold)
     733        {
     734            PDMDevHlpSUPSemEventWaitNsRelIntr(pDevIns, pThis->hTestingLockEvt, pThis->TestingLockControl.s.cUsHold);
     735            if (pThis->TestingLockControl.s.fPokeBeforeRelease)
     736                VMCC_FOR_EACH_VMCPU_STMT(pVM, RTThreadPoke(pVCpu->hThread));
     737            cNsNextWait = pThis->TestingLockControl.s.cUsBetween * RT_NS_1US;
     738        }
     739        else
     740            cNsNextWait = 0;
     741
     742        rc = PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect);
     743        AssertLogRelRCReturn(rc, rc);
     744
     745        /*
     746         * Wait for the next iteration.
     747         */
     748        if (RT_LIKELY(pThread->enmState == PDMTHREADSTATE_RUNNING))
     749        { /* likely */ }
     750        else
     751            break;
     752        if (cNsNextWait > 0)
     753            PDMDevHlpSUPSemEventWaitNsRelIntr(pDevIns, pThis->hTestingLockEvt, cNsNextWait);
     754        else
     755            PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pThis->hTestingLockEvt, RT_INDEFINITE_WAIT);
     756    }
     757
     758    return VINF_SUCCESS;
     759}
     760
     761
     762/**
     763 * @callback_method_impl{FNPDMTHREADWAKEUPDEV}
     764 */
     765static DECLCALLBACK(int) vmmdevR3TestingLockingThreadWakeup(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
     766{
     767    PVMMDEV pThis = PDMDEVINS_2_DATA(pDevIns, PVMMDEV);
     768    RT_NOREF(pThread);
     769    return PDMDevHlpSUPSemEventSignal(pDevIns, pThis->hTestingLockEvt);
     770}
     771
    680772
    681773/**
     
    739831
    740832    /*
     833     * Create the locking thread.
     834     */
     835    rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pThis->hTestingLockEvt);
     836    AssertRCReturn(rc, rc);
     837    rc = PDMDevHlpThreadCreate(pDevIns, &pThisCC->pTestingLockThread, NULL /*pvUser*/, vmmdevR3TestingLockingThread,
     838                               vmmdevR3TestingLockingThreadWakeup, 0 /*cbStack*/, RTTHREADTYPE_IO, "VMMLockT");
     839    AssertRCReturn(rc, rc);
     840
     841    /*
    741842     * Open the XML output file(/pipe/whatever) if specfied.
    742843     */
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