qcacmn: Statically allocate wlan logging buffer
To aid in debugging memory leaks, and improve the robustness of log recovery from crash dumps, statically allocate pglog_msg in the global scope. This allows logs to be inspected even in cases where a crash came late in the unload process. It also improves log recovery robustness by removing the possibility of using a NULL pointer offset under certain memory corruptions scenarios. Change-Id: I077198e358570661c2f3adf2704f2c48f4b2f6f8 CRs-Fixed: 2078548
This commit is contained in:
@@ -2566,14 +2566,12 @@ EXPORT_SYMBOL(QDF_PRINT_INFO);
|
|||||||
void qdf_logging_init(void)
|
void qdf_logging_init(void)
|
||||||
{
|
{
|
||||||
wlan_logging_sock_init_svc();
|
wlan_logging_sock_init_svc();
|
||||||
wlan_logging_sock_activate_svc(1, 10);
|
|
||||||
nl_srv_init(NULL);
|
nl_srv_init(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qdf_logging_exit(void)
|
void qdf_logging_exit(void)
|
||||||
{
|
{
|
||||||
nl_srv_exit();
|
nl_srv_exit();
|
||||||
wlan_logging_sock_deactivate_svc();
|
|
||||||
wlan_logging_sock_deinit_svc();
|
wlan_logging_sock_deinit_svc();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@@ -40,14 +40,14 @@
|
|||||||
|
|
||||||
int wlan_logging_sock_init_svc(void);
|
int wlan_logging_sock_init_svc(void);
|
||||||
int wlan_logging_sock_deinit_svc(void);
|
int wlan_logging_sock_deinit_svc(void);
|
||||||
int wlan_logging_sock_activate_svc(int log_to_console, int num_buf);
|
|
||||||
int wlan_logging_sock_deactivate_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);
|
||||||
|
|
||||||
#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);
|
||||||
void wlan_flush_host_logs_for_fatal(void);
|
void wlan_flush_host_logs_for_fatal(void);
|
||||||
|
void wlan_logging_set_active(bool active);
|
||||||
|
void wlan_logging_set_log_to_console(bool log_to_console);
|
||||||
#else
|
#else
|
||||||
static inline void wlan_flush_host_logs_for_fatal(void)
|
static inline void wlan_flush_host_logs_for_fatal(void)
|
||||||
{
|
{
|
||||||
@@ -58,6 +58,8 @@ static inline void wlan_logging_set_per_pkt_stats(void)
|
|||||||
static inline void wlan_logging_set_fw_flush_complete(void)
|
static inline void wlan_logging_set_fw_flush_complete(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void wlan_logging_set_active(bool active) {}
|
||||||
|
void wlan_logging_set_log_to_console(bool log_to_console) {}
|
||||||
#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
|
#endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
|
||||||
|
|
||||||
#ifdef FEATURE_WLAN_DIAG_SUPPORT
|
#ifdef FEATURE_WLAN_DIAG_SUPPORT
|
||||||
|
@@ -95,6 +95,9 @@ static uint8_t grx_count;
|
|||||||
|
|
||||||
#define ANI_NL_MSG_LOG_TYPE 89
|
#define ANI_NL_MSG_LOG_TYPE 89
|
||||||
#define ANI_NL_MSG_READY_IND_TYPE 90
|
#define ANI_NL_MSG_READY_IND_TYPE 90
|
||||||
|
#ifndef MAX_LOGMSG_COUNT
|
||||||
|
#define MAX_LOGMSG_COUNT 256
|
||||||
|
#endif
|
||||||
#define MAX_LOGMSG_LENGTH 2048
|
#define MAX_LOGMSG_LENGTH 2048
|
||||||
#define MAX_SKBMSG_LENGTH 4096
|
#define MAX_SKBMSG_LENGTH 4096
|
||||||
#define MAX_PKTSTATS_LENGTH 2048
|
#define MAX_PKTSTATS_LENGTH 2048
|
||||||
@@ -149,7 +152,8 @@ struct wlan_logging {
|
|||||||
/* Log Fatal and ERROR to console */
|
/* Log Fatal and ERROR to console */
|
||||||
bool log_to_console;
|
bool log_to_console;
|
||||||
/* Number of buffers to be used for logging */
|
/* Number of buffers to be used for logging */
|
||||||
int num_buf;
|
uint32_t num_buf;
|
||||||
|
uint32_t buffer_length;
|
||||||
/* Lock to synchronize access to shared logging resource */
|
/* Lock to synchronize access to shared logging resource */
|
||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
/* Holds the free node which can be used for filling logs */
|
/* Holds the free node which can be used for filling logs */
|
||||||
@@ -184,7 +188,7 @@ struct wlan_logging {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct wlan_logging gwlan_logging;
|
static struct wlan_logging gwlan_logging;
|
||||||
static struct log_msg *gplog_msg;
|
static struct log_msg gplog_msg[MAX_LOGMSG_COUNT];
|
||||||
static struct pkt_stats_msg *gpkt_stats_buffers;
|
static struct pkt_stats_msg *gpkt_stats_buffers;
|
||||||
|
|
||||||
/* Need to call this with spin_lock acquired */
|
/* Need to call this with spin_lock acquired */
|
||||||
@@ -370,8 +374,7 @@ int wlan_log_to_user(QDF_TRACE_LEVEL log_level, char *to_be_sent, int length)
|
|||||||
pfilled_length = &gwlan_logging.pcur_node->filled_length;
|
pfilled_length = &gwlan_logging.pcur_node->filled_length;
|
||||||
|
|
||||||
/* Check if we can accomodate more log into current node/buffer */
|
/* Check if we can accomodate more log into current node/buffer */
|
||||||
if ((MAX_LOGMSG_LENGTH <= (*pfilled_length +
|
if ((MAX_LOGMSG_LENGTH <= (*pfilled_length + sizeof(tAniNlHdr))) ||
|
||||||
sizeof(tAniNlHdr))) ||
|
|
||||||
((MAX_LOGMSG_LENGTH - (*pfilled_length +
|
((MAX_LOGMSG_LENGTH - (*pfilled_length +
|
||||||
sizeof(tAniNlHdr))) < total_log_len)) {
|
sizeof(tAniNlHdr))) < total_log_len)) {
|
||||||
wake_up_thread = true;
|
wake_up_thread = true;
|
||||||
@@ -829,27 +832,33 @@ static int wlan_logging_thread(void *Arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlan_logging_sock_activate_svc(int log_to_console, int num_buf)
|
void wlan_logging_set_active(bool active)
|
||||||
|
{
|
||||||
|
gwlan_logging.is_active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlan_logging_set_log_to_console(bool log_to_console)
|
||||||
|
{
|
||||||
|
gwlan_logging.log_to_console = log_to_console;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
gplog_msg = (struct log_msg *)vmalloc(num_buf * sizeof(struct log_msg));
|
spin_lock_init(&gwlan_logging.spin_lock);
|
||||||
if (!gplog_msg) {
|
spin_lock_init(&gwlan_logging.pkt_stats_lock);
|
||||||
pr_err("%s: Could not allocate memory\n", __func__);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
qdf_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg)));
|
gwlan_logging.log_to_console = true;
|
||||||
|
gwlan_logging.num_buf = MAX_LOGMSG_COUNT;
|
||||||
gwlan_logging.log_to_console = !!log_to_console;
|
gwlan_logging.buffer_length = MAX_LOGMSG_LENGTH;
|
||||||
gwlan_logging.num_buf = num_buf;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
||||||
INIT_LIST_HEAD(&gwlan_logging.free_list);
|
INIT_LIST_HEAD(&gwlan_logging.free_list);
|
||||||
INIT_LIST_HEAD(&gwlan_logging.filled_list);
|
INIT_LIST_HEAD(&gwlan_logging.filled_list);
|
||||||
|
|
||||||
for (i = 0; i < num_buf; i++) {
|
for (i = 0; i < gwlan_logging.num_buf; i++) {
|
||||||
list_add(&gplog_msg[i].node, &gwlan_logging.free_list);
|
list_add(&gplog_msg[i].node, &gwlan_logging.free_list);
|
||||||
gplog_msg[i].index = i;
|
gplog_msg[i].index = i;
|
||||||
}
|
}
|
||||||
@@ -931,17 +940,16 @@ err1:
|
|||||||
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
||||||
gwlan_logging.pcur_node = NULL;
|
gwlan_logging.pcur_node = NULL;
|
||||||
spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag);
|
spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag);
|
||||||
vfree(gplog_msg);
|
|
||||||
gplog_msg = NULL;
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlan_logging_sock_deactivate_svc(void)
|
int wlan_logging_sock_deinit_svc(void)
|
||||||
{
|
{
|
||||||
unsigned long irq_flag;
|
unsigned long irq_flag;
|
||||||
int i = 0;
|
int i;
|
||||||
|
|
||||||
if (!gplog_msg)
|
if (!gwlan_logging.pcur_node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_MCL
|
#ifdef CONFIG_MCL
|
||||||
@@ -962,8 +970,6 @@ int wlan_logging_sock_deactivate_svc(void)
|
|||||||
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
|
||||||
gwlan_logging.pcur_node = NULL;
|
gwlan_logging.pcur_node = NULL;
|
||||||
spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag);
|
spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag);
|
||||||
vfree(gplog_msg);
|
|
||||||
gplog_msg = NULL;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag);
|
spin_lock_irqsave(&gwlan_logging.pkt_stats_lock, irq_flag);
|
||||||
gwlan_logging.pkt_stats_pcur_node = NULL;
|
gwlan_logging.pkt_stats_pcur_node = NULL;
|
||||||
@@ -981,24 +987,6 @@ int wlan_logging_sock_deactivate_svc(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlan_logging_sock_init_svc(void)
|
|
||||||
{
|
|
||||||
spin_lock_init(&gwlan_logging.spin_lock);
|
|
||||||
spin_lock_init(&gwlan_logging.pkt_stats_lock);
|
|
||||||
gwlan_logging.pcur_node = NULL;
|
|
||||||
gwlan_logging.pkt_stats_pcur_node = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int wlan_logging_sock_deinit_svc(void)
|
|
||||||
{
|
|
||||||
gwlan_logging.pcur_node = NULL;
|
|
||||||
gwlan_logging.pkt_stats_pcur_node = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_logging_set_per_pkt_stats() - This function triggers per packet logging
|
* wlan_logging_set_per_pkt_stats() - This function triggers per packet logging
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user