thread: get debug stack traces on spinlocks
To help debug spinlocks, capture stack traces as spinlocks are used. Future commits in this series will make debugging with these stack traces easier. Signed-off-by: Mike Gerdts <mgerdts@nvidia.com> Change-Id: I597b730ca771ea3c5b831f5ba4058d359215f7f6 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15998 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <smatsumoto@nvidia.com>
This commit is contained in:
parent
709132d22d
commit
e85368a325
@ -904,6 +904,7 @@ bool spdk_interrupt_mode_is_enabled(void);
|
|||||||
struct spdk_spinlock {
|
struct spdk_spinlock {
|
||||||
pthread_spinlock_t spinlock;
|
pthread_spinlock_t spinlock;
|
||||||
struct spdk_thread *thread;
|
struct spdk_thread *thread;
|
||||||
|
struct spdk_spinlock_internal *internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,6 +25,11 @@
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SPDK_MSG_BATCH_SIZE 8
|
#define SPDK_MSG_BATCH_SIZE 8
|
||||||
@ -2876,6 +2881,48 @@ spdk_interrupt_mode_is_enabled(void)
|
|||||||
return g_interrupt_mode;
|
return g_interrupt_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SSPIN_DEBUG_STACK_FRAMES 16
|
||||||
|
|
||||||
|
struct sspin_stack {
|
||||||
|
void *addrs[SSPIN_DEBUG_STACK_FRAMES];
|
||||||
|
uint32_t depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spdk_spinlock_internal {
|
||||||
|
struct sspin_stack init_stack;
|
||||||
|
struct sspin_stack lock_stack;
|
||||||
|
struct sspin_stack unlock_stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
sspin_init_internal(struct spdk_spinlock *sspin)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
sspin->internal = calloc(1, sizeof(*sspin->internal));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sspin_fini_internal(struct spdk_spinlock *sspin)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
free(sspin->internal);
|
||||||
|
sspin->internal = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define SSPIN_GET_STACK(sspin, which) \
|
||||||
|
do { \
|
||||||
|
if (sspin->internal != NULL) { \
|
||||||
|
struct sspin_stack *stack = &sspin->internal->which ## _stack; \
|
||||||
|
stack->depth = backtrace(stack->addrs, SPDK_COUNTOF(stack->addrs)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define SSPIN_GET_STACK(sspin, which) do { } while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
spdk_spin_init(struct spdk_spinlock *sspin)
|
spdk_spin_init(struct spdk_spinlock *sspin)
|
||||||
{
|
{
|
||||||
@ -2884,6 +2931,8 @@ spdk_spin_init(struct spdk_spinlock *sspin)
|
|||||||
memset(sspin, 0, sizeof(*sspin));
|
memset(sspin, 0, sizeof(*sspin));
|
||||||
rc = pthread_spin_init(&sspin->spinlock, PTHREAD_PROCESS_PRIVATE);
|
rc = pthread_spin_init(&sspin->spinlock, PTHREAD_PROCESS_PRIVATE);
|
||||||
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
||||||
|
sspin_init_internal(sspin);
|
||||||
|
SSPIN_GET_STACK(sspin, init);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2895,6 +2944,8 @@ spdk_spin_destroy(struct spdk_spinlock *sspin)
|
|||||||
|
|
||||||
rc = pthread_spin_destroy(&sspin->spinlock);
|
rc = pthread_spin_destroy(&sspin->spinlock);
|
||||||
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
||||||
|
|
||||||
|
sspin_fini_internal(sspin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2911,6 +2962,8 @@ spdk_spin_lock(struct spdk_spinlock *sspin)
|
|||||||
|
|
||||||
sspin->thread = thread;
|
sspin->thread = thread;
|
||||||
sspin->thread->lock_count++;
|
sspin->thread->lock_count++;
|
||||||
|
|
||||||
|
SSPIN_GET_STACK(sspin, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2926,6 +2979,8 @@ spdk_spin_unlock(struct spdk_spinlock *sspin)
|
|||||||
thread->lock_count--;
|
thread->lock_count--;
|
||||||
sspin->thread = NULL;
|
sspin->thread = NULL;
|
||||||
|
|
||||||
|
SSPIN_GET_STACK(sspin, unlock);
|
||||||
|
|
||||||
rc = pthread_spin_unlock(&sspin->spinlock);
|
rc = pthread_spin_unlock(&sspin->spinlock);
|
||||||
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
SPIN_ASSERT_RETURN_VOID(rc == 0, SPIN_ERR_PTHREAD);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ endif
|
|||||||
SYS_LIBS =
|
SYS_LIBS =
|
||||||
|
|
||||||
ifeq ($(OS),FreeBSD)
|
ifeq ($(OS),FreeBSD)
|
||||||
SYS_LIBS += -L/usr/local/lib
|
SYS_LIBS += -lexecinfo -L/usr/local/lib
|
||||||
COMMON_CFLAGS += -I/usr/local/include
|
COMMON_CFLAGS += -I/usr/local/include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user