From 713d231125a221923f0213cf083c0c7fab806a5e Mon Sep 17 00:00:00 2001 From: "Bill(Shuzhou) Liu" Date: Mon, 14 Nov 2022 09:54:50 -0600 Subject: [PATCH] Remove the shared mutex if no process is using it If the code is crashed and the mutex may be in bad status. The user has to mannually remove it. The fix will remove the shared mutex if no process is using it. Change-Id: I18bf562f2e0a7de8b3f0cccf72d60950b0d9bb2d [ROCm/rocm_smi_lib commit: 76b5528feb244d5d24f8bed580578cbbba3dfc92] --- projects/rocm-smi-lib/src/rocm_smi_device.cc | 2 +- .../third_party/shared_mutex/shared_mutex.cc | 53 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/projects/rocm-smi-lib/src/rocm_smi_device.cc b/projects/rocm-smi-lib/src/rocm_smi_device.cc index 0d602f4595..0eade39ce5 100755 --- a/projects/rocm-smi-lib/src/rocm_smi_device.cc +++ b/projects/rocm-smi-lib/src/rocm_smi_device.cc @@ -41,10 +41,10 @@ * */ + #include #include #include - #include #include #include diff --git a/projects/rocm-smi-lib/third_party/shared_mutex/shared_mutex.cc b/projects/rocm-smi-lib/third_party/shared_mutex/shared_mutex.cc index 55fac1f5b5..ae211a81c3 100755 --- a/projects/rocm-smi-lib/third_party/shared_mutex/shared_mutex.cc +++ b/projects/rocm-smi-lib/third_party/shared_mutex/shared_mutex.cc @@ -1,5 +1,5 @@ /* -Modifications Copyright © 2019 – 2020 Advanced Micro Devices, Inc. All Rights +Modifications Copyright 2019 - 2022 Advanced Micro Devices, Inc. All Rights Reserved. Copyright (c) 2018 Oleg Yamnikov @@ -34,8 +34,50 @@ THE SOFTWARE. #include // clock_gettime #include +#include +#include +#include +#include +#include + #include "rocm_smi/rocm_smi_exception.h" +// find which processes are using the file by searching /proc/*/fd +static std::vector lsof(const char* filename) { + struct dirent *entry = nullptr; + DIR *dp = nullptr; + std::vector process_id; + + dp = opendir("/proc"); + if (dp != nullptr) { + while ((entry = readdir(dp))) { + std::string id(entry->d_name); + // the process id should be a number + if (std::all_of(id.begin(), id.end(), ::isdigit)) { + process_id.push_back(entry->d_name); + } + } + closedir(dp); + } + + std::vector matched_process; + for (unsigned int i=0; i < process_id.size(); i++) { + std::string folder_name("/proc/"); + folder_name += process_id[i]+"/fd/"; + dp = opendir(folder_name.c_str()); + if (dp == nullptr) continue; + while ((entry = readdir(dp))) { + std::string p(folder_name+entry->d_name); + char buf[512]; + memset(buf, 0, 512); + if (readlink(p.c_str(), buf, sizeof(buf)-1) < 0) continue; + if (!strcmp(filename, buf)) matched_process.push_back(process_id[i]); + } + closedir(dp); + } + return matched_process; +} + shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { shared_mutex_t mutex = {NULL, 0, NULL, 0}; errno = 0; @@ -81,6 +123,15 @@ shared_mutex_t shared_mutex_init(const char *name, mode_t mode) { pthread_mutex_t *mutex_ptr = reinterpret_cast(addr); + // When process crash before unlock the mutex, the mutex is in bad status. + // reset the mutex if no process is using it + std::vector ids = lsof(name); + if (ids.size() == 0) { // no process is using it + memset(mutex_ptr, 0, sizeof(pthread_mutex_t)); + // Set mutex.created == 1 so that it can be initialized latter. + mutex.created = 1; + } + // Make sure the mutex wasn't left in a locked state. If we can't // acquire it in 5 sec., re-do everything. struct timespec expireTime;