From a86de10a9af8286c362fb17a91121b9ab8f58efa Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Fri, 4 Aug 2017 17:01:11 -0700 Subject: [PATCH] qcacmn: Add qdf_print_thread_trace API Add an abstraction to QDF for printing the stack trace of a given thread. Change-Id: Ibea6e6bed7f3ebe67538b8ea8b6b437b643d5541 CRs-Fixed: 2088806 --- qdf/inc/qdf_threads.h | 14 ++++++++++++-- qdf/inc/qdf_util.h | 1 - qdf/linux/src/i_qdf_threads.h | 29 +++++++++++++++++++++++++++++ qdf/linux/src/i_qdf_util.h | 1 - qdf/linux/src/qdf_threads.c | 26 ++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 qdf/linux/src/i_qdf_threads.h diff --git a/qdf/inc/qdf_threads.h b/qdf/inc/qdf_threads.h index 128fb6492f..ff706dcdac 100644 --- a/qdf/inc/qdf_threads.h +++ b/qdf/inc/qdf_threads.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -34,7 +34,9 @@ #define __QDF_THREADS_H #include -#include +#include "i_qdf_threads.h" + +typedef __qdf_thread_t qdf_thread_t; /* Function declarations and documenation */ @@ -71,4 +73,12 @@ qdf_thread_t *qdf_create_thread(int (*thread_handler)(void *data), void *data, */ int qdf_wake_up_process(qdf_thread_t *thread); +/** + * qdf_print_stack_trace_thread() - prints the stack trace of the given thread + * @thread: the thread for which the stack trace will be printed + * + * Return: None + */ +void qdf_print_thread_trace(qdf_thread_t *thread); + #endif /* __QDF_THREADS_H */ diff --git a/qdf/inc/qdf_util.h b/qdf/inc/qdf_util.h index 7c6ba1a7d5..713534cd15 100644 --- a/qdf/inc/qdf_util.h +++ b/qdf/inc/qdf_util.h @@ -41,7 +41,6 @@ #define QDF_MAX_AVAILABLE_CPU 1 #endif -typedef __qdf_thread_t qdf_thread_t; typedef __qdf_wait_queue_head_t qdf_wait_queue_head_t; /** diff --git a/qdf/linux/src/i_qdf_threads.h b/qdf/linux/src/i_qdf_threads.h new file mode 100644 index 0000000000..4f6e1a9f64 --- /dev/null +++ b/qdf/linux/src/i_qdf_threads.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: i_qdf_threads + * Header file for linux-specific thead abstractions + */ + +#ifndef __I_QDF_THREADS_H +#define __I_QDF_THREADS_H + +typedef struct task_struct __qdf_thread_t; + +#endif /* __I_QDF_THREADS_H */ diff --git a/qdf/linux/src/i_qdf_util.h b/qdf/linux/src/i_qdf_util.h index 584312d778..afeca0d560 100644 --- a/qdf/linux/src/i_qdf_util.h +++ b/qdf/linux/src/i_qdf_util.h @@ -65,7 +65,6 @@ #include #endif -typedef struct task_struct __qdf_thread_t; typedef wait_queue_head_t __qdf_wait_queue_head_t; /* Generic compiler-dependent macros if defined by the OS */ diff --git a/qdf/linux/src/qdf_threads.c b/qdf/linux/src/qdf_threads.c index de767605c2..c5e4ed106d 100644 --- a/qdf/linux/src/qdf_threads.c +++ b/qdf/linux/src/qdf_threads.c @@ -44,6 +44,7 @@ #include #include #include +#include /* Function declarations and documenation */ @@ -129,3 +130,28 @@ int qdf_wake_up_process(qdf_thread_t *thread) return wake_up_process(thread); } EXPORT_SYMBOL(qdf_wake_up_process); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)) ||\ + defined(BACKPORTED_EXPORT_SAVE_STACK_TRACE_TSK) +/* save_stack_trace_tsk is not generally exported for arm architectures */ +#define QDF_PRINT_TRACE_COUNT 32 +void qdf_print_thread_trace(qdf_thread_t *thread) +{ + const int spaces = 4; + struct task_struct *task = thread; + unsigned long entries[QDF_PRINT_TRACE_COUNT] = {0}; + struct stack_trace trace = { + .nr_entries = 0, + .skip = 0, + .entries = &entries[0], + .max_entries = QDF_PRINT_TRACE_COUNT, + }; + + save_stack_trace_tsk(task, &trace); + print_stack_trace(&trace, spaces); +} +#else +void qdf_print_thread_trace(qdf_thread_t *thread) { } +#endif /* KERNEL_VERSION(4, 13, 0) */ +EXPORT_SYMBOL(qdf_print_thread_trace); +