qcacmn: Add timer to flush out log buffers periodically
Add timer to flush out log buffers periodically. Add command to set the time period value. Change-Id: I8e796a9bc7caac2661d00852420dd5fa66f5bca5 CRs-Fixed: 2296362
This commit is contained in:

committed by
nshrivas

parent
eeeeaded77
commit
12205b544b
@@ -1238,6 +1238,31 @@ QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
|
|||||||
QDF_TRACE_LEVEL verbose,
|
QDF_TRACE_LEVEL verbose,
|
||||||
bool is_set);
|
bool is_set);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_log_dump_at_kernel_level() - Enable/Disable printk call
|
||||||
|
* @enable: Indicates whether printk is enabled in QDF_TRACE
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void qdf_log_dump_at_kernel_level(bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_logging_set_flush_timer() - Set the time period in which host logs
|
||||||
|
* should be flushed out to user-space
|
||||||
|
* @milliseconds: milliseconds after which the logs should be flushed out to
|
||||||
|
* user-space
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS_SUCCESS for success and QDF_STATUS_E_FAILURE for failure
|
||||||
|
*/
|
||||||
|
int qdf_logging_set_flush_timer(uint32_t milliseconds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_logging_flush_logs() - Flush out the logs to user-space one time
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void qdf_logging_flush_logs(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qdf_print_is_category_enabled() - Get category information for the
|
* qdf_print_is_category_enabled() - Get category information for the
|
||||||
* print control object
|
* print control object
|
||||||
|
@@ -33,6 +33,12 @@
|
|||||||
#include <wlan_logging_sock_svc.h>
|
#include <wlan_logging_sock_svc.h>
|
||||||
#include <qdf_module.h>
|
#include <qdf_module.h>
|
||||||
static int qdf_pidx = -1;
|
static int qdf_pidx = -1;
|
||||||
|
static bool qdf_log_dump_at_kernel_enable = true;
|
||||||
|
qdf_declare_param(qdf_log_dump_at_kernel_enable, bool);
|
||||||
|
|
||||||
|
/* This value of 0 will disable the timer by default. */
|
||||||
|
static uint32_t qdf_log_flush_timer_period;
|
||||||
|
qdf_declare_param(qdf_log_flush_timer_period, uint);
|
||||||
|
|
||||||
#include "qdf_time.h"
|
#include "qdf_time.h"
|
||||||
#include "qdf_mc_timer.h"
|
#include "qdf_mc_timer.h"
|
||||||
@@ -2959,7 +2965,8 @@ void qdf_trace_msg_cmn(unsigned int idx,
|
|||||||
#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
|
#if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
|
||||||
wlan_log_to_user(verbose, (char *)str_buffer,
|
wlan_log_to_user(verbose, (char *)str_buffer,
|
||||||
strlen(str_buffer));
|
strlen(str_buffer));
|
||||||
print_to_console(str_buffer);
|
if (qdf_likely(qdf_log_dump_at_kernel_enable))
|
||||||
|
print_to_console(str_buffer);
|
||||||
#else
|
#else
|
||||||
pr_err("%s\n", str_buffer);
|
pr_err("%s\n", str_buffer);
|
||||||
#endif
|
#endif
|
||||||
@@ -3393,6 +3400,18 @@ QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
|
|||||||
}
|
}
|
||||||
qdf_export_symbol(qdf_print_set_category_verbose);
|
qdf_export_symbol(qdf_print_set_category_verbose);
|
||||||
|
|
||||||
|
void qdf_log_dump_at_kernel_level(bool enable)
|
||||||
|
{
|
||||||
|
if (qdf_log_dump_at_kernel_enable == enable) {
|
||||||
|
QDF_TRACE_INFO(QDF_MODULE_ID_QDF,
|
||||||
|
"qdf_log_dump_at_kernel_enable is already %d\n",
|
||||||
|
enable);
|
||||||
|
}
|
||||||
|
qdf_log_dump_at_kernel_enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qdf_log_dump_at_kernel_level);
|
||||||
|
|
||||||
bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
|
bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
|
||||||
{
|
{
|
||||||
QDF_TRACE_LEVEL verbose_mask;
|
QDF_TRACE_LEVEL verbose_mask;
|
||||||
@@ -3556,6 +3575,7 @@ void qdf_logging_init(void)
|
|||||||
{
|
{
|
||||||
wlan_logging_sock_init_svc();
|
wlan_logging_sock_init_svc();
|
||||||
nl_srv_init(NULL);
|
nl_srv_init(NULL);
|
||||||
|
wlan_logging_set_flush_timer(qdf_log_flush_timer_period);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qdf_logging_exit(void)
|
void qdf_logging_exit(void)
|
||||||
@@ -3563,6 +3583,20 @@ void qdf_logging_exit(void)
|
|||||||
nl_srv_exit();
|
nl_srv_exit();
|
||||||
wlan_logging_sock_deinit_svc();
|
wlan_logging_sock_deinit_svc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qdf_logging_set_flush_timer(uint32_t milliseconds)
|
||||||
|
{
|
||||||
|
if (wlan_logging_set_flush_timer(milliseconds) == 0)
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
else
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qdf_logging_flush_logs(void)
|
||||||
|
{
|
||||||
|
wlan_flush_host_logs_for_fatal();
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void qdf_logging_init(void)
|
void qdf_logging_init(void)
|
||||||
{
|
{
|
||||||
@@ -3573,8 +3607,20 @@ void qdf_logging_exit(void)
|
|||||||
{
|
{
|
||||||
nl_srv_exit();
|
nl_srv_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qdf_logging_set_flush_timer(uint32_t milliseconds)
|
||||||
|
{
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qdf_logging_flush_logs(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
qdf_export_symbol(qdf_logging_set_flush_timer);
|
||||||
|
qdf_export_symbol(qdf_logging_flush_logs);
|
||||||
|
|
||||||
#ifdef CONFIG_KALLSYMS
|
#ifdef CONFIG_KALLSYMS
|
||||||
inline int qdf_sprint_symbol(char *buffer, void *addr)
|
inline int qdf_sprint_symbol(char *buffer, void *addr)
|
||||||
{
|
{
|
||||||
|
@@ -33,6 +33,19 @@ int wlan_logging_sock_init_svc(void);
|
|||||||
int wlan_logging_sock_deinit_svc(void);
|
int wlan_logging_sock_deinit_svc(void);
|
||||||
int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length);
|
int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlan_logging_set_flush_timer() - Sets the time period for log flush timer
|
||||||
|
* @milliseconds: Time period in milliseconds
|
||||||
|
*
|
||||||
|
* This function sets the time period interval during which the log buffers
|
||||||
|
* will be flushed out to user space. Setting this interval can set an
|
||||||
|
* approximate maximum delay after which any message logged through QDF_TRACE
|
||||||
|
* will appear at user-space
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
int wlan_logging_set_flush_timer(uint32_t milliseconds);
|
||||||
|
|
||||||
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
|
#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
|
||||||
void wlan_logging_set_per_pkt_stats(void);
|
void wlan_logging_set_per_pkt_stats(void);
|
||||||
void wlan_logging_set_fw_flush_complete(void);
|
void wlan_logging_set_fw_flush_complete(void);
|
||||||
|
@@ -38,6 +38,8 @@
|
|||||||
#include <qdf_time.h>
|
#include <qdf_time.h>
|
||||||
#include <qdf_trace.h>
|
#include <qdf_trace.h>
|
||||||
#include <qdf_mc_timer.h>
|
#include <qdf_mc_timer.h>
|
||||||
|
#include <qdf_timer.h>
|
||||||
|
#include <qdf_lock.h>
|
||||||
#include <wlan_ptt_sock_svc.h>
|
#include <wlan_ptt_sock_svc.h>
|
||||||
#include <host_diag_core_event.h>
|
#include <host_diag_core_event.h>
|
||||||
#include "host_diag_core_log.h"
|
#include "host_diag_core_log.h"
|
||||||
@@ -134,6 +136,7 @@ struct pkt_stats_msg {
|
|||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_FLUSH_TIMER_PERIOD_VALUE 3600000 /* maximum of 1 hour (in ms) */
|
||||||
struct wlan_logging {
|
struct wlan_logging {
|
||||||
/* Log Fatal and ERROR to console */
|
/* Log Fatal and ERROR to console */
|
||||||
bool log_to_console;
|
bool log_to_console;
|
||||||
@@ -171,6 +174,10 @@ struct wlan_logging {
|
|||||||
unsigned int pkt_stat_drop_cnt;
|
unsigned int pkt_stat_drop_cnt;
|
||||||
spinlock_t pkt_stats_lock;
|
spinlock_t pkt_stats_lock;
|
||||||
unsigned int pkt_stats_msg_idx;
|
unsigned int pkt_stats_msg_idx;
|
||||||
|
qdf_timer_t flush_timer;
|
||||||
|
bool is_flush_timer_initialized;
|
||||||
|
uint32_t flush_timer_period;
|
||||||
|
qdf_spinlock_t flush_timer_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct wlan_logging gwlan_logging;
|
static struct wlan_logging gwlan_logging;
|
||||||
@@ -744,6 +751,19 @@ static void send_flush_completion_to_user(uint8_t ring_id)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void setup_flush_timer(void)
|
||||||
|
{
|
||||||
|
qdf_spin_lock(&gwlan_logging.flush_timer_lock);
|
||||||
|
if (!gwlan_logging.is_flush_timer_initialized ||
|
||||||
|
(gwlan_logging.flush_timer_period == 0)) {
|
||||||
|
qdf_spin_unlock(&gwlan_logging.flush_timer_lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qdf_timer_mod(&gwlan_logging.flush_timer,
|
||||||
|
gwlan_logging.flush_timer_period);
|
||||||
|
qdf_spin_unlock(&gwlan_logging.flush_timer_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_logging_thread() - The WLAN Logger thread
|
* wlan_logging_thread() - The WLAN Logger thread
|
||||||
* @Arg - pointer to the HDD context
|
* @Arg - pointer to the HDD context
|
||||||
@@ -757,6 +777,7 @@ static int wlan_logging_thread(void *Arg)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
while (!gwlan_logging.exit) {
|
while (!gwlan_logging.exit) {
|
||||||
|
setup_flush_timer();
|
||||||
ret_wait_status =
|
ret_wait_status =
|
||||||
wait_event_interruptible(gwlan_logging.wait_queue,
|
wait_event_interruptible(gwlan_logging.wait_queue,
|
||||||
(!list_empty
|
(!list_empty
|
||||||
@@ -852,11 +873,54 @@ void wlan_logging_set_log_to_console(bool log_to_console)
|
|||||||
gwlan_logging.log_to_console = log_to_console;
|
gwlan_logging.log_to_console = log_to_console;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flush_log_buffers_timer(void *dummy)
|
||||||
|
{
|
||||||
|
wlan_flush_host_logs_for_fatal();
|
||||||
|
}
|
||||||
|
|
||||||
|
int wlan_logging_set_flush_timer(uint32_t milliseconds)
|
||||||
|
{
|
||||||
|
if (milliseconds > MAX_FLUSH_TIMER_PERIOD_VALUE) {
|
||||||
|
QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
|
||||||
|
"ERROR! value should be (0 - %d)\n",
|
||||||
|
MAX_FLUSH_TIMER_PERIOD_VALUE);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (!gwlan_logging.is_active) {
|
||||||
|
QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
|
||||||
|
"WLAN-Logging not active");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
qdf_spin_lock(&gwlan_logging.flush_timer_lock);
|
||||||
|
if (!gwlan_logging.is_flush_timer_initialized) {
|
||||||
|
qdf_spin_unlock(&gwlan_logging.flush_timer_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
gwlan_logging.flush_timer_period = milliseconds;
|
||||||
|
if (milliseconds) {
|
||||||
|
qdf_timer_mod(&gwlan_logging.flush_timer,
|
||||||
|
gwlan_logging.flush_timer_period);
|
||||||
|
}
|
||||||
|
qdf_spin_unlock(&gwlan_logging.flush_timer_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flush_timer_init(void)
|
||||||
|
{
|
||||||
|
qdf_spinlock_create(&gwlan_logging.flush_timer_lock);
|
||||||
|
qdf_timer_init(NULL, &gwlan_logging.flush_timer,
|
||||||
|
flush_log_buffers_timer, NULL,
|
||||||
|
QDF_TIMER_TYPE_SW);
|
||||||
|
gwlan_logging.is_flush_timer_initialized = true;
|
||||||
|
gwlan_logging.flush_timer_period = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int wlan_logging_sock_init_svc(void)
|
int wlan_logging_sock_init_svc(void)
|
||||||
{
|
{
|
||||||
int i = 0, j, pkt_stats_size;
|
int i = 0, j, pkt_stats_size;
|
||||||
unsigned long irq_flag;
|
unsigned long irq_flag;
|
||||||
|
|
||||||
|
flush_timer_init();
|
||||||
spin_lock_init(&gwlan_logging.spin_lock);
|
spin_lock_init(&gwlan_logging.spin_lock);
|
||||||
spin_lock_init(&gwlan_logging.pkt_stats_lock);
|
spin_lock_init(&gwlan_logging.pkt_stats_lock);
|
||||||
|
|
||||||
@@ -961,6 +1025,16 @@ err1:
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flush_timer_deinit(void)
|
||||||
|
{
|
||||||
|
gwlan_logging.is_flush_timer_initialized = false;
|
||||||
|
qdf_spin_lock(&gwlan_logging.flush_timer_lock);
|
||||||
|
qdf_timer_stop(&gwlan_logging.flush_timer);
|
||||||
|
qdf_timer_free(&gwlan_logging.flush_timer);
|
||||||
|
qdf_spin_unlock(&gwlan_logging.flush_timer_lock);
|
||||||
|
qdf_spinlock_destroy(&gwlan_logging.flush_timer_lock);
|
||||||
|
}
|
||||||
|
|
||||||
int wlan_logging_sock_deinit_svc(void)
|
int wlan_logging_sock_deinit_svc(void)
|
||||||
{
|
{
|
||||||
unsigned long irq_flag;
|
unsigned long irq_flag;
|
||||||
@@ -1001,6 +1075,7 @@ int wlan_logging_sock_deinit_svc(void)
|
|||||||
vfree(gpkt_stats_buffers);
|
vfree(gpkt_stats_buffers);
|
||||||
gpkt_stats_buffers = NULL;
|
gpkt_stats_buffers = NULL;
|
||||||
free_log_msg_buffer();
|
free_log_msg_buffer();
|
||||||
|
flush_timer_deinit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1060,8 +1135,9 @@ void wlan_flush_host_logs_for_fatal(void)
|
|||||||
#ifdef CONFIG_MCL
|
#ifdef CONFIG_MCL
|
||||||
if (cds_is_log_report_in_progress()) {
|
if (cds_is_log_report_in_progress()) {
|
||||||
#endif
|
#endif
|
||||||
pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n",
|
if (gwlan_logging.flush_timer_period == 0)
|
||||||
__func__);
|
pr_info("%s:flush all host logs Setting HOST_LOG_POST_MASK\n",
|
||||||
|
__func__);
|
||||||
spin_lock_irqsave(&gwlan_logging.spin_lock, flags);
|
spin_lock_irqsave(&gwlan_logging.spin_lock, flags);
|
||||||
wlan_queue_logmsg_for_app();
|
wlan_queue_logmsg_for_app();
|
||||||
spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags);
|
spin_unlock_irqrestore(&gwlan_logging.spin_lock, flags);
|
||||||
|
Reference in New Issue
Block a user