Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backported s390x support for 6.0.0 #129

Merged
merged 3 commits into from
May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ OS Support
CPU Support
-----
* X86 32bit and 64bit
* Some ARM and PPC CPUs
* Some ARM, PPC and S390X CPUs


These approaches are used for getting info:
Expand Down
42 changes: 38 additions & 4 deletions cpuinfo/cpuinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ def _run_and_get_stdout(command, pipe_command=None):
# Make sure we are running on a supported system
def _check_arch():
arch, bits = _parse_arch(DataSource.arch_string_raw)
if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8', 'PPC_64']:
raise Exception("py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.")
if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8', 'PPC_64', 'S390X']:
raise Exception("py-cpuinfo currently only works on X86 and some ARM/PPC/S390X CPUs.")

def _obj_to_b64(thing):
import pickle
Expand Down Expand Up @@ -642,6 +642,10 @@ def _parse_arch(arch_string_raw):
elif re.match('^sparc64$|^sun4u$|^sun4v$', arch_string_raw):
arch = 'SPARC_64'
bits = 64
# S390X
elif re.match('^s390x$', arch_string_raw):
arch = 'S390X'
bits = 64

return (arch, bits)

Expand Down Expand Up @@ -1426,8 +1430,23 @@ def _get_cpu_info_from_proc_cpuinfo():
flags = flags.split()
flags.sort()

# Check for other cache format
if not cache_size:
try:
for i in range(0, 10):
name = "cache{0}".format(i)
value = _get_field(False, output, None, None, name)
if value:
value = [entry.split('=') for entry in value.split(' ')]
value = dict(value)
if 'level' in value and value['level'] == '3' and 'size' in value:
cache_size = value['size']
break
except Exception:
pass

# Convert from MHz string to Hz
hz_actual = _get_field(False, output, None, '', 'cpu MHz', 'cpu speed', 'clock')
hz_actual = _get_field(False, output, None, '', 'cpu MHz', 'cpu speed', 'clock', 'cpu MHz dynamic', 'cpu MHz static')
hz_actual = hz_actual.lower().rstrip('mhz').strip()
hz_actual = _to_decimal_string(hz_actual)

Expand Down Expand Up @@ -1535,6 +1554,15 @@ def _get_cpu_info_from_lscpu():
info['hz_advertised'] = _hz_short_to_full(new_hz, scale)
info['hz_actual'] = _hz_short_to_full(new_hz, scale)

new_hz = _get_field(False, output, None, None, 'CPU dynamic MHz', 'CPU static MHz')
if new_hz:
new_hz = _to_decimal_string(new_hz)
scale = 6
info['hz_advertised_friendly'] = _hz_short_to_friendly(new_hz, scale)
info['hz_actual_friendly'] = _hz_short_to_friendly(new_hz, scale)
info['hz_advertised'] = _hz_short_to_full(new_hz, scale)
info['hz_actual'] = _hz_short_to_full(new_hz, scale)

vendor_id = _get_field(False, output, None, None, 'Vendor ID')
if vendor_id:
info['vendor_id_raw'] = vendor_id
Expand Down Expand Up @@ -1563,7 +1591,7 @@ def _get_cpu_info_from_lscpu():
if l1_instruction_cache_size:
info['l1_instruction_cache_size'] = _to_friendly_bytes(l1_instruction_cache_size)

l2_cache_size = _get_field(False, output, None, None, 'L2 cache')
l2_cache_size = _get_field(False, output, None, None, 'L2 cache', 'L2d cache')
if l2_cache_size:
info['l2_cache_size'] = _to_friendly_bytes(l2_cache_size)

Expand All @@ -1589,6 +1617,12 @@ def _get_cpu_info_from_dmesg():
Returns the CPU info gathered from dmesg.
Returns {} if dmesg is not found or does not have the desired info.
'''

# Just return {} if this arch has an unreliable dmesg log
arch, bits = _parse_arch(DataSource.arch_string_raw)
if arch in ['S390X']:
return {}

# Just return {} if there is no dmesg
if not DataSource.has_dmesg():
return {}
Expand Down
2 changes: 2 additions & 0 deletions test_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from test_linux_fedora_24_x86_64 import TestLinuxFedora_24_X86_64
from test_linux_fedora_24_ppc64le import TestLinuxFedora_24_ppc64le
from test_linux_fedora_29_x86_64_ryzen_7 import Test_Linux_Fedora_29_X86_64_Ryzen_7
from test_linux_fedora_5_s390x import TestLinuxFedora_5_s390x
from test_linux_aarch64_64 import TestLinux_Aarch_64
from test_linux_gentoo_2_2_x86_64 import TestLinuxGentoo_2_2_X86_64
from test_linux_rhel_7_3_ppc64le import TestLinuxRHEL_7_3_ppc64le
Expand Down Expand Up @@ -91,6 +92,7 @@ def logger(msg):
TestLinuxFedora_24_X86_64,
TestLinuxFedora_24_ppc64le,
Test_Linux_Fedora_29_X86_64_Ryzen_7,
TestLinuxFedora_5_s390x,
TestLinux_Aarch_64,
TestLinuxGentoo_2_2_X86_64,
TestLinuxRHEL_7_3_ppc64le,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_invalid_cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ def test_check_arch_exception(self):
cpuinfo._check_arch()
self.fail('Failed to raise Exception')
except Exception as err:
self.assertEqual('py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.', err.args[0])
self.assertEqual('py-cpuinfo currently only works on X86 and some ARM/PPC/S390X CPUs.', err.args[0])