Changeset 59132 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Dec 15, 2015 12:42:54 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r59126 r59132 1729 1729 if (!fIsCaller) 1730 1730 { 1731 rc = RTSemEventMultiWait(pVM->vmm.s.hEvtMulRendezvousDone, RT_INDEFINITE_WAIT); 1732 AssertLogRelRC(rc); 1733 Assert(!pVM->vmm.s.fRendezvousRecursion); 1731 for (;;) 1732 { 1733 rc = RTSemEventMultiWait(pVM->vmm.s.hEvtMulRendezvousDone, RT_INDEFINITE_WAIT); 1734 AssertLogRelRC(rc); 1735 if (!pVM->vmm.s.fRendezvousRecursion) 1736 break; 1737 rcStrictRecursion = vmmR3EmtRendezvousCommonRecursion(pVM, pVCpu, rcStrictRecursion); 1738 } 1734 1739 1735 1740 return vmmR3EmtRendezvousNonCallerReturn(pVM, rcStrictRecursion); … … 1764 1769 rc = RTSemEventSignal(pVM->vmm.s.pahEvtRendezvousEnterOrdered[iFirst]); 1765 1770 AssertLogRelRC(rc); 1766 rc = RTSemEventWait(pVM->vmm.s.pahEvtRendezvousEnterOrdered[pVCpu->idCpu], RT_INDEFINITE_WAIT); 1767 AssertLogRelRC(rc); 1771 for (;;) 1772 { 1773 rc = RTSemEventWait(pVM->vmm.s.pahEvtRendezvousEnterOrdered[pVCpu->idCpu], RT_INDEFINITE_WAIT); 1774 AssertLogRelRC(rc); 1775 if (!pVM->vmm.s.fRendezvousRecursion) 1776 break; 1777 rcStrictRecursion = vmmR3EmtRendezvousCommonRecursion(pVM, pVCpu, rcStrictRecursion); 1778 } 1768 1779 } 1769 1780 } … … 1924 1935 AssertReturn( (fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING 1925 1936 || (fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING 1926 || (fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, 1937 || (fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE 1938 || (fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, 1927 1939 VERR_INTERNAL_ERROR); 1928 1940 AssertReturn(pVM->vmm.s.cRendezvousEmtsEntered == pVM->cCpus, VERR_INTERNAL_ERROR_2); … … 1945 1957 */ 1946 1958 ASMAtomicWriteU32(&pVM->vmm.s.cRendezvousEmtsRecursingPush, 0); 1947 ASMAtomicWriteU32(&pVM->vmm.s.cRendezvousEmtsRecursingPop, 0);1948 1959 ASMAtomicWriteBool(&pVM->vmm.s.fRendezvousRecursion, true); 1949 1960 1950 1961 uint32_t cLeft = pVM->cCpus - (cParentDone + 1U); 1951 if ((f Flags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE)1962 if ((fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE) 1952 1963 while (cLeft-- > 0) 1953 1964 { … … 1955 1966 AssertLogRelRC(rc); 1956 1967 } 1957 else if ((f Flags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING)1968 else if ((fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING) 1958 1969 { 1959 1970 Assert(cLeft == pVM->cCpus - (pVCpu->idCpu + 1U)); … … 1964 1975 } 1965 1976 } 1966 else if ((f Flags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING)1977 else if ((fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING) 1967 1978 { 1968 1979 Assert(cLeft == pVCpu->idCpu); 1969 for (VMCPUID iCpu = pVCpu->idCpu; iCpu > pVM->cCpus; iCpu--)1980 for (VMCPUID iCpu = pVCpu->idCpu; iCpu > 0; iCpu--) 1970 1981 { 1971 1982 rc = RTSemEventSignal(pVM->vmm.s.pahEvtRendezvousEnterOrdered[iCpu - 1U]); … … 1974 1985 } 1975 1986 else 1976 AssertLogRelFailedReturn(VERR_INTERNAL_ERROR_4); 1987 AssertLogRelReturn((fParentFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, 1988 VERR_INTERNAL_ERROR_4); 1977 1989 1978 1990 rc = RTSemEventMultiSignal(pVM->vmm.s.hEvtMulRendezvousDone); … … 2069 2081 * Usher the other EMTs back to their parent recursion routine, waiting 2070 2082 * for them to all get there before we return (makes sure they've been 2071 * scheduled and are in position again - paranoia, shouldn't be needed). 2072 */ 2073 rc = RTSemEventMultiSignal(pVM->vmm.s.hEvtMulRendezvousRecursionPush); 2083 * scheduled and are past the pop event sem, see below). 2084 */ 2085 ASMAtomicWriteU32(&pVM->vmm.s.cRendezvousEmtsRecursingPop, 0); 2086 rc = RTSemEventMultiSignal(pVM->vmm.s.hEvtMulRendezvousRecursionPop); 2074 2087 AssertLogRelRC(rc); 2075 2088 … … 2079 2092 AssertLogRelRC(rc); 2080 2093 } 2094 2095 /* 2096 * We must reset the pop semaphore on the way out (doing the pop caller too, 2097 * just in case). The parent may be another recursion. 2098 */ 2099 rc = RTSemEventMultiReset(pVM->vmm.s.hEvtMulRendezvousRecursionPop); AssertLogRelRC(rc); 2100 rc = vmmR3HlpResetEvent(pVM->vmm.s.hEvtRendezvousRecursionPopCaller); AssertLogRelMsg(rc == VERR_TIMEOUT, ("%Rrc\n", rc)); 2081 2101 2082 2102 ASMAtomicDecU32(&pVM->vmm.s.cRendezvousRecursions); … … 2135 2155 * Shortcut for the single EMT case. 2136 2156 */ 2137 AssertLogRelReturn(!pVCpu->vmm.s.fInRendezvous, VERR_DEADLOCK); 2138 pVCpu->vmm.s.fInRendezvous = true; 2139 rcStrict = pfnRendezvous(pVM, pVCpu, pvUser); 2140 pVCpu->vmm.s.fInRendezvous = false; 2157 if (!pVCpu->vmm.s.fInRendezvous) 2158 { 2159 pVCpu->vmm.s.fInRendezvous = true; 2160 pVM->vmm.s.fRendezvousFlags = fFlags; 2161 rcStrict = pfnRendezvous(pVM, pVCpu, pvUser); 2162 pVCpu->vmm.s.fInRendezvous = false; 2163 } 2164 else 2165 { 2166 /* Recursion. Do the same checks as in the SMP case. */ 2167 uint32_t fType = pVM->vmm.s.fRendezvousFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK; 2168 AssertLogRelReturn( !pVCpu->vmm.s.fInRendezvous 2169 || fType == VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING 2170 || fType == VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING 2171 || fType == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE 2172 || fType == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE 2173 , VERR_DEADLOCK); 2174 2175 AssertLogRelReturn(pVM->vmm.s.cRendezvousRecursions < 3, VERR_DEADLOCK); 2176 pVM->vmm.s.cRendezvousRecursions++; 2177 uint32_t const fParentFlags = pVM->vmm.s.fRendezvousFlags; 2178 pVM->vmm.s.fRendezvousFlags = fFlags; 2179 2180 rcStrict = pfnRendezvous(pVM, pVCpu, pvUser); 2181 2182 pVM->vmm.s.fRendezvousFlags = fParentFlags; 2183 pVM->vmm.s.cRendezvousRecursions--; 2184 } 2141 2185 } 2142 2186 else … … 2155 2199 || (pVM->vmm.s.fRendezvousFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING 2156 2200 || (pVM->vmm.s.fRendezvousFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE 2201 || (pVM->vmm.s.fRendezvousFlags & VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK) == VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE 2157 2202 )) 2158 2203 return VBOXSTRICTRC_TODO(vmmR3EmtRendezvousRecursive(pVM, pVCpu, fFlags, pfnRendezvous, pvUser));
Note:
See TracChangeset
for help on using the changeset viewer.