blob: 144e7b8ed14cfe460bef7d96e15b66b98c6fec71 [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2018, Linaro Limited
*/
#include <assert.h>
#include <kernel/lockdep.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <sys/queue.h>
#include <trace.h>
#include "mutex_lockdep.h"
/* Global graph of all mutexes used in the code */
static struct lockdep_node_head graph = TAILQ_HEAD_INITIALIZER(graph);
/* Protects @graph */
static unsigned int graph_lock = SPINLOCK_UNLOCK;
/*
* One queue per thread, contains the mutexes the thread owns at any point in
* time (in aquire order)
*/
static struct lockdep_lock_head owned[CFG_NUM_THREADS];
void mutex_lockdep_init(void)
{
int n = 0;
for (n = 0; n < CFG_NUM_THREADS; n++)
TAILQ_INIT(&owned[n]);
DMSG("lockdep is enabled for mutexes");
}
void mutex_lock_check(struct mutex *m)
{
int thread = thread_get_id();
uint32_t exceptions = 0;
exceptions = cpu_spin_lock_xsave(&graph_lock);
lockdep_lock_acquire(&graph, &owned[thread], (uintptr_t)m);
cpu_spin_unlock_xrestore(&graph_lock, exceptions);
}
void mutex_trylock_check(struct mutex *m)
{
int thread = thread_get_id();
uint32_t exceptions = 0;
exceptions = cpu_spin_lock_xsave(&graph_lock);
lockdep_lock_tryacquire(&graph, &owned[thread], (uintptr_t)m);
cpu_spin_unlock_xrestore(&graph_lock, exceptions);
}
void mutex_unlock_check(struct mutex *m)
{
int thread = thread_get_id();
uint32_t exceptions = 0;
exceptions = cpu_spin_lock_xsave(&graph_lock);
lockdep_lock_release(&owned[thread], (uintptr_t)m);
cpu_spin_unlock_xrestore(&graph_lock, exceptions);
}
void mutex_destroy_check(struct mutex *m)
{
uint32_t exceptions = cpu_spin_lock_xsave(&graph_lock);
lockdep_lock_destroy(&graph, (uintptr_t)m);
cpu_spin_unlock_xrestore(&graph_lock, exceptions);
}