So I have one process running on a host machine that creates a shared memory region. This shared memory region is then passed to a process running in a guest VM. The shared memory region gets exposed to the guest process using vfio and I use mmap to map the memory region. The guest and host processes write and read data from this shared memory region. Therefore, I created a mutex to synchronize access to the data.
As is the norm with sharing mutexes between regular processes, I set the mutex attribute to PTHREAD_PROCESS_SHARED
and lock any time a read or write to the shared memory region is made and unlock when it is done. Given the situation above I am encountering weird behaviour and deadlocks. So I was wondering if pthread_mutex still works when crossing these virtualization boundaries. Of course, there could be an error in my code and I didn't unlock the mux when I should, but I have looked over it so many times and can't find a situation where that would happen, thus leading me to wonder if the mutex is not working when exposed as a vfio device. If a mutex is not the right abstraction here, what is an alternative to synchronize access to the critical section?
This is how I create the shared memory region
/* Create shared memory */
void *shm;
int fd;
fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(fd, size);
shm = mmap(addr, size, PROT_READ | PROT_WRITE,
MAP_SHARED | (addr == NULL ? 0 : MAP_FIXED) | MAP_POPULATE, fd, 0);
memset(shm, 0, size);
And this is the mutex initialization
/* Initialize mutex */
struct shm_ring {
struct pthread_mutex_t *mux_addr;
void *data_addr;
};
struct shm_ring ring;
ring.mux_addr = shm;
ring.data_addr = shm + sizeof(struct pthread_mutex_t);
pthread_mutexattr_t *attr = malloc(sizeof(pthread_mutexattr_t));
pthread_mutexattr_init(attr);
pthread_mutexattr_setpshared(attr, PTHREAD_PROCESS_SHARED);
pthread_mutexattr_settype(attr, PTHREAD_MUTEX_NORMAL);
pthread_mutexattr_setrobust(attr, PTHREAD_MUTEX_ROBUST);
pthread_mutex_init(ring->mux_addr, attr);