Skip to content

Commit

Permalink
core: attempt to detect deadlock on spin locks
Browse files Browse the repository at this point in the history
Attempts to detect and report deadlock on spin locks..

Reviewed-by: Igor Opaniuk <igor.opaniuk@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jenswi-linaro committed Jul 10, 2017
1 parent 5d8aaa0 commit 98afff7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
59 changes: 57 additions & 2 deletions core/arch/arm/include/kernel/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,47 @@ void __cpu_spin_unlock(unsigned int *lock);
/* returns 0 on locking success, non zero on failure */
unsigned int __cpu_spin_trylock(unsigned int *lock);

static inline void cpu_spin_lock(unsigned int *lock)
static inline void cpu_spin_lock_no_dldetect(unsigned int *lock)
{
assert(thread_foreign_intr_disabled());
__cpu_spin_lock(lock);
spinlock_count_incr();
}

#ifdef CFG_TEE_CORE_DEBUG
#define cpu_spin_lock(lock) \
cpu_spin_lock_dldetect(__func__, __LINE__, lock)

static inline void cpu_spin_lock_dldetect(const char *func, const int line,
unsigned int *lock)
{
unsigned int retries = 0;
unsigned int reminder = 0;

assert(thread_foreign_intr_disabled());

while (__cpu_spin_trylock(lock)) {
retries++;
if (!retries) {
/* wrapped, time to report */
trace_printf(func, line, TRACE_ERROR, true,
"possible spinlock deadlock reminder %u",
reminder);
if (reminder < UINT_MAX)
reminder++;
}
}

spinlock_count_incr();
}
#else
static inline void cpu_spin_lock(unsigned int *lock)
{
cpu_spin_lock_no_dldetect(lock);
}
#endif


static inline bool cpu_spin_trylock(unsigned int *lock)
{
unsigned int rc;
Expand All @@ -82,14 +116,35 @@ static inline void cpu_spin_unlock(unsigned int *lock)
spinlock_count_decr();
}

static inline uint32_t cpu_spin_lock_xsave(unsigned int *lock)
static inline uint32_t cpu_spin_lock_xsave_no_dldetect(unsigned int *lock)
{
uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);

cpu_spin_lock(lock);
return exceptions;
}


#ifdef CFG_TEE_CORE_DEBUG
#define cpu_spin_lock_xsave(lock) \
cpu_spin_lock_xsave_dldetect(__func__, __LINE__, lock)

static inline uint32_t cpu_spin_lock_xsave_dldetect(const char *func,
const int line,
unsigned int *lock)
{
uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL);

cpu_spin_lock_dldetect(func, line, lock);
return exceptions;
}
#else
static inline uint32_t cpu_spin_lock_xsave(unsigned int *lock)
{
return cpu_spin_lock_xsave_no_dldetect(lock);
}
#endif

static inline void cpu_spin_unlock_xrestore(unsigned int *lock,
uint32_t exceptions)
{
Expand Down
2 changes: 1 addition & 1 deletion core/arch/arm/kernel/trace_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void trace_ext_puts(const char *str)

if (mmu_enabled && !cpu_spin_trylock(&puts_lock)) {
was_contended = true;
cpu_spin_lock(&puts_lock);
cpu_spin_lock_no_dldetect(&puts_lock);
}

console_flush();
Expand Down

0 comments on commit 98afff7

Please sign in to comment.