diff --git a/include/rocm_smi/rocm_smi_utils.h b/include/rocm_smi/rocm_smi_utils.h index abf5e98831..ab27d27c14 100755 --- a/include/rocm_smi/rocm_smi_utils.h +++ b/include/rocm_smi/rocm_smi_utils.h @@ -82,6 +82,7 @@ int SameFile(const std::string fileA, const std::string fileB); bool FileExists(char const *filename); std::vector globFilesExist(const std::string& filePattern); int isRegularFile(std::string fname, bool *is_reg); +int isReadOnlyForAll(const std::string& fname, bool *is_read_only); int ReadSysfsStr(std::string path, std::string *retStr); int WriteSysfsStr(std::string path, std::string val); bool IsInteger(const std::string & n_str); diff --git a/src/rocm_smi.cc b/src/rocm_smi.cc index 274fa3c113..da2f7a9702 100755 --- a/src/rocm_smi.cc +++ b/src/rocm_smi.cc @@ -1873,7 +1873,7 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind, return ret; } - int ret_i; + rsmi_status_t status; amd::smi::DevInfoTypes dev_type; const auto & clk_type_it = kClkTypeMap.find(clk_type); @@ -1883,8 +1883,19 @@ rsmi_dev_gpu_clk_freq_set(uint32_t dv_ind, return RSMI_STATUS_INVALID_ARGS; } - ret_i = dev->writeDevInfo(dev_type, freq_enable_str); - return amd::smi::ErrnoToRsmiStatus(ret_i); + status = amd::smi::ErrnoToRsmiStatus(dev->writeDevInfo(dev_type, freq_enable_str)); + + // If an operation is not supported, the dev file, ie /sys/class/drm/card1/device/pp_dpm_pcie + // 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); + if(read_only){ + return RSMI_STATUS_NOT_SUPPORTED; + } + } + + return status; CATCH } diff --git a/src/rocm_smi_utils.cc b/src/rocm_smi_utils.cc index 8437a27f31..bc3f0d3aaa 100755 --- a/src/rocm_smi_utils.cc +++ b/src/rocm_smi_utils.cc @@ -172,6 +172,24 @@ int isRegularFile(std::string fname, bool *is_reg) { return 0; } +int isReadOnlyForAll(const std::string& fname, bool *is_read_only){ + struct stat file_stat; + int ret; + + ret = stat(fname.c_str(), &file_stat); + if (ret) { + return errno; + } + + if (is_read_only != nullptr) { + *is_read_only = (file_stat.st_mode & (S_IRUSR | S_IRGRP | S_IROTH)) && !(file_stat.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)); + } else { + ret = 1; + } + + return ret; +} + int WriteSysfsStr(std::string path, std::string val) { // On success, zero is returned. On error, -1 is returned, and // errno is set to indicate the error.