Procházet zdrojové kódy

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
Dustin Brown před 7 roky
rodič
revize
9a489c42be

+ 0 - 2
qdf/linux/src/qdf_trace.c

@@ -2566,14 +2566,12 @@ EXPORT_SYMBOL(QDF_PRINT_INFO);
 void qdf_logging_init(void)
 {
 	wlan_logging_sock_init_svc();
-	wlan_logging_sock_activate_svc(1, 10);
 	nl_srv_init(NULL);
 }
 
 void qdf_logging_exit(void)
 {
 	nl_srv_exit();
-	wlan_logging_sock_deactivate_svc();
 	wlan_logging_sock_deinit_svc();
 }
 #else

+ 4 - 2
utils/logging/inc/wlan_logging_sock_svc.h

@@ -40,14 +40,14 @@
 
 int wlan_logging_sock_init_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);
 
 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
 void wlan_logging_set_per_pkt_stats(void);
 void wlan_logging_set_fw_flush_complete(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
 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)
 {
 }
+void wlan_logging_set_active(bool active) {}
+void wlan_logging_set_log_to_console(bool log_to_console) {}
 #endif /* WLAN_LOGGING_SOCK_SVC_ENABLE */
 
 #ifdef FEATURE_WLAN_DIAG_SUPPORT

+ 28 - 40
utils/logging/src/wlan_logging_sock_svc.c

@@ -95,6 +95,9 @@ static uint8_t grx_count;
 
 #define ANI_NL_MSG_LOG_TYPE 89
 #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_SKBMSG_LENGTH 4096
 #define MAX_PKTSTATS_LENGTH 2048
@@ -149,7 +152,8 @@ struct wlan_logging {
 	/* Log Fatal and ERROR to console */
 	bool log_to_console;
 	/* 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 */
 	spinlock_t spin_lock;
 	/* 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 log_msg *gplog_msg;
+static struct log_msg gplog_msg[MAX_LOGMSG_COUNT];
 static struct pkt_stats_msg *gpkt_stats_buffers;
 
 /* 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;
 
 	/* Check if we can accomodate more log into current node/buffer */
-	if ((MAX_LOGMSG_LENGTH <= (*pfilled_length +
-						sizeof(tAniNlHdr))) ||
+	if ((MAX_LOGMSG_LENGTH <= (*pfilled_length + sizeof(tAniNlHdr))) ||
 		((MAX_LOGMSG_LENGTH - (*pfilled_length +
 			sizeof(tAniNlHdr))) < total_log_len)) {
 		wake_up_thread = true;
@@ -829,27 +832,33 @@ static int wlan_logging_thread(void *Arg)
 	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;
 	unsigned long irq_flag;
 
-	gplog_msg = (struct log_msg *)vmalloc(num_buf * sizeof(struct log_msg));
-	if (!gplog_msg) {
-		pr_err("%s: Could not allocate memory\n", __func__);
-		return -ENOMEM;
-	}
-
-	qdf_mem_zero(gplog_msg, (num_buf * sizeof(struct log_msg)));
+	spin_lock_init(&gwlan_logging.spin_lock);
+	spin_lock_init(&gwlan_logging.pkt_stats_lock);
 
-	gwlan_logging.log_to_console = !!log_to_console;
-	gwlan_logging.num_buf = num_buf;
+	gwlan_logging.log_to_console = true;
+	gwlan_logging.num_buf = MAX_LOGMSG_COUNT;
+	gwlan_logging.buffer_length = MAX_LOGMSG_LENGTH;
 
 	spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
 	INIT_LIST_HEAD(&gwlan_logging.free_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);
 		gplog_msg[i].index = i;
 	}
@@ -931,17 +940,16 @@ err1:
 	spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
 	gwlan_logging.pcur_node = NULL;
 	spin_unlock_irqrestore(&gwlan_logging.spin_lock, irq_flag);
-	vfree(gplog_msg);
-	gplog_msg = NULL;
+
 	return -ENOMEM;
 }
 
-int wlan_logging_sock_deactivate_svc(void)
+int wlan_logging_sock_deinit_svc(void)
 {
 	unsigned long irq_flag;
-	int i = 0;
+	int i;
 
-	if (!gplog_msg)
+	if (!gwlan_logging.pcur_node)
 		return 0;
 
 #ifdef CONFIG_MCL
@@ -962,8 +970,6 @@ int wlan_logging_sock_deactivate_svc(void)
 	spin_lock_irqsave(&gwlan_logging.spin_lock, irq_flag);
 	gwlan_logging.pcur_node = NULL;
 	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);
 	gwlan_logging.pkt_stats_pcur_node = NULL;
@@ -981,24 +987,6 @@ int wlan_logging_sock_deactivate_svc(void)
 	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
  *