VirtualBox

Changeset 40675 in vbox


Ignore:
Timestamp:
Mar 28, 2012 12:06:52 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
77124
Message:

SUPDrv-dtrace.cpp: Check dtrace_unregister return code, introducing zombie provider list for dealing with failure.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp

    r40636 r40675  
    8181    /** The number of probes we've provided to DTrace. */
    8282    uint32_t            cProvidedProbes;
     83    /** Set when the module is unloaded or the driver deregisters its probes. */
     84    bool                fZombie;
    8385} SUPDRVDTPROVIDER;
    8486/** Pointer to the data for a provider. */
     
    374376
    375377/**
     378 * Frees the provider structure and associated resources.
     379 * 
     380 * @param   pProv               The provider to free.
     381 */
     382static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv)
     383{
     384    pProv->fZombie = true;
     385    pProv->pDesc   = NULL;
     386    pProv->pHdr    = NULL;
     387    RTMemFree(pProv);
     388}
     389
     390
     391/**
    376392 * Registers the VTG tracepoint providers of a driver.
    377393 *
     
    444460            pProv->idDtProv         = 0;
    445461            pProv->cProvidedProbes  = 0;
     462            pProv->fZombie          = false;
    446463            supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf);
    447464            supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod,      &pDesc->AttrModules);
     
    477494        {
    478495            PSUPDRVDTPROVIDER   pProvNext;
    479             RTMemFree(pProv);
     496            supdrvVtgFreeProvider(pProv);
    480497
    481498            RTSemFastMutexRequest(pDevExt->mtxDTrace);
     
    503520
    504521/**
     522 * Deregisters a provider.
     523 * 
     524 * If the provider is still busy, it will be put in the zombie list.
     525 * 
     526 * @param   pDevExt             The device extension.
     527 * @param   pProv               The provider.
     528 * 
     529 * @remarks The caller owns mtxDTrace.
     530 */
     531static void supdrvVtgDeregister(PSUPDRVDEVEXT pDevExt, PSUPDRVDTPROVIDER pProv)
     532{
     533    int rc;
     534
     535    dtrace_invalidate(pProv->idDtProv);
     536    rc = dtrace_unregister(pProv->idDtProv);
     537    if (!rc)
     538    {
     539        supdrvVtgFreeProvider(pProv);
     540        return;
     541    }
     542
     543    pProv->fZombie = true;
     544    RTListAppend(&pDevExt->DtProviderZombieList, &pProv->ListEntry);
     545}
     546
     547
     548/**
     549 * Processes the zombie list.
     550 * 
     551 * @param   pDevExt             The device extension.
     552 */
     553static void supdrvVtgProcessZombies(PSUPDRVDEVEXT pDevExt)
     554{
     555    PSUPDRVDTPROVIDER pProv, pProvNext;
     556
     557    RTSemFastMutexRequest(pDevExt->mtxDTrace);
     558    RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
     559    {
     560        int rc = dtrace_unregister(pProv->idDtProv);
     561        if (!rc)
     562        {
     563            RTListNodeRemove(&pProv->ListEntry);
     564            supdrvVtgFreeProvider(pProv);
     565        }
     566    }
     567    RTSemFastMutexRelease(pDevExt->mtxDTrace);
     568}
     569
     570
     571/**
    505572 * Registers the VTG tracepoint providers of a driver.
    506573 *
     
    512579SUPR0DECL(int) SUPR0VtgRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName)
    513580{
     581    int rc;
     582
    514583    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
    515584    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
    516585    AssertPtrReturn(pVtgHdr, VERR_INVALID_POINTER);
    517 
    518     return supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
     586    AssertReturn(pSession->R0Process == NIL_RTR0PROCESS, VERR_INVALID_PARAMETER);
     587
     588    rc = supdrvVtgRegister(pSession->pDevExt, pVtgHdr, _1M, NULL /*pImage*/, pSession, pszName);
     589
     590    /*
     591     * Try unregister zombies while we have a chance.
     592     */
     593    supdrvVtgProcessZombies(pSession->pDevExt);
     594
     595    return rc;
    519596}
    520597
     
    531608    PSUPDRVDEVEXT     pDevExt;
    532609    AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
     610    AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS);
    533611
    534612    pDevExt = pSession->pDevExt;
     613
     614    /*
     615     * Search for providers belonging to this driver session.
     616     */
    535617    RTSemFastMutexRequest(pDevExt->mtxDTrace);
    536618    RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
     
    539621        {
    540622            RTListNodeRemove(&pProv->ListEntry);
    541             RTSemFastMutexRelease(pDevExt->mtxDTrace);
    542 
    543             dtrace_unregister(pProv->idDtProv);
    544             RTMemFree(pProv);
    545 
    546             RTSemFastMutexRequest(pDevExt->mtxDTrace);
     623            supdrvVtgDeregister(pDevExt, pProv);
    547624        }
    548625    }
    549626    RTSemFastMutexRelease(pDevExt->mtxDTrace);
     627
     628    /*
     629     * Try unregister zombies while we have a chance.
     630     */
     631    supdrvVtgProcessZombies(pDevExt);
    550632}
    551633
     
    566648    PSUPDRVDEVEXT   pDevExt;
    567649    uintptr_t       cbVtgObj;
     650    int             rc;
    568651
    569652    /*
     
    587670    cbVtgObj = pImage->cbImageBits - cbVtgObj;
    588671
    589     return supdrvVtgRegister(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
     672    rc = supdrvVtgRegister(pDevExt, pVtgHdr, cbVtgObj, pImage, NULL, pImage->szName);
     673
     674    /*
     675     * Try unregister zombies while we have a chance.
     676     */
     677    supdrvVtgProcessZombies(pDevExt);
     678
     679    return rc;
    590680}
    591681
     
    610700        {
    611701            RTListNodeRemove(&pProv->ListEntry);
    612             RTSemFastMutexRelease(pDevExt->mtxDTrace);
    613 
    614             dtrace_unregister(pProv->idDtProv);
    615             RTMemFree(pProv);
    616 
    617             RTSemFastMutexRequest(pDevExt->mtxDTrace);
     702            supdrvVtgDeregister(pDevExt, pProv);
    618703        }
    619704    }
    620705    RTSemFastMutexRelease(pDevExt->mtxDTrace);
     706
     707    /*
     708     * Try unregister zombies while we have a chance.
     709     */
     710    supdrvVtgProcessZombies(pDevExt);
    621711}
    622712
     
    643733#endif
    644734        RTListInit(&pDevExt->DtProviderList);
     735        RTListInit(&pDevExt->DtProviderZombieList);
    645736        rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv");
    646737        if (RT_SUCCESS(rc))
     
    659750 * @param   pDevExt             The device extension structure.
    660751 */
    661 int VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)
     752void VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)
    662753{
    663754    PSUPDRVDTPROVIDER pProv, pProvNext;
     755    uint32_t i;
    664756
    665757    /*
     
    670762    {
    671763        RTListNodeRemove(&pProv->ListEntry);
     764        supdrvVtgDeregister(pDevExt, pProv);
     765    }
     766    RTSemFastMutexRelease(pDevExt->mtxDTrace);
     767
     768    /*
     769     * Try unregister zombies now, sleep on busy ones.
     770     */
     771    for (i = 0; ; i++)
     772    {
     773        bool fEmpty;
     774
     775        RTSemFastMutexRequest(pDevExt->mtxDTrace);
     776        RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry)
     777        {
     778            int rc = dtrace_unregister(pProv->idDtProv);
     779            if (!rc)
     780            {
     781                RTListNodeRemove(&pProv->ListEntry);
     782                supdrvVtgFreeProvider(pProv);
     783            }
     784            else if (!(i & 0xf))
     785                SUPR0Printf("supdrvVtgTerm: Waiting on busy provider %p\n", pProv->idDtProv);
     786        }
     787
     788        fEmpty = RTListIsEmpty(&pDevExt->DtProviderZombieList);
    672789        RTSemFastMutexRelease(pDevExt->mtxDTrace);
    673 
    674         dtrace_unregister(pProv->idDtProv);
    675         RTMemFree(pProv);
    676 
    677         RTSemFastMutexRequest(pDevExt->mtxDTrace);
    678     }
    679     RTSemFastMutexRelease(pDevExt->mtxDTrace);
     790        if (fEmpty)
     791            break;
     792
     793        /* Delay...*/
     794        RTThreadSleep(1000);
     795    }
     796
    680797    RTSemFastMutexDestroy(pDevExt->mtxDTrace);
    681798    pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX;
    682     return VINF_SUCCESS;
    683799}
    684800
     
    690806{
    691807    PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    692     uint16_t const      idxProv    = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
     808    uint16_t            idxProv;
    693809    PVTGPROBELOC        pProbeLoc;
    694810    PVTGPROBELOC        pProbeLocEnd;
     
    698814    if (pDtProbeDesc)
    699815        return;  /* We don't generate probes, so never mind these requests. */
     816
     817    if (pProv->fZombie)
     818        return;
    700819
    701820    if (pProv->cProvidedProbes >= pProv->pDesc->cProbes)
     
    712831      * this provider.
    713832      */
     833     idxProv      = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);
    714834     pProbeLoc    = pProv->pHdr->paProbLocs;
    715835     pProbeLocEnd = pProv->pHdr->paProbLocsEnd;
     
    796916{
    797917    PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    798     PVTGPROBELOC        pProbeLoc  = (PVTGPROBELOC)pvProbe;
    799     PVTGDESCPROBE       pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    800 
    801     if (!pProbeLoc->fEnabled)
    802     {
    803         pProbeLoc->fEnabled = 1;
    804         if (ASMAtomicIncU32(&pProbeDesc->u32User) == 1)
    805             pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
    806     }
    807 
    808     NOREF(pvProv);
     918    if (!pProv->fZombie)
     919    {
     920        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     921        PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
     922
     923        if (!pProbeLoc->fEnabled)
     924        {
     925            pProbeLoc->fEnabled = 1;
     926            if (ASMAtomicIncU32(&pProbeDesc->u32User) == 1)
     927                pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
     928        }
     929    }
     930
    809931    return 0;
    810932}
     
    817939{
    818940    PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    819     PVTGPROBELOC        pProbeLoc  = (PVTGPROBELOC)pvProbe;
    820     PVTGDESCPROBE       pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    821 
    822     if (pProbeLoc->fEnabled)
    823     {
    824         pProbeLoc->fEnabled = 0;
    825         if (ASMAtomicDecU32(&pProbeDesc->u32User) == 0)
    826             pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
    827     }
    828 
    829     NOREF(pvProv);
     941    if (!pProv->fZombie)
     942    {
     943        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     944        PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
     945
     946        if (pProbeLoc->fEnabled)
     947        {
     948            pProbeLoc->fEnabled = 0;
     949            if (ASMAtomicDecU32(&pProbeDesc->u32User) == 0)
     950                pProv->pHdr->pafProbeEnabled[pProbeDesc->idxEnabled] = 1;
     951        }
     952    }
    830953}
    831954
     
    838961{
    839962    PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    840     PVTGPROBELOC        pProbeLoc  = (PVTGPROBELOC)pvProbe;
    841     PVTGDESCPROBE       pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
    842     PVTGDESCARGLIST     pArgList   = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList);
    843 
    844     Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
    845     if (pArgList->cArgs > pArgDesc->dtargd_ndx)
    846     {
    847         const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[pArgDesc->dtargd_ndx].offType);
    848         size_t      cchType = strlen(pszType);
    849         if (cchType < sizeof(pArgDesc->dtargd_native))
    850         {
    851             memcpy(pArgDesc->dtargd_native, pszType, cchType + 1);
    852             /** @todo mapping */
    853         }
    854         else
    855             pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
    856     }
    857     else
    858         pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
     963    unsigned            uArg       = pArgDesc->dtargd_ndx;
     964
     965    if (!pProv->fZombie)
     966    {
     967        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     968        PVTGDESCPROBE   pProbeDesc = (PVTGDESCPROBE)pProbeLoc->pbProbe;
     969        PVTGDESCARGLIST pArgList   = (PVTGDESCARGLIST)((uintptr_t)pProv->pHdr->paArgLists + pProbeDesc->offArgList);
     970
     971        Assert(pProbeDesc->offArgList < pProv->pHdr->cbArgLists);
     972        if (pArgList->cArgs > uArg)
     973        {
     974            const char *pszType = supdrvVtgGetString(pProv->pHdr, pArgList->aArgs[uArg].offType);
     975            size_t      cchType = strlen(pszType);
     976            if (cchType < sizeof(pArgDesc->dtargd_native))
     977            {
     978                memcpy(pArgDesc->dtargd_native, pszType, cchType + 1);
     979                /** @todo mapping */
     980                return;
     981            }
     982        }
     983    }
     984
     985    pArgDesc->dtargd_ndx = DTRACE_ARGNONE;
    859986}
    860987
     
    8781005{
    8791006    PSUPDRVDTPROVIDER   pProv      = (PSUPDRVDTPROVIDER)pvProv;
    880     PVTGPROBELOC        pProbeLoc  = (PVTGPROBELOC)pvProbe;
    881 
    882     Assert(!pProbeLoc->fEnabled);
    883     Assert(pProbeLoc->idProbe == idProbe); NOREF(idProbe);
    884     pProbeLoc->idProbe = UINT32_MAX;
     1007    if (!pProv->fZombie)
     1008    {
     1009        PVTGPROBELOC    pProbeLoc  = (PVTGPROBELOC)pvProbe;
     1010        Assert(!pProbeLoc->fEnabled);
     1011        Assert(pProbeLoc->idProbe == idProbe); NOREF(idProbe);
     1012        pProbeLoc->idProbe = UINT32_MAX;
     1013    }
    8851014    pProv->cProvidedProbes--;
    8861015}
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r40636 r40675  
    542542    /** List of DTrace providers (SUPDRVDTPROVIDER). */
    543543    RTLISTANCHOR                    DtProviderList;
     544    /** List of zombie DTrace providers (SUPDRVDTPROVIDER). */
     545    RTLISTANCHOR                    DtProviderZombieList;
    544546#endif
    545547
     
    635637#ifdef VBOX_WITH_DTRACE_R0DRV
    636638int  VBOXCALL   supdrvVtgInit(PSUPDRVDEVEXT pDevExt, PSUPFUNC pVtgFireProbe);
    637 int VBOXCALL   supdrvVtgTerm(PSUPDRVDEVEXT pDevExt);
     639void VBOXCALL   supdrvVtgTerm(PSUPDRVDEVEXT pDevExt);
    638640void VBOXCALL   supdrvVtgModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
    639641#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette