diff options
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 128 |
1 files changed, 3 insertions, 125 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index c4f8971c954d..3686471be32b 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -2103,66 +2103,6 @@ static void init_master_vcore(struct kvmppc_vcore *vc) | |||
2103 | vc->conferring_threads = 0; | 2103 | vc->conferring_threads = 0; |
2104 | } | 2104 | } |
2105 | 2105 | ||
2106 | /* | ||
2107 | * See if the existing subcores can be split into 3 (or fewer) subcores | ||
2108 | * of at most two threads each, so we can fit in another vcore. This | ||
2109 | * assumes there are at most two subcores and at most 6 threads in total. | ||
2110 | */ | ||
2111 | static bool can_split_piggybacked_subcores(struct core_info *cip) | ||
2112 | { | ||
2113 | int sub, new_sub; | ||
2114 | int large_sub = -1; | ||
2115 | int thr; | ||
2116 | int n_subcores = cip->n_subcores; | ||
2117 | struct kvmppc_vcore *vc, *vcnext; | ||
2118 | struct kvmppc_vcore *master_vc = NULL; | ||
2119 | |||
2120 | for (sub = 0; sub < cip->n_subcores; ++sub) { | ||
2121 | if (cip->subcore_threads[sub] <= 2) | ||
2122 | continue; | ||
2123 | if (large_sub >= 0) | ||
2124 | return false; | ||
2125 | large_sub = sub; | ||
2126 | vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore, | ||
2127 | preempt_list); | ||
2128 | if (vc->num_threads > 2) | ||
2129 | return false; | ||
2130 | n_subcores += (cip->subcore_threads[sub] - 1) >> 1; | ||
2131 | } | ||
2132 | if (large_sub < 0 || !subcore_config_ok(n_subcores + 1, 2)) | ||
2133 | return false; | ||
2134 | |||
2135 | /* | ||
2136 | * Seems feasible, so go through and move vcores to new subcores. | ||
2137 | * Note that when we have two or more vcores in one subcore, | ||
2138 | * all those vcores must have only one thread each. | ||
2139 | */ | ||
2140 | new_sub = cip->n_subcores; | ||
2141 | thr = 0; | ||
2142 | sub = large_sub; | ||
2143 | list_for_each_entry_safe(vc, vcnext, &cip->vcs[sub], preempt_list) { | ||
2144 | if (thr >= 2) { | ||
2145 | list_del(&vc->preempt_list); | ||
2146 | list_add_tail(&vc->preempt_list, &cip->vcs[new_sub]); | ||
2147 | /* vc->num_threads must be 1 */ | ||
2148 | if (++cip->subcore_threads[new_sub] == 1) { | ||
2149 | cip->subcore_vm[new_sub] = vc->kvm; | ||
2150 | init_master_vcore(vc); | ||
2151 | master_vc = vc; | ||
2152 | ++cip->n_subcores; | ||
2153 | } else { | ||
2154 | vc->master_vcore = master_vc; | ||
2155 | ++new_sub; | ||
2156 | } | ||
2157 | } | ||
2158 | thr += vc->num_threads; | ||
2159 | } | ||
2160 | cip->subcore_threads[large_sub] = 2; | ||
2161 | cip->max_subcore_threads = 2; | ||
2162 | |||
2163 | return true; | ||
2164 | } | ||
2165 | |||
2166 | static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip) | 2106 | static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip) |
2167 | { | 2107 | { |
2168 | int n_threads = vc->num_threads; | 2108 | int n_threads = vc->num_threads; |
@@ -2173,23 +2113,9 @@ static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip) | |||
2173 | 2113 | ||
2174 | if (n_threads < cip->max_subcore_threads) | 2114 | if (n_threads < cip->max_subcore_threads) |
2175 | n_threads = cip->max_subcore_threads; | 2115 | n_threads = cip->max_subcore_threads; |
2176 | if (subcore_config_ok(cip->n_subcores + 1, n_threads)) { | 2116 | if (!subcore_config_ok(cip->n_subcores + 1, n_threads)) |
2177 | cip->max_subcore_threads = n_threads; | ||
2178 | } else if (cip->n_subcores <= 2 && cip->total_threads <= 6 && | ||
2179 | vc->num_threads <= 2) { | ||
2180 | /* | ||
2181 | * We may be able to fit another subcore in by | ||
2182 | * splitting an existing subcore with 3 or 4 | ||
2183 | * threads into two 2-thread subcores, or one | ||
2184 | * with 5 or 6 threads into three subcores. | ||
2185 | * We can only do this if those subcores have | ||
2186 | * piggybacked virtual cores. | ||
2187 | */ | ||
2188 | if (!can_split_piggybacked_subcores(cip)) | ||
2189 | return false; | ||
2190 | } else { | ||
2191 | return false; | 2117 | return false; |
2192 | } | 2118 | cip->max_subcore_threads = n_threads; |
2193 | 2119 | ||
2194 | sub = cip->n_subcores; | 2120 | sub = cip->n_subcores; |
2195 | ++cip->n_subcores; | 2121 | ++cip->n_subcores; |
@@ -2203,45 +2129,6 @@ static bool can_dynamic_split(struct kvmppc_vcore *vc, struct core_info *cip) | |||
2203 | return true; | 2129 | return true; |
2204 | } | 2130 | } |
2205 | 2131 | ||
2206 | static bool can_piggyback_subcore(struct kvmppc_vcore *pvc, | ||
2207 | struct core_info *cip, int sub) | ||
2208 | { | ||
2209 | struct kvmppc_vcore *vc; | ||
2210 | int n_thr; | ||
2211 | |||
2212 | vc = list_first_entry(&cip->vcs[sub], struct kvmppc_vcore, | ||
2213 | preempt_list); | ||
2214 | |||
2215 | /* require same VM and same per-core reg values */ | ||
2216 | if (pvc->kvm != vc->kvm || | ||
2217 | pvc->tb_offset != vc->tb_offset || | ||
2218 | pvc->pcr != vc->pcr || | ||
2219 | pvc->lpcr != vc->lpcr) | ||
2220 | return false; | ||
2221 | |||
2222 | /* | ||
2223 | * P8 guests can't do piggybacking, because then the | ||
2224 | * VTB would be shared between the vcpus. | ||
2225 | */ | ||
2226 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
2227 | return false; | ||
2228 | |||
2229 | n_thr = cip->subcore_threads[sub] + pvc->num_threads; | ||
2230 | if (n_thr > cip->max_subcore_threads) { | ||
2231 | if (!subcore_config_ok(cip->n_subcores, n_thr)) | ||
2232 | return false; | ||
2233 | cip->max_subcore_threads = n_thr; | ||
2234 | } | ||
2235 | |||
2236 | cip->total_threads += pvc->num_threads; | ||
2237 | cip->subcore_threads[sub] = n_thr; | ||
2238 | pvc->master_vcore = vc; | ||
2239 | list_del(&pvc->preempt_list); | ||
2240 | list_add_tail(&pvc->preempt_list, &cip->vcs[sub]); | ||
2241 | |||
2242 | return true; | ||
2243 | } | ||
2244 | |||
2245 | /* | 2132 | /* |
2246 | * Work out whether it is possible to piggyback the execution of | 2133 | * Work out whether it is possible to piggyback the execution of |
2247 | * vcore *pvc onto the execution of the other vcores described in *cip. | 2134 | * vcore *pvc onto the execution of the other vcores described in *cip. |
@@ -2249,19 +2136,10 @@ static bool can_piggyback_subcore(struct kvmppc_vcore *pvc, | |||
2249 | static bool can_piggyback(struct kvmppc_vcore *pvc, struct core_info *cip, | 2136 | static bool can_piggyback(struct kvmppc_vcore *pvc, struct core_info *cip, |
2250 | int target_threads) | 2137 | int target_threads) |
2251 | { | 2138 | { |
2252 | int sub; | ||
2253 | |||
2254 | if (cip->total_threads + pvc->num_threads > target_threads) | 2139 | if (cip->total_threads + pvc->num_threads > target_threads) |
2255 | return false; | 2140 | return false; |
2256 | for (sub = 0; sub < cip->n_subcores; ++sub) | ||
2257 | if (cip->subcore_threads[sub] && | ||
2258 | can_piggyback_subcore(pvc, cip, sub)) | ||
2259 | return true; | ||
2260 | 2141 | ||
2261 | if (can_dynamic_split(pvc, cip)) | 2142 | return can_dynamic_split(pvc, cip); |
2262 | return true; | ||
2263 | |||
2264 | return false; | ||
2265 | } | 2143 | } |
2266 | 2144 | ||
2267 | static void prepare_threads(struct kvmppc_vcore *vc) | 2145 | static void prepare_threads(struct kvmppc_vcore *vc) |