Add mutex for multi-process access to device sysfs files

This commit uses a pthread mutex in shared memory to prevent
almost all cases of multiple processes simultaneously
reading/writing to device sysfs files. The main existing race
condition is when 2 processes are starting at the same time,
setting up their shared memory and mutexes. Since this is meant
to prevent collisions among thread and processes, the small
shared memory segments (big enough for a pthread_mutex) will
persist until reboot.
This commit is contained in:
Chris Freehill
2019-05-04 15:10:58 -05:00
szülő bb73c2607f
commit 5e24a77193
8 fájl változott, egészen pontosan 372 új sor hozzáadva és 3 régi sor törölve
+8 -1
Fájl megtekintése
@@ -42,6 +42,9 @@
*/
#ifndef INCLUDE_ROCM_SMI_ROCM_SMI_DEVICE_H_
#define INCLUDE_ROCM_SMI_ROCM_SMI_DEVICE_H_
#include <pthread.h>
#include <string>
#include <memory>
#include <utility>
@@ -52,6 +55,9 @@
#include "rocm_smi/rocm_smi_power_mon.h"
#include "rocm_smi/rocm_smi_common.h"
#include "rocm_smi/rocm_smi.h"
extern "C" {
#include "shared_mutex.h"
};
namespace amd {
namespace smi {
@@ -109,11 +115,12 @@ class Device {
uint64_t bdfid(void) const {return bdfid_;}
void set_bdfid(uint64_t val) {bdfid_ = val;}
uint64_t get_bdfid(void) const {return bdfid_;}
pthread_mutex_t *mutex(void) {return mutex_.ptr;}
private:
std::shared_ptr<Monitor> monitor_;
std::shared_ptr<PowerMon> power_monitor_;
std::string path_;
shared_mutex_t mutex_;
uint32_t index_;
const RocmSMI_env_vars *env_;
template <typename T> int openSysfsFileStream(DevInfoTypes type, T *fs,
@@ -43,6 +43,8 @@
#ifndef INCLUDE_ROCM_SMI_ROCM_SMI_UTILS_H_
#define INCLUDE_ROCM_SMI_ROCM_SMI_UTILS_H_
#include <pthread.h>
#include <string>
#include <cstdint>
@@ -63,6 +65,28 @@ namespace smi {
int ReadSysfsStr(std::string path, std::string *retStr);
int WriteSysfsStr(std::string path, std::string val);
struct pthread_wrap {
public:
pthread_wrap(pthread_mutex_t &p_mut) : mutex_(p_mut) {}
void Acquire() { pthread_mutex_lock(&mutex_); }
void Release() { pthread_mutex_unlock(&mutex_); }
private:
pthread_mutex_t& mutex_;
};
struct ScopedPthread {
ScopedPthread(pthread_wrap& mutex) : pthrd_ref_(mutex) {
pthrd_ref_.Acquire();
};
~ScopedPthread() {
pthrd_ref_.Release();
}
private:
ScopedPthread(const ScopedPthread&);
pthread_wrap& pthrd_ref_;
};
} // namespace smi
} // namespace amd