Skip to content

Commit 2e07bd7

Browse files
authored
More conservative CPU name based feature detection (#37482)
It seems that it's actually possible to pair cores with different feature set using big.LITTLE or DynamIQ so we at least need to constrain ourselves to the intersection of the features for all the cores.
1 parent f28defc commit 2e07bd7

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

src/processor_arm.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,17 +1195,41 @@ static NOINLINE std::pair<uint32_t,FeatureList<feature_sz>> _get_host_cpu()
11951195

11961196
std::set<uint32_t> cpus;
11971197
std::vector<std::pair<uint32_t,CPUID>> list;
1198+
// Ideally the feature detection above should be enough.
1199+
// However depending on the kernel version not all features are available
1200+
// and it's also impossible to detect the ISA version which contains
1201+
// some features not yet exposed by the kernel.
1202+
// We therefore try to get a more complete feature list from the CPU name.
1203+
// Since it is possible to pair cores that have different feature set
1204+
// (Observed for exynos 9810 with exynos-m3 + cortex-a55) we'll compute
1205+
// an intersection of the known features from each core.
1206+
// If there's a core that we don't recognize, treat it as generic.
1207+
bool extra_initialized = false;
1208+
FeatureList<feature_sz> extra_features = {};
11981209
for (auto info: cpuinfo) {
11991210
auto name = (uint32_t)get_cpu_name(info);
1200-
if (name == 0)
1211+
if (name == 0) {
1212+
// no need to clear the feature set if it wasn't initialized
1213+
if (extra_initialized)
1214+
extra_features = FeatureList<feature_sz>{};
1215+
extra_initialized = true;
12011216
continue;
1217+
}
12021218
if (!check_cpu_arch_ver(name, arch))
12031219
continue;
12041220
if (cpus.insert(name).second) {
1205-
features = features | find_cpu(name)->features;
1221+
if (extra_initialized) {
1222+
extra_features = extra_features & find_cpu(name)->features;
1223+
}
1224+
else {
1225+
extra_initialized = true;
1226+
extra_features = find_cpu(name)->features;
1227+
}
12061228
list.emplace_back(name, info);
12071229
}
12081230
}
1231+
features = features | extra_features;
1232+
12091233
// Not all elements/pairs are valid
12101234
static constexpr CPU v8order[] = {
12111235
CPU::arm_cortex_a35,

0 commit comments

Comments
 (0)