[SWDEV-522623] Add afid functionality to API and CLI (#330)
Change-Id: I015bde926491d54e09da8f39b05650515711e09f [SWDEV-522623] Add afid functionality to API and CLI Change-Id: I015bde926491d54e09da8f39b05650515711e09f Signed-off-by: Oosman Saeed <oossaeed@amd.com> Co-authored-by: Oosman Saeed <oossaeed@amd.com>
This commit is contained in:
@@ -60,6 +60,9 @@ AMDSMI_MAX_NUM_JPEG = 32
|
||||
AMDSMI_MAX_NUM_XCC = 8
|
||||
AMDSMI_MAX_NUM_XCP = 8
|
||||
|
||||
# max num afids per cper record
|
||||
MAX_NUMBER_OF_AFIDS_PER_RECORD = 12
|
||||
|
||||
# Max number of DPM policies
|
||||
AMDSMI_MAX_NUM_PM_POLICIES = 32
|
||||
|
||||
@@ -1888,7 +1891,6 @@ def amdsmi_get_gpu_asic_info(
|
||||
# Remove commas from vendor name for clean output
|
||||
asic_info["vendor_name"] = asic_info["vendor_name"].replace(',', '')
|
||||
|
||||
# logging.debug("amdsmi_interface.py | amdsmi_get_gpu_asic_info | return_dictionary = \n" + str(json.dumps(asic_info, indent=4)))
|
||||
return asic_info
|
||||
|
||||
|
||||
@@ -2300,9 +2302,10 @@ def notifyTypeToString(notify_type_b):
|
||||
idx = idx +1
|
||||
return "".join(guid[::-1])
|
||||
|
||||
def amdsmi_get_gpu_cper_entries(processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
|
||||
def amdsmi_get_gpu_cper_entries(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
|
||||
severity_mask: int,
|
||||
buffer_size: int = 4*1048576,
|
||||
buffer_size: int = 4 * 1048576,
|
||||
cursor: int = 0
|
||||
) -> Tuple[List[Dict[str, Any]], int]:
|
||||
|
||||
@@ -2316,6 +2319,7 @@ def amdsmi_get_gpu_cper_entries(processor_handle: amdsmi_wrapper.amdsmi_processo
|
||||
buf_size = ctypes.c_uint64(buffer_size)
|
||||
entry_count = ctypes.c_uint64(20)
|
||||
cur = ctypes.c_uint64(cursor)
|
||||
|
||||
# Allocate a pointer for the CPER header array.
|
||||
cper_hdrs_array = (ctypes.POINTER(amdsmi_wrapper.amdsmi_cper_hdr_t) * 20)()
|
||||
cper_hdrs = ctypes.cast(cper_hdrs_array, ctypes.POINTER(ctypes.POINTER(amdsmi_wrapper.amdsmi_cper_hdr_t)))
|
||||
@@ -2336,51 +2340,114 @@ def amdsmi_get_gpu_cper_entries(processor_handle: amdsmi_wrapper.amdsmi_processo
|
||||
entries = {}
|
||||
cper_data = []
|
||||
offset = 0
|
||||
|
||||
# Iterate over each entry using its variable record_length.
|
||||
for i in range(entry_count.value):
|
||||
entry_address = ctypes.addressof(buf) + offset
|
||||
entry_ptr = ctypes.cast(entry_address, ctypes.POINTER(amdsmi_wrapper.amdsmi_cper_hdr_t))
|
||||
|
||||
# Extract the raw bytes and size of the entry.
|
||||
cper_data.append({
|
||||
"bytes":list((entry_ptr.contents.record_length * ctypes.c_byte).from_address(entry_address)),
|
||||
"size":entry_ptr.contents.record_length
|
||||
"bytes": list((entry_ptr.contents.record_length * ctypes.c_byte).from_address(entry_address)),
|
||||
"size": entry_ptr.contents.record_length
|
||||
})
|
||||
|
||||
# Extract the timestamp fields.
|
||||
year = entry_ptr.contents.timestamp.year
|
||||
# Adjust the year if it's less than 100. You can tweak this logic based on your expected data.
|
||||
if year < 100:
|
||||
year += 2000
|
||||
if year < 100: # Adjust the year if it's less than 100.
|
||||
year += 2000
|
||||
formatted_timestamp = (
|
||||
f"{year:04d}/"
|
||||
f"{entry_ptr.contents.timestamp.month:02d}/"
|
||||
f"{entry_ptr.contents.timestamp.day:02d} "
|
||||
f"{entry_ptr.contents.timestamp.hours:02d}:"
|
||||
f"{entry_ptr.contents.timestamp.minutes:02d}:"
|
||||
f"{entry_ptr.contents.timestamp.seconds:02d}"
|
||||
f"{year:04d}/"
|
||||
f"{entry_ptr.contents.timestamp.month:02d}/"
|
||||
f"{entry_ptr.contents.timestamp.day:02d} "
|
||||
f"{entry_ptr.contents.timestamp.hours:02d}:"
|
||||
f"{entry_ptr.contents.timestamp.minutes:02d}:"
|
||||
f"{entry_ptr.contents.timestamp.seconds:02d}"
|
||||
)
|
||||
|
||||
# Create a dictionary for the CPER entry.
|
||||
cper_entry = {
|
||||
"error_severity": amdsmi_wrapper.amdsmi_cper_sev_t__enumvalues.get(entry_ptr.contents.error_severity, "AMDSMI_CPER_SEV_UNUSED").replace("AMDSMI_CPER_SEV_", "").lower(),
|
||||
"error_severity": amdsmi_wrapper.amdsmi_cper_sev_t__enumvalues.get(
|
||||
entry_ptr.contents.error_severity, "AMDSMI_CPER_SEV_UNUSED"
|
||||
).replace("AMDSMI_CPER_SEV_", "").lower(),
|
||||
"notify_type": _notifyTypeToString(entry_ptr.contents.notify_type.b),
|
||||
"timestamp": formatted_timestamp,
|
||||
"signature" : entry_ptr.contents.signature,
|
||||
"revision" : entry_ptr.contents.revision,
|
||||
"signature_end" : hex(entry_ptr.contents.signature_end),
|
||||
"sec_cnt" : entry_ptr.contents.sec_cnt,
|
||||
"record_length" : entry_ptr.contents.record_length,
|
||||
"platform_id" : entry_ptr.contents.platform_id,
|
||||
"creator_id" : entry_ptr.contents.creator_id,
|
||||
"record_id" : entry_ptr.contents.record_id,
|
||||
"flags" : entry_ptr.contents.flags,
|
||||
"persistence_info" : entry_ptr.contents.persistence_info,
|
||||
"signature": entry_ptr.contents.signature,
|
||||
"revision": entry_ptr.contents.revision,
|
||||
"signature_end": hex(entry_ptr.contents.signature_end),
|
||||
"sec_cnt": entry_ptr.contents.sec_cnt,
|
||||
"record_length": entry_ptr.contents.record_length,
|
||||
"platform_id": entry_ptr.contents.platform_id,
|
||||
"creator_id": entry_ptr.contents.creator_id,
|
||||
"record_id": entry_ptr.contents.record_id,
|
||||
"flags": entry_ptr.contents.flags,
|
||||
"persistence_info": entry_ptr.contents.persistence_info,
|
||||
#"reserved" : entry_ptr.contents.reserved
|
||||
#"cper_valid_bit" : entry_ptr.contents.cper_valid_bits,
|
||||
#"partition_id" : entry_ptr.contents.partition_id,
|
||||
}
|
||||
|
||||
entries[i] = cper_entry.copy()
|
||||
offset += entry_ptr.contents.record_length # Use the actual record length to advance the offset
|
||||
offset += entry_ptr.contents.record_length # Use the actual record length to advance the offset.
|
||||
|
||||
return entries, cur.value, cper_data
|
||||
|
||||
|
||||
def amdsmi_get_afids_from_cper(
|
||||
cper_afid_data: Union[bytes, bytearray, List[Dict[str, Any]]]
|
||||
) -> Tuple[List[int], int]:
|
||||
"""
|
||||
Extract AFIDs from one or more CPER blobs.
|
||||
|
||||
Args:
|
||||
cper_afid_data: Either
|
||||
- raw bytes or bytearray of a single CPER record, or
|
||||
- a list of dicts each with keys "bytes" (List[int]) and "size" (int).
|
||||
|
||||
Returns:
|
||||
Tuple[List[int], int]: A tuple containing:
|
||||
- A list of extracted AFIDs.
|
||||
- The total count of AFIDs.
|
||||
"""
|
||||
# Normalize single blob into a list of records
|
||||
if isinstance(cper_afid_data, (bytes, bytearray)):
|
||||
cper_records = [{
|
||||
"bytes": list(cper_afid_data),
|
||||
"size": len(cper_afid_data)
|
||||
}]
|
||||
else:
|
||||
cper_records = cper_afid_data
|
||||
|
||||
all_afids: List[int] = []
|
||||
|
||||
for record in cper_records:
|
||||
raw_bytes = bytes(record["bytes"])
|
||||
record_size = record["size"]
|
||||
|
||||
# Wrap as char*
|
||||
buf = ctypes.create_string_buffer(raw_bytes, record_size)
|
||||
buf_ptr = ctypes.cast(buf, ctypes.POINTER(ctypes.c_char))
|
||||
|
||||
afid_array = (ctypes.c_uint64 * MAX_NUMBER_OF_AFIDS_PER_RECORD)()
|
||||
num_afids_ct = ctypes.c_uint32(MAX_NUMBER_OF_AFIDS_PER_RECORD)
|
||||
|
||||
# Call the wrapper function
|
||||
status = amdsmi_wrapper.amdsmi_get_afids_from_cper(
|
||||
buf_ptr,
|
||||
ctypes.c_uint32(record_size),
|
||||
afid_array,
|
||||
ctypes.byref(num_afids_ct)
|
||||
)
|
||||
if status != amdsmi_wrapper.AMDSMI_STATUS_SUCCESS:
|
||||
raise AmdSmiLibraryException(f"get_afids failed: {status}")
|
||||
|
||||
# Collect exactly the decoded AFIDs
|
||||
count = num_afids_ct.value
|
||||
all_afids.extend(afid_array[i] for i in range(count))
|
||||
|
||||
return all_afids, len(all_afids)
|
||||
|
||||
|
||||
def amdsmi_get_gpu_board_info(
|
||||
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
@@ -2642,6 +2642,9 @@ amdsmi_cper_hdr_t = struct_amdsmi_cper_hdr_t
|
||||
amdsmi_get_gpu_cper_entries = _libraries['libamd_smi.so'].amdsmi_get_gpu_cper_entries
|
||||
amdsmi_get_gpu_cper_entries.restype = amdsmi_status_t
|
||||
amdsmi_get_gpu_cper_entries.argtypes = [amdsmi_processor_handle, uint32_t, ctypes.POINTER(ctypes.c_char), ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.POINTER(struct_amdsmi_cper_hdr_t)), ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64)]
|
||||
amdsmi_get_afids_from_cper = _libraries['libamd_smi.so'].amdsmi_get_afids_from_cper
|
||||
amdsmi_get_afids_from_cper.restype = amdsmi_status_t
|
||||
amdsmi_get_afids_from_cper.argtypes = [ctypes.POINTER(ctypes.c_char), uint32_t, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint32)]
|
||||
amdsmi_get_gpu_ecc_status = _libraries['libamd_smi.so'].amdsmi_get_gpu_ecc_status
|
||||
amdsmi_get_gpu_ecc_status.restype = amdsmi_status_t
|
||||
amdsmi_get_gpu_ecc_status.argtypes = [amdsmi_processor_handle, amdsmi_gpu_block_t, ctypes.POINTER(amdsmi_ras_err_state_t)]
|
||||
@@ -3171,9 +3174,9 @@ __all__ = \
|
||||
'amdsmi_free_name_value_pairs', 'amdsmi_freq_ind_t',
|
||||
'amdsmi_freq_volt_region_t', 'amdsmi_frequencies_t',
|
||||
'amdsmi_frequency_range_t', 'amdsmi_fw_block_t',
|
||||
'amdsmi_fw_info_t', 'amdsmi_get_clk_freq',
|
||||
'amdsmi_get_clock_info', 'amdsmi_get_cpu_cclk_limit',
|
||||
'amdsmi_get_cpu_core_boostlimit',
|
||||
'amdsmi_fw_info_t', 'amdsmi_get_afids_from_cper',
|
||||
'amdsmi_get_clk_freq', 'amdsmi_get_clock_info',
|
||||
'amdsmi_get_cpu_cclk_limit', 'amdsmi_get_cpu_core_boostlimit',
|
||||
'amdsmi_get_cpu_core_current_freq_limit',
|
||||
'amdsmi_get_cpu_core_energy',
|
||||
'amdsmi_get_cpu_current_io_bandwidth',
|
||||
|
||||
Reference in New Issue
Block a user