1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2018, Linaro Limited
4 */
5
6 #include <assert.h>
7 #include <kernel/lockdep.h>
8 #include <kernel/spinlock.h>
9 #include <kernel/thread.h>
10 #include <sys/queue.h>
11 #include <trace.h>
12
13 #include "mutex_lockdep.h"
14
15 /* Global graph of all mutexes used in the code */
16 static struct lockdep_node_head graph = TAILQ_HEAD_INITIALIZER(graph);
17
18 /* Protects @graph */
19 static unsigned int graph_lock = SPINLOCK_UNLOCK;
20
21 /*
22 * One queue per thread, contains the mutexes the thread owns at any point in
23 * time (in aquire order)
24 */
25 static struct lockdep_lock_head owned[CFG_NUM_THREADS];
26
mutex_lockdep_init(void)27 void mutex_lockdep_init(void)
28 {
29 int n = 0;
30
31 for (n = 0; n < CFG_NUM_THREADS; n++)
32 TAILQ_INIT(&owned[n]);
33
34 DMSG("lockdep is enabled for mutexes");
35 }
36
mutex_lock_check(struct mutex * m)37 void mutex_lock_check(struct mutex *m)
38 {
39 short int thread = thread_get_id();
40 uint32_t exceptions = 0;
41
42 exceptions = cpu_spin_lock_xsave(&graph_lock);
43 lockdep_lock_acquire(&graph, &owned[thread], (uintptr_t)m);
44 cpu_spin_unlock_xrestore(&graph_lock, exceptions);
45 }
46
mutex_trylock_check(struct mutex * m)47 void mutex_trylock_check(struct mutex *m)
48 {
49 short int thread = thread_get_id();
50 uint32_t exceptions = 0;
51
52 exceptions = cpu_spin_lock_xsave(&graph_lock);
53 lockdep_lock_tryacquire(&graph, &owned[thread], (uintptr_t)m);
54 cpu_spin_unlock_xrestore(&graph_lock, exceptions);
55 }
56
mutex_unlock_check(struct mutex * m)57 void mutex_unlock_check(struct mutex *m)
58 {
59 short int thread = thread_get_id();
60 uint32_t exceptions = 0;
61
62 exceptions = cpu_spin_lock_xsave(&graph_lock);
63 lockdep_lock_release(&owned[thread], (uintptr_t)m);
64 cpu_spin_unlock_xrestore(&graph_lock, exceptions);
65 }
66
mutex_destroy_check(struct mutex * m)67 void mutex_destroy_check(struct mutex *m)
68 {
69 uint32_t exceptions = cpu_spin_lock_xsave(&graph_lock);
70
71 lockdep_lock_destroy(&graph, (uintptr_t)m);
72 cpu_spin_unlock_xrestore(&graph_lock, exceptions);
73 }
74