From a513dbb0223c52086260c67335e633bd510ca40a Mon Sep 17 00:00:00 2001 From: Pat Riehecky Date: Tue, 30 Jan 2024 13:36:19 -0600 Subject: [PATCH] feat(processor.extensions) Add support for CPU flag detection Signed-off-by: Pat Riehecky --- .../facts/linux/processors/extensions.rb | 16 ++++++++++++ lib/facter/framework/core/file_loader.rb | 1 + lib/facter/resolvers/processors.rb | 22 ++++++++++++++++ spec/facter/resolvers/processors_spec.rb | 25 +++++++++++++++++++ spec/facter/resolvers/uname_spec.rb | 4 +++ 5 files changed, 68 insertions(+) create mode 100644 lib/facter/facts/linux/processors/extensions.rb diff --git a/lib/facter/facts/linux/processors/extensions.rb b/lib/facter/facts/linux/processors/extensions.rb new file mode 100644 index 0000000000..9512ddd1cd --- /dev/null +++ b/lib/facter/facts/linux/processors/extensions.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Facts + module Linux + module Processors + class Extensions + FACT_NAME = 'processors.extensions' + + def call_the_resolver + fact_value = Facter::Resolvers::Linux::Processors.resolve(:extensions) + Facter::ResolvedFact.new(FACT_NAME, fact_value) + end + end + end + end +end diff --git a/lib/facter/framework/core/file_loader.rb b/lib/facter/framework/core/file_loader.rb index 8aa07a1fec..dfa59e38be 100644 --- a/lib/facter/framework/core/file_loader.rb +++ b/lib/facter/framework/core/file_loader.rb @@ -482,6 +482,7 @@ require_relative '../../facts/linux/processor' require_relative '../../facts/linux/processors/cores' require_relative '../../facts/linux/processors/count' + require_relative '../../facts/linux/processors/extensions' require_relative '../../facts/linux/processors/isa' require_relative '../../facts/linux/processors/models' require_relative '../../facts/linux/processors/physicalcount' diff --git a/lib/facter/resolvers/processors.rb b/lib/facter/resolvers/processors.rb index f89ce56fc3..001d61d903 100644 --- a/lib/facter/resolvers/processors.rb +++ b/lib/facter/resolvers/processors.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'set' + module Facter module Resolvers module Linux @@ -12,6 +14,7 @@ class Processors < BaseResolver class << self # :count + # :extensions # :models # :physical_count # :speed @@ -34,6 +37,7 @@ def read_cpuinfo(fact_name) end def read_processors(cpuinfo_output) + @fact_list[:extensions] = Set[Facter::Resolvers::Uname.resolve(:processor)] @fact_list[:processors] = 0 @fact_list[:models] = [] @fact_list[:physical_processors] = [] @@ -43,7 +47,10 @@ def read_processors(cpuinfo_output) construct_models_list(tokens) count_physical_processors(tokens) build_speed(tokens) + check_extensions(tokens) end + @fact_list[:extensions] = @fact_list[:extensions].to_a + @fact_list[:extensions].sort! end def count_processors(tokens) @@ -84,6 +91,21 @@ def build_speed_for_x86(tokens) speed = tokens.last.strip.match(/^(\d+).*/)[1] @fact_list[:speed] = speed.to_i * MHZ_TO_HZ end + + def check_extensions(tokens) + return unless tokens.first.strip == 'flags' + + flags = tokens.last.split(' ') + + # TODO: As we gain support for other arches, change the guard + # so we only check the flags for the corosponding arches + return unless @fact_list[:extensions].include?('x86_64') + + @fact_list[:extensions].add('x86_64-v1') if (%w[cmov cx8 fpu fxsr lm mmx syscall sse2] - flags).empty? + @fact_list[:extensions].add('x86_64-v2') if (%w[cx16 lahf_lm popcnt sse4_1 sse4_2 ssse3] - flags).empty? + @fact_list[:extensions].add('x86_64-v3') if (%w[abm avx avx2 bmi1 bmi2 f16c fma movbe xsave] - flags).empty? + @fact_list[:extensions].add('x86_64-v4') if (%w[avx512f avx512bw avx512cd avx512dq avx512vl] - flags).empty? + end end end end diff --git a/spec/facter/resolvers/processors_spec.rb b/spec/facter/resolvers/processors_spec.rb index 246f3699c9..3b253e3c5a 100644 --- a/spec/facter/resolvers/processors_spec.rb +++ b/spec/facter/resolvers/processors_spec.rb @@ -3,6 +3,7 @@ describe Facter::Resolvers::Linux::Processors do after do Facter::Resolvers::Linux::Processors.invalidate_cache + Facter::Resolvers::Uname.invalidate_cache end context 'when on x86 architecture' do @@ -21,6 +22,9 @@ end let(:speed) { 2_294_000_000 } + let(:extensions) do + %w[x86_64 x86_64-v1 x86_64-v2 x86_64-v3] + end it 'returns number of processors' do result = Facter::Resolvers::Linux::Processors.resolve(:processors) @@ -45,6 +49,16 @@ expect(result).to eq(speed) end + + it 'returns extensions supported' do + allow(Facter::Resolvers::Uname).to receive(:resolve) + .with(:processor) + .and_return('x86_64') + + result = Facter::Resolvers::Linux::Processors.resolve(:extensions) + + expect(result).to eq(extensions) + end end context 'when cpuinfo file is readable but no physical id' do @@ -73,6 +87,7 @@ after do Facter::Resolvers::Linux::Processors.invalidate_cache + Facter::Resolvers::Uname.invalidate_cache end let(:physical_processors) { 2 } @@ -129,6 +144,11 @@ .and_return('1') end + after do + Facter::Resolvers::Linux::Processors.invalidate_cache + Facter::Resolvers::Uname.invalidate_cache + end + let(:speed) { 2_926_000_000 } let(:physical_processors) { 2 } @@ -176,6 +196,11 @@ .and_return('0') end + after do + Facter::Resolvers::Linux::Processors.invalidate_cache + Facter::Resolvers::Uname.invalidate_cache + end + let(:physical_processors) { 1 } it 'returns physical_devices_count' do diff --git a/spec/facter/resolvers/uname_spec.rb b/spec/facter/resolvers/uname_spec.rb index 59e2af6769..e5fd7d310f 100644 --- a/spec/facter/resolvers/uname_spec.rb +++ b/spec/facter/resolvers/uname_spec.rb @@ -22,6 +22,10 @@ Darwin Kernel Version 18.2.0: Fri Oct 5 19:41:49 PDT 2018; root:xnu-4903.221.2~2/RELEASE_X86_64') end + after do + Facter::Resolvers::Uname.invalidate_cache + end + it 'returns machine' do expect(uname_resolver.resolve(:machine)).to eq('x86_64') end