From 664ade7354b16db160b4c35a7421d9fda984bdc0 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 2 Dec 2024 16:30:06 -0600 Subject: [PATCH 01/23] [SWDEV-502001] Fix link for amd_hsmp.h Signed-off-by: Maisam Arif Change-Id: I402ee539cdd4c896acd7ccc83f3090c3a5eeba12 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85821c49ad..d2c118b072 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,7 +129,7 @@ if(ENABLE_ESMI_LIB) endif() if(NOT EXISTS ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) file(DOWNLOAD - https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/plain/arch/x86/include/uapi/asm/amd_hsmp.h?h=review-ilpo + https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/plain/arch/x86/include/uapi/asm/amd_hsmp.h ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) endif() add_definitions("-DENABLE_ESMI_LIB=1") From fc7e1ddb4a9f00b48ff389a786c46ebf7b458d3f Mon Sep 17 00:00:00 2001 From: Bindhiya Kanangot Balakrishnan Date: Fri, 15 Nov 2024 14:44:50 -0600 Subject: [PATCH 02/23] [SWDEV-498507] Tool amd-smi could be more case insensitive Modified amdsmi_cli to accept case insensitive arguments if the argument does not start with a single dash(-). Signed-off-by: Bindhiya Kanangot Balakrishnan Change-Id: I1b6320db0afaad0900d5a2049206002c3899fa71 --- CHANGELOG.md | 19 +++++++++++++++++++ amdsmi_cli/amdsmi_cli.py | 2 ++ 2 files changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dec23bb3c0..915f52bbd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ***All information listed below is for reference and subject to change.*** +## amd_smi_lib for ROCm 6.4.0 + +### Added + +### Changed + +### Removed + +### Optimized + +- **Modified `amd-smi` CLI to allow case insensitive arguments if the argument does not begin with a single dash**. + - With this change `amd-smi version` and `amd-smi VERSION` will now yield the same output. + - `amd-smi static --bus` and `amd-smi STATIC --BUS` will produce identical results. + - `amd-smi static -b` and `amd-smi static -B` will still return different results (-b for bus and -B for board). + +### Resolved issues + +### Upcoming changes + ## amd_smi_lib for ROCm 6.3.0 ### Added diff --git a/amdsmi_cli/amdsmi_cli.py b/amdsmi_cli/amdsmi_cli.py index 15fe9051c2..ddec9921bb 100755 --- a/amdsmi_cli/amdsmi_cli.py +++ b/amdsmi_cli/amdsmi_cli.py @@ -100,6 +100,8 @@ if __name__ == "__main__": except NameError: logging.debug("argcomplete module not found. Autocomplete will not work.") + sys.argv = [arg.lower() if arg.startswith('--') or not arg.startswith('-') + else arg for arg in sys.argv] args = amd_smi_parser.parse_args(args=None if sys.argv[1:] else ['--help']) # Handle command modifiers before subcommand execution From bc77330a744fc9b9c39fbb975191db9466abfb95 Mon Sep 17 00:00:00 2001 From: Bindhiya Kanangot Balakrishnan Date: Tue, 3 Dec 2024 11:01:11 -0600 Subject: [PATCH 03/23] [SWDEV-499030] Fix truncated FRU_ID The FRU_ID was truncated because the string copied from sysfs was limited to 32 characters. This limit has been increased to AMDSMI_MAX_STRING_LENGTH to accommodate longer FRU_IDs. Also updated the deprecated string length macros. Signed-off-by: Bindhiya Kanangot Balakrishnan Change-Id: I8becaf9f37609b2e5aecdf92b6ae60f4419ad8ef --- src/amd_smi/amd_smi_utils.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index 564923029c..d067ebd789 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -190,12 +190,11 @@ amdsmi_status_t smi_amdgpu_get_board_info(amd::smi::AMDSmiGPUDevice* device, amd std::string manufacturer_name_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/manufacturer"); std::string product_name_path = "/sys/class/drm/" + device->get_gpu_path() + std::string("/device/product_name"); - openFileAndModifyBuffer(model_number_path, info->model_number, AMDSMI_256_LENGTH); - openFileAndModifyBuffer(product_serial_path, info->product_serial, AMDSMI_NORMAL_STRING_LENGTH); - openFileAndModifyBuffer(fru_id_path, info->fru_id, AMDSMI_NORMAL_STRING_LENGTH); - openFileAndModifyBuffer(manufacturer_name_path, info->manufacturer_name, - AMDSMI_MAX_STRING_LENGTH); - openFileAndModifyBuffer(product_name_path, info->product_name, AMDSMI_256_LENGTH); + openFileAndModifyBuffer(model_number_path, info->model_number, AMDSMI_MAX_STRING_LENGTH); + openFileAndModifyBuffer(product_serial_path, info->product_serial, AMDSMI_MAX_STRING_LENGTH); + openFileAndModifyBuffer(fru_id_path, info->fru_id, AMDSMI_MAX_STRING_LENGTH); + openFileAndModifyBuffer(manufacturer_name_path, info->manufacturer_name, AMDSMI_MAX_STRING_LENGTH); + openFileAndModifyBuffer(product_name_path, info->product_name, AMDSMI_MAX_STRING_LENGTH); std::ostringstream ss; ss << __PRETTY_FUNCTION__ << "[Before correction] " From 2370aa1b40019ef556f359b1c8e378cf23acd722 Mon Sep 17 00:00:00 2001 From: Justin Williams Date: Mon, 18 Nov 2024 10:10:13 -0600 Subject: [PATCH 04/23] [SWDEV-469278] Removed PyYAML Dependency Signed-off-by: Justin Williams Change-Id: Idec32cfb0de84cc255b506d7f972e2750992745e --- CMakeLists.txt | 13 +++---------- amdsmi_cli/amdsmi_logger.py | 34 +++++++++++++++------------------- py-interface/pyproject.toml.in | 3 --- py-interface/setup.py.in | 3 --- 4 files changed, 18 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d2c118b072..a0d9b33c77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ find_program(GIT NAMES git) ## Setup the package version based on git tags. set(PKG_VERSION_GIT_TAG_PREFIX "amdsmi_pkg_ver") -get_package_version_number("24.7.1" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) +get_package_version_number("24.7.0" ${PKG_VERSION_GIT_TAG_PREFIX} GIT) message("Package version: ${PKG_VERSION_STR}") set(${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR "${CPACK_PACKAGE_VERSION_MAJOR}") set(${AMD_SMI_LIBS_TARGET}_VERSION_MINOR "${CPACK_PACKAGE_VERSION_MINOR}") @@ -107,13 +107,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2 -fno-common -Wstrict-overflow # Intentionally leave out -Wsign-promo. It causes spurious warnings. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -Wreorder") -# Add CMAKE debug flags -if ("${CMAKE_BUILD_TYPE}" STREQUAL Release) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") -else () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -O0 -DDEBUG") -endif () - set(COMMON_SRC_DIR "${PROJECT_SOURCE_DIR}/src") set(ROCM_SRC_DIR "${PROJECT_SOURCE_DIR}/rocm_smi/src") set(AMDSMI_SRC_DIR "${PROJECT_SOURCE_DIR}/src/amd_smi") @@ -261,7 +254,7 @@ install( add_subdirectory(goamdsmi_shim) #Debian package specific variables -set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python3-argcomplete, libdrm-dev, python3-yaml") +set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python3-argcomplete, libdrm-dev") set(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) set(CPACK_DEBIAN_PACKAGE_DEPENDS "sudo, python3 (>= 3.6.8), python3-pip") @@ -285,7 +278,7 @@ set(CPACK_RPM_PACKAGE_SUGGESTS "python3-argcomplete") set(CPACK_RPM_DEV_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS}) set(CPACK_RPM_ASAN_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS}) # python version gated by rhel8 :( -set(CPACK_RPM_PACKAGE_REQUIRES "sudo, python3 >= 3.6.8, python3-pip, python3-PyYAML") +set(CPACK_RPM_PACKAGE_REQUIRES "sudo, python3 >= 3.6.8, python3-pip") set(CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES}) set(CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES}) diff --git a/amdsmi_cli/amdsmi_logger.py b/amdsmi_cli/amdsmi_logger.py index a409d4f578..d52abdf1fb 100644 --- a/amdsmi_cli/amdsmi_logger.py +++ b/amdsmi_cli/amdsmi_logger.py @@ -25,20 +25,10 @@ import re import time from typing import Dict from enum import Enum -import yaml import inspect - from amdsmi_helpers import AMDSMIHelpers import amdsmi_cli_exceptions -### Custom YAML Functions -# Dumper class to preserve order of yaml.dump -class CustomDumper(yaml.Dumper): - def represent_dict_preserve_order(self, data): - return self.represent_dict(data.items()) -def has_sort_keys_option(): # to check if sort_keys is available - return 'sort_keys' in inspect.signature(yaml.dump).parameters - class AMDSMILogger(): def __init__(self, format='human_readable', destination='stdout') -> None: self.output = {} @@ -233,15 +223,8 @@ class AMDSMILogger(): capitalized_json["AMDSMI_SPACING_REMOVAL"] = tabbed_dictionary - json_string = json.dumps(capitalized_json, indent=4) - - if has_sort_keys_option(): - yaml_data = yaml.safe_load(json_string) - yaml_output = yaml.dump(yaml_data, sort_keys=False, allow_unicode=True) - else: - CustomDumper.add_representer(dict, CustomDumper.represent_dict_preserve_order) - yaml_data = yaml.safe_load(json_string) - yaml_output = yaml.dump(yaml_data, Dumper=CustomDumper, allow_unicode=True, default_flow_style=False) + # Convert the capitalized JSON to a YAML-like string + yaml_output = self.custom_dump(capitalized_json) # Remove a key line if it is a spacer yaml_output = yaml_output.replace("AMDSMI_SPACING_REMOVAL:\n", "") @@ -264,6 +247,19 @@ class AMDSMILogger(): return clean_yaml_output + def custom_dump(self, data, indent=0): + """Converts a Python dictionary to a YAML-like string.""" + yaml_string = "" + for key, value in data.items(): + if isinstance(value, dict): + yaml_string += " " * indent + f"{key}:\n" + self.custom_dump(value, indent + 1) + elif isinstance(value, list): + yaml_string += " " * indent + f"{key}:\n" + for item in value: + yaml_string += " " * (indent + 1) + f"- {item}\n" + else: + yaml_string += " " * indent + f"{key}: {value}\n" + return yaml_string def flatten_dict(self, target_dict, topology_override=False): """This will flatten a dictionary out to a single level of key value stores diff --git a/py-interface/pyproject.toml.in b/py-interface/pyproject.toml.in index 507faea358..93185b27e1 100644 --- a/py-interface/pyproject.toml.in +++ b/py-interface/pyproject.toml.in @@ -15,9 +15,6 @@ license = {file = "amdsmi/LICENSE"} readme = {file = "amdsmi/README.md", content-type = "text/markdown"} description = "AMDSMI Python LIB - AMD GPU Monitoring Library" requires-python = ">=3.6" -dependencies = [ - "PyYAML >= 3.0", -] classifiers = [ "Programming Language :: Python :: 3" ] diff --git a/py-interface/setup.py.in b/py-interface/setup.py.in index 8aa2091a78..eb3e992f65 100644 --- a/py-interface/setup.py.in +++ b/py-interface/setup.py.in @@ -9,9 +9,6 @@ setup( description="AMDSMI Python LIB - AMD GPU Monitoring Library", url="https://github.com/ROCm/amdsmi", packages=find_packages(), - install_requires=[ - "PyYAML>=3.0", - ], classifiers=[ "Programming Language :: Python :: 3", ], From 547db10384999420e1ae1297e025d8204f13d4a2 Mon Sep 17 00:00:00 2001 From: Joe Narlo Date: Tue, 3 Dec 2024 14:13:27 -0600 Subject: [PATCH 05/23] SWDEV-502330 [AMD-SMI][Unified Header] Convert struct to typedef struct Change struct to a typedef struct Signed-off-by: Joe Narlo Change-Id: I6f3b22a5219c0db0aab2c308b71213ae75334476 --- include/amd_smi/amdsmi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 1b17643ef9..4db08619b3 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -1415,7 +1415,7 @@ typedef struct { /** * @brief The following structures hold the gpu statistics for a device. */ -struct amdsmi_gpu_xcp_metrics_t { +typedef struct { /* Utilization Instantaneous (%) */ uint32_t gfx_busy_inst[AMDSMI_MAX_NUM_XCC]; uint16_t jpeg_busy[AMDSMI_MAX_NUM_JPEG]; @@ -1423,7 +1423,7 @@ struct amdsmi_gpu_xcp_metrics_t { /* Utilization Accumulated (%) */ uint64_t gfx_busy_acc[AMDSMI_MAX_NUM_XCC]; -}; +} amdsmi_gpu_xcp_metrics_t; typedef struct { @@ -1622,7 +1622,7 @@ typedef struct { uint16_t num_partition; /* XCP (Graphic Cluster Partitions) metrics stats */ - struct amdsmi_gpu_xcp_metrics_t xcp_stats[AMDSMI_MAX_NUM_XCP]; + amdsmi_gpu_xcp_metrics_t xcp_stats[AMDSMI_MAX_NUM_XCP]; /* PCIE other end recovery counter */ uint32_t pcie_lc_perf_other_end_recovery; From bc3ac61641f58491b29330dd9f3683e6a6927fb7 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 5 Dec 2024 15:18:13 -0600 Subject: [PATCH 06/23] Added gpu_metrics table debug logs in monitor Signed-off-by: Maisam Arif Change-Id: I8aa96629a65df7a2d52ef9ed42a884732d097a54 --- amdsmi_cli/amdsmi_commands.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 79971db3a4..1632d6a6fc 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -4717,6 +4717,23 @@ class AMDSMICommands(): self.logger.store_output(args.gpu, 'timestamp', int(time.time())) self.logger.table_header = 'TIMESTAMP'.rjust(10) + ' ' + self.logger.table_header + if args.loglevel == "DEBUG": + try: + # Get GPU Metrics table version + gpu_metric_version_info = amdsmi_interface.amdsmi_get_gpu_metrics_header_info(args.gpu) + gpu_metric_version_str = json.dumps(gpu_metric_version_info, indent=4) + logging.debug("GPU Metrics table Version for GPU %s | %s", gpu_id, gpu_metric_version_str) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Unable to load GPU Metrics table version for %s | %s", gpu_id, e.err_info) + + try: + # Get GPU Metrics table + gpu_metric_debug_info = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu) + gpu_metric_str = json.dumps(gpu_metric_debug_info, indent=4) + logging.debug("GPU Metrics table for GPU %s | %s", gpu_id, str(gpu_metric_str)) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Unable to load GPU Metrics table for %s | %s", gpu_id, e.err_info) + # Store the pcie_bw values due to possible increase in bandwidth due to repeated gpu_metrics calls if args.pcie: try: From 2c24cab86c401e7a94804a34e6f830962b459b72 Mon Sep 17 00:00:00 2001 From: Justin Williams Date: Tue, 3 Dec 2024 14:37:11 -0600 Subject: [PATCH 07/23] [SWDEV-502001] Added amd_hsmp.h locally Signed-off-by: Justin Williams Change-Id: I28e48913743f86fb5fc9082307ec326830d55960 --- CMakeLists.txt | 5 +- include/amd_smi/impl/amd_hsmp.h | 417 ++++++++++++++++++++++++++++++++ 2 files changed, 419 insertions(+), 3 deletions(-) create mode 100644 include/amd_smi/impl/amd_hsmp.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a0d9b33c77..99589cd3d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,9 +121,8 @@ if(ENABLE_ESMI_LIB) execute_process(COMMAND git clone --depth=1 -b esmi_pkg_ver-3.0.3 https://github.com/amd/esmi_ib_library.git ${PROJECT_SOURCE_DIR}/esmi_ib_library) endif() if(NOT EXISTS ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) - file(DOWNLOAD - https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/plain/arch/x86/include/uapi/asm/amd_hsmp.h - ${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm/amd_hsmp.h) + file(COPY "${PROJECT_SOURCE_DIR}/include/amd_smi/impl/amd_hsmp.h" + DESTINATION "${PROJECT_SOURCE_DIR}/esmi_ib_library/include/asm") endif() add_definitions("-DENABLE_ESMI_LIB=1") set(ESMI_INC_DIR "${PROJECT_SOURCE_DIR}/esmi_ib_library/include") diff --git a/include/amd_smi/impl/amd_hsmp.h b/include/amd_smi/impl/amd_hsmp.h new file mode 100644 index 0000000000..b027cec2ad --- /dev/null +++ b/include/amd_smi/impl/amd_hsmp.h @@ -0,0 +1,417 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +#ifndef _UAPI_ASM_X86_AMD_HSMP_H_ +#define _UAPI_ASM_X86_AMD_HSMP_H_ + +#include + +#pragma pack(4) + +#define HSMP_MAX_MSG_LEN 8 + +/* + * HSMP Messages supported + */ +enum hsmp_message_ids { + HSMP_TEST = 1, /* 01h Increments input value by 1 */ + HSMP_GET_SMU_VER, /* 02h SMU FW version */ + HSMP_GET_PROTO_VER, /* 03h HSMP interface version */ + HSMP_GET_SOCKET_POWER, /* 04h average package power consumption */ + HSMP_SET_SOCKET_POWER_LIMIT, /* 05h Set the socket power limit */ + HSMP_GET_SOCKET_POWER_LIMIT, /* 06h Get current socket power limit */ + HSMP_GET_SOCKET_POWER_LIMIT_MAX,/* 07h Get maximum socket power value */ + HSMP_SET_BOOST_LIMIT, /* 08h Set a core maximum frequency limit */ + HSMP_SET_BOOST_LIMIT_SOCKET, /* 09h Set socket maximum frequency level */ + HSMP_GET_BOOST_LIMIT, /* 0Ah Get current frequency limit */ + HSMP_GET_PROC_HOT, /* 0Bh Get PROCHOT status */ + HSMP_SET_XGMI_LINK_WIDTH, /* 0Ch Set max and min width of xGMI Link */ + HSMP_SET_DF_PSTATE, /* 0Dh Alter APEnable/Disable messages behavior */ + HSMP_SET_AUTO_DF_PSTATE, /* 0Eh Enable DF P-State Performance Boost algorithm */ + HSMP_GET_FCLK_MCLK, /* 0Fh Get FCLK and MEMCLK for current socket */ + HSMP_GET_CCLK_THROTTLE_LIMIT, /* 10h Get CCLK frequency limit in socket */ + HSMP_GET_C0_PERCENT, /* 11h Get average C0 residency in socket */ + HSMP_SET_NBIO_DPM_LEVEL, /* 12h Set max/min LCLK DPM Level for a given NBIO */ + HSMP_GET_NBIO_DPM_LEVEL, /* 13h Get LCLK DPM level min and max for a given NBIO */ + HSMP_GET_DDR_BANDWIDTH, /* 14h Get theoretical maximum and current DDR Bandwidth */ + HSMP_GET_TEMP_MONITOR, /* 15h Get socket temperature */ + HSMP_GET_DIMM_TEMP_RANGE, /* 16h Get per-DIMM temperature range and refresh rate */ + HSMP_GET_DIMM_POWER, /* 17h Get per-DIMM power consumption */ + HSMP_GET_DIMM_THERMAL, /* 18h Get per-DIMM thermal sensors */ + HSMP_GET_SOCKET_FREQ_LIMIT, /* 19h Get current active frequency per socket */ + HSMP_GET_CCLK_CORE_LIMIT, /* 1Ah Get CCLK frequency limit per core */ + HSMP_GET_RAILS_SVI, /* 1Bh Get SVI-based Telemetry for all rails */ + HSMP_GET_SOCKET_FMAX_FMIN,/* 1Ch Get Fmax and Fmin per socket */ + HSMP_GET_IOLINK_BANDWITH, /* 1Dh Get current bandwidth on IO Link */ + HSMP_GET_XGMI_BANDWITH, /* 1Eh Get current bandwidth on xGMI Link */ + HSMP_SET_GMI3_WIDTH, /* 1Fh Set max and min GMI3 Link width */ + HSMP_SET_PCI_RATE, /* 20h Control link rate on PCIe devices */ + HSMP_SET_POWER_MODE, /* 21h Select power efficiency profile policy */ + HSMP_SET_PSTATE_MAX_MIN, /* 22h Set the max and min DF P-State */ + HSMP_GET_METRIC_TABLE_VER,/* 23h Get metrics table version */ + HSMP_GET_METRIC_TABLE, /* 24h Get metrics table */ + HSMP_GET_METRIC_TABLE_DRAM_ADDR,/* 25h Get metrics table dram address */ + HSMP_MSG_ID_MAX, +}; + +struct hsmp_message { + __u32 msg_id; /* Message ID */ + __u16 num_args; /* Number of input argument words in message */ + __u16 response_sz; /* Number of expected output/response words */ + __u32 args[HSMP_MAX_MSG_LEN]; /* argument/response buffer */ + __u16 sock_ind; /* socket number */ +}; + +enum hsmp_msg_type { + HSMP_RSVD = -1, + HSMP_SET = 0, + HSMP_GET = 1, +}; + +enum hsmp_proto_versions { + HSMP_PROTO_VER2 = 2, + HSMP_PROTO_VER3, + HSMP_PROTO_VER4, + HSMP_PROTO_VER5, + HSMP_PROTO_VER6 +}; + +struct hsmp_msg_desc { + int num_args; + int response_sz; + enum hsmp_msg_type type; +}; + +/* + * User may use these comments as reference, please find the + * supported list of messages and message definition in the + * HSMP chapter of respective family/model PPR. + * + * Not supported messages would return -ENOMSG. + */ +static const struct hsmp_msg_desc hsmp_msg_desc_table[] + __attribute__((unused)) = { + /* RESERVED */ + {0, 0, HSMP_RSVD}, + + /* + * HSMP_TEST, num_args = 1, response_sz = 1 + * input: args[0] = xx + * output: args[0] = xx + 1 + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_SMU_VER, num_args = 0, response_sz = 1 + * output: args[0] = smu fw ver + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_PROTO_VER, num_args = 0, response_sz = 1 + * output: args[0] = proto version + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_SOCKET_POWER, num_args = 0, response_sz = 1 + * output: args[0] = socket power in mWatts + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_SET_SOCKET_POWER_LIMIT, num_args = 1, response_sz = 0 + * input: args[0] = power limit value in mWatts + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_GET_SOCKET_POWER_LIMIT, num_args = 0, response_sz = 1 + * output: args[0] = socket power limit value in mWatts + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_SOCKET_POWER_LIMIT_MAX, num_args = 0, response_sz = 1 + * output: args[0] = maximuam socket power limit in mWatts + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_SET_BOOST_LIMIT, num_args = 1, response_sz = 0 + * input: args[0] = apic id[31:16] + boost limit value in MHz[15:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_SET_BOOST_LIMIT_SOCKET, num_args = 1, response_sz = 0 + * input: args[0] = boost limit value in MHz + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_GET_BOOST_LIMIT, num_args = 1, response_sz = 1 + * input: args[0] = apic id + * output: args[0] = boost limit value in MHz + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_PROC_HOT, num_args = 0, response_sz = 1 + * output: args[0] = proc hot status + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_SET_XGMI_LINK_WIDTH, num_args = 1, response_sz = 0 + * input: args[0] = min link width[15:8] + max link width[7:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_SET_DF_PSTATE, num_args = 1, response_sz = 0 + * input: args[0] = df pstate[7:0] + */ + {1, 0, HSMP_SET}, + + /* HSMP_SET_AUTO_DF_PSTATE, num_args = 0, response_sz = 0 */ + {0, 0, HSMP_SET}, + + /* + * HSMP_GET_FCLK_MCLK, num_args = 0, response_sz = 2 + * output: args[0] = fclk in MHz, args[1] = mclk in MHz + */ + {0, 2, HSMP_GET}, + + /* + * HSMP_GET_CCLK_THROTTLE_LIMIT, num_args = 0, response_sz = 1 + * output: args[0] = core clock in MHz + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_C0_PERCENT, num_args = 0, response_sz = 1 + * output: args[0] = average c0 residency + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_SET_NBIO_DPM_LEVEL, num_args = 1, response_sz = 0 + * input: args[0] = nbioid[23:16] + max dpm level[15:8] + min dpm level[7:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_GET_NBIO_DPM_LEVEL, num_args = 1, response_sz = 1 + * input: args[0] = nbioid[23:16] + * output: args[0] = max dpm level[15:8] + min dpm level[7:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_DDR_BANDWIDTH, num_args = 0, response_sz = 1 + * output: args[0] = max bw in Gbps[31:20] + utilised bw in Gbps[19:8] + + * bw in percentage[7:0] + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_TEMP_MONITOR, num_args = 0, response_sz = 1 + * output: args[0] = temperature in degree celsius. [15:8] integer part + + * [7:5] fractional part + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_DIMM_TEMP_RANGE, num_args = 1, response_sz = 1 + * input: args[0] = DIMM address[7:0] + * output: args[0] = refresh rate[3] + temperature range[2:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_DIMM_POWER, num_args = 1, response_sz = 1 + * input: args[0] = DIMM address[7:0] + * output: args[0] = DIMM power in mW[31:17] + update rate in ms[16:8] + + * DIMM address[7:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_DIMM_THERMAL, num_args = 1, response_sz = 1 + * input: args[0] = DIMM address[7:0] + * output: args[0] = temperature in degree celsius[31:21] + update rate in ms[16:8] + + * DIMM address[7:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_SOCKET_FREQ_LIMIT, num_args = 0, response_sz = 1 + * output: args[0] = frequency in MHz[31:16] + frequency source[15:0] + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_CCLK_CORE_LIMIT, num_args = 1, response_sz = 1 + * input: args[0] = apic id [31:0] + * output: args[0] = frequency in MHz[31:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_RAILS_SVI, num_args = 0, response_sz = 1 + * output: args[0] = power in mW[31:0] + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_SOCKET_FMAX_FMIN, num_args = 0, response_sz = 1 + * output: args[0] = fmax in MHz[31:16] + fmin in MHz[15:0] + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_IOLINK_BANDWITH, num_args = 1, response_sz = 1 + * input: args[0] = link id[15:8] + bw type[2:0] + * output: args[0] = io bandwidth in Mbps[31:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_GET_XGMI_BANDWITH, num_args = 1, response_sz = 1 + * input: args[0] = link id[15:8] + bw type[2:0] + * output: args[0] = xgmi bandwidth in Mbps[31:0] + */ + {1, 1, HSMP_GET}, + + /* + * HSMP_SET_GMI3_WIDTH, num_args = 1, response_sz = 0 + * input: args[0] = min link width[15:8] + max link width[7:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_SET_PCI_RATE, num_args = 1, response_sz = 1 + * input: args[0] = link rate control value + * output: args[0] = previous link rate control value + */ + {1, 1, HSMP_SET}, + + /* + * HSMP_SET_POWER_MODE, num_args = 1, response_sz = 0 + * input: args[0] = power efficiency mode[2:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_SET_PSTATE_MAX_MIN, num_args = 1, response_sz = 0 + * input: args[0] = min df pstate[15:8] + max df pstate[7:0] + */ + {1, 0, HSMP_SET}, + + /* + * HSMP_GET_METRIC_TABLE_VER, num_args = 0, response_sz = 1 + * output: args[0] = metrics table version + */ + {0, 1, HSMP_GET}, + + /* + * HSMP_GET_METRIC_TABLE, num_args = 0, response_sz = 0 + */ + {0, 0, HSMP_GET}, + + /* + * HSMP_GET_METRIC_TABLE_DRAM_ADDR, num_args = 0, response_sz = 2 + * output: args[0] = lower 32 bits of the address + * output: args[1] = upper 32 bits of the address + */ + {0, 2, HSMP_GET}, +}; + +/* Metrics table (supported only with proto version 6) */ +struct hsmp_metric_table { + __u32 accumulation_counter; + + /* TEMPERATURE */ + __u32 max_socket_temperature; + __u32 max_vr_temperature; + __u32 max_hbm_temperature; + __u64 max_socket_temperature_acc; + __u64 max_vr_temperature_acc; + __u64 max_hbm_temperature_acc; + + /* POWER */ + __u32 socket_power_limit; + __u32 max_socket_power_limit; + __u32 socket_power; + + /* ENERGY */ + __u64 timestamp; + __u64 socket_energy_acc; + __u64 ccd_energy_acc; + __u64 xcd_energy_acc; + __u64 aid_energy_acc; + __u64 hbm_energy_acc; + + /* FREQUENCY */ + __u32 cclk_frequency_limit; + __u32 gfxclk_frequency_limit; + __u32 fclk_frequency; + __u32 uclk_frequency; + __u32 socclk_frequency[4]; + __u32 vclk_frequency[4]; + __u32 dclk_frequency[4]; + __u32 lclk_frequency[4]; + __u64 gfxclk_frequency_acc[8]; + __u64 cclk_frequency_acc[96]; + + /* FREQUENCY RANGE */ + __u32 max_cclk_frequency; + __u32 min_cclk_frequency; + __u32 max_gfxclk_frequency; + __u32 min_gfxclk_frequency; + __u32 fclk_frequency_table[4]; + __u32 uclk_frequency_table[4]; + __u32 socclk_frequency_table[4]; + __u32 vclk_frequency_table[4]; + __u32 dclk_frequency_table[4]; + __u32 lclk_frequency_table[4]; + __u32 max_lclk_dpm_range; + __u32 min_lclk_dpm_range; + + /* XGMI */ + __u32 xgmi_width; + __u32 xgmi_bitrate; + __u64 xgmi_read_bandwidth_acc[8]; + __u64 xgmi_write_bandwidth_acc[8]; + + /* ACTIVITY */ + __u32 socket_c0_residency; + __u32 socket_gfx_busy; + __u32 dram_bandwidth_utilization; + __u64 socket_c0_residency_acc; + __u64 socket_gfx_busy_acc; + __u64 dram_bandwidth_acc; + __u32 max_dram_bandwidth; + __u64 dram_bandwidth_utilization_acc; + __u64 pcie_bandwidth_acc[4]; + + /* THROTTLERS */ + __u32 prochot_residency_acc; + __u32 ppt_residency_acc; + __u32 socket_thm_residency_acc; + __u32 vr_thm_residency_acc; + __u32 hbm_thm_residency_acc; + __u32 spare; + + /* New items at the end to maintain driver compatibility */ + __u32 gfxclk_frequency[8]; +}; + +/* Reset to default packing */ +#pragma pack() + +/* Define unique ioctl command for hsmp msgs using generic _IOWR */ +#define HSMP_BASE_IOCTL_NR 0xF8 +#define HSMP_IOCTL_CMD _IOWR(HSMP_BASE_IOCTL_NR, 0, struct hsmp_message) + +#endif /*_ASM_X86_AMD_HSMP_H_*/ From 1586005a5b10119e84fe6f7756a7455fd09c34d9 Mon Sep 17 00:00:00 2001 From: Bindhiya Kanangot Balakrishnan Date: Thu, 5 Dec 2024 19:34:39 -0600 Subject: [PATCH 08/23] [SWDEV-457845] Error code unification for amd-smi set Earlier amd-smi set was returning different outputs in Linux and Windows. In Linux it was returning ValueError. As part of Error Code unification, corrected this output message. Signed-off-by: Bindhiya Kanangot Balakrishnan Change-Id: Iba9ddd9c5b2bed0456f303e4373f6771c93608be --- amdsmi_cli/amdsmi_commands.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 1632d6a6fc..9c3ec17dbe 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -4318,6 +4318,18 @@ class AMDSMICommands(): core_args_enabled = True break + # Error if no subcommand args are passed + if self.helpers.is_baremetal(): + if not any([args.gpu, args.fan, args.perf_level, args.profile, args.perf_determinism, \ + args.compute_partition, args.memory_partition, args.power_cap,\ + args.soc_pstate, args.xgmi_plpd, args.clk_limit, args.process_isolation]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + else: + if not any([args.clean_local_data]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + # Only allow one device's arguments to be set at a time if not any([gpu_args_enabled, cpu_args_enabled, core_args_enabled]): raise ValueError('No GPU, CPU, or CORE arguments provided, specific arguments are needed') From bd01cfc203c932f5eb364c85bbe8737d2075cb64 Mon Sep 17 00:00:00 2001 From: gabrpham Date: Thu, 14 Nov 2024 14:39:59 -0600 Subject: [PATCH 09/23] Fixed post reset and ring_hang issues Issues include: SWDEV-480250 SWDEV-480255 SWDEV-480248 Known issue: `amd-smi event` has threads taking events from the same device which, in the case of resetting gpus, makes it seem like some gpus have reset mulitple times and other have not reset at all. Signed-off-by: gabrpham Change-Id: Ic7dcc214e0366fc1532ece579d915d34d35d5407 --- amdsmi_cli/amdsmi_commands.py | 9 +- include/amd_smi/amdsmi.h | 3 +- py-interface/amdsmi_interface.py | 2 +- py-interface/amdsmi_wrapper.py | 14 +- rocm_smi/include/rocm_smi/kfd_ioctl.h | 1378 ++++++++++++++++++++++--- rocm_smi/include/rocm_smi/rocm_smi.h | 17 +- rocm_smi/src/rocm_smi.cc | 220 +++- 7 files changed, 1466 insertions(+), 177 deletions(-) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9c3ec17dbe..109a01e0cd 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -5579,7 +5579,14 @@ class AMDSMICommands(): events = listener.read(2000) for event in events: values_dict["event"] = event["event"] - values_dict["message"] = event["message"] + # parse message as it's own dictionary + message_list = event["message"].split(" ") + message_dict = {} + for item in message_list: + if not item == "": + item_list = item.split(": ") + message_dict.update({item_list[0]: item_list[1]}) + values_dict["message"] = message_dict commands.logger.store_output(device, 'values', values_dict) commands.logger.print_output() except amdsmi_exception.AmdSmiLibraryException as e: diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 4db08619b3..e27b255007 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -961,7 +961,8 @@ typedef enum { #define AMDSMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1)) //! Maximum number of characters an event notification message will be -#define MAX_EVENT_NOTIFICATION_MSG_SIZE 64 +// matches kfd message max size +#define MAX_EVENT_NOTIFICATION_MSG_SIZE 96 /** * Event notification data returned from event notification API diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 2c4a6b46ba..5d3db14d34 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -69,7 +69,7 @@ AMDSMI_MAX_CACHE_TYPES = 10 AMDSMI_MAX_NUM_XGMI_PHYSICAL_LINK = 64 AMDSMI_GPU_UUID_SIZE = 38 MAX_AMDSMI_NAME_LENGTH = 64 -MAX_EVENT_NOTIFICATION_MSG_SIZE = 64 +MAX_EVENT_NOTIFICATION_MSG_SIZE = 96 class AmdSmiInitFlags(IntEnum): diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index c65800da99..e1513cdbb7 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -1300,7 +1300,7 @@ struct_amdsmi_evt_notification_data_t._pack_ = 1 # source:False struct_amdsmi_evt_notification_data_t._fields_ = [ ('processor_handle', ctypes.POINTER(None)), ('event', amdsmi_evt_notification_type_t), - ('message', ctypes.c_char * 64), + ('message', ctypes.c_char * 96), ('PADDING_0', ctypes.c_ubyte * 4), ] @@ -1741,6 +1741,7 @@ struct_amdsmi_gpu_xcp_metrics_t._fields_ = [ ('gfx_busy_acc', ctypes.c_uint64 * 8), ] +amdsmi_gpu_xcp_metrics_t = struct_amdsmi_gpu_xcp_metrics_t class struct_amdsmi_gpu_metrics_t(Structure): pass @@ -2869,11 +2870,12 @@ __all__ = \ 'amdsmi_gpu_cache_info_t', 'amdsmi_gpu_control_counter', 'amdsmi_gpu_counter_group_supported', 'amdsmi_gpu_create_counter', 'amdsmi_gpu_destroy_counter', 'amdsmi_gpu_metrics_t', - 'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status', - 'amdsmi_hsmp_freqlimit_src_names', 'amdsmi_hsmp_metrics_table_t', - 'amdsmi_init', 'amdsmi_init_flags_t', - 'amdsmi_init_gpu_event_notification', 'amdsmi_io_bw_encoding_t', - 'amdsmi_io_link_type_t', 'amdsmi_is_P2P_accessible', + 'amdsmi_gpu_read_counter', 'amdsmi_gpu_xcp_metrics_t', + 'amdsmi_gpu_xgmi_error_status', 'amdsmi_hsmp_freqlimit_src_names', + 'amdsmi_hsmp_metrics_table_t', 'amdsmi_init', + 'amdsmi_init_flags_t', 'amdsmi_init_gpu_event_notification', + 'amdsmi_io_bw_encoding_t', 'amdsmi_io_link_type_t', + 'amdsmi_is_P2P_accessible', 'amdsmi_is_gpu_power_management_enabled', 'amdsmi_kfd_info_t', 'amdsmi_link_id_bw_type_t', 'amdsmi_link_metrics_t', 'amdsmi_link_type_t', 'amdsmi_memory_page_status_t', diff --git a/rocm_smi/include/rocm_smi/kfd_ioctl.h b/rocm_smi/include/rocm_smi/kfd_ioctl.h index 99895d2036..2334afb9c0 100644 --- a/rocm_smi/include/rocm_smi/kfd_ioctl.h +++ b/rocm_smi/include/rocm_smi/kfd_ioctl.h @@ -20,28 +20,37 @@ * THE SOFTWARE. */ -#ifndef INCLUDE_ROCM_SMI_KFD_IOCTL_H_ -#define INCLUDE_ROCM_SMI_KFD_IOCTL_H_ +#ifndef KFD_IOCTL_H_INCLUDED +#define KFD_IOCTL_H_INCLUDED -#include +#include #include +/* + * - 1.1 - initial version + * - 1.3 - Add SMI events support + * - 1.4 - Indicate new SRAM EDC bit in device properties + * - 1.5 - Add SVM API + * - 1.6 - Query clear flags in SVM get_attr API + * - 1.7 - Checkpoint Restore (CRIU) API + * - 1.8 - CRIU - Support for SDMA transfers with GTT BOs + * - 1.9 - Add available memory ioctl + * - 1.10 - Add SMI profiler event log + * - 1.11 - Add unified memory for ctx save/restore area + * - 1.12 - Add DMA buf export ioctl + * - 1.13 - Add debugger API + * - 1.14 - Update kfd_event_data + * - 1.15 - Enable managing mappings in compute VMs with GEM_VA ioctl + * - 1.16 - Add contiguous VRAM allocation flag + */ #define KFD_IOCTL_MAJOR_VERSION 1 -#define KFD_IOCTL_MINOR_VERSION 2 -#define KFD_IOCTL_DBG_MAJOR_VERSION 1 -#define KFD_IOCTL_DBG_MINOR_VERSION 0 +#define KFD_IOCTL_MINOR_VERSION 16 struct kfd_ioctl_get_version_args { __u32 major_version; /* from KFD */ __u32 minor_version; /* from KFD */ }; -struct kfd_ioctl_get_available_memory_args { - __u64 available; /* from KFD */ - __u32 gpu_id; /* to KFD */ - __u32 pad; -}; - /* For kfd_ioctl_create_queue_args.queue_type. */ #define KFD_IOC_QUEUE_TYPE_COMPUTE 0x0 #define KFD_IOC_QUEUE_TYPE_SDMA 0x1 @@ -99,17 +108,36 @@ struct kfd_ioctl_get_queue_wave_state_args { __u32 pad; }; -struct kfd_queue_snapshot_entry { - __u64 ring_base_address; - __u64 write_pointer_address; - __u64 read_pointer_address; - __u64 ctx_save_restore_address; - __u32 queue_id; +struct kfd_ioctl_get_available_memory_args { + __u64 available; /* from KFD */ + __u32 gpu_id; /* to KFD */ + __u32 pad; +}; + +struct kfd_dbg_device_info_entry { + __u64 exception_status; + __u64 lds_base; + __u64 lds_limit; + __u64 scratch_base; + __u64 scratch_limit; + __u64 gpuvm_base; + __u64 gpuvm_limit; __u32 gpu_id; - __u32 ring_size; - __u32 queue_type; - __u32 queue_status; - __u32 reserved[19]; + __u32 location_id; + __u32 vendor_id; + __u32 device_id; + __u32 revision_id; + __u32 subsystem_vendor_id; + __u32 subsystem_device_id; + __u32 fw_version; + __u32 gfx_target_version; + __u32 simd_count; + __u32 max_waves_per_simd; + __u32 array_count; + __u32 simd_arrays_per_engine; + __u32 num_xcc; + __u32 capability; + __u32 debug_prop; }; /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */ @@ -208,88 +236,17 @@ struct kfd_ioctl_dbg_wave_control_args { __u32 buf_size_in_bytes; /*including gpu_id and buf_size */ }; -/* mapping event types to API spec */ -#define KFD_DBG_EV_STATUS_TRAP 1 -#define KFD_DBG_EV_STATUS_VMFAULT 2 -#define KFD_DBG_EV_STATUS_SUSPENDED 4 -#define KFD_DBG_EV_STATUS_NEW_QUEUE 8 -#define KFD_DBG_EV_FLAG_CLEAR_STATUS 1 +#define KFD_INVALID_FD 0xffffffff -#define KFD_INVALID_QUEUEID 0xffffffff - -/* KFD_IOC_DBG_TRAP_ENABLE: - * ptr: unused - * data1: 0=disable, 1=enable - * data2: queue ID (for future use) - * data3: return value for fd - */ -#define KFD_IOC_DBG_TRAP_ENABLE 0 - -/* KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE: - * ptr: unused - * data1: override mode: 0=OR, 1=REPLACE - * data2: mask - * data3: unused - */ -#define KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE 1 - -/* KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE: - * ptr: unused - * data1: 0=normal, 1=halt, 2=kill, 3=singlestep, 4=disable - * data2: unused - * data3: unused - */ -#define KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE 2 - -/* KFD_IOC_DBG_TRAP_NODE_SUSPEND: - * ptr: pointer to an array of Queues IDs - * data1: flags - * data2: number of queues - * data3: grace period - */ -#define KFD_IOC_DBG_TRAP_NODE_SUSPEND 3 - -/* KFD_IOC_DBG_TRAP_NODE_RESUME: - * ptr: pointer to an array of Queues IDs - * data1: flags - * data2: number of queues - * data3: unused - */ -#define KFD_IOC_DBG_TRAP_NODE_RESUME 4 - -/* KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT: - * ptr: unused - * data1: queue id (IN/OUT) - * data2: flags (IN) - * data3: suspend[2:2], event type [1:0] (OUT) - */ -#define KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT 5 - -/* KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT: - * ptr: user buffer (IN) - * data1: flags (IN) - * data2: number of queue snapshot entries (IN/OUT) - * data3: unused - */ -#define KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT 6 - -/* KFD_IOC_DBG_TRAP_GET_VERSION: - * prt: unsused - * data1: major version (OUT) - * data2: minor version (OUT) - * data3: unused - */ -#define KFD_IOC_DBG_TRAP_GET_VERSION 7 - - -struct kfd_ioctl_dbg_trap_args { +struct kfd_ioctl_dbg_trap_args_deprecated { + __u64 exception_mask; /* to KFD */ __u64 ptr; /* to KFD -- used for pointer arguments: queue arrays */ __u32 pid; /* to KFD */ - __u32 gpu_id; /* to KFD */ __u32 op; /* to KFD */ __u32 data1; /* to KFD */ __u32 data2; /* to KFD */ __u32 data3; /* to KFD */ + __u32 data4; /* to KFD */ }; /* Matching HSA_EVENTTYPE */ @@ -328,7 +285,8 @@ struct kfd_ioctl_create_event_args { __u32 event_trigger_data; /* from KFD - signal events only */ __u32 event_type; /* to KFD */ __u32 auto_reset; /* to KFD */ - __u32 node_id; /* to KFD - only valid for certain event types */ + __u32 node_id; /* to KFD - only valid for certain + event types */ __u32 event_id; /* from KFD */ __u32 event_slot_index; /* from KFD */ }; @@ -360,11 +318,12 @@ struct kfd_hsa_memory_exception_data { struct kfd_memory_exception_failure failure; __u64 va; __u32 gpu_id; - __u32 ErrorType; // 0 = no RAS error, - // 1 = ECC_SRAM, - // 2 = Link_SYNFLOOD (poison), - // 3 = GPU hang (not attributable to a specific cause), - // other values reserved + __u32 ErrorType; /* 0 = no RAS error, + * 1 = ECC_SRAM, + * 2 = Link_SYNFLOOD (poison), + * 3 = GPU hang (not attributable to a specific cause), + * other values reserved + */ }; /* hw exception data */ @@ -375,21 +334,29 @@ struct kfd_hsa_hw_exception_data { __u32 gpu_id; }; +/* hsa signal event data */ +struct kfd_hsa_signal_event_data { + __u64 last_event_age; /* to and from KFD */ +}; + /* Event data */ struct kfd_event_data { union { + /* From KFD */ struct kfd_hsa_memory_exception_data memory_exception_data; struct kfd_hsa_hw_exception_data hw_exception_data; - }; /* From KFD */ - __u64 kfd_event_data_ext; // pointer to an extension structure - // for future exception types + /* To and From KFD */ + struct kfd_hsa_signal_event_data signal_event_data; + }; + __u64 kfd_event_data_ext; /* pointer to an extension structure + for future exception types */ __u32 event_id; /* to KFD */ __u32 pad; }; struct kfd_ioctl_wait_events_args { - __u64 events_ptr; // pointed to struct - // kfd_event_data array, to KFD + __u64 events_ptr; /* pointed to struct + kfd_event_data array, to KFD */ __u32 num_events; /* to KFD */ __u32 wait_for_all; /* to KFD */ __u32 timeout; /* to KFD */ @@ -450,6 +417,9 @@ struct kfd_ioctl_acquire_vm_args { #define KFD_IOC_ALLOC_MEM_FLAGS_NO_SUBSTITUTE (1 << 28) #define KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM (1 << 27) #define KFD_IOC_ALLOC_MEM_FLAGS_COHERENT (1 << 26) +#define KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED (1 << 25) +#define KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT (1 << 24) +#define KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS (1 << 23) /* Allocate memory for later SVM (shared virtual memory) mapping. * @@ -524,14 +494,15 @@ struct kfd_ioctl_alloc_queue_gws_args { __u32 queue_id; /* to KFD */ __u32 num_gws; /* to KFD */ __u32 first_gws; /* from KFD */ - __u32 pad; /* to KFD */ + __u32 pad; }; struct kfd_ioctl_get_dmabuf_info_args { __u64 size; /* from KFD */ __u64 metadata_ptr; /* to KFD */ - __u32 metadata_size; // to KFD (space allocated by user) - // from KFD (actual metadata size) + __u32 metadata_size; /* to KFD (space allocated by user) + * from KFD (actual metadata size) + */ __u32 gpu_id; /* from KFD */ __u32 flags; /* from KFD (KFD_IOC_ALLOC_MEM_FLAGS) */ __u32 dmabuf_fd; /* to KFD */ @@ -544,6 +515,12 @@ struct kfd_ioctl_import_dmabuf_args { __u32 dmabuf_fd; /* to KFD */ }; +struct kfd_ioctl_export_dmabuf_args { + __u64 handle; /* to KFD */ + __u32 flags; /* to KFD */ + __u32 dmabuf_fd; /* from KFD */ +}; + /* * KFD SMI(System Management Interface) events */ @@ -553,16 +530,203 @@ enum kfd_smi_event { KFD_SMI_EVENT_THERMAL_THROTTLE = 2, KFD_SMI_EVENT_GPU_PRE_RESET = 3, KFD_SMI_EVENT_GPU_POST_RESET = 4, - KFD_SMI_EVENT_RING_HANG = 5, + KFD_SMI_EVENT_MIGRATE_START = 5, + KFD_SMI_EVENT_MIGRATE_END = 6, + KFD_SMI_EVENT_PAGE_FAULT_START = 7, + KFD_SMI_EVENT_PAGE_FAULT_END = 8, + KFD_SMI_EVENT_QUEUE_EVICTION = 9, + KFD_SMI_EVENT_QUEUE_RESTORE = 10, + KFD_SMI_EVENT_UNMAP_FROM_GPU = 11, + + /* + * max event number, as a flag bit to get events from all processes, + * this requires super user permission, otherwise will not be able to + * receive event from any process. Without this flag to receive events + * from same process. + */ + KFD_SMI_EVENT_ALL_PROCESS = 64 +}; + +enum KFD_MIGRATE_TRIGGERS { + KFD_MIGRATE_TRIGGER_PREFETCH, + KFD_MIGRATE_TRIGGER_PAGEFAULT_GPU, + KFD_MIGRATE_TRIGGER_PAGEFAULT_CPU, + KFD_MIGRATE_TRIGGER_TTM_EVICTION +}; + +enum KFD_QUEUE_EVICTION_TRIGGERS { + KFD_QUEUE_EVICTION_TRIGGER_SVM, + KFD_QUEUE_EVICTION_TRIGGER_USERPTR, + KFD_QUEUE_EVICTION_TRIGGER_TTM, + KFD_QUEUE_EVICTION_TRIGGER_SUSPEND, + KFD_QUEUE_EVICTION_CRIU_CHECKPOINT, + KFD_QUEUE_EVICTION_CRIU_RESTORE +}; + +enum KFD_SVM_UNMAP_TRIGGERS { + KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY, + KFD_SVM_UNMAP_TRIGGER_MMU_NOTIFY_MIGRATE, + KFD_SVM_UNMAP_TRIGGER_UNMAP_FROM_CPU }; #define KFD_SMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1)) +#define KFD_SMI_EVENT_MSG_SIZE 96 struct kfd_ioctl_smi_events_args { - __u32 gpuid; /* to KFD */ + __u32 gpuid; /* to KFD */ __u32 anon_fd; /* from KFD */ }; +/** + * kfd_ioctl_spm_op - SPM ioctl operations + * + * @KFD_IOCTL_SPM_OP_ACQUIRE: acquire exclusive access to SPM + * @KFD_IOCTL_SPM_OP_RELEASE: release exclusive access to SPM + * @KFD_IOCTL_SPM_OP_SET_DEST_BUF: set or unset destination buffer for SPM streaming + */ +enum kfd_ioctl_spm_op { + KFD_IOCTL_SPM_OP_ACQUIRE, + KFD_IOCTL_SPM_OP_RELEASE, + KFD_IOCTL_SPM_OP_SET_DEST_BUF +}; + +/** + * kfd_ioctl_spm_args - Arguments for SPM ioctl + * + * @op[in]: specifies the operation to perform + * @gpu_id[in]: GPU ID of the GPU to profile + * @dst_buf[in]: used for the address of the destination buffer + * in @KFD_IOCTL_SPM_SET_DEST_BUFFER + * @buf_size[in]: size of the destination buffer + * @timeout[in/out]: [in]: timeout in milliseconds, [out]: amount of time left + * `in the timeout window + * @bytes_copied[out]: amount of data that was copied to the previous dest_buf + * @has_data_loss: boolean indicating whether data was lost + * (e.g. due to a ring-buffer overflow) + * + * This ioctl performs different functions depending on the @op parameter. + * + * KFD_IOCTL_SPM_OP_ACQUIRE + * ------------------------ + * + * Acquires exclusive access of SPM on the specified @gpu_id for the calling process. + * This must be called before using KFD_IOCTL_SPM_OP_SET_DEST_BUF. + * + * KFD_IOCTL_SPM_OP_RELEASE + * ------------------------ + * + * Releases exclusive access of SPM on the specified @gpu_id for the calling process, + * which allows another process to acquire it in the future. + * + * KFD_IOCTL_SPM_OP_SET_DEST_BUF + * ----------------------------- + * + * If @dst_buf is NULL, the destination buffer address is unset and copying of counters + * is stopped. + * + * If @dst_buf is not NULL, it specifies the pointer to a new destination buffer. + * @buf_size specifies the size of the buffer. + * + * If @timeout is non-0, the call will wait for up to @timeout ms for the previous + * buffer to be filled. If previous buffer to be filled before timeout, the @timeout + * will be updated value with the time remaining. If the timeout is exceeded, the function + * copies any partial data available into the previous user buffer and returns success. + * The amount of valid data in the previous user buffer is indicated by @bytes_copied. + * + * If @timeout is 0, the function immediately replaces the previous destination buffer + * without waiting for the previous buffer to be filled. That means the previous buffer + * may only be partially filled, and @bytes_copied will indicate how much data has been + * copied to it. + * + * If data was lost, e.g. due to a ring buffer overflow, @has_data_loss will be non-0. + * + * Returns negative error code on failure, 0 on success. + */ +struct kfd_ioctl_spm_args { + __u64 dest_buf; + __u32 buf_size; + __u32 op; + __u32 timeout; + __u32 gpu_id; + __u32 bytes_copied; + __u32 has_data_loss; +}; + +/************************************************************************************************** + * CRIU IOCTLs (Checkpoint Restore In Userspace) + * + * When checkpointing a process, the userspace application will perform: + * 1. PROCESS_INFO op to determine current process information. This pauses execution and evicts + * all the queues. + * 2. CHECKPOINT op to checkpoint process contents (BOs, queues, events, svm-ranges) + * 3. UNPAUSE op to un-evict all the queues + * + * When restoring a process, the CRIU userspace application will perform: + * + * 1. RESTORE op to restore process contents + * 2. RESUME op to start the process + * + * Note: Queues are forced into an evicted state after a successful PROCESS_INFO. User + * application needs to perform an UNPAUSE operation after calling PROCESS_INFO. + */ + +enum kfd_criu_op { + KFD_CRIU_OP_PROCESS_INFO, + KFD_CRIU_OP_CHECKPOINT, + KFD_CRIU_OP_UNPAUSE, + KFD_CRIU_OP_RESTORE, + KFD_CRIU_OP_RESUME, +}; + +/** + * kfd_ioctl_criu_args - Arguments perform CRIU operation + * @devices: [in/out] User pointer to memory location for devices information. + * This is an array of type kfd_criu_device_bucket. + * @bos: [in/out] User pointer to memory location for BOs information + * This is an array of type kfd_criu_bo_bucket. + * @priv_data: [in/out] User pointer to memory location for private data + * @priv_data_size: [in/out] Size of priv_data in bytes + * @num_devices: [in/out] Number of GPUs used by process. Size of @devices array. + * @num_bos [in/out] Number of BOs used by process. Size of @bos array. + * @num_objects: [in/out] Number of objects used by process. Objects are opaque to + * user application. + * @pid: [in/out] PID of the process being checkpointed + * @op [in] Type of operation (kfd_criu_op) + * + * Return: 0 on success, -errno on failure + */ +struct kfd_ioctl_criu_args { + __u64 devices; /* Used during ops: CHECKPOINT, RESTORE */ + __u64 bos; /* Used during ops: CHECKPOINT, RESTORE */ + __u64 priv_data; /* Used during ops: CHECKPOINT, RESTORE */ + __u64 priv_data_size; /* Used during ops: PROCESS_INFO, RESTORE */ + __u32 num_devices; /* Used during ops: PROCESS_INFO, RESTORE */ + __u32 num_bos; /* Used during ops: PROCESS_INFO, RESTORE */ + __u32 num_objects; /* Used during ops: PROCESS_INFO, RESTORE */ + __u32 pid; /* Used during ops: PROCESS_INFO, RESUME */ + __u32 op; +}; + +struct kfd_criu_device_bucket { + __u32 user_gpu_id; + __u32 actual_gpu_id; + __u32 drm_fd; + __u32 pad; +}; + +struct kfd_criu_bo_bucket { + __u64 addr; + __u64 size; + __u64 offset; + __u64 restored_offset; /* During restore, updated offset for BO */ + __u32 gpu_id; /* This is the user_gpu_id */ + __u32 alloc_flags; + __u32 dmabuf_fd; + __u32 pad; +}; + +/* CRIU IOCTLs - END */ +/**************************************************************************************************/ /* Register offset inside the remapped mmio page */ enum kfd_mmio_remap { @@ -574,33 +738,19 @@ struct kfd_ioctl_ipc_export_handle_args { __u64 handle; /* to KFD */ __u32 share_handle[4]; /* from KFD */ __u32 gpu_id; /* to KFD */ - __u32 pad; + __u32 flags; /* to KFD */ }; struct kfd_ioctl_ipc_import_handle_args { __u64 handle; /* from KFD */ __u64 va_addr; /* to KFD */ - __u64 mmap_offset; /* from KFD */ + __u64 mmap_offset; /* from KFD */ __u32 share_handle[4]; /* to KFD */ __u32 gpu_id; /* to KFD */ - __u32 pad; + __u32 flags; /* from KFD */ }; -struct kfd_memory_range { - __u64 va_addr; - __u64 size; -}; - -/* flags definitions - * BIT0: 0: read operation, 1: write operation. - * This also identifies if the src or dst array belongs to remote process - */ -#define KFD_CROSS_MEMORY_RW_BIT (1 << 0) -#define KFD_SET_CROSS_MEMORY_READ(flags) (flags &= ~KFD_CROSS_MEMORY_RW_BIT) -#define KFD_SET_CROSS_MEMORY_WRITE(flags) (flags |= KFD_CROSS_MEMORY_RW_BIT) -#define KFD_IS_CROSS_MEMORY_WRITE(flags) (flags & KFD_CROSS_MEMORY_RW_BIT) // NOLINT - -struct kfd_ioctl_cross_memory_copy_args { +struct kfd_ioctl_cross_memory_copy_deprecated_args { /* to KFD: Process ID of the remote process */ __u32 pid; /* to KFD: See above definition */ @@ -617,6 +767,874 @@ struct kfd_ioctl_cross_memory_copy_args { __u64 bytes_copied; }; +/* Guarantee host access to memory */ +#define KFD_IOCTL_SVM_FLAG_HOST_ACCESS 0x00000001 +/* Fine grained coherency between all devices with access */ +#define KFD_IOCTL_SVM_FLAG_COHERENT 0x00000002 +/* Use any GPU in same hive as preferred device */ +#define KFD_IOCTL_SVM_FLAG_HIVE_LOCAL 0x00000004 +/* GPUs only read, allows replication */ +#define KFD_IOCTL_SVM_FLAG_GPU_RO 0x00000008 +/* Allow execution on GPU */ +#define KFD_IOCTL_SVM_FLAG_GPU_EXEC 0x00000010 +/* GPUs mostly read, may allow similar optimizations as RO, but writes fault */ +#define KFD_IOCTL_SVM_FLAG_GPU_READ_MOSTLY 0x00000020 +/* Keep GPU memory mapping always valid as if XNACK is disable */ +#define KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED 0x00000040 +/* Fine grained coherency between all devices using device-scope atomics */ +#define KFD_IOCTL_SVM_FLAG_EXT_COHERENT 0x00000080 + +/** + * kfd_ioctl_svm_op - SVM ioctl operations + * + * @KFD_IOCTL_SVM_OP_SET_ATTR: Modify one or more attributes + * @KFD_IOCTL_SVM_OP_GET_ATTR: Query one or more attributes + */ +enum kfd_ioctl_svm_op { + KFD_IOCTL_SVM_OP_SET_ATTR, + KFD_IOCTL_SVM_OP_GET_ATTR +}; + +/** kfd_ioctl_svm_location - Enum for preferred and prefetch locations + * + * GPU IDs are used to specify GPUs as preferred and prefetch locations. + * Below definitions are used for system memory or for leaving the preferred + * location unspecified. + */ +enum kfd_ioctl_svm_location { + KFD_IOCTL_SVM_LOCATION_SYSMEM = 0, + KFD_IOCTL_SVM_LOCATION_UNDEFINED = 0xffffffff +}; + +/** + * kfd_ioctl_svm_attr_type - SVM attribute types + * + * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: gpuid of the preferred location, 0 for + * system memory + * @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC: gpuid of the prefetch location, 0 for + * system memory. Setting this triggers an + * immediate prefetch (migration). + * @KFD_IOCTL_SVM_ATTR_ACCESS: + * @KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE: + * @KFD_IOCTL_SVM_ATTR_NO_ACCESS: specify memory access for the gpuid given + * by the attribute value + * @KFD_IOCTL_SVM_ATTR_SET_FLAGS: bitmask of flags to set (see + * KFD_IOCTL_SVM_FLAG_...) + * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS: bitmask of flags to clear + * @KFD_IOCTL_SVM_ATTR_GRANULARITY: migration granularity + * (log2 num pages) + */ +enum kfd_ioctl_svm_attr_type { + KFD_IOCTL_SVM_ATTR_PREFERRED_LOC, + KFD_IOCTL_SVM_ATTR_PREFETCH_LOC, + KFD_IOCTL_SVM_ATTR_ACCESS, + KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE, + KFD_IOCTL_SVM_ATTR_NO_ACCESS, + KFD_IOCTL_SVM_ATTR_SET_FLAGS, + KFD_IOCTL_SVM_ATTR_CLR_FLAGS, + KFD_IOCTL_SVM_ATTR_GRANULARITY +}; + +/** + * kfd_ioctl_svm_attribute - Attributes as pairs of type and value + * + * The meaning of the @value depends on the attribute type. + * + * @type: attribute type (see enum @kfd_ioctl_svm_attr_type) + * @value: attribute value + */ +struct kfd_ioctl_svm_attribute { + __u32 type; + __u32 value; +}; + +/** + * kfd_ioctl_svm_args - Arguments for SVM ioctl + * + * @op specifies the operation to perform (see enum + * @kfd_ioctl_svm_op). @start_addr and @size are common for all + * operations. + * + * A variable number of attributes can be given in @attrs. + * @nattr specifies the number of attributes. New attributes can be + * added in the future without breaking the ABI. If unknown attributes + * are given, the function returns -EINVAL. + * + * @KFD_IOCTL_SVM_OP_SET_ATTR sets attributes for a virtual address + * range. It may overlap existing virtual address ranges. If it does, + * the existing ranges will be split such that the attribute changes + * only apply to the specified address range. + * + * @KFD_IOCTL_SVM_OP_GET_ATTR returns the intersection of attributes + * over all memory in the given range and returns the result as the + * attribute value. If different pages have different preferred or + * prefetch locations, 0xffffffff will be returned for + * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC or + * @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC resepctively. For + * @KFD_IOCTL_SVM_ATTR_SET_FLAGS, flags of all pages will be + * aggregated by bitwise AND. That means, a flag will be set in the + * output, if that flag is set for all pages in the range. For + * @KFD_IOCTL_SVM_ATTR_CLR_FLAGS, flags of all pages will be + * aggregated by bitwise NOR. That means, a flag will be set in the + * output, if that flag is clear for all pages in the range. + * The minimum migration granularity throughout the range will be + * returned for @KFD_IOCTL_SVM_ATTR_GRANULARITY. + * + * Querying of accessibility attributes works by initializing the + * attribute type to @KFD_IOCTL_SVM_ATTR_ACCESS and the value to the + * GPUID being queried. Multiple attributes can be given to allow + * querying multiple GPUIDs. The ioctl function overwrites the + * attribute type to indicate the access for the specified GPU. + */ +struct kfd_ioctl_svm_args { + __u64 start_addr; + __u64 size; + __u32 op; + __u32 nattr; + /* Variable length array of attributes */ + struct kfd_ioctl_svm_attribute attrs[]; +}; + +/** + * kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode + * + * @xnack_enabled: [in/out] Whether to enable XNACK mode for this process + * + * @xnack_enabled indicates whether recoverable page faults should be + * enabled for the current process. 0 means disabled, positive means + * enabled, negative means leave unchanged. If enabled, virtual address + * translations on GFXv9 and later AMD GPUs can return XNACK and retry + * the access until a valid PTE is available. This is used to implement + * device page faults. + * + * On output, @xnack_enabled returns the (new) current mode (0 or + * positive). Therefore, a negative input value can be used to query + * the current mode without changing it. + * + * The XNACK mode fundamentally changes the way SVM managed memory works + * in the driver, with subtle effects on application performance and + * functionality. + * + * Enabling XNACK mode requires shader programs to be compiled + * differently. Furthermore, not all GPUs support changing the mode + * per-process. Therefore changing the mode is only allowed while no + * user mode queues exist in the process. This ensure that no shader + * code is running that may be compiled for the wrong mode. And GPUs + * that cannot change to the requested mode will prevent the XNACK + * mode from occurring. All GPUs used by the process must be in the + * same XNACK mode. + * + * GFXv8 or older GPUs do not support 48 bit virtual addresses or SVM. + * Therefore those GPUs are not considered for the XNACK mode switch. + * + * Return: 0 on success, -errno on failure + */ +struct kfd_ioctl_set_xnack_mode_args { + __s32 xnack_enabled; +}; + +/* Wave launch override modes */ +enum kfd_dbg_trap_override_mode { + KFD_DBG_TRAP_OVERRIDE_OR = 0, + KFD_DBG_TRAP_OVERRIDE_REPLACE = 1 +}; + +/* Wave launch overrides */ +enum kfd_dbg_trap_mask { + KFD_DBG_TRAP_MASK_FP_INVALID = 1, + KFD_DBG_TRAP_MASK_FP_INPUT_DENORMAL = 2, + KFD_DBG_TRAP_MASK_FP_DIVIDE_BY_ZERO = 4, + KFD_DBG_TRAP_MASK_FP_OVERFLOW = 8, + KFD_DBG_TRAP_MASK_FP_UNDERFLOW = 16, + KFD_DBG_TRAP_MASK_FP_INEXACT = 32, + KFD_DBG_TRAP_MASK_INT_DIVIDE_BY_ZERO = 64, + KFD_DBG_TRAP_MASK_DBG_ADDRESS_WATCH = 128, + KFD_DBG_TRAP_MASK_DBG_MEMORY_VIOLATION = 256, + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_START = (1 << 30), + KFD_DBG_TRAP_MASK_TRAP_ON_WAVE_END = (1 << 31) +}; + +/* Wave launch modes */ +enum kfd_dbg_trap_wave_launch_mode { + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_NORMAL = 0, + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_HALT = 1, + KFD_DBG_TRAP_WAVE_LAUNCH_MODE_DEBUG = 3 +}; + +/* Address watch modes */ +enum kfd_dbg_trap_address_watch_mode { + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_READ = 0, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_NONREAD = 1, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ATOMIC = 2, + KFD_DBG_TRAP_ADDRESS_WATCH_MODE_ALL = 3 +}; + +/* Additional wave settings */ +enum kfd_dbg_trap_flags { + KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1, + KFD_DBG_TRAP_FLAG_SINGLE_ALU_OP = 2, +}; + +/* Trap exceptions */ +enum kfd_dbg_trap_exception_code { + EC_NONE = 0, + /* per queue */ + EC_QUEUE_WAVE_ABORT = 1, + EC_QUEUE_WAVE_TRAP = 2, + EC_QUEUE_WAVE_MATH_ERROR = 3, + EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION = 4, + EC_QUEUE_WAVE_MEMORY_VIOLATION = 5, + EC_QUEUE_WAVE_APERTURE_VIOLATION = 6, + EC_QUEUE_PACKET_DISPATCH_DIM_INVALID = 16, + EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID = 17, + EC_QUEUE_PACKET_DISPATCH_CODE_INVALID = 18, + EC_QUEUE_PACKET_RESERVED = 19, + EC_QUEUE_PACKET_UNSUPPORTED = 20, + EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID = 21, + EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID = 22, + EC_QUEUE_PACKET_VENDOR_UNSUPPORTED = 23, + EC_QUEUE_PREEMPTION_ERROR = 30, + EC_QUEUE_NEW = 31, + /* per device */ + EC_DEVICE_QUEUE_DELETE = 32, + EC_DEVICE_MEMORY_VIOLATION = 33, + EC_DEVICE_RAS_ERROR = 34, + EC_DEVICE_FATAL_HALT = 35, + EC_DEVICE_NEW = 36, + /* per process */ + EC_PROCESS_RUNTIME = 48, + EC_PROCESS_DEVICE_REMOVE = 49, + EC_MAX +}; + +/* Mask generated by ecode in kfd_dbg_trap_exception_code */ +#define KFD_EC_MASK(ecode) (1ULL << (ecode - 1)) + +/* Masks for exception code type checks below */ +#define KFD_EC_MASK_QUEUE (KFD_EC_MASK(EC_QUEUE_WAVE_ABORT) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_TRAP) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_MATH_ERROR) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_ILLEGAL_INSTRUCTION) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_MEMORY_VIOLATION) | \ + KFD_EC_MASK(EC_QUEUE_WAVE_APERTURE_VIOLATION) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED) | \ + KFD_EC_MASK(EC_QUEUE_PREEMPTION_ERROR) | \ + KFD_EC_MASK(EC_QUEUE_NEW)) +#define KFD_EC_MASK_DEVICE (KFD_EC_MASK(EC_DEVICE_QUEUE_DELETE) | \ + KFD_EC_MASK(EC_DEVICE_RAS_ERROR) | \ + KFD_EC_MASK(EC_DEVICE_FATAL_HALT) | \ + KFD_EC_MASK(EC_DEVICE_MEMORY_VIOLATION) | \ + KFD_EC_MASK(EC_DEVICE_NEW)) +#define KFD_EC_MASK_PROCESS (KFD_EC_MASK(EC_PROCESS_RUNTIME) | \ + KFD_EC_MASK(EC_PROCESS_DEVICE_REMOVE)) +#define KFD_EC_MASK_PACKET (KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_DIM_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_GROUP_SEGMENT_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_CODE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_RESERVED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_UNSUPPORTED) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_WORK_GROUP_SIZE_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_DISPATCH_REGISTER_INVALID) | \ + KFD_EC_MASK(EC_QUEUE_PACKET_VENDOR_UNSUPPORTED)) + +/* Checks for exception code types for KFD search */ +#define KFD_DBG_EC_IS_VALID(ecode) (ecode > EC_NONE && ecode < EC_MAX) +#define KFD_DBG_EC_TYPE_IS_QUEUE(ecode) \ + (KFD_DBG_EC_IS_VALID(ecode) && !!(KFD_EC_MASK(ecode) & KFD_EC_MASK_QUEUE)) +#define KFD_DBG_EC_TYPE_IS_DEVICE(ecode) \ + (KFD_DBG_EC_IS_VALID(ecode) && !!(KFD_EC_MASK(ecode) & KFD_EC_MASK_DEVICE)) +#define KFD_DBG_EC_TYPE_IS_PROCESS(ecode) \ + (KFD_DBG_EC_IS_VALID(ecode) && !!(KFD_EC_MASK(ecode) & KFD_EC_MASK_PROCESS)) +#define KFD_DBG_EC_TYPE_IS_PACKET(ecode) \ + (KFD_DBG_EC_IS_VALID(ecode) && !!(KFD_EC_MASK(ecode) & KFD_EC_MASK_PACKET)) + + +/* Runtime enable states */ +enum kfd_dbg_runtime_state { + DEBUG_RUNTIME_STATE_DISABLED = 0, + DEBUG_RUNTIME_STATE_ENABLED = 1, + DEBUG_RUNTIME_STATE_ENABLED_BUSY = 2, + DEBUG_RUNTIME_STATE_ENABLED_ERROR = 3 +}; + +/* Runtime enable status */ +struct kfd_runtime_info { + __u64 r_debug; + __u32 runtime_state; + __u32 ttmp_setup; +}; + +/* Enable modes for runtime enable */ +#define KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK 1 +#define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK 2 + +/** + * kfd_ioctl_runtime_enable_args - Arguments for runtime enable + * + * Coordinates debug exception signalling and debug device enablement with runtime. + * + * @r_debug - pointer to user struct for sharing information between ROCr and the debuggger + * @mode_mask - mask to set mode + * KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK - enable runtime for debugging, otherwise disable + * KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK - enable trap temporary setup (ignore on disable) + * @capabilities_mask - mask to notify runtime on what KFD supports + * + * Return - 0 on SUCCESS. + * - EBUSY if runtime enable call already pending. + * - EEXIST if user queues already active prior to call. + * If process is debug enabled, runtime enable will enable debug devices and + * wait for debugger process to send runtime exception EC_PROCESS_RUNTIME + * to unblock - see kfd_ioctl_dbg_trap_args. + * + */ +struct kfd_ioctl_runtime_enable_args { + __u64 r_debug; + __u32 mode_mask; + __u32 capabilities_mask; +}; + +/* Queue information */ +struct kfd_queue_snapshot_entry { + __u64 exception_status; + __u64 ring_base_address; + __u64 write_pointer_address; + __u64 read_pointer_address; + __u64 ctx_save_restore_address; + __u32 queue_id; + __u32 gpu_id; + __u32 ring_size; + __u32 queue_type; + __u32 ctx_save_restore_area_size; + __u32 reserved; +}; + +/* Queue status return for suspend/resume */ +#define KFD_DBG_QUEUE_ERROR_BIT 30 +#define KFD_DBG_QUEUE_INVALID_BIT 31 +#define KFD_DBG_QUEUE_ERROR_MASK (1 << KFD_DBG_QUEUE_ERROR_BIT) +#define KFD_DBG_QUEUE_INVALID_MASK (1 << KFD_DBG_QUEUE_INVALID_BIT) + +/* Context save area header information */ +struct kfd_context_save_area_header { + struct { + __u32 control_stack_offset; + __u32 control_stack_size; + __u32 wave_state_offset; + __u32 wave_state_size; + } wave_state; + __u32 debug_offset; + __u32 debug_size; + __u64 err_payload_addr; + __u32 err_event_id; + __u32 reserved1; +}; + +/* + * Debug operations + * + * For specifics on usage and return values, see documentation per operation + * below. Otherwise, generic error returns apply: + * - ESRCH if the process to debug does not exist. + * + * - EINVAL (with KFD_IOC_DBG_TRAP_ENABLE exempt) if operation + * KFD_IOC_DBG_TRAP_ENABLE has not succeeded prior. + * Also returns this error if GPU hardware scheduling is not supported. + * + * - EPERM (with KFD_IOC_DBG_TRAP_DISABLE exempt) if target process is not + * PTRACE_ATTACHED. KFD_IOC_DBG_TRAP_DISABLE is exempt to allow + * clean up of debug mode as long as process is debug enabled. + * + * - EACCES if any DBG_HW_OP (debug hardware operation) is requested when + * AMDKFD_IOC_RUNTIME_ENABLE has not succeeded prior. + * + * - ENODEV if any GPU does not support debugging on a DBG_HW_OP call. + * + * - Other errors may be returned when a DBG_HW_OP occurs while the GPU + * is in a fatal state. + * + */ +enum kfd_dbg_trap_operations { + KFD_IOC_DBG_TRAP_ENABLE = 0, + KFD_IOC_DBG_TRAP_DISABLE = 1, + KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT = 2, + KFD_IOC_DBG_TRAP_SET_EXCEPTIONS_ENABLED = 3, + KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE = 4, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE = 5, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SUSPEND_QUEUES = 6, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_RESUME_QUEUES = 7, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH = 8, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH = 9, /* DBG_HW_OP */ + KFD_IOC_DBG_TRAP_SET_FLAGS = 10, + KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT = 11, + KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO = 12, + KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT = 13, + KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT = 14 +}; + +/** + * kfd_ioctl_dbg_trap_enable_args + * + * Arguments for KFD_IOC_DBG_TRAP_ENABLE. + * + * Enables debug session for target process. Call @op KFD_IOC_DBG_TRAP_DISABLE in + * kfd_ioctl_dbg_trap_args to disable debug session. + * + * @exception_mask (IN) - exceptions to raise to the debugger + * @rinfo_ptr (IN) - pointer to runtime info buffer (see kfd_runtime_info) + * @rinfo_size (IN/OUT) - size of runtime info buffer in bytes + * @dbg_fd (IN) - fd the KFD will nofify the debugger with of raised + * exceptions set in exception_mask. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies KFD saved kfd_runtime_info to @rinfo_ptr on enable. + * Size of kfd_runtime saved by the KFD returned to @rinfo_size. + * - EBADF if KFD cannot get a reference to dbg_fd. + * - EFAULT if KFD cannot copy runtime info to rinfo_ptr. + * - EINVAL if target process is already debug enabled. + * + */ +struct kfd_ioctl_dbg_trap_enable_args { + __u64 exception_mask; + __u64 rinfo_ptr; + __u32 rinfo_size; + __u32 dbg_fd; +}; + +/** + * kfd_ioctl_dbg_trap_send_runtime_event_args + * + * + * Arguments for KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT. + * Raises exceptions to runtime. + * + * @exception_mask (IN) - exceptions to raise to runtime + * @gpu_id (IN) - target device id + * @queue_id (IN) - target queue id + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - ENODEV if gpu_id not found. + * If exception_mask contains EC_PROCESS_RUNTIME, unblocks pending + * AMDKFD_IOC_RUNTIME_ENABLE call - see kfd_ioctl_runtime_enable_args. + * All other exceptions are raised to runtime through err_payload_addr. + * See kfd_context_save_area_header. + */ +struct kfd_ioctl_dbg_trap_send_runtime_event_args { + __u64 exception_mask; + __u32 gpu_id; + __u32 queue_id; +}; + +/** + * kfd_ioctl_dbg_trap_set_exceptions_enabled_args + * + * Arguments for KFD_IOC_SET_EXCEPTIONS_ENABLED + * Set new exceptions to be raised to the debugger. + * + * @exception_mask (IN) - new exceptions to raise the debugger + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + */ +struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args { + __u64 exception_mask; +}; + +/** + * kfd_ioctl_dbg_trap_set_wave_launch_override_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE + * Enable HW exceptions to raise trap. + * + * @override_mode (IN) - see kfd_dbg_trap_override_mode + * @enable_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * IN is the override modes requested to be enabled. + * OUT is referenced in Return below. + * @support_request_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * IN is the override modes requested for support check. + * OUT is referenced in Return below. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Previous enablement is returned in @enable_mask. + * Actual override support is returned in @support_request_mask. + * - EINVAL if override mode is not supported. + * - EACCES if trap support requested is not actually supported. + * i.e. enable_mask (IN) is not a subset of support_request_mask (OUT). + * Otherwise it is considered a generic error (see kfd_dbg_trap_operations). + */ +struct kfd_ioctl_dbg_trap_set_wave_launch_override_args { + __u32 override_mode; + __u32 enable_mask; + __u32 support_request_mask; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_set_wave_launch_mode_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE + * Set wave launch mode. + * + * @mode (IN) - see kfd_dbg_trap_wave_launch_mode + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + */ +struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args { + __u32 launch_mode; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_suspend_queues_ags + * + * Arguments for KFD_IOC_DBG_TRAP_SUSPEND_QUEUES + * Suspend queues. + * + * @exception_mask (IN) - raised exceptions to clear + * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * to suspend + * @num_queues (IN) - number of queues to suspend in @queue_array_ptr + * @grace_period (IN) - wave time allowance before preemption + * per 1K GPU clock cycle unit + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Destruction of a suspended queue is blocked until the queue is + * resumed. This allows the debugger to access queue information and + * the its context save area without running into a race condition on + * queue destruction. + * Automatically copies per queue context save area header information + * into the save area base + * (see kfd_queue_snapshot_entry and kfd_context_save_area_header). + * + * Return - Number of queues suspended on SUCCESS. + * . KFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK masked + * for each queue id in @queue_array_ptr array reports unsuccessful + * suspend reason. + * KFD_DBG_QUEUE_ERROR_MASK = HW failure. + * KFD_DBG_QUEUE_INVALID_MASK = queue does not exist, is new or + * is being destroyed. + */ +struct kfd_ioctl_dbg_trap_suspend_queues_args { + __u64 exception_mask; + __u64 queue_array_ptr; + __u32 num_queues; + __u32 grace_period; +}; + +/** + * kfd_ioctl_dbg_trap_resume_queues_args + * + * Arguments for KFD_IOC_DBG_TRAP_RESUME_QUEUES + * Resume queues. + * + * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * to resume + * @num_queues (IN) - number of queues to resume in @queue_array_ptr + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - Number of queues resumed on SUCCESS. + * KFD_DBG_QUEUE_ERROR_MASK and KFD_DBG_QUEUE_INVALID_MASK mask + * for each queue id in @queue_array_ptr array reports unsuccessful + * resume reason. + * KFD_DBG_QUEUE_ERROR_MASK = HW failure. + * KFD_DBG_QUEUE_INVALID_MASK = queue does not exist. + */ +struct kfd_ioctl_dbg_trap_resume_queues_args { + __u64 queue_array_ptr; + __u32 num_queues; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_set_node_address_watch_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH + * Sets address watch for device. + * + * @address (IN) - watch address to set + * @mode (IN) - see kfd_dbg_trap_address_watch_mode + * @mask (IN) - watch address mask + * @gpu_id (IN) - target gpu to set watch point + * @id (OUT) - watch id allocated + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Allocated watch ID returned to @id. + * - ENODEV if gpu_id not found. + * - ENOMEM if watch IDs can be allocated + */ +struct kfd_ioctl_dbg_trap_set_node_address_watch_args { + __u64 address; + __u32 mode; + __u32 mask; + __u32 gpu_id; + __u32 id; +}; + +/** + * kfd_ioctl_dbg_trap_clear_node_address_watch_args + * + * Arguments for KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH + * Clear address watch for device. + * + * @gpu_id (IN) - target device to clear watch point + * @id (IN) - allocated watch id to clear + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - ENODEV if gpu_id not found. + * - EINVAL if watch ID has not been allocated. + */ +struct kfd_ioctl_dbg_trap_clear_node_address_watch_args { + __u32 gpu_id; + __u32 id; +}; + +/** + * kfd_ioctl_dbg_trap_set_flags_args + * + * Arguments for KFD_IOC_DBG_TRAP_SET_FLAGS + * Sets flags for wave behaviour. + * + * @flags (IN/OUT) - IN = flags to enable, OUT = flags previously enabled + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * - EACCESS if any debug device does not allow flag options. + */ +struct kfd_ioctl_dbg_trap_set_flags_args { + __u32 flags; + __u32 pad; +}; + +/** + * kfd_ioctl_dbg_trap_query_debug_event_args + * + * Arguments for KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT + * + * Find one or more raised exceptions. This function can return multiple + * exceptions from a single queue or a single device with one call. To find + * all raised exceptions, this function must be called repeatedly until it + * returns -EAGAIN. Returned exceptions can optionally be cleared by + * setting the corresponding bit in the @exception_mask input parameter. + * However, clearing an exception prevents retrieving further information + * about it with KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO. + * + * @exception_mask (IN/OUT) - exception to clear (IN) and raised (OUT) + * @gpu_id (OUT) - gpu id of exceptions raised + * @queue_id (OUT) - queue id of exceptions raised + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on raised exception found + * Raised exceptions found are returned in @exception mask + * with reported source id returned in @gpu_id or @queue_id. + * - EAGAIN if no raised exception has been found + */ +struct kfd_ioctl_dbg_trap_query_debug_event_args { + __u64 exception_mask; + __u32 gpu_id; + __u32 queue_id; +}; + +/** + * kfd_ioctl_dbg_trap_query_exception_info_args + * + * Arguments KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO + * Get additional info on raised exception. + * + * @info_ptr (IN) - pointer to exception info buffer to copy to + * @info_size (IN/OUT) - exception info buffer size (bytes) + * @source_id (IN) - target gpu or queue id + * @exception_code (IN) - target exception + * @clear_exception (IN) - clear raised @exception_code exception + * (0 = false, 1 = true) + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * If @exception_code is EC_DEVICE_MEMORY_VIOLATION, copy @info_size(OUT) + * bytes of memory exception data to @info_ptr. + * If @exception_code is EC_PROCESS_RUNTIME, copy saved + * kfd_runtime_info to @info_ptr. + * Actual required @info_ptr size (bytes) is returned in @info_size. + */ +struct kfd_ioctl_dbg_trap_query_exception_info_args { + __u64 info_ptr; + __u32 info_size; + __u32 source_id; + __u32 exception_code; + __u32 clear_exception; +}; + +/** + * kfd_ioctl_dbg_trap_get_queue_snapshot_args + * + * Arguments KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT + * Get queue information. + * + * @exception_mask (IN) - exceptions raised to clear + * @snapshot_buf_ptr (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry) + * @num_queues (IN/OUT) - number of queue snapshot entries + * The debugger specifies the size of the array allocated in @num_queues. + * KFD returns the number of queues that actually existed. If this is + * larger than the size specified by the debugger, KFD will not overflow + * the array allocated by the debugger. + * + * @entry_size (IN/OUT) - size per entry in bytes + * The debugger specifies sizeof(struct kfd_queue_snapshot_entry) in + * @entry_size. KFD returns the number of bytes actually populated per + * entry. The debugger should use the KFD_IOCTL_MINOR_VERSION to determine, + * which fields in struct kfd_queue_snapshot_entry are valid. This allows + * growing the ABI in a backwards compatible manner. + * Note that entry_size(IN) should still be used to stride the snapshot buffer in the + * event that it's larger than actual kfd_queue_snapshot_entry. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies @num_queues(IN) queue snapshot entries of size @entry_size(IN) + * into @snapshot_buf_ptr if @num_queues(IN) > 0. + * Otherwise return @num_queues(OUT) queue snapshot entries that exist. + */ +struct kfd_ioctl_dbg_trap_queue_snapshot_args { + __u64 exception_mask; + __u64 snapshot_buf_ptr; + __u32 num_queues; + __u32 entry_size; +}; + +/** + * kfd_ioctl_dbg_trap_get_device_snapshot_args + * + * Arguments for KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT + * Get device information. + * + * @exception_mask (IN) - exceptions raised to clear + * @snapshot_buf_ptr (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry) + * @num_devices (IN/OUT) - number of debug devices to snapshot + * The debugger specifies the size of the array allocated in @num_devices. + * KFD returns the number of devices that actually existed. If this is + * larger than the size specified by the debugger, KFD will not overflow + * the array allocated by the debugger. + * + * @entry_size (IN/OUT) - size per entry in bytes + * The debugger specifies sizeof(struct kfd_dbg_device_info_entry) in + * @entry_size. KFD returns the number of bytes actually populated. The + * debugger should use KFD_IOCTL_MINOR_VERSION to determine, which fields + * in struct kfd_dbg_device_info_entry are valid. This allows growing the + * ABI in a backwards compatible manner. + * Note that entry_size(IN) should still be used to stride the snapshot buffer in the + * event that it's larger than actual kfd_dbg_device_info_entry. + * + * Generic errors apply (see kfd_dbg_trap_operations). + * Return - 0 on SUCCESS. + * Copies @num_devices(IN) device snapshot entries of size @entry_size(IN) + * into @snapshot_buf_ptr if @num_devices(IN) > 0. + * Otherwise return @num_devices(OUT) queue snapshot entries that exist. + */ +struct kfd_ioctl_dbg_trap_device_snapshot_args { + __u64 exception_mask; + __u64 snapshot_buf_ptr; + __u32 num_devices; + __u32 entry_size; +}; + +/** + * kfd_ioctl_dbg_trap_args + * + * Arguments to debug target process. + * + * @pid - target process to debug + * @op - debug operation (see kfd_dbg_trap_operations) + * + * @op determines which union struct args to use. + * Refer to kern docs for each kfd_ioctl_dbg_trap_*_args struct. + */ +struct kfd_ioctl_dbg_trap_args { + __u32 pid; + __u32 op; + + union { + struct kfd_ioctl_dbg_trap_enable_args enable; + struct kfd_ioctl_dbg_trap_send_runtime_event_args send_runtime_event; + struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args set_exceptions_enabled; + struct kfd_ioctl_dbg_trap_set_wave_launch_override_args launch_override; + struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args launch_mode; + struct kfd_ioctl_dbg_trap_suspend_queues_args suspend_queues; + struct kfd_ioctl_dbg_trap_resume_queues_args resume_queues; + struct kfd_ioctl_dbg_trap_set_node_address_watch_args set_node_address_watch; + struct kfd_ioctl_dbg_trap_clear_node_address_watch_args clear_node_address_watch; + struct kfd_ioctl_dbg_trap_set_flags_args set_flags; + struct kfd_ioctl_dbg_trap_query_debug_event_args query_debug_event; + struct kfd_ioctl_dbg_trap_query_exception_info_args query_exception_info; + struct kfd_ioctl_dbg_trap_queue_snapshot_args queue_snapshot; + struct kfd_ioctl_dbg_trap_device_snapshot_args device_snapshot; + }; +}; + +/** + * kfd_ioctl_pc_sample_op - PC Sampling ioctl operations + * + * @KFD_IOCTL_PCS_OP_QUERY_CAPABILITIES: Query device PC Sampling capabilities + * @KFD_IOCTL_PCS_OP_CREATE: Register this process with a per-device PC sampler instance + * @KFD_IOCTL_PCS_OP_DESTROY: Unregister from a previously registered PC sampler instance + * @KFD_IOCTL_PCS_OP_START: Process begins taking samples from a previously registered PC sampler instance + * @KFD_IOCTL_PCS_OP_STOP: Process stops taking samples from a previously registered PC sampler instance + */ +enum kfd_ioctl_pc_sample_op { + KFD_IOCTL_PCS_OP_QUERY_CAPABILITIES, + KFD_IOCTL_PCS_OP_CREATE, + KFD_IOCTL_PCS_OP_DESTROY, + KFD_IOCTL_PCS_OP_START, + KFD_IOCTL_PCS_OP_STOP, +}; + +/* Values have to be a power of 2*/ +#define KFD_IOCTL_PCS_FLAG_POWER_OF_2 0x00000001 + +enum kfd_ioctl_pc_sample_method { + KFD_IOCTL_PCS_METHOD_HOSTTRAP = 1, + KFD_IOCTL_PCS_METHOD_STOCHASTIC, +}; + +enum kfd_ioctl_pc_sample_type { + KFD_IOCTL_PCS_TYPE_TIME_US, + KFD_IOCTL_PCS_TYPE_CLOCK_CYCLES, + KFD_IOCTL_PCS_TYPE_INSTRUCTIONS +}; + +struct kfd_pc_sample_info { + __u64 interval; /* [IN] if PCS_TYPE_INTERVAL_US: sample interval in us + * if PCS_TYPE_CLOCK_CYCLES: sample interval in graphics core clk cycles + * if PCS_TYPE_INSTRUCTIONS: sample interval in instructions issued by + * graphics compute units + */ + __u64 interval_min; /* [OUT] */ + __u64 interval_max; /* [OUT] */ + __u64 flags; /* [OUT] indicate potential restrictions e.g FLAG_POWER_OF_2 */ + __u32 method; /* [IN/OUT] kfd_ioctl_pc_sample_method */ + __u32 type; /* [IN/OUT] kfd_ioctl_pc_sample_type */ +}; + +#define KFD_IOCTL_PCS_QUERY_TYPE_FULL (1 << 0) /* If not set, return current */ + +struct kfd_ioctl_pc_sample_args { + __u64 sample_info_ptr; /* array of kfd_pc_sample_info */ + __u32 num_sample_info; + __u32 op; /* kfd_ioctl_pc_sample_op */ + __u32 gpu_id; + __u32 trace_id; + __u32 flags; /* kfd_ioctl_pcs_query flags */ + __u32 version; +}; + #define AMDKFD_IOCTL_BASE 'K' #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr) #define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type) @@ -659,45 +1677,44 @@ struct kfd_ioctl_cross_memory_copy_args { #define AMDKFD_IOC_WAIT_EVENTS \ AMDKFD_IOWR(0x0C, struct kfd_ioctl_wait_events_args) -#define AMDKFD_IOC_DBG_REGISTER \ +#define AMDKFD_IOC_DBG_REGISTER_DEPRECATED \ AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args) -#define AMDKFD_IOC_DBG_UNREGISTER \ +#define AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED \ AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args) -#define AMDKFD_IOC_DBG_ADDRESS_WATCH \ +#define AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED \ AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args) -#define AMDKFD_IOC_DBG_WAVE_CONTROL \ +#define AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED \ AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args) #define AMDKFD_IOC_SET_SCRATCH_BACKING_VA \ AMDKFD_IOWR(0x11, struct kfd_ioctl_set_scratch_backing_va_args) -#define AMDKFD_IOC_GET_TILE_CONFIG \ +#define AMDKFD_IOC_GET_TILE_CONFIG \ AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args) #define AMDKFD_IOC_SET_TRAP_HANDLER \ AMDKFD_IOW(0x13, struct kfd_ioctl_set_trap_handler_args) -#define AMDKFD_IOC_GET_PROCESS_APERTURES_NEW \ - AMDKFD_IOWR(0x14, \ - struct kfd_ioctl_get_process_apertures_new_args) +#define AMDKFD_IOC_DBG_REGISTER_DEPRECATED \ + AMDKFD_IOW(0x0D, struct kfd_ioctl_dbg_register_args) -#define AMDKFD_IOC_ACQUIRE_VM \ - AMDKFD_IOW(0x15, struct kfd_ioctl_acquire_vm_args) +#define AMDKFD_IOC_DBG_UNREGISTER_DEPRECATED \ + AMDKFD_IOW(0x0E, struct kfd_ioctl_dbg_unregister_args) -#define AMDKFD_IOC_ALLOC_MEMORY_OF_GPU \ - AMDKFD_IOWR(0x16, struct kfd_ioctl_alloc_memory_of_gpu_args) +#define AMDKFD_IOC_DBG_ADDRESS_WATCH_DEPRECATED \ + AMDKFD_IOW(0x0F, struct kfd_ioctl_dbg_address_watch_args) -#define AMDKFD_IOC_FREE_MEMORY_OF_GPU \ - AMDKFD_IOW(0x17, struct kfd_ioctl_free_memory_of_gpu_args) +#define AMDKFD_IOC_DBG_WAVE_CONTROL_DEPRECATED \ + AMDKFD_IOW(0x10, struct kfd_ioctl_dbg_wave_control_args) #define AMDKFD_IOC_MAP_MEMORY_TO_GPU \ AMDKFD_IOWR(0x18, struct kfd_ioctl_map_memory_to_gpu_args) -#define AMDKFD_IOC_UNMAP_MEMORY_FROM_GPU \ - AMDKFD_IOWR(0x19, struct kfd_ioctl_unmap_memory_from_gpu_args) +#define AMDKFD_IOC_GET_TILE_CONFIG \ + AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args) #define AMDKFD_IOC_SET_CU_MASK \ AMDKFD_IOW(0x1A, struct kfd_ioctl_set_cu_mask_args) @@ -717,28 +1734,69 @@ struct kfd_ioctl_cross_memory_copy_args { #define AMDKFD_IOC_SMI_EVENTS \ AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args) +#define AMDKFD_IOC_SVM AMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args) + +#define AMDKFD_IOC_SET_XNACK_MODE \ + AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args) + +#define AMDKFD_IOC_CRIU_OP \ + AMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args) + +#define AMDKFD_IOC_AVAILABLE_MEMORY \ + AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args) + +#define AMDKFD_IOC_EXPORT_DMABUF \ + AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args) + +#define AMDKFD_IOC_RUNTIME_ENABLE \ + AMDKFD_IOWR(0x25, struct kfd_ioctl_runtime_enable_args) + +#define AMDKFD_IOC_DBG_TRAP \ + AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args) + +#define AMDKFD_IOC_SVM AMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args) + +#define AMDKFD_IOC_SET_XNACK_MODE \ + AMDKFD_IOWR(0x21, struct kfd_ioctl_set_xnack_mode_args) + +#define AMDKFD_IOC_CRIU_OP \ + AMDKFD_IOWR(0x22, struct kfd_ioctl_criu_args) + +#define AMDKFD_IOC_AVAILABLE_MEMORY \ + AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args) + +#define AMDKFD_IOC_EXPORT_DMABUF \ + AMDKFD_IOWR(0x24, struct kfd_ioctl_export_dmabuf_args) + +#define AMDKFD_IOC_RUNTIME_ENABLE \ + AMDKFD_IOWR(0x25, struct kfd_ioctl_runtime_enable_args) + +#define AMDKFD_IOC_DBG_TRAP \ + AMDKFD_IOWR(0x26, struct kfd_ioctl_dbg_trap_args) + #define AMDKFD_COMMAND_START 0x01 -#define AMDKFD_COMMAND_END 0x20 +#define AMDKFD_COMMAND_END 0x27 /* non-upstream ioctls */ #define AMDKFD_IOC_IPC_IMPORT_HANDLE \ - AMDKFD_IOWR(0x1F, struct kfd_ioctl_ipc_import_handle_args) + AMDKFD_IOWR(0x80, struct kfd_ioctl_ipc_import_handle_args) #define AMDKFD_IOC_IPC_EXPORT_HANDLE \ - AMDKFD_IOWR(0x20, struct kfd_ioctl_ipc_export_handle_args) + AMDKFD_IOWR(0x81, struct kfd_ioctl_ipc_export_handle_args) -#define AMDKFD_IOC_DBG_TRAP \ - AMDKFD_IOWR(0x21, struct kfd_ioctl_dbg_trap_args) +#define AMDKFD_IOC_DBG_TRAP_DEPRECATED \ + AMDKFD_IOWR(0x82, struct kfd_ioctl_dbg_trap_args_deprecated) -#define AMDKFD_IOC_CROSS_MEMORY_COPY \ - AMDKFD_IOWR(0x22, struct kfd_ioctl_cross_memory_copy_args) +#define AMDKFD_IOC_CROSS_MEMORY_COPY_DEPRECATED \ + AMDKFD_IOWR(0x83, struct kfd_ioctl_cross_memory_copy_deprecated_args) +#define AMDKFD_IOC_RLC_SPM \ + AMDKFD_IOWR(0x84, struct kfd_ioctl_spm_args) -#define AMDKFD_IOC_AVAILABLE_MEMORY \ - AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args) +#define AMDKFD_IOC_PC_SAMPLE \ + AMDKFD_IOWR(0x85, struct kfd_ioctl_pc_sample_args) -#define AMDKFD_COMMAND_START 0x01 -#undef AMDKFD_COMMAND_END -#define AMDKFD_COMMAND_END 0x22 +#define AMDKFD_COMMAND_START_2 0x80 +#define AMDKFD_COMMAND_END_2 0x86 -#endif // INCLUDE_ROCM_SMI_KFD_IOCTL_H_ +#endif diff --git a/rocm_smi/include/rocm_smi/rocm_smi.h b/rocm_smi/include/rocm_smi/rocm_smi.h index 40b2180b51..f4c58b5bcc 100644 --- a/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/rocm_smi/include/rocm_smi/rocm_smi.h @@ -344,9 +344,15 @@ typedef enum { RSMI_EVT_NOTIF_THERMAL_THROTTLE = KFD_SMI_EVENT_THERMAL_THROTTLE, RSMI_EVT_NOTIF_GPU_PRE_RESET = KFD_SMI_EVENT_GPU_PRE_RESET, RSMI_EVT_NOTIF_GPU_POST_RESET = KFD_SMI_EVENT_GPU_POST_RESET, - RSMI_EVT_NOTIF_RING_HANG = KFD_SMI_EVENT_RING_HANG, - - RSMI_EVT_NOTIF_LAST = RSMI_EVT_NOTIF_RING_HANG + RSMI_EVT_NOTIF_EVENT_MIGRATE_START = KFD_SMI_EVENT_MIGRATE_START, + RSMI_EVT_NOTIF_EVENT_MIGRATE_END = KFD_SMI_EVENT_MIGRATE_END, + RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_START = KFD_SMI_EVENT_PAGE_FAULT_START, + RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_END = KFD_SMI_EVENT_PAGE_FAULT_END, + RSMI_EVT_NOTIF_EVENT_QUEUE_EVICTION = KFD_SMI_EVENT_QUEUE_EVICTION, + RSMI_EVT_NOTIF_EVENT_QUEUE_RESTORE = KFD_SMI_EVENT_QUEUE_RESTORE, + RSMI_EVT_NOTIF_EVENT_UNMAP_FROM_GPU = KFD_SMI_EVENT_UNMAP_FROM_GPU, + RSMI_EVT_NOTIF_EVENT_ALL_PROCESS = KFD_SMI_EVENT_ALL_PROCESS, + RSMI_EVT_NOTIF_LAST = KFD_SMI_EVENT_ALL_PROCESS } rsmi_evt_notification_type_t; /** @@ -355,7 +361,8 @@ typedef enum { #define RSMI_EVENT_MASK_FROM_INDEX(i) (1ULL << ((i) - 1)) //! Maximum number of characters an event notification message will be -#define MAX_EVENT_NOTIFICATION_MSG_SIZE 64 +// matches kfd message max size +#define MAX_EVENT_NOTIFICATION_MSG_SIZE 96 /** * Event notification data returned from event notification API @@ -1264,7 +1271,7 @@ typedef struct { /** * Accumulated throttler residencies * - * Socket (thermal) - + * Socket (thermal) - * Socket thermal violation % (greater than 0% is a violation); * aka TVIOL * diff --git a/rocm_smi/src/rocm_smi.cc b/rocm_smi/src/rocm_smi.cc index 5f36e8d256..6c0a6767f5 100644 --- a/rocm_smi/src/rocm_smi.cc +++ b/rocm_smi/src/rocm_smi.cc @@ -6618,16 +6618,230 @@ rsmi_event_notification_get(int timeout_ms, reinterpret_cast(&data[*num_elem]); uint32_t event; - while (fscanf(anon_fp, "%x %63s\n", &event, - reinterpret_cast(&data_item->message)) == 2) { - /* Output is in format as "event information\n" + char event_in[MAX_EVENT_NOTIFICATION_MSG_SIZE]; + memcpy(reinterpret_cast(event_in), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE); + while (fgets(event_in, MAX_EVENT_NOTIFICATION_MSG_SIZE, anon_fp)) { + /* Output is in format as "event_number message_information\n" * Both event are expressed in hex. * information is a string */ + char message[MAX_EVENT_NOTIFICATION_MSG_SIZE]; + // parse the line here for event_number and rest of message_information + sscanf(event_in, "%x %[^\n]\n", &event, message); + + // parse message based on event received + switch (event){ + case RSMI_EVT_NOTIF_NONE: + strcpy(reinterpret_cast(&data_item->message), "Event type None received"); + break; + case RSMI_EVT_NOTIF_VMFAULT: + { + uint32_t pid; + char task_name[MAX_EVENT_NOTIFICATION_MSG_SIZE]; + memcpy(reinterpret_cast(task_name), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE); + + sscanf(message, "%x:%s\n", &pid, task_name); + std::stringstream final_message; + final_message << "PID: " << std::to_string(pid).c_str() + << " task name: " << task_name; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_THERMAL_THROTTLE: + { + uint64_t bitmask; + uint64_t counter; + + sscanf(message, "%llx:%llx\n", &bitmask, &counter); + std::stringstream final_message; + final_message << "bitmask: 0x" << std::hex << bitmask + << " counter: 0x" << std::hex << counter; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_GPU_PRE_RESET: + { + uint32_t reset_seq_num; + char reset_cause[MAX_EVENT_NOTIFICATION_MSG_SIZE]; + memcpy(reinterpret_cast(reset_cause), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE); + + sscanf(message, "%x %[^\n]\n", &reset_seq_num, reset_cause); + std::stringstream final_message; + final_message << "reset sequence number: " << std::to_string(reset_seq_num).c_str() + << " reset cause: " << reset_cause; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_GPU_POST_RESET: + { + uint32_t reset_seq_num; + + sscanf(message, "%x %[^\n]\n", &reset_seq_num); + std::stringstream final_message; + final_message << "reset sequence number: " << std::to_string(reset_seq_num).c_str(); + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_MIGRATE_START: + { + int64_t ns; + int32_t pid; + uint32_t start; + uint32_t size; + uint16_t from; + uint16_t to; + uint16_t prefetch_loc; + uint16_t preferred_loc; + int32_t migrate_trigger; + + sscanf(message, "%lld -%d @%lx(%lx) %x->%x %x:%x %d\n", &ns, &pid, &start, &size, &from, &to, &prefetch_loc, &preferred_loc, &migrate_trigger); + std::stringstream final_message; + final_message << "nd: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " start: 0x" << std::hex << start + << " size: 0x" << std::hex << size + << " from: 0x" << std::hex << from + << " to: 0x" << std::hex << to + << " prefetch_loc: 0x" << std::hex << prefetch_loc + << " preferred_loc: 0x" << std::hex << preferred_loc + << " migrate_trigger: " << std::to_string(migrate_trigger).c_str(); + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_MIGRATE_END: + { + int64_t ns; + int32_t pid; + uint32_t start; + uint32_t size; + uint32_t from; + uint32_t to; + uint32_t migrate_trigger; + uint32_t error_code; + + sscanf(message, "%lld -%d @%lx(%lx) %x->%x %d %d\n", &ns, &pid, &start, &size, &from, &to, &migrate_trigger, &error_code); + std::stringstream final_message; + final_message << "nd: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " start: 0x" << std::hex << start + << " size: 0x" << std::hex << size + << " from: 0x" << std::hex << from + << " to: 0x" << std::hex << to + << " migrate_trigger: " << std::to_string(migrate_trigger).c_str() + << " error_code: " << std::to_string(error_code).c_str(); + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_START: + { + int64_t ns; + int32_t pid; + uint32_t addr; + uint32_t node; + char *rw; + + sscanf(message, "%lld -%d @%lx(%x) %c\n", &ns, &pid, &addr, &node, rw); + std::stringstream final_message; + final_message << "ns: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " addr: 0x" << std::hex << addr + << " node: 0x" << std::hex << node + << " rw: " << rw; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_PAGE_FAULT_END: + { + int64_t ns; + int32_t pid; + uint32_t addr; + uint32_t node; + char *migrate_update; + + sscanf(message, "%lld -%d @%lx(%x) %c\n", &ns, &pid, &addr, &node, migrate_update); + std::stringstream final_message; + final_message << "ns: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " addr: 0x" << std::hex << addr + << " node: 0x" << std::hex << node + << " migrate_udpate: " << migrate_update; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_QUEUE_EVICTION: + { + int64_t ns; + int32_t pid; + uint32_t node; + uint32_t evict_trigger; + + sscanf(message, "%lld -%d %x %d\n", &ns, &pid, &node, &evict_trigger); + std::stringstream final_message; + final_message << "ns: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " node: 0x" << std::hex << node + << " evict_trigger: " << std::to_string(evict_trigger).c_str(); + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_QUEUE_RESTORE: + { + int64_t ns; + int32_t pid; + uint32_t node; + char *rescheduled; + + sscanf(message, "%lld -%d %x %c\n", &ns, &pid, &node, rescheduled); + std::stringstream final_message; + final_message << "ns: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " node: 0x" << std::hex << node + << " rescheduled: " << rescheduled; + + strcpy(reinterpret_cast(&data_item->message), final_message.str().c_str()); + } + break; + case RSMI_EVT_NOTIF_EVENT_UNMAP_FROM_GPU: + { + int64_t ns; + int32_t pid; + uint32_t addr; + uint32_t size; + uint32_t node; + uint32_t unmap_trigger; + + sscanf(message, "%lld -%d @%lx(%lx) %x %d\n", &ns, &pid, &addr, &size, &node, &unmap_trigger); + std::stringstream final_message; + final_message << "ns: " << std::to_string(ns).c_str() + << " pid: " << std::to_string(pid).c_str() + << " addr: 0x" <(&data_item->message), final_message.str().c_str()); + } + break; + default: + strcpy(reinterpret_cast(&data_item->message), "Unknown event received"); + break; + } data_item->event = (rsmi_evt_notification_type_t)event; data_item->dv_ind = fd_indx_to_dev_id[i]; ++(*num_elem); + // zero out event_in after each use + memcpy(reinterpret_cast(event_in), "\0", MAX_EVENT_NOTIFICATION_MSG_SIZE); + if (*num_elem >= buffer_size) { break; } From d323ecff97df232b734bd2a0d5740fe8a1968f84 Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Fri, 6 Dec 2024 12:18:21 -0600 Subject: [PATCH 10/23] [SWDEV-502744] Fix "amd-smi monitor" shows VCN ENC utilization & clock but not VCN DEC Reason for this fix: Navi products use vclk and dclk for both encode and decode. On MI products, only decode is supported. Navi products cannot support displaying ENC_UTIL % at this time. Change-Id: I107bb761794ae4724949ac21c110b23a4f616700 Signed-off-by: Charis Poag --- CHANGELOG.md | 80 +++++++++++++++++++++++++++++++++++ amdsmi_cli/amdsmi_commands.py | 80 +++++++++++++++++++++++------------ amdsmi_cli/amdsmi_logger.py | 4 +- 3 files changed, 135 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 915f52bbd7..e9e7f17f9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,86 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Upcoming changes +### Known issues + +## amd_smi_lib for ROCm 6.3.1 + +### Added + +### Changed + +- **Changed `amd-smi monitor`: No longer display `ENC_CLOCK`/`DEC_CLOCK` but `VCLOCK` and `DCLOCK`**. + Due to fix mentioned in `Resolved Issues`, this change was needed. + Reason: Navi products use vclk and dclk for both encode and decode. On MI products, only decode is supported. + Before: + ```shell + $ amd-smi monitor -n -d + GPU ENC_UTIL ENC_CLOCK DEC_UTIL DEC_CLOCK + 0 0.0 % 29 MHz N/A 22 MHz + 1 0.0 % 29 MHz N/A 22 MHz + 2 0.0 % 29 MHz N/A 22 MHz + 3 0.0 % 29 MHz N/A 22 MHz + 4 0.0 % 29 MHz N/A 22 MHz + 5 0.0 % 29 MHz N/A 22 MHz + 6 0.0 % 29 MHz N/A 22 MHz + 7 0.0 % 29 MHz N/A 22 MHz + ``` + After: + ```shell + $ amd-smi monitor -n -d + GPU ENC_UTIL DEC_UTIL VCLOCK DCLOCK + 0 N/A 0.0 % 29 MHz 22 MHz + 1 N/A 0.0 % 29 MHz 22 MHz + 2 N/A 0.0 % 29 MHz 22 MHz + 3 N/A 0.0 % 29 MHz 22 MHz + 4 N/A 0.0 % 29 MHz 22 MHz + 5 N/A 0.0 % 29 MHz 22 MHz + 6 N/A 0.0 % 29 MHz 22 MHz + 7 N/A 0.0 % 29 MHz 22 MHz + ``` + +### Removed + +### Optimized + +### Resolved issues + +- **Fixed `amd-smi monitor`'s encode/decode: `ENC_UTIL`, `DEC_UTIL`, and now associate `VCLOCK`/`DCLOCK` with both**. + Navi products use vclk and dclk for both encode and decode. On MI products, only decode is supported. + + Navi products cannot support displaying ENC_UTIL % at this time. + + Before: + ```shell + $ amd-smi monitor -n -d + GPU ENC_UTIL ENC_CLOCK DEC_UTIL DEC_CLOCK + 0 0.0 % 29 MHz N/A 22 MHz + 1 0.0 % 29 MHz N/A 22 MHz + 2 0.0 % 29 MHz N/A 22 MHz + 3 0.0 % 29 MHz N/A 22 MHz + 4 0.0 % 29 MHz N/A 22 MHz + 5 0.0 % 29 MHz N/A 22 MHz + 6 0.0 % 29 MHz N/A 22 MHz + 7 0.0 % 29 MHz N/A 22 MHz + ``` + After: + ```shell + $ amd-smi monitor -n -d + GPU ENC_UTIL DEC_UTIL VCLOCK DCLOCK + 0 N/A 0.0 % 29 MHz 22 MHz + 1 N/A 0.0 % 29 MHz 22 MHz + 2 N/A 0.0 % 29 MHz 22 MHz + 3 N/A 0.0 % 29 MHz 22 MHz + 4 N/A 0.0 % 29 MHz 22 MHz + 5 N/A 0.0 % 29 MHz 22 MHz + 6 N/A 0.0 % 29 MHz 22 MHz + 7 N/A 0.0 % 29 MHz 22 MHz + ``` + +### Upcoming changes + +### Known issues + ## amd_smi_lib for ROCm 6.3.0 ### Added diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 109a01e0cd..cf2ba3378a 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -4874,9 +4874,10 @@ class AMDSMICommands(): self.logger.table_header += 'MEM_CLOCK'.rjust(11) if args.encoder: + # TODO: The encoding utilization is in progress for Navi. Note: MI3x ASICs only support decoding. try: # Get List of vcn activity values - encoder_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['vcn_activity'] + encoder_util = "N/A" # Not yet implemented encoding_activity_avg = [] for value in encoder_util: if isinstance(value, int): @@ -4903,49 +4904,72 @@ class AMDSMICommands(): self.logger.table_header += 'ENC_UTIL'.rjust(10) - try: - encoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_vclk0'] - monitor_values['encoder_clock'] = encoder_clock - freq_unit = 'MHz' - if encoder_clock != "N/A": - if self.logger.is_human_readable_format(): - monitor_values['encoder_clock'] = f"{monitor_values['encoder_clock']} {freq_unit}" - if self.logger.is_json_format(): - monitor_values['encoder_clock'] = {"value" : monitor_values['encoder_clock'], - "unit" : freq_unit} - except amdsmi_exception.AmdSmiLibraryException as e: - monitor_values['encoder_clock'] = "N/A" - logging.debug("Failed to get encoder clock on gpu %s | %s", gpu_id, e.get_error_info()) - - self.logger.table_header += 'ENC_CLOCK'.rjust(11) if args.decoder: try: - decoder_util = "N/A" # Not yet implemented - monitor_values['decoder'] = decoder_util - # if self.logger.is_human_readable_format(): - # monitor_values['decoder'] = f"{monitor_values['decoder']} %" + # Get List of vcn activity values + # Note: MI3x ASICs only support decoding, so the vcn_activity is used for decoding activity. + decoder_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['vcn_activity'] + decoding_activity_avg = [] + for value in decoder_util: + if isinstance(value, int): + decoding_activity_avg.append(value) + + # Averaging the possible decoding activity values + if decoding_activity_avg: + decoding_activity_avg = sum(decoding_activity_avg) / len(decoding_activity_avg) + else: + decoding_activity_avg = "N/A" + + monitor_values['decoder'] = decoding_activity_avg + + activity_unit = '%' + if monitor_values['decoder'] != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['decoder'] = f"{monitor_values['decoder']} {activity_unit}" + if self.logger.is_json_format(): + monitor_values['decoder'] = {"value" : monitor_values['decoder'], + "unit" : activity_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['decoder'] = "N/A" logging.debug("Failed to get decoder utilization on gpu %s | %s", gpu_id, e.get_error_info()) self.logger.table_header += 'DEC_UTIL'.rjust(10) + if args.encoder or args.decoder: try: - decoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_dclk0'] - monitor_values['decoder_clock'] = decoder_clock + vclock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_vclk0'] + monitor_values['vclock'] = vclock freq_unit = 'MHz' - if decoder_clock != "N/A": + if vclock != "N/A": if self.logger.is_human_readable_format(): - monitor_values['decoder_clock'] = f"{monitor_values['decoder_clock']} {freq_unit}" + monitor_values['vclock'] = f"{monitor_values['vclock']} {freq_unit}" if self.logger.is_json_format(): - monitor_values['decoder_clock'] = {"value" : monitor_values['decoder_clock'], + monitor_values['vclock'] = {"value" : monitor_values['vclock'], "unit" : freq_unit} except amdsmi_exception.AmdSmiLibraryException as e: - monitor_values['decoder_clock'] = "N/A" - logging.debug("Failed to get decoder clock on gpu %s | %s", gpu_id, e.get_error_info()) + monitor_values['vclock'] = "N/A" + logging.debug("Failed to get dclock on gpu %s | %s", gpu_id, e.get_error_info()) + + self.logger.table_header += 'VCLOCK'.rjust(8) + + try: + dclock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_dclk0'] + monitor_values['dclock'] = dclock + + freq_unit = 'MHz' + if dclock != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['dclock'] = f"{monitor_values['dclock']} {freq_unit}" + if self.logger.is_json_format(): + monitor_values['dclock'] = {"value" : monitor_values['dclock'], + "unit" : freq_unit} + except amdsmi_exception.AmdSmiLibraryException as e: + monitor_values['dclock'] = "N/A" + logging.debug("Failed to get vclock on gpu %s | %s", gpu_id, e.get_error_info()) + + self.logger.table_header += 'DCLOCK'.rjust(8) - self.logger.table_header += 'DEC_CLOCK'.rjust(11) if args.ecc: try: ecc = amdsmi_interface.amdsmi_get_gpu_total_ecc_count(args.gpu) diff --git a/amdsmi_cli/amdsmi_logger.py b/amdsmi_cli/amdsmi_logger.py index d52abdf1fb..9997e7b4c7 100644 --- a/amdsmi_cli/amdsmi_logger.py +++ b/amdsmi_cli/amdsmi_logger.py @@ -117,8 +117,10 @@ class AMDSMILogger(): table_values += string_value.rjust(10) + ' ' elif key == 'power_usage': table_values += string_value.rjust(7) - elif key in ('gfx_clock', 'mem_clock', 'encoder_clock', 'decoder_clock', 'vram_used'): + elif key in ('gfx_clock', 'mem_clock', 'vram_used'): table_values += string_value.rjust(11) + elif key in ('vclock', 'dclock'): + table_values += string_value.rjust(8) elif key == 'vram_total' or 'ecc' in key or key == 'pcie_bw': table_values += string_value.rjust(12) elif key in ['pcie_replay']: From 288b11df37c6c8a81025634e4c14aafc5d3f2edb Mon Sep 17 00:00:00 2001 From: Bindhiya Kanangot Balakrishnan Date: Tue, 19 Nov 2024 09:37:43 -0600 Subject: [PATCH 11/23] [SWDEV-496639] Align amd-smi xgmi statistics The xgmi read and write values were displayed in KB. The numbers became unreadable due to misalignment. So, converted read and write values to readable units using helper function. Updated Changelog. Signed-off-by: Bindhiya Kanangot Balakrishnan Change-Id: I4c90a1de8a58c29cbdf43fe3480a1546f3946673 --- CHANGELOG.md | 20 ++++++++++++++++++++ amdsmi_cli/amdsmi_commands.py | 8 ++++---- amdsmi_cli/amdsmi_helpers.py | 14 ++++++++++++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9e7f17f9a..0ad25a11ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,26 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr - `amd-smi static --bus` and `amd-smi STATIC --BUS` will produce identical results. - `amd-smi static -b` and `amd-smi static -B` will still return different results (-b for bus and -B for board). +- **Converted xgmi read and write from KB's to readable units**. + - With this change `amd-smi xgmi` will now display the statistics in dynamically selected readable units. + - Example output is shown below. + +```shell +$ amd-smi xgmi +LINK METRIC TABLE: + bdf bit_rate max_bandwidth link_type 0000:05:00.0 0000:26:00.0 0000:46:00.0 0000:65:00.0 0000:85:00.0 0000:a6:00.0 0000:c6:00.0 0000:e5:00.0 +GPU0 0000:05:00.0 32 Gb/s 512 Gb/s XGMI + Read N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB + Write N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB +GPU1 0000:26:00.0 32 Gb/s 512 Gb/s XGMI + Read 1.123 PB N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB + Write 229.1 MB N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB +GPU2 0000:46:00.0 32 Gb/s 512 Gb/s XGMI + Read 1.123 PB 1.123 PB N/A 1.123 PB 1.123 PB 1.123 PB 1.123 PB 1.123 PB + Write 229.1 MB 229.1 MB N/A 229.1 MB 229.1 MB 229.1 MB 229.1 MB 229.1 MB +... +``` + ### Resolved issues ### Upcoming changes diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index cf2ba3378a..aefa176031 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -5298,8 +5298,8 @@ class AMDSMICommands(): data_unit = 'KB' if self.logger.is_human_readable_format(): - dest_link_dict['read'] = f"{read} {data_unit}" - dest_link_dict['write'] = f"{write} {data_unit}" + dest_link_dict['read'] = self.helpers.convert_bytes_to_readable(read * 1024, True) + dest_link_dict['write'] = self.helpers.convert_bytes_to_readable(write * 1024, True) elif self.logger.is_json_format(): dest_link_dict['read'] = {"value" : read, "unit" : data_unit} @@ -5350,8 +5350,8 @@ class AMDSMICommands(): tabular_output.append(tabular_output_dict) # Create Read and Write rows and add to tabular_output - read_output_dict = {"RW" : "Read"} - write_output_dict = {"RW" : "Write"} + read_output_dict = {"RW" : " Read"} + write_output_dict = {"RW" : " Write"} for key, value in xgmi_dict.items(): if key == "link_metrics": for link_key, link_value in value.items(): diff --git a/amdsmi_cli/amdsmi_helpers.py b/amdsmi_cli/amdsmi_helpers.py index 2fce5f4940..7018d8f72f 100644 --- a/amdsmi_cli/amdsmi_helpers.py +++ b/amdsmi_cli/amdsmi_helpers.py @@ -779,10 +779,20 @@ class AMDSMIHelpers(): return False, profile_presets.values() - def convert_bytes_to_readable(self, bytes_input): + def convert_bytes_to_readable(self, bytes_input, format_length=None): for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]: if abs(bytes_input) < 1024: - return f"{bytes_input:3.1f} {unit}" + if format_length is not None: + if bytes_input < 10: + return f"{bytes_input:4.3f} {unit}" + elif bytes_input < 100: + return f"{bytes_input:4.2f} {unit}" + elif bytes_input < 1000: + return f"{bytes_input:4.1f} {unit}" + else: + return f"{bytes_input:4.0f} {unit}" + else: + return f"{bytes_input:3.1f} {unit}" bytes_input /= 1024 return f"{bytes_input:.1f} YB" From ddcfe28520138ae33a6fa18d0d709c0d4e57319e Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 9 Dec 2024 14:13:28 -0600 Subject: [PATCH 12/23] [SWDEV-503491] Updated Market Names Signed-off-by: Maisam Arif Change-Id: Ib56c4c96190e18708ef4d0d6358dd8d5b1ee9e6a --- src/amd_smi/amd_smi_utils.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index d067ebd789..7f79b24a09 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -583,6 +583,9 @@ amdsmi_status_t smi_amdgpu_get_market_name_from_dev_id(uint32_t device_id, char case 0x74b6: strcpy(market_name, "MI308X"); break; + case 0x74a5: + strcpy(market_name, "AMD Instinct MI325X"); + break; case 0x74a9: case 0x74bd: strcpy(market_name, "AMD Instinct MI300X HF"); From b911a0606a1a1dedeb080e0773eb05020b762f2d Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Thu, 5 Dec 2024 19:23:16 -0600 Subject: [PATCH 13/23] [SWDEV-495824] AMD SMI reporting CPX partitions incorrectly Updated changelog to provide options to users on how to fix. Change-Id: I4fd04b1e65ff9d678b2d13109599f57a03c84d41 Signed-off-by: Charis Poag --- CHANGELOG.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ad25a11ea..9198857f1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,72 @@ GPU2 0000:46:00.0 32 Gb/s 512 Gb/s XGMI ### Known issues +- **AMD SMI only reports 63 GPU devices when setting CPX on all 8 GPUs** + When setting CPX as a partition mode, there is a DRM node limitation of 64. + + This is a known limitation of the Linux kernel, not the driver. Other drivers, such as those using PCIe space (e.g., ast), may be occupying the necessary DRM nodes. + + The number of DRM nodes used can be checked via `ls /sys/class/drm` + + Options are as follows: + 1) ***Workaround - removing other devices using DRM nodes*** + + Recommended steps for removing unnecessary drivers: + a. Unload amdgpu - `sudo rmmod amdgpu` + b. Remove unnecessary driver(s) - ex. `sudo rmmod ast` + c. Reload amgpu - `sudo modprobe amdgpu` + d. Confirm `amd-smi list` reports all nodes (this can vary per MI ASIC) + + 2) ***Update your OS' kernel*** + Typically you can find examples online by searching "`Update kernel command line`" + + Ex. "Update kernel Ubuntu 22.04 command line" should provide some good examples. + https://phoenixnap.com/kb/how-to-update-kernel-ubuntu + + 3) ***Building and installing your own kernel*** + *This option is helpful for users on OS distributions that have not yet merged the necessary changes.* + https://phoenixnap.com/kb/build-linux-kernel + + All changes are in the mainline kernel if users need to build their own. + + References to kernel changes: + ```text + for libdrm : + Author: James Zhu + + Date: Mon Aug 7 10:14:18 2023 -0400 + + xf86drm: use drm device name to identify drm node type + + Currently drm node's minor range is used to identify node's type. + + Since kernel drm uses node type name and minor to generate drm + + device name, It will be more general to use drm device name to + + identify drm node type. + + Signed-off-by: James Zhu + + Reviewed-by: Simon Ser + + commit 1080273c2b31db6f031a7f889f3104f53ab4502c + + Author: James Zhu + + Date: Mon Aug 7 10:06:32 2023 -0400 + + xf86drm: update DRM_NODE_NAME_MAX supporting more nodes + + Current DRM_NODE_NAME_MAX only can support up to 999 nodes, + + Update to support up to 2^MINORBITS nodes. + + Signed-off-by: James Zhu + + Reviewed-by: Simon Ser + ``` + ## amd_smi_lib for ROCm 6.3.1 ### Added From bc0015fd36c8bc909061d534427f07534fe70700 Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Thu, 5 Dec 2024 20:44:02 -0600 Subject: [PATCH 14/23] [SWDEV-488288] Remove GFX_BUSY_ACC from amd-smi metric --usage Output is not helpful to users. Change-Id: I12a60e28b8eab2fc3ffca4ea88f03018bf0ef3ce Signed-off-by: Charis Poag --- CHANGELOG.md | 44 +++++++++++++++++++++++++++++++++++ amdsmi_cli/amdsmi_commands.py | 6 ----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9198857f1d..a41098f0a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,50 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Removed +- **Removed `GFX_BUSY_ACC` from `amd-smi metric --usage`**. + Displaying `GFX_BUSY_ACC` does not provide helpful outputs for users. + + Old output: + ```shell + $ amd-smi metric --usage + GPU: 0 + USAGE: + GFX_ACTIVITY: 0 % + UMC_ACTIVITY: 0 % + MM_ACTIVITY: N/A + VCN_ACTIVITY: [0 %, 0 %, 0 %, 0 %] + JPEG_ACTIVITY: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + GFX_BUSY_INST: + XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + JPEG_BUSY: + XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + VCN_BUSY: + XCP_0: [0 %, 0 %, 0 %, 0 %] + GFX_BUSY_ACC: + XCP_0: [N/A, N/A, N/A, N/A, N/A, N/A, N/A, N/A] + ... + ``` + + New Output: + ```shell + $ amd-smi metric --usage + GPU: 0 + USAGE: + GFX_ACTIVITY: 0 % + UMC_ACTIVITY: 0 % + MM_ACTIVITY: N/A + VCN_ACTIVITY: [0 %, 0 %, 0 %, 0 %] + JPEG_ACTIVITY: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + GFX_BUSY_INST: + XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + JPEG_BUSY: + XCP_0: [0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %, 0 %] + VCN_BUSY: + XCP_0: [0 %, 0 %, 0 %, 0 %] + ... + ``` + + ### Optimized - **Modified `amd-smi` CLI to allow case insensitive arguments if the argument does not begin with a single dash**. diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index aefa176031..fdb2d80408 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -1471,7 +1471,6 @@ class AMDSMICommands(): engine_usage['gfx_busy_inst'] = "N/A" engine_usage['jpeg_busy'] = "N/A" engine_usage['vcn_busy'] = "N/A" - engine_usage['gfx_busy_acc'] = "N/A" if num_partition != "N/A": # these are one after another, in order to display each in sub-sections @@ -1490,11 +1489,6 @@ class AMDSMICommands(): new_xcp_dict[f"xcp_{current_xcp}"] = gpu_metric['xcp_stats.vcn_busy'][current_xcp] engine_usage['vcn_busy'] = new_xcp_dict - new_xcp_dict = {} - for current_xcp in range(num_partition): - new_xcp_dict[f"xcp_{current_xcp}"] = gpu_metric['xcp_stats.gfx_busy_acc'][current_xcp] - engine_usage['gfx_busy_acc'] = new_xcp_dict - logging.debug(f"After updates to engine_usage dictionary = {engine_usage}") for key, value in engine_usage.items(): From 7543a058ea2ba4129fcd271206cb27f0938c3adc Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Sun, 8 Dec 2024 22:14:19 -0600 Subject: [PATCH 15/23] [SWDEV-475712] Fix MI2x target_graphics_version Removed correcting target_graphics_version by product name. Instead detected target_graphics_version which needs to be corrected -> populate accordingly. Change-Id: Ie9240a049313d9338f831ef47be973cd5c228612 Signed-off-by: Charis Poag --- py-interface/amdsmi_interface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 5d3db14d34..95abd19238 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -1653,7 +1653,7 @@ def amdsmi_get_gpu_asic_info( market_name = _pad_hex_value(asic_info_struct.market_name.decode("utf-8"), 4) target_graphics_version = str(asic_info_struct.target_graphics_version) - if len(target_graphics_version) == 4 and ("Instinct MI2" in market_name): + if target_graphics_version == "9010": hex_part = str(hex(int(str(asic_info_struct.target_graphics_version)[2:]))).replace("0x", "") target_graphics_version = str(asic_info_struct.target_graphics_version)[:2] + hex_part asic_info = { From 554203c13afa98ae0cd2eeba3b0ea376375ee726 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 10 Dec 2024 14:44:22 -0600 Subject: [PATCH 16/23] Fixed spacing in `amd-smi --xgmi` Signed-off-by: Maisam Arif Change-Id: I9fbd20c50a25aa3be80c8aa68eea37b81a74dc67 --- amdsmi_cli/amdsmi_logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amdsmi_cli/amdsmi_logger.py b/amdsmi_cli/amdsmi_logger.py index 9997e7b4c7..b776bd5450 100644 --- a/amdsmi_cli/amdsmi_logger.py +++ b/amdsmi_cli/amdsmi_logger.py @@ -166,7 +166,7 @@ class AMDSMILogger(): elif key == "resources_shared": table_values += string_value.ljust(18) elif key == "RW": - table_values += string_value.ljust(52) + table_values += string_value.ljust(53) elif key == "process_list": #Add an additional padding between the first instance of GPU and NAME table_values += ' ' From 2a1e2eed189192a43ab13bcf36444113e5a32f2d Mon Sep 17 00:00:00 2001 From: Justin Williams Date: Thu, 5 Dec 2024 13:34:47 -0600 Subject: [PATCH 17/23] [SWDEV-479339/498804] Added AMDSMI Dockerfile Signed-off-by: Justin Williams Change-Id: Ic7cc6eb6417708cff3f4a33b91a8ef6dcd2b2807 --- Dockerfile | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..a79d7c0520 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ + # Use ubuntu 20.04 base image + FROM compute-artifactory.amd.com:5000/rocm-base-images/ubuntu-20.04-bld:2024112501 + + # Set environment variables + ENV BUILD_FOLDER=/src/build + ENV DEB_BUILD="amd-smi-lib*99999-local_amd64.deb" + ENV DEB_BUILD_TEST='amd-smi-lib-tests*99999-local_amd64.deb' + + # Set up the working directory + WORKDIR /src + + # Copy the source code into the container + COPY . /src + + # Run the build and install commands + RUN rm -rf ${BUILD_FOLDER} && \ + mkdir -p ${BUILD_FOLDER} && \ + cd ${BUILD_FOLDER} && \ + cmake .. -DBUILD_TESTS=ON -DENABLE_ESMI_LIB=ON && \ + make -j $(nproc) VERBOSE=1 && \ + make package && \ + sudo apt install -y ${BUILD_FOLDER}/${DEB_BUILD} && \ + sudo ln -s /opt/rocm/bin/amd-smi /usr/local/bin + + # Verify installation + RUN python3 -m pip list | grep amd && \ + python3 -m pip list | grep pip && \ + python3 -m pip list | grep setuptools + + # Set the entrypoint + ENTRYPOINT ["/bin/bash"] From 57f45954b723b18c956e2050a1b397cb2b31f059 Mon Sep 17 00:00:00 2001 From: Charis Poag Date: Mon, 9 Dec 2024 09:43:03 -0600 Subject: [PATCH 18/23] Fix amd-smi firmware not printing YAML-like dictionary correctly List string should take into account dictionary value types Change-Id: Icc08288cb0007d43eacd1aff6d44c40a84ea9448 Signed-off-by: Charis Poag --- amdsmi_cli/amdsmi_logger.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/amdsmi_cli/amdsmi_logger.py b/amdsmi_cli/amdsmi_logger.py index b776bd5450..f967910f7e 100644 --- a/amdsmi_cli/amdsmi_logger.py +++ b/amdsmi_cli/amdsmi_logger.py @@ -258,7 +258,10 @@ class AMDSMILogger(): elif isinstance(value, list): yaml_string += " " * indent + f"{key}:\n" for item in value: - yaml_string += " " * (indent + 1) + f"- {item}\n" + if isinstance(item, dict): + yaml_string += self.custom_dump(item, indent + 1) + else: # If the list is not a dictionary, print it as a string + yaml_string += " " * (indent + 1) + f"- {item}\n" else: yaml_string += " " * indent + f"{key}: {value}\n" return yaml_string From aed7749a2c0a006ae310a176e5f1094b8c06869b Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 11 Dec 2024 16:40:51 -0600 Subject: [PATCH 19/23] [SWDEV-489060] Added python3-setuptools & python3-wheel for base images Signed-off-by: Maisam Arif Change-Id: I222395e656469f67405bc94a86ab7f8fd1ed34a2 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99589cd3d1..1a3b53dd81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,7 +256,7 @@ add_subdirectory(goamdsmi_shim) set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "python3-argcomplete, libdrm-dev") set(CPACK_DEBIAN_ASAN_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) -set(CPACK_DEBIAN_PACKAGE_DEPENDS "sudo, python3 (>= 3.6.8), python3-pip") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "sudo, python3 (>= 3.6.8), python3-pip, python3-setuptools, python3-wheel") set(CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS}) set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS}) @@ -277,7 +277,7 @@ set(CPACK_RPM_PACKAGE_SUGGESTS "python3-argcomplete") set(CPACK_RPM_DEV_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS}) set(CPACK_RPM_ASAN_PACKAGE_SUGGESTS ${CPACK_RPM_PACKAGE_SUGGESTS}) # python version gated by rhel8 :( -set(CPACK_RPM_PACKAGE_REQUIRES "sudo, python3 >= 3.6.8, python3-pip") +set(CPACK_RPM_PACKAGE_REQUIRES "sudo, python3 >= 3.6.8, python3-pip, python3-setuptools, python3-wheel") set(CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES}) set(CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES}) From bc16e1a5da5fed0330d193c51fed0157595abfc4 Mon Sep 17 00:00:00 2001 From: gabrpham Date: Wed, 4 Dec 2024 00:10:32 -0600 Subject: [PATCH 20/23] [SWDEV-484382] Added new command `amd-smi static --clock` Signed-off-by: gabrpham Change-Id: I49e1aa2e699734d81c40c76c62da1cecc5bd3c0e --- CHANGELOG.md | 41 ++++++++++++++++++ amdsmi_cli/amdsmi_commands.py | 76 ++++++++++++++++++++++++++++++---- amdsmi_cli/amdsmi_parser.py | 5 +++ docs/how-to/amdsmi-cli-tool.md | 32 ++++++++++++++ 4 files changed, 146 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a41098f0a9..d6749e6226 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,47 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/projects/amdsmi](https://rocm.docs.amd.com/projects/amdsmi/en/latest/). ***All information listed below is for reference and subject to change.*** +## amd_smi_lib for ROCm 6.4.0 + +### Added + +- **Added new command `amd-smi static -C/--clock`**. + This new command displays the clock frequency performance levels for the selected GPUs and clocks. + +```shell +amd-smi static --clock all -g 0 +GPU: 0 + CLOCK: + SYS: + CURRENT LEVEL: 2 + FREQUENCY_LEVELS: + 0: 300 MHz + 1: 904 MHz + 2: 1165 MHz + 3: 1360 MHz + 4: 1440 MHz + 5: 1544 MHz + 6: 1627 MHz + 7: 1720 MHz + 8: 1800 MHz + MEM: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 167 MHz + DF: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 1400 MHz + SOC: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 302 MHz + DCEF: N/A + VCLK0: N/A + VCLK1: N/A + DCLK0: N/A + DCLK1: N/A +``` ## amd_smi_lib for ROCm 6.4.0 diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index fdb2d80408..9262e02ca7 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -31,7 +31,7 @@ import os from _version import __version__ from amdsmi_helpers import AMDSMIHelpers from amdsmi_logger import AMDSMILogger -from amdsmi_cli_exceptions import AmdSmiRequiredCommandException +from amdsmi_cli_exceptions import AmdSmiRequiredCommandException, AmdSmiInvalidParameterValueException from rocm_version import get_rocm_version from amdsmi import amdsmi_interface from amdsmi import amdsmi_exception @@ -271,7 +271,7 @@ class AMDSMICommands(): def static_gpu(self, args, multiple_devices=False, gpu=None, asic=None, bus=None, vbios=None, limit=None, driver=None, ras=None, board=None, numa=None, vram=None, cache=None, partition=None, dfc_ucode=None, fb_info=None, num_vf=None, - soc_pstate=None, xgmi_plpd=None, process_isolation=None): + soc_pstate=None, xgmi_plpd=None, process_isolation=None, clock=None): """Get Static information for target gpu Args: @@ -321,12 +321,19 @@ class AMDSMICommands(): args.cache = cache if process_isolation: args.process_isolation = process_isolation + if clock: + args.clock = clock + # args.clock defaults to False so if it was overwritten to empty list, that indicates that it was given as an arguments but with an empty list + if args.clock == []: + args.clock = True # Store args that are applicable to the current platform current_platform_args = ["asic", "bus", "vbios", "driver", "ras", - "vram", "cache", "board", "process_isolation"] + "vram", "cache", "board", "process_isolation", + "clock"] current_platform_values = [args.asic, args.bus, args.vbios, args.driver, args.ras, - args.vram, args.cache, args.board, args.process_isolation] + args.vram, args.cache, args.board, args.process_isolation, + args.clock] if self.helpers.is_linux() and self.helpers.is_baremetal(): if partition: @@ -829,6 +836,58 @@ class AMDSMICommands(): logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) static_dict['cache_info'] = cache_info_list + if 'clock' in current_platform_args: + if isinstance(args.clock, bool) and args.clock == True: + args.clock = ['sys', 'mem', 'df', 'soc', 'dcef', 'vclk0', 'vclk1', 'dclk0', 'dclk1'] + if isinstance(args.clock, list): + # remove potential duplicates from list + args.clock = list(set(args.clock)) + # check that clock is valid option + if "all" in args.clock or len(args.clock) == 0: + args.clock = ['sys', 'mem', 'df', 'soc', 'dcef', 'vclk0', 'vclk1', 'dclk0', 'dclk1'] + clk_dict = {} + + for clk in args.clock: + clk_type = clk.lower() + if clk_type == "sys": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.SYS + elif clk_type == "mem": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.MEM + elif clk_type == "df": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.DF + elif clk_type == "soc": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.SOC + elif clk_type == "dcef": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCEF + # vclk and dclk currently do not support levels so average clk is given for frequency levels + elif clk_type == "vclk0": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.VCLK0 + elif clk_type == "vclk1": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.VCLK1 + elif clk_type == "dclk0": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCLK0 + elif clk_type == "dclk1": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.DCLK1 + else: + clk_type_conversion = "N/A" + output_format = self.helpers.get_output_format() + raise AmdSmiInvalidParameterValueException(clk_type, output_format) # clk type given is bad + + try: + frequencies = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, clk_type_conversion) + freq_dict = {} + freq_dict.update({'current level':frequencies['current']}) + freq_dict.update({'frequency_levels':{}}) + for level in range(len(frequencies['frequency'])): + freq = str(self.helpers.convert_SI_unit(frequencies['frequency'][level], AMDSMIHelpers.SI_Unit.MICRO)) + " MHz" + freq_dict['frequency_levels'].update({level:freq}) + except amdsmi_exception.AmdSmiLibraryException as e: + freq_dict = "N/A" + clk_dict.update({clk:freq_dict}) + + static_dict['clock'] = clk_dict + else: + raise amdsmi_exception.AmdSmiParameterException(args.clock, list[str]) # Convert and store output by pid for csv format multiple_devices_csv_override = False @@ -864,7 +923,8 @@ class AMDSMICommands(): bus=None, vbios=None, limit=None, driver=None, ras=None, board=None, numa=None, vram=None, cache=None, partition=None, dfc_ucode=None, fb_info=None, num_vf=None, cpu=None, - interface_ver=None, soc_pstate=None, xgmi_plpd = None, process_isolation=None): + interface_ver=None, soc_pstate=None, xgmi_plpd = None, process_isolation=None, + clock=None): """Get Static information for target gpu and cpu Args: @@ -916,7 +976,7 @@ class AMDSMICommands(): gpu_attributes = ["asic", "bus", "vbios", "limit", "driver", "ras", "board", "numa", "vram", "cache", "partition", "dfc_ucode", "fb_info", "num_vf", "soc_pstate", "xgmi_plpd", - "process_isolation"] + "process_isolation", "clock"] for attr in gpu_attributes: if hasattr(args, attr): if getattr(args, attr): @@ -947,7 +1007,7 @@ class AMDSMICommands(): bus, vbios, limit, driver, ras, board, numa, vram, cache, partition, dfc_ucode, fb_info, num_vf, soc_pstate, - process_isolation) + process_isolation, clock) elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized if args.cpu == None: args.cpu = self.cpu_handles @@ -962,7 +1022,7 @@ class AMDSMICommands(): bus, vbios, limit, driver, ras, board, numa, vram, cache, partition, dfc_ucode, fb_info, num_vf, soc_pstate, xgmi_plpd, - process_isolation) + process_isolation, clock) def firmware(self, args, multiple_devices=False, gpu=None, fw_list=True): diff --git a/amdsmi_cli/amdsmi_parser.py b/amdsmi_cli/amdsmi_parser.py index 27d0aeb601..21aec247cb 100644 --- a/amdsmi_cli/amdsmi_parser.py +++ b/amdsmi_cli/amdsmi_parser.py @@ -607,6 +607,10 @@ class AMDSMIParser(argparse.ArgumentParser): soc_pstate_help = "The available soc pstate policy" xgmi_plpd_help = "The available XGMI per-link power down policy" process_isolation_help = "The process isolation status" + clk_options = self.helpers.get_clock_types()[0] + clk_options.remove('PCIE') + clk_option_str = ", ".join(clk_options) + ", ALL" + clock_help = f"Show one or more valid clock frequency levels. Available options:\n\t{clk_option_str}" # Options arguments help text for Hypervisors and Baremetal ras_help = "Displays RAS features information" @@ -642,6 +646,7 @@ class AMDSMIParser(argparse.ArgumentParser): static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) static_parser.add_argument('-R', '--process-isolation', action='store_true', required=False, help=process_isolation_help) static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) + static_parser.add_argument('-C', '--clock', default=False, nargs='*', type=str, required=False, help=clock_help) # Options to display on Hypervisors and Baremetal if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): diff --git a/docs/how-to/amdsmi-cli-tool.md b/docs/how-to/amdsmi-cli-tool.md index 687d164ede..daaf17056e 100644 --- a/docs/how-to/amdsmi-cli-tool.md +++ b/docs/how-to/amdsmi-cli-tool.md @@ -158,6 +158,8 @@ Static Arguments: -B, --board All board information -R, --process-isolation The process isolation status -r, --ras Displays RAS features information + -C, --clock [CLOCK ...] Show one or more valid clock frequency levels. Available options: + SYS, DF, DCEF, SOC, MEM, VCLK0, VCLK1, DCLK0, DCLK1, ALL -p, --partition Partition information -l, --limit All limit metric values (i.e. power and thermal limits) -P, --policy The available DPM policy @@ -855,5 +857,35 @@ GPU: 0 CACHE_LEVEL: 3 MAX_NUM_CU_SHARED: 228 NUM_CACHE_INSTANCE: 1 + CLOCK: + SYS: + CURRENT LEVEL: 2 + FREQUENCY_LEVELS: + 0: 300 MHz + 1: 904 MHz + 2: 1165 MHz + 3: 1360 MHz + 4: 1440 MHz + 5: 1544 MHz + 6: 1627 MHz + 7: 1720 MHz + 8: 1800 MHz + DF: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 1400 MHz + DCEF: N/A + SOC: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 302 MHz + MEM: + CURRENT LEVEL: 0 + FREQUENCY_LEVELS: + 0: 167 MHz + VCLK0: N/A + VCLK1: N/A + DCLK1: N/A + DCLK0: N/A ... ``` From 5f9c2db6f37d93335ce2ddc3af5c0c2acfcfd20d Mon Sep 17 00:00:00 2001 From: gabrpham Date: Wed, 4 Dec 2024 11:46:59 -0600 Subject: [PATCH 21/23] [SWDEV-484382] Added new command `amd-smi set -c/--clk-level` Signed-off-by: gabrpham Change-Id: If45152e3a3c94f65b6a8a960601b9ed16fa3d0d7 --- CHANGELOG.md | 12 ++++++ amdsmi_cli/amdsmi_commands.py | 73 +++++++++++++++++++++++++++++--- amdsmi_cli/amdsmi_parser.py | 33 +++++++++++++++ docs/how-to/amdsmi-cli-tool.md | 2 + py-interface/amdsmi_interface.py | 18 ++++++-- 5 files changed, 127 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6749e6226..f450b505e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Added +- **Added new command `amd-smi set -c/--clock-level`**. + This new command sets the performance level of the selected clock on the desired GPUs. The command can accept a range of acceptable levels, but will not set the level when a level is beyond the number of frequency levels as show in `amd-smi static -C/--clock` + +```shell +sudo amd-smi set -c sclk 5 6 +GPU: 0 + CLK_LEVEL: Successfully changed sclk perf level(s) to 5, 6 + +GPU: 1 + CLK_LEVEL: level(s) 5, 6 is/are greater than performance levels supported for device +``` + - **Added new command `amd-smi static -C/--clock`**. This new command displays the clock frequency performance levels for the selected GPUs and clocks. diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9262e02ca7..9073594e99 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -31,7 +31,7 @@ import os from _version import __version__ from amdsmi_helpers import AMDSMIHelpers from amdsmi_logger import AMDSMILogger -from amdsmi_cli_exceptions import AmdSmiRequiredCommandException, AmdSmiInvalidParameterValueException +from amdsmi_cli_exceptions import AmdSmiRequiredCommandException, AmdSmiInvalidParameterException from rocm_version import get_rocm_version from amdsmi import amdsmi_interface from amdsmi import amdsmi_exception @@ -871,7 +871,7 @@ class AMDSMICommands(): else: clk_type_conversion = "N/A" output_format = self.helpers.get_output_format() - raise AmdSmiInvalidParameterValueException(clk_type, output_format) # clk type given is bad + raise AmdSmiInvalidParameterException(clk_type, output_format) # clk type given is bad try: frequencies = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, clk_type_conversion) @@ -3897,7 +3897,7 @@ class AMDSMICommands(): def set_gpu(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, profile=None, perf_determinism=None, compute_partition=None, memory_partition=None, power_cap=None, soc_pstate=None, xgmi_plpd = None, - process_isolation=None, clk_limit=None): + process_isolation=None, clk_limit=None, clk_level=None): """Issue reset commands to target gpu(s) Args: @@ -3946,6 +3946,8 @@ class AMDSMICommands(): args.process_isolation = process_isolation if clk_limit: args.clk_limit = clk_limit + if clk_level: + args.clk_level = clk_level # Handle No GPU passed if args.gpu == None: @@ -3969,6 +3971,7 @@ class AMDSMICommands(): args.power_cap is not None, args.soc_pstate is not None, args.xgmi_plpd is not None, + args.clk_level is not None, args.clk_limit is not None, args.process_isolation is not None]): command = " ".join(sys.argv[1:]) @@ -4220,6 +4223,62 @@ class AMDSMICommands(): raise PermissionError('Command requires elevation') from e raise ValueError(f"Unable to set XGMI policy to {args.xgmi_plpd} on {gpu_string}") from e self.logger.store_output(args.gpu, 'xgmiplpd', f"Successfully set per-link power down policy to id {args.xgmi_plpd}") + if isinstance(args.clk_level, tuple): + clk_type = args.clk_level.clk_type + perf_levels = args.clk_level.perf_levels + + # check if perf levels are all valid levels + try: + if clk_type == "sclk": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.SYS + elif clk_type == "mclk": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.MEM + elif clk_type == "pcie": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.PCIE + elif clk_type == "fclk": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.DF + elif clk_type == "socclk": + clk_type_conversion = amdsmi_interface.AmdSmiClkType.SOC + else: + clk_type_conversion = "N/A" + frequencies = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, clk_type_conversion) + num_supported = frequencies['num_supported'] + except amdsmi_exception.AmdSmiLibraryException as e: + pass + + # convert perf_levels given to freq bit mask + freq_mask = 0 + valid_level = True + invalid_levels = [] + for level in perf_levels: + if level < num_supported: + freq_mask += 2**level + else: + # cancel this instance since the level should not be possible + invalid_levels.append(level) + valid_level = False + + if valid_level: + perf_levels_str = str(perf_levels).strip('[]') + if clk_type.lower() == "pcie": + try: + amdsmi_interface.amdsmi_set_gpu_pci_bandwidth(args.gpu, freq_mask) + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + raise ValueError(f"Unable to set pcie bandwidth to perf level(s) {perf_levels_str} on {gpu_string}") from e + else: + try: + amdsmi_interface.amdsmi_set_clk_freq(args.gpu, clk_type, freq_mask) + except amdsmi_exception.AmdSmiLibraryException as e: + if e.get_error_code() == amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NO_PERM: + raise PermissionError('Command requires elevation') from e + raise ValueError(f"Unable to set {clk_type} to perf level(s) {perf_levels_str} on {gpu_string}") from e + self.logger.store_output(args.gpu, 'clk_level', f"Successfully changed {clk_type} perf level(s) to {perf_levels_str}") + else: + invalid_levels_str = str(invalid_levels).strip('[]') + self.logger.store_output(args.gpu, 'clk_level', f"level(s) {invalid_levels_str} is/are greater than performance levels supported for device") + if isinstance(args.clk_limit, tuple): clk_type = args.clk_limit.clk_type lim_type = args.clk_limit.lim_type @@ -4294,7 +4353,7 @@ class AMDSMICommands(): cpu_pwr_eff_mode=None, cpu_gmi3_link_width=None, cpu_pcie_link_rate=None, cpu_df_pstate_range=None, cpu_enable_apb=None, cpu_disable_apb=None, soc_boost_limit=None, core=None, core_boost_limit=None, soc_pstate=None, xgmi_plpd=None, - process_isolation=None, clk_limit=None): + process_isolation=None, clk_limit=None, clk_level=None): """Issue reset commands to target gpu(s) Args: @@ -4346,7 +4405,7 @@ class AMDSMICommands(): gpu_args_enabled = False gpu_attributes = ["fan", "perf_level", "profile", "perf_determinism", "compute_partition", "memory_partition", "power_cap", "soc_pstate", "xgmi_plpd", - "process_isolation", "clk_limit"] + "process_isolation", "clk_limit", "clk_level"] for attr in gpu_attributes: if hasattr(args, attr): if getattr(args, attr) is not None: @@ -4414,7 +4473,7 @@ class AMDSMICommands(): self.set_gpu(args, multiple_devices, gpu, fan, perf_level, profile, perf_determinism, compute_partition, memory_partition, power_cap, soc_pstate, xgmi_plpd, - process_isolation, clk_limit) + process_isolation, clk_limit, clk_level) elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized if args.cpu == None and args.core == None: raise ValueError('No CPU or CORE provided, specific target(s) are needed') @@ -4434,7 +4493,7 @@ class AMDSMICommands(): self.set_gpu(args, multiple_devices, gpu, fan, perf_level, profile, perf_determinism, compute_partition, memory_partition, power_cap, soc_pstate, xgmi_plpd, - process_isolation, clk_limit) + process_isolation, clk_limit, clk_level) def reset(self, args, multiple_devices=False, gpu=None, gpureset=None, diff --git a/amdsmi_cli/amdsmi_parser.py b/amdsmi_cli/amdsmi_parser.py index 21aec247cb..a6fbbc0c15 100644 --- a/amdsmi_cli/amdsmi_parser.py +++ b/amdsmi_cli/amdsmi_parser.py @@ -203,6 +203,37 @@ class AMDSMIParser(argparse.ArgumentParser): return AMDSMILimitArgs + def _level_select(self): + """Custom action for setting clock frequencies to particular performance level""" + output_format = self.helpers.get_output_format() + + class AMDSMIFreqArgs(argparse.Action): + def __call__(self, parser: AMDSMIParser, namespace: argparse.Namespace, + values: list, option_string: Optional[str] = None) -> None: + # valid values + valid_clk_types = ('sclk', 'mclk', 'pcie', 'fclk', 'socclk') + clk_type = values[0] + perf_levels_str = values[1:] + + # Check if the sclk and mclk parameters are valid + if clk_type not in valid_clk_types: + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterException(clk_type, output_format) + + perf_levels = [] + # Check if every item in perf level is valid + for level in perf_levels_str: + if not level.isdigit(): + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(level, output_format) + level = int(level) + if level < 0: + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(level, output_format) + perf_levels.append(level) + + clk_level_args = collections.namedtuple('clk_level_args', ['clk_type', 'perf_levels']) + setattr(namespace, self.dest, clk_level_args(clk_type, perf_levels)) + return AMDSMIFreqArgs + + def _check_output_file_path(self): """ Argument action validator: Returns a path to a file from the output file path provided. @@ -1052,6 +1083,7 @@ class AMDSMIParser(argparse.ArgumentParser): set_soc_pstate_help = "Set the GPU soc pstate policy using policy id\n" set_xgmi_plpd_help = "Set the GPU XGMI per-link power down policy using policy id\n" set_clk_limit_help = "Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies:\n\tamd-smi set -L (sclk | mclk) (min | max) value" + set_clock_freq_help = "Set the sclk (aka gfxclk), mclk, fclk, pcie, or socclk frequency performance level.\nCan take range of acceptable levels." set_process_isolation_help = "Enable or disable the GPU process isolation on a per partition basis:\n\t0 for disable and 1 for enable.\n" # Help text for CPU set options @@ -1091,6 +1123,7 @@ class AMDSMIParser(argparse.ArgumentParser): set_value_parser.add_argument('-o', '--power-cap', action='store', type=self._positive_int, required=False, help=set_power_cap_help, metavar='WATTS') set_value_parser.add_argument('-p', '--soc-pstate', action='store', required=False, type=self._not_negative_int, help=set_soc_pstate_help, metavar='POLICY_ID') set_value_parser.add_argument('-x', '--xgmi-plpd', action='store', required=False, type=self._not_negative_int, help=set_xgmi_plpd_help, metavar='POLICY_ID') + set_value_parser.add_argument('-c', '--clk-level', action=self._level_select(), nargs='+', required=False, help=set_clock_freq_help, metavar=('CLK_TYPE', 'PERF_LEVELS')) set_value_parser.add_argument('-L', '--clk-limit', action=self._limit_select(), nargs=3, required=False, help=set_clk_limit_help, metavar=('CLK_TYPE', 'LIM_TYPE', 'VALUE')) set_value_parser.add_argument('-R', '--process-isolation', action='store', choices=[0,1], type=self._not_negative_int, required=False, help=set_process_isolation_help, metavar='STATUS') diff --git a/docs/how-to/amdsmi-cli-tool.md b/docs/how-to/amdsmi-cli-tool.md index daaf17056e..1f3589dec2 100644 --- a/docs/how-to/amdsmi-cli-tool.md +++ b/docs/how-to/amdsmi-cli-tool.md @@ -540,6 +540,8 @@ Set Arguments: -o, --power-cap WATTS Set power capacity limit -p, --soc-pstate POLICY_ID Set the GPU soc pstate policy using policy id -x, --xgmi-plpd POLICY_ID Set the GPU XGMI per-link power down policy using policy id + -c, --clk-level CLK_TYPE [PERF_LEVELS ...] Set the sclk (aka gfxclk), mclk, fclk, pcie, or socclk frequency performance level. + Can take range of acceptable levels. -L, --clk-limit CLK_TYPE LIM_TYPE VALUE Sets the sclk (aka gfxclk) or mclk minimum and maximum frequencies amd-smi set -L (sclk | mclk) (min | max) value -R, --process-isolation STATUS Enable or disable the GPU process isolation: diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 95abd19238..1a809a0fe6 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -2956,21 +2956,31 @@ def amdsmi_reset_gpu_fan( def amdsmi_set_clk_freq( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, - clk_type: AmdSmiClkType, + clk_type: str, freq_bitmask: int, ): if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): raise AmdSmiParameterException( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) - if not isinstance(clk_type, AmdSmiClkType): - raise AmdSmiParameterException(clk_type, AmdSmiParameterException) + if clk_type.lower() == "sclk": + clk_type_conversion = AmdSmiClkType.SYS + elif clk_type.lower() == "mclk": + clk_type_conversion = AmdSmiClkType.MEM + elif clk_type.lower() == "fclk": + clk_type_conversion = AmdSmiClkType.DF + elif clk_type.lower() == "socclk": + clk_type_conversion = AmdSmiClkType.SOC + else: + clk_type_conversion = "N/A" + if not isinstance(clk_type_conversion, AmdSmiClkType): + raise AmdSmiParameterException(clk_type_conversion, AmdSmiClkType) if not isinstance(freq_bitmask, int): raise AmdSmiParameterException(freq_bitmask, int) freq_bitmask = ctypes.c_uint64(freq_bitmask) _check_res( amdsmi_wrapper.amdsmi_set_clk_freq( - processor_handle, clk_type, freq_bitmask + processor_handle, clk_type_conversion, freq_bitmask ) ) From fe290a20569bd4adeee3b2da88dd4a8fc61e45a2 Mon Sep 17 00:00:00 2001 From: gabrpham Date: Wed, 4 Dec 2024 13:54:20 -0600 Subject: [PATCH 22/23] [SWDEV-484382] Added fclk and socclk to `amd-smi metric -c` Signed-off-by: gabrpham Change-Id: Ie7e19c757b05455693c0d26eeb5e8b6c1e238375 --- CHANGELOG.md | 22 +++++++++++- amdsmi_cli/amdsmi_commands.py | 67 +++++++++++++++++++++++++++++++++++ src/amd_smi/amd_smi.cc | 7 ++++ src/amd_smi/amd_smi_utils.cc | 6 ++++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f450b505e5..d8c59176fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,28 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Added +- **Added fclk and socclk info to `amd-smi metric -c/--clock`**. + fclk and socclk information such as min and max clock have been added to the metric command, in line with all the other clocks. + + ```shell + amd-smi metric -c -g 1 + ... + FCLK_0: + CLK: 2301 MHz + MIN_CLK: 601 MHz + MAX_CLK: 2301 MHz + CLK_LOCKED: N/A + DEEP_SLEEP: DISABLED + SOCCLK_0: + CLK: 1500 MHz + MIN_CLK: 500 MHz + MAX_CLK: 1500 MHz + CLK_LOCKED: N/A + DEEP_SLEEP: DISABLED + ``` + - **Added new command `amd-smi set -c/--clock-level`**. - This new command sets the performance level of the selected clock on the desired GPUs. The command can accept a range of acceptable levels, but will not set the level when a level is beyond the number of frequency levels as show in `amd-smi static -C/--clock` + This new command sets the performance level of the selected clock on the desired GPUs. The command can accept a range of acceptable levels, but will not set the level when a level is beyond the number of frequency levels as show in `amd-smi static -C/--clock`. ```shell sudo amd-smi set -c sclk 5 6 diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 9073594e99..957b2c8031 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -1682,6 +1682,18 @@ class AMDSMICommands(): "clk_locked" : "N/A", "deep_sleep" : "N/A"} + clocks["fclk_0"] = {"clk" : "N/A", + "min_clk" : "N/A", + "max_clk" : "N/A", + "clk_locked" : "N/A", + "deep_sleep" : "N/A"} + + clocks["socclk_0"] = {"clk" : "N/A", + "min_clk" : "N/A", + "max_clk" : "N/A", + "clk_locked" : "N/A", + "deep_sleep" : "N/A"} + clock_unit = "MHz" # TODO make the deepsleep threshold correspond to the * in sysfs for current deep sleep status deep_sleep_threshold = 140 @@ -1759,6 +1771,31 @@ class AMDSMICommands(): clocks[dclk_index]["deep_sleep"] = "ENABLED" else: clocks[dclk_index]["deep_sleep"] = "DISABLED" + + # Populate FCLK clock value; fclk not present in gpu_metrics so use amdsmi_get_clk_freq + frequency_dict = amdsmi_interface.amdsmi_get_clk_freq(args.gpu, amdsmi_interface.AmdSmiClkType.DF) + current_fclk_clock = frequency_dict['frequency'][frequency_dict['current']] + current_fclk_clock = self.helpers.convert_SI_unit(current_fclk_clock, self.helpers.SI_Unit.MICRO) + clocks["fclk_0"]["clk"] = self.helpers.unit_format(self.logger, + current_fclk_clock, + clock_unit) + + if int(current_fclk_clock) <= deep_sleep_threshold: + clocks["fclk_0"]["deep_sleep"] = "ENABLED" + else: + clocks["fclk_0"]["deep_sleep"] = "DISABLED" + + # Populate SOCCLK clock value + current_socclk_clock = gpu_metric["current_socclk"] + clocks["socclk_0"]["clk"] = self.helpers.unit_format(self.logger, + current_socclk_clock, + clock_unit) + + if int(current_socclk_clock) <= deep_sleep_threshold: + clocks["socclk_0"]["deep_sleep"] = "ENABLED" + else: + clocks["socclk_0"]["deep_sleep"] = "DISABLED" + except Exception as e: logging.debug("Failed to get gpu_metrics_info for gpu %s | %s", gpu_id, e) @@ -1831,6 +1868,36 @@ class AMDSMICommands(): except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get vclk and/or dclk clock info for gpu %s | %s", gpu_id, e.get_error_info()) + # FCLK min and max clocks + try: + fclk_clk_info_dict = amdsmi_interface.amdsmi_get_clock_info(args.gpu, + amdsmi_interface.AmdSmiClkType.DF) + # if the current clock is N/A then we shouldn't populate the max and min values + if clocks["fclk_0"]["clk"] != "N/A": + clocks["fclk_0"]["min_clk"] = self.helpers.unit_format(self.logger, + fclk_clk_info_dict["min_clk"], + clock_unit) + clocks["fclk_0"]["max_clk"] = self.helpers.unit_format(self.logger, + fclk_clk_info_dict["max_clk"], + clock_unit) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get fclk info for gpu %s | %s", gpu_id, e.get_error_info()) + + # SOCCLK min and max clocks + try: + socclk_clk_info_dict = amdsmi_interface.amdsmi_get_clock_info(args.gpu, + amdsmi_interface.AmdSmiClkType.SOC) + # if the current clock is N/A then we shouldn't populate the max and min values + if clocks["socclk_0"]["clk"] != "N/A": + clocks["socclk_0"]["min_clk"] = self.helpers.unit_format(self.logger, + socclk_clk_info_dict["min_clk"], + clock_unit) + clocks["socclk_0"]["max_clk"] = self.helpers.unit_format(self.logger, + socclk_clk_info_dict["max_clk"], + clock_unit) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get socclk info for gpu %s | %s", gpu_id, e.get_error_info()) + values_dict['clock'] = clocks if "temperature" in current_platform_args: if args.temperature: diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 2f5cfd3821..4bed5a380f 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -2217,6 +2217,13 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_ case AMDSMI_CLK_TYPE_DCLK1: info->clk = metrics.current_dclk1; break; + case AMDSMI_CLK_TYPE_SOC: + info->clk = metrics.current_socclk; + break; + // fclk/df not supported by gpu metrics so providing default value which cannot be contrued to be valid + case AMDSMI_CLK_TYPE_DF: + info->clk = UINT32_MAX; + break; default: return AMDSMI_STATUS_INVAL; } diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index 7f79b24a09..4c6a8cc74e 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -275,6 +275,12 @@ amdsmi_status_t smi_amdgpu_get_ranges(amd::smi::AMDSmiGPUDevice* device, amdsmi_ case AMDSMI_CLK_TYPE_DCLK1: fullpath += "/pp_dpm_dclk1"; break; + case AMDSMI_CLK_TYPE_SOC: + fullpath += "/pp_dpm_socclk"; + break; + case AMDSMI_CLK_TYPE_DF: + fullpath += "/pp_dpm_fclk"; + break; default: return AMDSMI_STATUS_INVAL; } From d0a7332d3257928886b494c13cd92089e34ee847 Mon Sep 17 00:00:00 2001 From: Joe Narlo Date: Tue, 19 Nov 2024 08:13:18 -0600 Subject: [PATCH 23/23] SWDEV-492272 [AMDSMI] Build/Compiler warnings messages Fix compiler warnings Signed-off-by: Joe Narlo Change-Id: I10657b8f3ef18a9b45311e8f6509958297a57823 --- example/amd_smi_drm_example.cc | 92 +++++++++---------- example/amd_smi_nodrm_example.cc | 20 ++-- example/amdsmi_esmi_intg_example.cc | 5 +- rocm_smi/example/rocm_smi_example.cc | 4 +- rocm_smi/include/rocm_smi/rocm_smi_utils.h | 2 +- rocm_smi/src/rocm_smi.cc | 65 ++----------- rocm_smi/src/rocm_smi_binary_parser.cc | 23 ++--- rocm_smi/src/rocm_smi_device.cc | 2 - rocm_smi/src/rocm_smi_gpu_metrics.cc | 15 ++- rocm_smi/src/rocm_smi_kfd.cc | 5 +- rocm_smi/src/rocm_smi_main.cc | 11 +-- rocm_smi/src/rocm_smi_utils.cc | 25 +---- src/amd_smi/amd_smi.cc | 41 +++++---- src/amd_smi/amd_smi_drm.cc | 7 +- src/amd_smi/amd_smi_system.cc | 4 + src/amd_smi/amd_smi_utils.cc | 3 +- src/amd_smi/fdinfo.cc | 24 ++--- .../functional/api_support_read.cc | 2 - tests/amd_smi_test/functional/fan_read.cc | 2 +- .../amd_smi_test/functional/fan_read_write.cc | 7 +- .../amd_smi_test/functional/gpu_busy_read.cc | 3 - .../functional/hw_topology_read.cc | 8 +- tests/amd_smi_test/functional/id_info_read.cc | 1 - .../functional/init_shutdown_refcount.cc | 2 +- .../amd_smi_test/functional/mem_util_read.cc | 2 +- .../functional/metrics_counter_read.cc | 2 +- .../functional/mutual_exclusion.cc | 1 - .../functional/perf_cntr_read_write.cc | 6 +- tests/amd_smi_test/functional/power_read.cc | 2 - .../amd_smi_test/functional/sys_info_read.cc | 2 - .../functional/xgmi_read_write.cc | 1 - 31 files changed, 164 insertions(+), 225 deletions(-) diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index f006ac05f9..56050d6bb2 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -262,11 +263,11 @@ int main() { ret = amdsmi_get_gpu_device_bdf(processor_handles[j], &bdf); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_gpu_device_bdf:\n"); - printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i, - bdf.domain_number, - bdf.bus_number, - bdf.device_number, - bdf.function_number); + printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i, + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); // Get handle from BDF amdsmi_processor_handle dev_handle; @@ -408,12 +409,12 @@ int main() { printf("\tPCIe max speed: %d\n", pcie_info.pcie_static.max_pcie_speed); // additional pcie related metrics - printf("\tPCIe bandwidth: %d\n", pcie_info.pcie_metric.pcie_bandwidth); - printf("\tPCIe replay count: %d\n", pcie_info.pcie_metric.pcie_replay_count); - printf("\tPCIe L0 recovery count: %d\n", pcie_info.pcie_metric.pcie_l0_to_recovery_count); - printf("\tPCIe rollover count: %d\n", pcie_info.pcie_metric.pcie_replay_roll_over_count); - printf("\tPCIe nak received count: %d\n", pcie_info.pcie_metric.pcie_nak_received_count); - printf("\tPCIe nak sent count: %d\n", pcie_info.pcie_metric.pcie_nak_sent_count); + printf("\tPCIe bandwidth: %u\n", pcie_info.pcie_metric.pcie_bandwidth); + printf("\tPCIe replay count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_replay_count); + printf("\tPCIe L0 recovery count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_l0_to_recovery_count); + printf("\tPCIe rollover count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_replay_roll_over_count); + printf("\tPCIe nak received count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_nak_received_count); + printf("\tPCIe nak sent count: %" PRIu64 "\n", pcie_info.pcie_metric.pcie_nak_sent_count); // Get VRAM temperature limit int64_t temperature = 0; @@ -522,13 +523,6 @@ int main() { printf("\tCorrectable errors: %lu\n", err_cnt_info.correctable_count); printf("\tUncorrectable errors: %lu\n\n", err_cnt_info.uncorrectable_count); - // Get process list - auto compare = [](const void *a, const void *b) -> int { - return (*(amdsmi_proc_info_t *)a).pid > - (*(amdsmi_proc_info_t *)b).pid - ? 1 - : -1; - }; uint32_t num_process = 0; ret = amdsmi_get_gpu_process_list(processor_handles[j], &num_process, nullptr); @@ -542,18 +536,17 @@ int main() { uint64_t mem = 0, gtt_mem = 0, cpu_mem = 0, vram_mem = 0; uint64_t gfx = 0, enc = 0; char bdf_str[20]; - sprintf(bdf_str, "%04lx:%02x:%02x.%d", - bdf.domain_number, - bdf.bus_number, - bdf.device_number, - bdf.function_number); - int num = 0; + sprintf(bdf_str, "%04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32, + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); ret = amdsmi_get_gpu_process_list(processor_handles[j], &num_process, process_info_list); std::cout << "Allocation size for process list: " << num_process << "\n"; CHK_AMDSMI_RET(ret); for (auto idx = uint32_t(0); idx < num_process; ++idx) { process = static_cast(process_info_list[idx]); - printf("\t *Process id: %ld / Name: %s / VRAM: %lld \n", process.pid, process.name, process.memory_usage.vram_mem); + printf("\t *Process id: %d / Name: %s / VRAM: %ld \n", process.pid, process.name, process.memory_usage.vram_mem); } printf("+=======+==================+============+==============" @@ -569,7 +562,7 @@ int main() { printf("+=======+" "+=============+=============+=============+============" "==+=========================================+\n"); - for (int it = 0; it < num_process; it++) { + for (int it = 0; it < static_cast(num_process); it++) { char command[30]; struct passwd *pwd = nullptr; struct stat st; @@ -609,11 +602,13 @@ int main() { "-+-------------+-------------+-------------+----------" "----+-----------------------------------------+\n"); } + // TODO: To remove compiler warning, the last 3 values in this printf were + // set to 0L. Need to find out what these values need to be. printf("| TOTAL:| %s | %7ld " "KiB | %7ld KiB | %7ld KiB | %7ld KiB | %lu %lu " "%lu %lu %lu |\n", bdf_str, mem, gtt_mem, cpu_mem, vram_mem, gfx, - enc); + enc, 0L, 0L, 0L); printf("+=======+==================+============+==============" "+=============+=============+=============+============" "=+==========================================+\n"); @@ -674,11 +669,11 @@ int main() { ret = amdsmi_get_gpu_metrics_info(processor_handles[j], &smu); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_gpu_metrics_info:\n"); - printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i, - bdf.domain_number, - bdf.bus_number, - bdf.device_number, - bdf.function_number); + printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i, + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); std::cout << "METRIC TABLE HEADER:\n"; std::cout << "structure_size=" << std::dec @@ -706,7 +701,7 @@ int main() { auto idx = 0; for (const auto& temp : smu.temperature_hbm) { std::cout << temp; - if ((idx + 1) != std::size(smu.temperature_hbm)) { + if ((idx + 1) != static_cast(std::size(smu.temperature_hbm))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -723,7 +718,7 @@ int main() { idx = 0; for (const auto& temp : smu.vcn_activity) { std::cout << temp; - if ((idx + 1) != std::size(smu.vcn_activity)) { + if ((idx + 1) != static_cast(std::size(smu.vcn_activity))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -736,7 +731,7 @@ int main() { idx = 0; for (const auto& temp : smu.jpeg_activity) { std::cout << temp; - if ((idx + 1) != std::size(smu.jpeg_activity)) { + if ((idx + 1) != static_cast(std::size(smu.jpeg_activity))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -773,7 +768,7 @@ int main() { idx = 0; for (const auto& temp : smu.current_gfxclks) { std::cout << temp; - if ((idx + 1) != std::size(smu.current_gfxclks)) { + if ((idx + 1) != static_cast(std::size(smu.current_gfxclks))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -786,7 +781,7 @@ int main() { idx = 0; for (const auto& temp : smu.current_socclks) { std::cout << temp; - if ((idx + 1) != std::size(smu.current_socclks)) { + if ((idx + 1) != static_cast(std::size(smu.current_socclks))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -800,7 +795,7 @@ int main() { idx = 0; for (const auto& temp : smu.current_vclk0s) { std::cout << temp; - if ((idx + 1) != std::size(smu.current_vclk0s)) { + if ((idx + 1) != static_cast(std::size(smu.current_vclk0s))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -813,7 +808,7 @@ int main() { idx = 0; for (const auto& temp : smu.current_dclk0s) { std::cout << temp; - if ((idx + 1) != std::size(smu.current_dclk0s)) { + if ((idx + 1) != static_cast(std::size(smu.current_dclk0s))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -850,7 +845,7 @@ int main() { idx = 0; for (const auto& temp : smu.xgmi_read_data_acc) { std::cout << temp; - if ((idx + 1) != std::size(smu.xgmi_read_data_acc)) { + if ((idx + 1) != static_cast(std::size(smu.xgmi_read_data_acc))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -862,7 +857,7 @@ int main() { idx = 0; for (const auto& temp : smu.xgmi_write_data_acc) { std::cout << temp; - if ((idx + 1) != std::size(smu.xgmi_write_data_acc)) { + if ((idx + 1) != static_cast(std::size(smu.xgmi_write_data_acc))) { std::cout << ", "; } else { std::cout << "]\n"; @@ -922,7 +917,7 @@ int main() { for (auto& row : smu.xcp_stats) { std::cout << "\t XCP [" << idx << "] : ["; for (auto& col : row.gfx_busy_inst) { - if ((idy + 1) != std::size(row.gfx_busy_inst)) { + if ((idy + 1) != static_cast(std::size(row.gfx_busy_inst))) { std::cout << col << ", "; } else { std::cout << col; @@ -940,7 +935,7 @@ int main() { for (auto& row : smu.xcp_stats) { std::cout << "\t XCP [" << idx << "] : ["; for (auto& col : row.vcn_busy) { - if ((idy + 1) != std::size(row.vcn_busy)) { + if ((idy + 1) != static_cast(std::size(row.vcn_busy))) { std::cout << col << ", "; } else { std::cout << col; @@ -958,7 +953,7 @@ int main() { for (auto& row : smu.xcp_stats) { std::cout << "\t XCP [" << idx << "] : ["; for (auto& col : row.jpeg_busy) { - if ((idy + 1) != std::size(row.jpeg_busy)) { + if ((idy + 1) != static_cast(std::size(row.jpeg_busy))) { std::cout << col << ", "; } else { std::cout << col; @@ -976,7 +971,7 @@ int main() { for (auto& row : smu.xcp_stats) { std::cout << "\t XCP [" << idx << "] : ["; for (auto& col : row.gfx_busy_acc) { - if ((idy + 1) != std::size(row.gfx_busy_acc)) { + if ((idy + 1) != static_cast(std::size(row.gfx_busy_acc))) { std::cout << col << ", "; } else { std::cout << col; @@ -1040,8 +1035,11 @@ int main() { amdsmi_bdf_t bdf = {}; ret = amdsmi_get_gpu_device_bdf(topology_nearest_info.processor_list[k], &bdf); CHK_AMDSMI_RET(ret) - printf("\t\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number, - bdf.bus_number, bdf.device_number, bdf.function_number); + printf("\t\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n", + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); } } } diff --git a/example/amd_smi_nodrm_example.cc b/example/amd_smi_nodrm_example.cc index bdcca88838..583af1a178 100644 --- a/example/amd_smi_nodrm_example.cc +++ b/example/amd_smi_nodrm_example.cc @@ -21,6 +21,7 @@ */ #include +#include #include #include @@ -114,11 +115,11 @@ int main() { ret = amdsmi_get_gpu_device_bdf(processor_handles[j], &bdf); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_gpu_device_bdf:\n"); - printf("\tDevice[%d] BDF %04lx:%02x:%02x.%d\n\n", i, - bdf.domain_number, - bdf.bus_number, - bdf.device_number, - bdf.function_number); + printf("\tDevice[%d] BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n\n", i, + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); amdsmi_asic_info_t asic_info = {}; ret = amdsmi_get_gpu_asic_info(processor_handles[j], &asic_info); @@ -319,7 +320,7 @@ int main() { CHK_AMDSMI_RET(ret) std::cout << "\t amdsmi_get_soc_pstate total:" << policy.num_supported <<" current:" << policy.current << "\n"; - for (int x=0; x < policy.num_supported; x++) { + for (uint32_t x=0; x < policy.num_supported; x++) { std::cout << x <<": (" << policy.policies[x].policy_id <<"," << policy.policies[x].policy_description << ")\n"; } @@ -349,8 +350,11 @@ int main() { amdsmi_bdf_t bdf = {}; ret = amdsmi_get_gpu_device_bdf(topology_nearest_info.processor_list[k], &bdf); CHK_AMDSMI_RET(ret) - printf("\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number, - bdf.bus_number, bdf.device_number, bdf.function_number); + printf("\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n", + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); } } } diff --git a/example/amdsmi_esmi_intg_example.cc b/example/amdsmi_esmi_intg_example.cc index 5f24eb27d0..ea156484ac 100644 --- a/example/amdsmi_esmi_intg_example.cc +++ b/example/amdsmi_esmi_intg_example.cc @@ -54,7 +54,7 @@ using std::fixed; using std::setprecision; using std::vector; -int main(int argc, char **argv) { +int main([[maybe_unused]] int argc, [[maybe_unused]] char **argv) { amdsmi_status_t ret; uint32_t proto_ver; amdsmi_smu_fw_version_t smu_fw = {}; @@ -157,7 +157,7 @@ int main(int argc, char **argv) { retVal = snprintf(str, SHOWLINESZ, "\n| mclk (Mhz)\t\t\t |"); len = strlen(str); - uint32_t fclk, mclk, cclk; + uint32_t fclk, mclk; err_bits = 0; ret = amdsmi_get_cpu_fclk_mclk(plist[index], &fclk, &mclk); @@ -265,7 +265,6 @@ int main(int argc, char **argv) { double fraction_q10 = 1/pow(2,10); double fraction_uq10 = fraction_q10; - const char* err_str1; amdsmi_hsmp_metrics_table_t mtbl = {}; ret = amdsmi_get_hsmp_metrics_table(plist[index], &mtbl); diff --git a/rocm_smi/example/rocm_smi_example.cc b/rocm_smi/example/rocm_smi_example.cc index 8efa6e9288..d5ab8b1cf5 100644 --- a/rocm_smi/example/rocm_smi_example.cc +++ b/rocm_smi/example/rocm_smi_example.cc @@ -695,7 +695,7 @@ static rsmi_status_t test_set_memory_partition(uint32_t dv_ind) { } template constexpr float convert_mw_to_w(T mw) { - return static_cast(mw / 1000.0); + return static_cast(static_cast(mw) / 1000.0); } @@ -1112,7 +1112,7 @@ int main() { if (ret == RSMI_STATUS_SUCCESS) { ret = rsmi_dev_fan_speed_max_get(i, 0, &val_ui64); CHK_AND_PRINT_RSMI_ERR_RET(ret) - std::cout << (static_cast(val_i64)/val_ui64) * 100; + std::cout << (static_cast(val_i64)/static_cast(val_ui64)) * 100; std::cout << "% (" << std::dec << val_i64 << "/" << std::dec << val_ui64 << ")" << "\n"; } diff --git a/rocm_smi/include/rocm_smi/rocm_smi_utils.h b/rocm_smi/include/rocm_smi/rocm_smi_utils.h index 18cfce0d9b..e86780ee3f 100644 --- a/rocm_smi/include/rocm_smi/rocm_smi_utils.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_utils.h @@ -427,7 +427,7 @@ class TagTextContents_t decltype(auto) get_structured_data_subkey_last(const PrimaryKeyType& prim_key) { return (get_structured_value_by_keys(prim_key, get_structured_data_subkey_by_position(prim_key, - (get_structured_subkeys_size(prim_key) - 1)))); + static_cast((get_structured_subkeys_size(prim_key) - 1))))); } void reset() { diff --git a/rocm_smi/src/rocm_smi.cc b/rocm_smi/src/rocm_smi.cc index 6c0a6767f5..2a4b6d1aae 100644 --- a/rocm_smi/src/rocm_smi.cc +++ b/rocm_smi/src/rocm_smi.cc @@ -186,39 +186,6 @@ static uint64_t freq_string_to_int(const std::vector &freq_lines, return static_cast(freq*multiplier); } -static void freq_volt_string_to_point(std::string in_line, - rsmi_od_vddc_point_t *pt) { - std::istringstream fs_vlt(in_line); - - assert(pt != nullptr); - THROW_IF_NULLPTR_DEREF(pt) - - uint32_t ind; - float freq; - float volts; - std::string junk; - std::string freq_units_str; - std::string volts_units_str; - - fs_vlt >> ind; - fs_vlt >> junk; // colon - fs_vlt >> freq; - fs_vlt >> freq_units_str; - fs_vlt >> volts; - fs_vlt >> volts_units_str; - - if (freq < 0) { - throw amd::smi::rsmi_exception(RSMI_STATUS_UNEXPECTED_SIZE, __FUNCTION__); - } - - long double multiplier = get_multiplier_from_str(freq_units_str[0]); - - pt->frequency = static_cast(freq*multiplier); - - multiplier = get_multiplier_from_str(volts_units_str[0]); - pt->voltage = static_cast(volts*multiplier); -} - static void od_value_pair_str_to_range(std::string in_line, rsmi_range_t *rg) { std::istringstream fs_rng(in_line); @@ -898,7 +865,7 @@ rsmi_status_t rsmi_ras_feature_info_get( auto eeprom_version = strtoul( feature_line.substr(strlen(version_key)).c_str(), nullptr, 16); if (errno == 0) { - ras_feature->ras_eeprom_version = eeprom_version; + ras_feature->ras_eeprom_version = static_cast(eeprom_version); } else { return RSMI_STATUS_NOT_SUPPORTED; } @@ -922,7 +889,7 @@ rsmi_status_t rsmi_ras_feature_info_get( auto schema = strtoul( feature_line.substr(strlen(schema_key)).c_str(), nullptr, 16); if (errno == 0) { - ras_feature->ecc_correction_schema_flag = schema; + ras_feature->ecc_correction_schema_flag = static_cast(schema); } else { return RSMI_STATUS_NOT_SUPPORTED; } @@ -2044,7 +2011,7 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind, // will have read-only perms, and the OS will deny access, before the request hits the driver level if (status == RSMI_STATUS_PERMISSION){ bool read_only = false; - int perms = amd::smi::isReadOnlyForAll(dev->path(), &read_only); + amd::smi::isReadOnlyForAll(dev->path(), &read_only); if(read_only){ return RSMI_STATUS_NOT_SUPPORTED; } @@ -2113,8 +2080,6 @@ rsmi_status_t rsmi_dev_process_isolation_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind, uint32_t pisolate) { - rsmi_status_t ret; - TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << " | ======= start ======="; @@ -2178,8 +2143,6 @@ rsmi_status_t rsmi_dev_process_isolation_set(uint32_t dv_ind, } rsmi_status_t rsmi_dev_gpu_run_cleaner_shader(uint32_t dv_ind) { - rsmi_status_t ret; - TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << " | ======= start ======="; @@ -2294,8 +2257,6 @@ rsmi_dev_xgmi_plpd_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_xgmi_plpd_set(uint32_t dv_ind, uint32_t plpd_id) { - rsmi_status_t ret; - TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << " | ======= start ======="; @@ -2408,8 +2369,6 @@ rsmi_dev_soc_pstate_get(uint32_t dv_ind, rsmi_status_t rsmi_dev_soc_pstate_set(uint32_t dv_ind, uint32_t policy_id) { - rsmi_status_t ret; - TRY std::ostringstream ss; ss << __PRETTY_FUNCTION__ << " | ======= start ======="; @@ -2977,25 +2936,25 @@ rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) { return ret; } - // Hardcode based on PCIe specification: Search PCI_Express on wikipedia + // Hardcode based on PCIe specification: search PCI_Express on wikipedia const uint32_t link_width[] = {1, 2, 4, 8, 12, 16}; const uint32_t link_speed[] = {25, 50, 80, 160}; // 0.1 Ghz const uint32_t WIDTH_DATA_LENGTH = sizeof(link_width)/sizeof(uint32_t); const uint32_t SPEED_DATA_LENGTH = sizeof(link_speed)/sizeof(uint32_t); // Calculate the index - uint32_t width_index = -1; - uint32_t speed_index = -1; + int32_t width_index = -1; + int32_t speed_index = -1; uint32_t cur_index = 0; for (cur_index = 0; cur_index < WIDTH_DATA_LENGTH; cur_index++) { if (link_width[cur_index] == gpu_metrics.pcie_link_width) { - width_index = cur_index; + width_index = static_cast(cur_index); break; } } for (cur_index = 0; cur_index < SPEED_DATA_LENGTH; cur_index++) { if (link_speed[cur_index] == gpu_metrics.pcie_link_speed) { - speed_index = cur_index; + speed_index = static_cast(cur_index); break; } } @@ -3004,7 +2963,7 @@ rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) { } // Set possible lanes and frequencies b->transfer_rate.num_supported = WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH; - b->transfer_rate.current = speed_index*WIDTH_DATA_LENGTH + width_index; + b->transfer_rate.current = static_cast(speed_index)*WIDTH_DATA_LENGTH + static_cast(width_index); for (cur_index = 0; cur_index < WIDTH_DATA_LENGTH * SPEED_DATA_LENGTH; cur_index++) { b->transfer_rate.frequency[cur_index] = static_cast(link_speed[cur_index/WIDTH_DATA_LENGTH]) * 100 * 1000000L; @@ -3930,7 +3889,6 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type, rsmi_status_t rsmi_dev_cache_info_get( uint32_t dv_ind, rsmi_gpu_cache_info_t *info) { TRY - rsmi_status_t ret; std::ostringstream ss; ss << __PRETTY_FUNCTION__ << "| ======= start ======="; LOG_TRACE(ss); @@ -4214,7 +4172,6 @@ rsmi_utilization_count_get(uint32_t dv_ind, rsmi_status_t ret; rsmi_gpu_metrics_t gpu_metrics; - uint32_t val_ui32; uint16_t val_counter(0); ret = rsmi_dev_gpu_metrics_info_get(dv_ind, &gpu_metrics); @@ -5704,10 +5661,6 @@ rsmi_dev_memory_partition_set(uint32_t dv_ind, REQUIRE_ROOT_ACCESS DEVICE_MUTEX const int k1000_MS_WAIT = 1000; - const uint32_t kMaxBoardLength = 128; - bool isCorrectDevice = false; - char boardName[kMaxBoardLength]; - boardName[0] = '\0'; const uint32_t kMaxMemoryCapabilitiesSize = 30; char available_memory_capabilities[kMaxMemoryCapabilitiesSize]; diff --git a/rocm_smi/src/rocm_smi_binary_parser.cc b/rocm_smi/src/rocm_smi_binary_parser.cc index 36100ae738..2b6a660cd7 100644 --- a/rocm_smi/src/rocm_smi_binary_parser.cc +++ b/rocm_smi/src/rocm_smi_binary_parser.cc @@ -30,6 +30,7 @@ #include "rocm_smi/rocm_smi_logger.h" #include +#include #include #include @@ -134,7 +135,7 @@ int present_pmmetrics(const char* fname, } table = NULL; - len = fread(buf1, 1, 65536, infile); + len = static_cast(fread(buf1, 1, 65536, infile)); fseek(infile, 0, SEEK_SET); memcpy(&pmmetrics_version, &buf1[12], 4); @@ -156,11 +157,11 @@ int present_pmmetrics(const char* fname, static int parse_reg_state_table(uint8_t *buf, int32_t buflen, struct metric_field *table, rsmi_name_value_t **kv, uint32_t *kvnum) { - int skip_smn, x, y, cur_instance, cur_smn, - num_instance, num_smn, instance_start, smn_start; + uint64_t skip_smn, x, y, cur_instance, cur_smn, + num_instance, num_smn, instance_start, smn_start; uint64_t v; uint8_t *obuf, *origbuf; - int kvsize = 64; + uint32_t kvsize = 64; *kv = reinterpret_cast(calloc(kvsize, sizeof **kv)); *kvnum = 0; @@ -171,7 +172,7 @@ static int parse_reg_state_table(uint8_t *buf, int32_t buflen, origbuf = buf; top: while (table[x].field_name != NULL) { - for (y = 0; y < table[x].field_arr_size; y++) { + for (y = 0; y < static_cast(table[x].field_arr_size); y++) { obuf = buf; v = get_value(&buf, &table[x]); if ((intptr_t)(buf - origbuf) > buflen) { @@ -203,10 +204,10 @@ top: } break; case FIELD_FLAG_NUM_INSTANCE: - num_instance = v; + num_instance = static_cast(v); break; case FIELD_FLAG_NUM_SMN: - num_smn = v; + num_smn = static_cast(v); if (v) skip_smn = 0; else @@ -220,12 +221,12 @@ top: } sprintf((*kv)[*kvnum].name, "%s", table[x].field_name); if (table[x].field_arr_size > 1) { - sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), "[%d]", y); + sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), "[%" PRId64 "]", y); } if (x >= instance_start) - sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".instance[%d]", cur_instance); + sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".instance[%" PRId64 "]", cur_instance); if (x >= smn_start) - sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".smn[%d]", cur_smn); + sprintf((*kv)[*kvnum].name + strlen((*kv)[*kvnum].name), ".smn[%" PRId64 "]", cur_smn); (*kv)[*kvnum].value = v; ++(*kvnum); } @@ -290,7 +291,7 @@ int present_reg_state(const char* fname, return -2; } - len = fread(buf, 1, sizeof buf, infile); + len = static_cast(fread(buf, 1, sizeof buf, infile)); fclose(infile); return parse_reg_state_table(buf, len, tab, kv, kvnum); } diff --git a/rocm_smi/src/rocm_smi_device.cc b/rocm_smi/src/rocm_smi_device.cc index 7621d2819c..6715cfa6d4 100644 --- a/rocm_smi/src/rocm_smi_device.cc +++ b/rocm_smi/src/rocm_smi_device.cc @@ -1474,7 +1474,6 @@ rsmi_status_t Device::restartAMDGpuDriver(void) { bool success = false; std::string out; bool wasGdmServiceActive = false; - bool restartInProgress = true; bool isRestartInProgress = true; bool isAMDGPUModuleLive = false; bool restartGDM = false; @@ -1560,7 +1559,6 @@ rsmi_status_t Device::isRestartInProgress(bool *isRestartInProgress, bool *isAMDGPUModuleLive) { REQUIRE_ROOT_ACCESS std::ostringstream ss; - bool restartSuccessful = true; bool success = false; std::string out; bool deviceRestartInProgress = true; // Assume in progress, we intend to disprove diff --git a/rocm_smi/src/rocm_smi_gpu_metrics.cc b/rocm_smi/src/rocm_smi_gpu_metrics.cc index 69946ac8a6..b7443652bd 100644 --- a/rocm_smi/src/rocm_smi_gpu_metrics.cc +++ b/rocm_smi/src/rocm_smi_gpu_metrics.cc @@ -63,7 +63,7 @@ namespace amd::smi constexpr uint16_t join_metrics_version(uint8_t format_rev, uint8_t content_rev) { - return (format_rev << 8 | content_rev); + return static_cast((format_rev << 8 | content_rev)); } constexpr uint16_t join_metrics_version(const AMDGpuMetricsHeader_v1_t& metrics_header) @@ -473,8 +473,8 @@ AMDGpuDynamicMetricTblValues_t format_metric_row(const T& metric, const std::str void GpuMetricsBase_v16_t::dump_internal_metrics_table() { std::ostringstream ss; - auto idx = uint64_t(0); - auto idy = uint64_t(0); + auto idx = int64_t(0); + auto idy = int64_t(0); std::cout << __PRETTY_FUNCTION__ << " | ======= start ======= \n"; ss << __PRETTY_FUNCTION__ << " | ======= DEBUG ======= " @@ -570,9 +570,16 @@ void GpuMetricsBase_v16_t::dump_internal_metrics_table() } for (auto& col : row.gfx_busy_inst) { ss << "\t [" << idx << "] [" << idy << "]: " << col; +#if 1 // TODO: Refactor this code using make_ostream_joiner + // Do for all occurences in this file if (idy + 1 != (std::end(row.gfx_busy_inst) - std::end(row.gfx_busy_inst) - 1)) { ss << ", "; } +#else + std::copy(std::begin(row.gfx_busy_inst), + std::end(row.gfx_busy_inst), + amd::smi::make_ostream_joiner(&ss, ", ")); +#endif if (idx + 1 != (std::end(m_gpu_metrics_tbl.m_xcp_stats) - std::end(m_gpu_metrics_tbl.m_xcp_stats) - 1)) { ss << "\n"; @@ -4024,7 +4031,7 @@ rsmi_dev_gpu_metrics_info_get(uint32_t dv_ind, rsmi_gpu_metrics_t* smu) { dev->set_smi_device_id(dv_ind); uint32_t partition_id = 0; - auto ret = rsmi_dev_partition_id_get(dv_ind, &partition_id); + rsmi_dev_partition_id_get(dv_ind, &partition_id); dev->set_smi_partition_id(partition_id); dev->dev_log_gpu_metrics(ostrstream); const auto [error_code, external_metrics] = dev->dev_copy_internal_to_external_metrics(); diff --git a/rocm_smi/src/rocm_smi_kfd.cc b/rocm_smi/src/rocm_smi_kfd.cc index 558c7e7660..18c060337a 100644 --- a/rocm_smi/src/rocm_smi_kfd.cc +++ b/rocm_smi/src/rocm_smi_kfd.cc @@ -879,7 +879,7 @@ int KFDNode::get_used_memory(uint64_t* used) { return 1; } struct kfd_ioctl_get_available_memory_args mem = {0, 0, 0}; - mem.gpu_id = gpu_id_; + mem.gpu_id = static_cast(gpu_id_); if (ioctl(kfd_fd, AMDKFD_IOC_AVAILABLE_MEMORY , &mem) != 0) { close(kfd_fd); return 1; @@ -925,8 +925,7 @@ int KFDNode::get_cache_info(rsmi_gpu_cache_info_t *info) { // num_cu_shared – this can be fetched by counting the number of 1’s in the sibling_map. std::string sibling_map = get_properties_from_file(prop_file, "sibling_map "); - uint32_t num_cu_shared = - std::count(sibling_map.begin(), sibling_map.end(), '1'); + uint32_t num_cu_shared = static_cast(std::count(sibling_map.begin(), sibling_map.end(), '1')); // known cache type bool is_count_already = false; diff --git a/rocm_smi/src/rocm_smi_main.cc b/rocm_smi/src/rocm_smi_main.cc index 7d72a96789..d0d1394221 100644 --- a/rocm_smi/src/rocm_smi_main.cc +++ b/rocm_smi/src/rocm_smi_main.cc @@ -755,10 +755,9 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { int ret_unique_id = read_node_properties(node_id, "unique_id", &unique_id); int ret_loc_id = read_node_properties(node_id, "location_id", &location_id); - int ret_domain = - read_node_properties(node_id, "domain", &domain); + read_node_properties(node_id, "domain", &domain); if (ret_gpu_id == 0 && - ~(ret_unique_id != 0 || ret_loc_id != 0 || ret_unique_id != 0)) { + !(ret_unique_id != 0 || ret_loc_id != 0 || ret_unique_id != 0)) { // Do not try to build a node if one of these fields // do not exist in KFD (0 as values okay) systemNode myNode; @@ -804,7 +803,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { uint32_t cardAdded = 0; // Discover all root cards & gpu partitions associated with each - for (uint32_t cardId = 0; cardId <= max_cardId; cardId++) { + for (int32_t cardId = 0; cardId <= max_cardId; cardId++) { std::string path = kPathDRMRoot; path += "/card"; path += std::to_string(cardId); @@ -917,7 +916,6 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { LOG_DEBUG(ss); uint64_t temp_primary_unique_id = 0; - uint64_t primary_location_id = 0; if (allSystemNodes.empty()) { cardAdded++; ss << __PRETTY_FUNCTION__ @@ -966,7 +964,7 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { } else { cardAdded++; // remove already added nodes associated with current card - auto erasedNodes = allSystemNodes.erase(0); + allSystemNodes.erase(0); continue; } @@ -988,7 +986,6 @@ uint32_t RocmSMI::DiscoverAmdgpuDevices(void) { auto removalLocId = it->second.s_location_id; auto removaldomain = it->second.s_domain; auto nodesErased = 1; - primary_location_id = removalLocId; allSystemNodes.erase(it++); ss << __PRETTY_FUNCTION__ << "\nPRIMARY --> num_nodes == temp_numb_nodes; ERASING " diff --git a/rocm_smi/src/rocm_smi_utils.cc b/rocm_smi/src/rocm_smi_utils.cc index 0f31a5b69e..0dafa5795a 100644 --- a/rocm_smi/src/rocm_smi_utils.cc +++ b/rocm_smi/src/rocm_smi_utils.cc @@ -1090,6 +1090,7 @@ std::string splitString(std::string str, char delim) { tokens.push_back(token); return token; // return 1st match } + return ""; } static std::string pt_rng_Mhz(std::string title, rsmi_range *r) { @@ -1118,26 +1119,6 @@ static std::string pt_rng_mV(std::string title, rsmi_range *r) { return ss.str(); } -static std::string print_pnt(rsmi_od_vddc_point_t *pt) { - std::ostringstream ss; - ss << "\t\t** Frequency: " << pt->frequency/1000000 << " MHz\n"; - ss << "\t\t** Voltage: " << pt->voltage << " mV\n"; - return ss.str(); -} - -static std::string pt_vddc_curve(rsmi_od_volt_curve *c) { - std::ostringstream ss; - if (c == nullptr) { - ss << "pt_vddc_curve | rsmi_od_volt_curve c = nullptr\n"; - return ss.str(); - } - - for (uint32_t i = 0; i < RSMI_NUM_VOLTAGE_CURVE_POINTS; ++i) { - ss << print_pnt(&c->vc_points[i]); - } - return ss.str(); -} - std::string print_rsmi_od_volt_freq_data_t(rsmi_od_volt_freq_data_t *odv) { std::ostringstream ss; if (odv == nullptr) { @@ -1242,7 +1223,7 @@ rsmi_status_t rsmi_dev_number_of_computes_get(uint32_t dv_ind, uint32_t* num_com return rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED; } - *num_computes = (tmp_simd_count / tmp_simd_per_cu); + *num_computes = static_cast((tmp_simd_count / tmp_simd_per_cu)); return rsmi_status_t::RSMI_STATUS_SUCCESS; } @@ -1296,7 +1277,7 @@ void system_wait(int milli_seconds) { } int countDigit(uint64_t n) { - return static_cast(std::floor(log10(n) + 1)); + return static_cast(std::floor(log10(static_cast(n)) + 1)); } } // namespace smi diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 4bed5a380f..6d48476128 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -1020,8 +1020,9 @@ amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_i // If vendor name is empty and the vendor id is 0x1002, set vendor name to AMD vendor string if ((info->vendor_name != NULL && info->vendor_name[0] == '\0') && info->vendor_id == 0x1002) { - memset(info->vendor_name, 0, 38); - strncpy(info->vendor_name, "Advanced Micro Devices Inc. [AMD/ATI]", 37); + std::string amd_name = "Advanced Micro Devices Inc. [AMD/ATI]"; + memset(info->vendor_name, 0, amd_name.size()+1); + strncpy(info->vendor_name, amd_name.c_str(), amd_name.size()+1); } // default to 0xffff as not supported @@ -1506,7 +1507,6 @@ amdsmi_get_gpu_accelerator_partition_profile(amdsmi_processor_handle processor_h // TODO(amdsmi_team): add resources here ^ auto tmp_partition_id = uint32_t(0); - auto tmp_xcd_count = uint16_t(0); amdsmi_status_t status = AMDSMI_STATUS_NOT_SUPPORTED; status = rsmi_wrapper(rsmi_dev_partition_id_get, processor_handle, &tmp_partition_id); @@ -2196,7 +2196,7 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_ } info->max_clk = max_freq; info->min_clk = min_freq; - info->clk_deep_sleep = sleep_state_freq; + info->clk_deep_sleep = static_cast(sleep_state_freq); switch (clk_type) { case AMDSMI_CLK_TYPE_GFX: @@ -2493,7 +2493,6 @@ amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned in amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; SMIGPUDEVICE_MUTEX(gpu_device->get_mutex()) - size_t len = AMDSMI_GPU_UUID_SIZE; amdsmi_asic_info_t asic_info = {}; const uint8_t fcn = 0xff; @@ -2556,7 +2555,7 @@ amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, a } // pcie speed in sysfs returns in GT/s - info->pcie_static.max_pcie_speed = pcie_speed * 1000; + info->pcie_static.max_pcie_speed = static_cast(pcie_speed * 1000); switch (info->pcie_static.max_pcie_speed) { case 2500: @@ -2722,8 +2721,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle, auto status(amdsmi_status_t::AMDSMI_STATUS_SUCCESS); - constexpr auto kKFD_CRAT_INTRA_SOCKET_WEIGHT = uint32_t(13); - constexpr auto kKFD_CRAT_XGMI_WEIGHT = uint32_t(15); /* * Note: This will need to be eventually consolidated within a unique link type. @@ -2766,7 +2763,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle, uint64_t link_weight; }; - using LinkTopogyOrderPair_t = std::pair; /* * Note: The link topology table is sorted by the number of hops and link weight. */ @@ -2822,7 +2818,6 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle, // Link type matches what we are searching for? auto io_link_type = translated_link_type(link_type); - auto io_link_type_bck(io_link_type); auto num_hops = uint64_t(0); if (auto api_status = amdsmi_topo_get_link_type(processor_handle, device_list[device_idx], &num_hops, &io_link_type); (api_status != amdsmi_status_t::AMDSMI_STATUS_SUCCESS) || (translated_io_link_type(io_link_type) != link_type)) { @@ -2853,7 +2848,7 @@ amdsmi_get_link_topology_nearest(amdsmi_processor_handle processor_handle, * Note: The link topology table is sorted by the number of hops and link weight. */ topology_nearest_info->processor_list[AMDSMI_MAX_DEVICES] = {nullptr}; - topology_nearest_info->count = link_topology_order.size(); + topology_nearest_info->count = static_cast(link_topology_order.size()); auto topology_nearest_counter = uint32_t(0); while (!link_topology_order.empty()) { auto link_info = link_topology_order.top(); @@ -3959,13 +3954,15 @@ amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count, } // Get the cpu count - *cpu_count = cpu_handles.size(); - if (processor_handles == nullptr) + *cpu_count = static_cast(cpu_handles.size()); + if (processor_handles == nullptr) { return AMDSMI_STATUS_SUCCESS; + } // Copy the cpu socket handles - for (uint32_t i = 0; i < *cpu_count; i++) + for (uint32_t i = 0; i < *cpu_count; i++) { processor_handles[i] = reinterpret_cast(cpu_handles[i]); + } return status; } @@ -4008,28 +4005,32 @@ amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count, // Get the coress for each socket status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, &plist[0], &cores_per_soc); - if (status != AMDSMI_STATUS_SUCCESS) + if (status != AMDSMI_STATUS_SUCCESS) { return status; + } core_handles.insert(core_handles.end(), plist.begin(), plist.end()); } // Get the cores count - *cores_count = core_handles.size(); - if (processor_handles == nullptr) + *cores_count = static_cast(core_handles.size()); + if (processor_handles == nullptr) { return AMDSMI_STATUS_SUCCESS; + } // Copy the core handles - for (uint32_t i = 0; i < *cores_count; i++) + for (uint32_t i = 0; i < *cores_count; i++) { processor_handles[i] = reinterpret_cast(core_handles[i]); + } return status; } amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **status_string) { - for (auto& iter : amd::smi::esmi_status_map) { - if (iter.first == status) { + for (const auto& iter : amd::smi::esmi_status_map) { + const amdsmi_status_t _status = status; + if (static_cast(iter.first) == static_cast(_status)) { *status_string = esmi_get_err_msg(static_cast(iter.first)); return iter.second; } diff --git a/src/amd_smi/amd_smi_drm.cc b/src/amd_smi/amd_smi_drm.cc index 41606dfd40..55f0ffb010 100644 --- a/src/amd_smi/amd_smi_drm.cc +++ b/src/amd_smi/amd_smi_drm.cc @@ -41,6 +41,8 @@ namespace smi { std::string AMDSmiDrm::find_file_in_folder(const std::string& folder, const std::string& regex) { std::string file_name; + // TODO: The closedir function has some non-standard attributes that are being ignored here + // which is causing a warning to be thrown using dir_ptr = std::unique_ptr; struct dirent *dir = nullptr; @@ -64,7 +66,6 @@ amdsmi_status_t AMDSmiDrm::init() { // using drm_device_ptr = std::unique_ptr(drmDevicePtr, // decltype(&drmFreeDevice)); - struct dirent *dir = nullptr; int fd = -1; @@ -162,7 +163,7 @@ amdsmi_status_t AMDSmiDrm::init() { << "bdf_rocm | Received bdf: " << "\nWhole BDF: " << amd::smi::print_unsigned_hex_and_int(bdf_rocm) << "\nDomain = " - << amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xFFFFFFFF00000000) >> 32) + << amd::smi::print_unsigned_hex_and_int((bdf_rocm & static_cast(0xFFFFFFFF00000000)) >> 32) << "; \nBus# = " << amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xFF00) >> 8) << "; \nDevice# = "<< amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0xF8) >> 3) << "; \nFunction# = " << amd::smi::print_unsigned_hex_and_int((bdf_rocm & 0x7)); @@ -170,6 +171,8 @@ amdsmi_status_t AMDSmiDrm::init() { bdf.function_number = ((bdf_rocm & 0x7)); bdf.device_number = ((bdf_rocm & 0xF8) >> 3); bdf.bus_number = ((bdf_rocm & 0xFF00) >> 8); + // TODO: This is throwing a compiler warning since bdf.domain_number is part of a struct + // and is 48 bits long and throws a conversion warning bdf.domain_number = ((bdf_rocm & 0xFFFFFFFF00000000) >> 32); ss << __PRETTY_FUNCTION__ << " | " << "Received bdf: Domain = " << bdf.domain_number << "; Bus# = " << bdf.bus_number << "; Device# = "<< bdf.device_number diff --git a/src/amd_smi/amd_smi_system.cc b/src/amd_smi/amd_smi_system.cc index 435413dc0b..ea5172ec86 100644 --- a/src/amd_smi/amd_smi_system.cc +++ b/src/amd_smi/amd_smi_system.cc @@ -229,11 +229,15 @@ amdsmi_status_t AMDSmiSystem::get_gpu_socket_id(uint32_t index, */ uint64_t domain = (bdfid >> 32) & 0xffffffff; + /* May need later // may need to identify with partition_id in the future as well... TBD uint64_t partition_id = (bdfid >> 28) & 0xf; + */ uint64_t bus = (bdfid >> 8) & 0xff; uint64_t device_id = (bdfid >> 3) & 0x1f; + /* May need later uint64_t function = bdfid & 0x7; + */ // The BD part of the BDF is used as the socket id as it // represents a physical device. diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index 4c6a8cc74e..b8a7b34601 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -527,7 +527,7 @@ amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device, fclose(fp); if (length) { - *length = version[len-1] == '\n' ? len - 1 : len; + *length = version[len-1] == '\n' ? static_cast(len - 1) : static_cast(len); } version[len-1] = version[len-1] == '\n' ? '\0' : version[len-1]; } @@ -647,6 +647,7 @@ std::string smi_amdgpu_split_string(std::string str, char delim) { tokens.push_back(token); return token; // return 1st match } + return ""; } // wrapper to return string expression of a rsmi_status_t return diff --git a/src/amd_smi/fdinfo.cc b/src/amd_smi/fdinfo.cc index df3a068817..235194e852 100644 --- a/src/amd_smi/fdinfo.cc +++ b/src/amd_smi/fdinfo.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -75,11 +76,11 @@ amdsmi_status_t gpuvsmi_get_pids(const amdsmi_bdf_t &bdf, std::vector struct dirent *dir; /* 0000:00:00.0 */ - snprintf(bdf_str, 13, "%04x:%02x:%02x.%d", - bdf.domain_number & 0xffff, - bdf.bus_number & 0xff, - bdf.device_number & 0x1f, - bdf.function_number & 0x7); + snprintf(bdf_str, 13, "%04" PRIx32 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32, + static_cast(bdf.domain_number & 0xffff), + static_cast(bdf.bus_number & 0xff), + static_cast(bdf.device_number & 0x1f), + static_cast(bdf.function_number & 0x7)); d = opendir("/proc"); if (!d) @@ -124,12 +125,11 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid, struct dirent *dir; /* 0000:00:00.0 */ - snprintf(bdf_str, 13, "%04x:%02x:%02x.%d", - bdf.domain_number & 0xffff, - bdf.bus_number & 0xff, - bdf.device_number & 0x1f, - bdf.function_number & 0x7); - + snprintf(bdf_str, 13, "%04" PRIx32 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32, + static_cast(bdf.domain_number & 0xffff), + static_cast(bdf.bus_number & 0xff), + static_cast(bdf.device_number & 0x1f), + static_cast(bdf.function_number & 0x7)); std::string path = "/proc/" + std::to_string(pid) + "/fdinfo/"; std::string name_path = "/proc/" + std::to_string(pid) + "/comm"; @@ -158,7 +158,7 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid, char fd_bdf_str[13]; /* Only check against fdinfo files that contain a bdf */ - if (sscanf(bdfline.c_str(), "drm-pdev: %s", &fd_bdf_str) != 1) + if (sscanf(bdfline.c_str(), "drm-pdev: %s", &fd_bdf_str[0]) != 1) continue; /* Populate amdsmi_proc_info_t struct only if the bdf in diff --git a/tests/amd_smi_test/functional/api_support_read.cc b/tests/amd_smi_test/functional/api_support_read.cc index 4f58f7b7a0..6be61a276b 100644 --- a/tests/amd_smi_test/functional/api_support_read.cc +++ b/tests/amd_smi_test/functional/api_support_read.cc @@ -63,8 +63,6 @@ void TestAPISupportRead::Close() { } void TestAPISupportRead::Run(void) { - amdsmi_status_t err; - TestBase::Run(); if (setup_failed_) { IF_VERB(STANDARD) { diff --git a/tests/amd_smi_test/functional/fan_read.cc b/tests/amd_smi_test/functional/fan_read.cc index 0f923eed94..0a351cb826 100644 --- a/tests/amd_smi_test/functional/fan_read.cc +++ b/tests/amd_smi_test/functional/fan_read.cc @@ -100,7 +100,7 @@ void TestFanRead::Run(void) { err = amdsmi_get_gpu_fan_speed_max(processor_handles_[i], 0, &val_ui64); CHK_ERR_ASRT(err) IF_VERB(STANDARD) { - std::cout << val_i64/static_cast(val_ui64)*100; + std::cout << static_cast(val_i64)/static_cast(val_ui64)*100; std::cout << "% ("<< val_i64 << "/" << val_ui64 << ")" << std::endl; } // Verify api support checking functionality is working diff --git a/tests/amd_smi_test/functional/fan_read_write.cc b/tests/amd_smi_test/functional/fan_read_write.cc index 32b3fb2802..ee3a1c5a21 100644 --- a/tests/amd_smi_test/functional/fan_read_write.cc +++ b/tests/amd_smi_test/functional/fan_read_write.cc @@ -100,7 +100,7 @@ void TestFanReadWrite::Run(void) { ret = amdsmi_get_gpu_fan_speed_max(processor_handles_[dv_ind], 0, &max_speed); CHK_ERR_ASRT(ret) - new_speed = 1.1 * orig_speed; + new_speed = static_cast(1.1F * static_cast(orig_speed)); if (new_speed > static_cast(max_speed)) { std::cout << @@ -135,8 +135,9 @@ void TestFanReadWrite::Run(void) { // cur_speed < 1.1 * new_speed) || // cur_speed > 0.95 * AMDSMI_MAX_FAN_SPEED); IF_VERB(STANDARD) { - if (!((cur_speed > 0.95 * new_speed && cur_speed < 1.1 * new_speed) || - (cur_speed > 0.95 * AMDSMI_MAX_FAN_SPEED))) { + if (!((cur_speed > static_cast(0.95 * static_cast(new_speed)) && + cur_speed < static_cast(1.10 * static_cast(new_speed))) || + (cur_speed > static_cast(0.95 * AMDSMI_MAX_FAN_SPEED)))) { std::cout << "WARNING: Fan speed is not within the expected range!" << std::endl; } diff --git a/tests/amd_smi_test/functional/gpu_busy_read.cc b/tests/amd_smi_test/functional/gpu_busy_read.cc index 5e290374da..56f92a28c6 100644 --- a/tests/amd_smi_test/functional/gpu_busy_read.cc +++ b/tests/amd_smi_test/functional/gpu_busy_read.cc @@ -63,9 +63,6 @@ void TestGPUBusyRead::Close() { void TestGPUBusyRead::Run(void) { - amdsmi_status_t err; - uint32_t val_ui32; - TestBase::Run(); if (setup_failed_) { std::cout << "** SetUp Failed for this test. Skipping.**" << std::endl; diff --git a/tests/amd_smi_test/functional/hw_topology_read.cc b/tests/amd_smi_test/functional/hw_topology_read.cc index 1079b31be9..390dbec0ce 100644 --- a/tests/amd_smi_test/functional/hw_topology_read.cc +++ b/tests/amd_smi_test/functional/hw_topology_read.cc @@ -20,6 +20,7 @@ * THE SOFTWARE. */ +#include #include #include @@ -477,8 +478,11 @@ void TestHWTopologyRead::Run(void) { continue; } - printf("\tGPU BDF %04lx:%02x:%02x.%d\n", bdf.domain_number, - bdf.bus_number, bdf.device_number, bdf.function_number); + printf("\tGPU BDF %04" PRIx64 ":%02" PRIx32 ":%02" PRIx32 ".%" PRIu32 "\n", + static_cast(bdf.domain_number), + static_cast(bdf.bus_number), + static_cast(bdf.device_number), + static_cast(bdf.function_number)); } } else { diff --git a/tests/amd_smi_test/functional/id_info_read.cc b/tests/amd_smi_test/functional/id_info_read.cc index e85f57d102..91649cf97b 100644 --- a/tests/amd_smi_test/functional/id_info_read.cc +++ b/tests/amd_smi_test/functional/id_info_read.cc @@ -67,7 +67,6 @@ void TestIdInfoRead::Run(void) { amdsmi_status_t err; uint16_t id; uint64_t val_ui64; - uint32_t drm_render_minor; char buffer[kBufferLen]; diff --git a/tests/amd_smi_test/functional/init_shutdown_refcount.cc b/tests/amd_smi_test/functional/init_shutdown_refcount.cc index b9fb9eef2a..55f7733278 100644 --- a/tests/amd_smi_test/functional/init_shutdown_refcount.cc +++ b/tests/amd_smi_test/functional/init_shutdown_refcount.cc @@ -38,7 +38,7 @@ rsmi_test_refcount(uint64_t refcnt_type); static void rand_sleep_mod(int msec) { assert(msec > 10); - unsigned int seed = time(NULL); + uint64_t seed = static_cast(time(NULL)); std::mt19937_64 eng{seed}; std::uniform_int_distribution<> dist{10, msec}; std::this_thread::sleep_for(std::chrono::milliseconds{dist(eng)}); diff --git a/tests/amd_smi_test/functional/mem_util_read.cc b/tests/amd_smi_test/functional/mem_util_read.cc index ce327b5341..ba10947138 100644 --- a/tests/amd_smi_test/functional/mem_util_read.cc +++ b/tests/amd_smi_test/functional/mem_util_read.cc @@ -117,7 +117,7 @@ void TestMemUtilRead::Run(void) { std::cout << "\t**" << kDevMemoryTypeNameMap.at(static_cast(mem_type)) << " Calculated Utilization: " << - (static_cast(usage)*100)/total << "% ("<< usage << + (static_cast(usage)*100)/static_cast(total) << "% ("<< usage << "/" << total << ")" << std::endl; } } diff --git a/tests/amd_smi_test/functional/metrics_counter_read.cc b/tests/amd_smi_test/functional/metrics_counter_read.cc index f6cd1ff95e..b2e9c91b9e 100644 --- a/tests/amd_smi_test/functional/metrics_counter_read.cc +++ b/tests/amd_smi_test/functional/metrics_counter_read.cc @@ -99,7 +99,7 @@ void TestMetricsCounterRead::Run(void) { std::cout << std::dec << "energy_accumulator counter=" << energy_accumulator << '\n'; std::cout << "energy_accumulator in uJ=" - << (double)(energy_accumulator * counter_resolution) << '\n'; + << static_cast((static_cast(energy_accumulator) * counter_resolution)) << '\n'; std::cout << std::dec << "timestamp=" << timestamp << '\n'; } diff --git a/tests/amd_smi_test/functional/mutual_exclusion.cc b/tests/amd_smi_test/functional/mutual_exclusion.cc index ecff87461d..51ce7648ab 100644 --- a/tests/amd_smi_test/functional/mutual_exclusion.cc +++ b/tests/amd_smi_test/functional/mutual_exclusion.cc @@ -155,7 +155,6 @@ void TestMutualExclusion::Run(void) { // Set dummy values should to working, deterministic values. uint16_t dmy_ui16 = 0; uint32_t dmy_ui32 = 1; - uint32_t dmy_i32 = 0; uint64_t dmy_ui64 = 0; int64_t dmy_i64 = 0; char dmy_str[10]; diff --git a/tests/amd_smi_test/functional/perf_cntr_read_write.cc b/tests/amd_smi_test/functional/perf_cntr_read_write.cc index da65c75e0c..5d96c45252 100644 --- a/tests/amd_smi_test/functional/perf_cntr_read_write.cc +++ b/tests/amd_smi_test/functional/perf_cntr_read_write.cc @@ -121,7 +121,7 @@ void TestPerfCntrReadWrite::CountEvents(amdsmi_processor_handle dv_ind, std::cout << "\t\t\tTime Enabled (nS): " << val->time_enabled << std::endl; std::cout << "\t\t\tTime Running (nS): " << val->time_running << std::endl; std::cout << "\t\t\tEvents/Second Running: " << - val->value/static_cast(val->time_running) << std::endl; + static_cast(val->value)/static_cast(val->time_running) << std::endl; } ret = amdsmi_gpu_destroy_counter(evt_handle); CHK_ERR_ASRT(ret) @@ -158,14 +158,14 @@ TestPerfCntrReadWrite::testEventsIndividually(amdsmi_processor_handle dv_ind) { CountEvents(dv_ind, evt, &val, 1); double coll_time_sec = static_cast(val.time_running)/kGig; - throughput = (val.value * 32)/coll_time_sec; + throughput = static_cast(static_cast((val.value * 32L))/coll_time_sec); std::cout << "\t\t\tCollected events for " << coll_time_sec << " seconds" << std::endl; std::cout << "\t\t\tEvents collected: " << val.value << std::endl; std::cout << "\t\t\tXGMI throughput: " << throughput << " bytes/second" << std::endl; std::cout << "\t\t\tXGMI Channel Utilization: " << - 100*throughput/static_cast(kVg20Level1Bandwidth*kGigByte) << + static_cast(100*throughput)/static_cast(kVg20Level1Bandwidth*kGigByte) << "%" << std::endl; std::cout << "\t\t\t****" << std::endl; } diff --git a/tests/amd_smi_test/functional/power_read.cc b/tests/amd_smi_test/functional/power_read.cc index 345b17fb8a..e898aca165 100644 --- a/tests/amd_smi_test/functional/power_read.cc +++ b/tests/amd_smi_test/functional/power_read.cc @@ -64,8 +64,6 @@ void TestPowerRead::Close() { void TestPowerRead::Run(void) { amdsmi_status_t err; - uint64_t val_ui64, val2_ui64; - amdsmi_power_type_t type = AMDSMI_INVALID_POWER; TestBase::Run(); if (setup_failed_) { diff --git a/tests/amd_smi_test/functional/sys_info_read.cc b/tests/amd_smi_test/functional/sys_info_read.cc index 6466af4a90..b6e5cbd9ba 100644 --- a/tests/amd_smi_test/functional/sys_info_read.cc +++ b/tests/amd_smi_test/functional/sys_info_read.cc @@ -69,9 +69,7 @@ void TestSysInfoRead::Close() { void TestSysInfoRead::Run(void) { amdsmi_status_t err; uint64_t val_ui64; - uint32_t val_ui32; int32_t val_i32; - char buffer[80]; amdsmi_version_t ver = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, nullptr}; TestBase::Run(); diff --git a/tests/amd_smi_test/functional/xgmi_read_write.cc b/tests/amd_smi_test/functional/xgmi_read_write.cc index d1017c7aae..7efdf57489 100644 --- a/tests/amd_smi_test/functional/xgmi_read_write.cc +++ b/tests/amd_smi_test/functional/xgmi_read_write.cc @@ -65,7 +65,6 @@ void TestXGMIReadWrite::Run(void) { GTEST_SKIP_("Temporarily disabled"); amdsmi_status_t err; amdsmi_xgmi_status_t err_stat; - uint64_t hive_id; TestBase::Run(); if (setup_failed_) {