Changeset 40675 in vbox
- Timestamp:
- Mar 28, 2012 12:06:52 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 77124
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv-dtrace.cpp
r40636 r40675 81 81 /** The number of probes we've provided to DTrace. */ 82 82 uint32_t cProvidedProbes; 83 /** Set when the module is unloaded or the driver deregisters its probes. */ 84 bool fZombie; 83 85 } SUPDRVDTPROVIDER; 84 86 /** Pointer to the data for a provider. */ … … 374 376 375 377 /** 378 * Frees the provider structure and associated resources. 379 * 380 * @param pProv The provider to free. 381 */ 382 static void supdrvVtgFreeProvider(PSUPDRVDTPROVIDER pProv) 383 { 384 pProv->fZombie = true; 385 pProv->pDesc = NULL; 386 pProv->pHdr = NULL; 387 RTMemFree(pProv); 388 } 389 390 391 /** 376 392 * Registers the VTG tracepoint providers of a driver. 377 393 * … … 444 460 pProv->idDtProv = 0; 445 461 pProv->cProvidedProbes = 0; 462 pProv->fZombie = false; 446 463 supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_provider, &pDesc->AttrSelf); 447 464 supdrvVtgConvAttr(&pProv->DtAttrs.dtpa_mod, &pDesc->AttrModules); … … 477 494 { 478 495 PSUPDRVDTPROVIDER pProvNext; 479 RTMemFree(pProv);496 supdrvVtgFreeProvider(pProv); 480 497 481 498 RTSemFastMutexRequest(pDevExt->mtxDTrace); … … 503 520 504 521 /** 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 */ 531 static 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 */ 553 static 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 /** 505 572 * Registers the VTG tracepoint providers of a driver. 506 573 * … … 512 579 SUPR0DECL(int) SUPR0VtgRegisterDrv(PSUPDRVSESSION pSession, PVTGOBJHDR pVtgHdr, const char *pszName) 513 580 { 581 int rc; 582 514 583 AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER); 515 584 AssertPtrReturn(pszName, VERR_INVALID_POINTER); 516 585 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; 519 596 } 520 597 … … 531 608 PSUPDRVDEVEXT pDevExt; 532 609 AssertReturnVoid(SUP_IS_SESSION_VALID(pSession)); 610 AssertReturnVoid(pSession->R0Process == NIL_RTR0PROCESS); 533 611 534 612 pDevExt = pSession->pDevExt; 613 614 /* 615 * Search for providers belonging to this driver session. 616 */ 535 617 RTSemFastMutexRequest(pDevExt->mtxDTrace); 536 618 RTListForEachSafe(&pDevExt->DtProviderList, pProv, pProvNext, SUPDRVDTPROVIDER, ListEntry) … … 539 621 { 540 622 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); 547 624 } 548 625 } 549 626 RTSemFastMutexRelease(pDevExt->mtxDTrace); 627 628 /* 629 * Try unregister zombies while we have a chance. 630 */ 631 supdrvVtgProcessZombies(pDevExt); 550 632 } 551 633 … … 566 648 PSUPDRVDEVEXT pDevExt; 567 649 uintptr_t cbVtgObj; 650 int rc; 568 651 569 652 /* … … 587 670 cbVtgObj = pImage->cbImageBits - cbVtgObj; 588 671 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; 590 680 } 591 681 … … 610 700 { 611 701 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); 618 703 } 619 704 } 620 705 RTSemFastMutexRelease(pDevExt->mtxDTrace); 706 707 /* 708 * Try unregister zombies while we have a chance. 709 */ 710 supdrvVtgProcessZombies(pDevExt); 621 711 } 622 712 … … 643 733 #endif 644 734 RTListInit(&pDevExt->DtProviderList); 735 RTListInit(&pDevExt->DtProviderZombieList); 645 736 rc = supdrvVtgRegister(pDevExt, &g_VTGObjHeader, _1M, NULL /*pImage*/, NULL /*pSession*/, "vboxdrv"); 646 737 if (RT_SUCCESS(rc)) … … 659 750 * @param pDevExt The device extension structure. 660 751 */ 661 intVBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt)752 void VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt) 662 753 { 663 754 PSUPDRVDTPROVIDER pProv, pProvNext; 755 uint32_t i; 664 756 665 757 /* … … 670 762 { 671 763 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); 672 789 RTSemFastMutexRelease(pDevExt->mtxDTrace); 673 674 dtrace_unregister(pProv->idDtProv);675 RTMemFree(pProv); 676 677 RT SemFastMutexRequest(pDevExt->mtxDTrace);678 } 679 RTSemFastMutexRelease(pDevExt->mtxDTrace); 790 if (fEmpty) 791 break; 792 793 /* Delay...*/ 794 RTThreadSleep(1000); 795 } 796 680 797 RTSemFastMutexDestroy(pDevExt->mtxDTrace); 681 798 pDevExt->mtxDTrace = NIL_RTSEMFASTMUTEX; 682 return VINF_SUCCESS;683 799 } 684 800 … … 690 806 { 691 807 PSUPDRVDTPROVIDER pProv = (PSUPDRVDTPROVIDER)pvProv; 692 uint16_t const idxProv = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc);808 uint16_t idxProv; 693 809 PVTGPROBELOC pProbeLoc; 694 810 PVTGPROBELOC pProbeLocEnd; … … 698 814 if (pDtProbeDesc) 699 815 return; /* We don't generate probes, so never mind these requests. */ 816 817 if (pProv->fZombie) 818 return; 700 819 701 820 if (pProv->cProvidedProbes >= pProv->pDesc->cProbes) … … 712 831 * this provider. 713 832 */ 833 idxProv = (uint16_t)(&pProv->pHdr->paProviders[0] - pProv->pDesc); 714 834 pProbeLoc = pProv->pHdr->paProbLocs; 715 835 pProbeLocEnd = pProv->pHdr->paProbLocsEnd; … … 796 916 { 797 917 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 809 931 return 0; 810 932 } … … 817 939 { 818 940 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 } 830 953 } 831 954 … … 838 961 { 839 962 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; 859 986 } 860 987 … … 878 1005 { 879 1006 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 } 885 1014 pProv->cProvidedProbes--; 886 1015 } -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r40636 r40675 542 542 /** List of DTrace providers (SUPDRVDTPROVIDER). */ 543 543 RTLISTANCHOR DtProviderList; 544 /** List of zombie DTrace providers (SUPDRVDTPROVIDER). */ 545 RTLISTANCHOR DtProviderZombieList; 544 546 #endif 545 547 … … 635 637 #ifdef VBOX_WITH_DTRACE_R0DRV 636 638 int VBOXCALL supdrvVtgInit(PSUPDRVDEVEXT pDevExt, PSUPFUNC pVtgFireProbe); 637 intVBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt);639 void VBOXCALL supdrvVtgTerm(PSUPDRVDEVEXT pDevExt); 638 640 void VBOXCALL supdrvVtgModuleUnloading(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage); 639 641 #endif
Note:
See TracChangeset
for help on using the changeset viewer.