Bläddra i källkod

qcacld-3.0: Avoid access of deleted peer during RX thread close

During SSR case in wlan_hdd_stop_modules(), ol_txrx_pdev_pre_detach()
cleanup the peer forcibly. Later RX Thread is getting closed as part
of cds_sched_close(). So chances of accessing deleted peer is there.

Shutdown RX thread before doing ol_txrx_pdev_pre_detach() to avoid
the chances of accessing deleted peer.

Change-Id: Iae27262396d8245eeb7a9b39cb678fad14815260
CRs-Fixed: 2349994
Alok Kumar 6 år sedan
förälder
incheckning
ac74177daa
3 ändrade filer med 65 tillägg och 17 borttagningar
  1. 23 1
      core/cds/inc/cds_sched.h
  2. 8 1
      core/cds/src/cds_api.c
  3. 34 15
      core/cds/src/cds_sched.c

+ 23 - 1
core/cds/inc/cds_sched.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 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
@@ -260,6 +260,15 @@ void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId);
 void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
 			struct cds_ol_rx_pkt *pkt);
 
+/**
+ * cds_close_rx_thread() - close the Rx thread
+ *
+ * This api closes the Rx thread:
+ *
+ * Return: qdf status
+ */
+QDF_STATUS cds_close_rx_thread(void);
+
 /*---------------------------------------------------------------------------
    \brief cds_alloc_ol_rx_pkt() - API to return next available cds message
    The \a cds_alloc_ol_rx_pkt() returns next available cds message buffer
@@ -331,6 +340,19 @@ void cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
 {
 }
 
+/**
+ * cds_close_rx_thread() - close the Rx thread
+ *
+ * This api closes the Rx thread:
+ *
+ * Return: qdf status
+ */
+static inline
+QDF_STATUS cds_close_rx_thread(void)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * cds_alloc_ol_rx_pkt() - API to return next available cds message
  * @pSchedContext: pointer to  CDS Sched Context

+ 8 - 1
core/cds/src/cds_api.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 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
@@ -1052,6 +1052,7 @@ QDF_STATUS cds_post_disable(void)
 	struct hif_opaque_softc *hif_ctx;
 	struct cdp_pdev *txrx_pdev;
 	struct scheduler_ctx *sched_ctx;
+	QDF_STATUS qdf_status;
 
 	wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
 	if (!wma_handle) {
@@ -1096,6 +1097,12 @@ QDF_STATUS cds_post_disable(void)
 		htc_stop(gp_cds_context->htc_ctx);
 	}
 
+	qdf_status = cds_close_rx_thread();
+	if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+		cds_err("Failed to close RX thread!");
+		return QDF_STATUS_E_INVAL;
+	}
+
 	cdp_pdev_pre_detach(cds_get_context(QDF_MODULE_ID_SOC),
 		       (struct cdp_pdev *)txrx_pdev, 1);
 

+ 34 - 15
core/cds/src/cds_sched.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2019 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
@@ -608,6 +608,38 @@ cds_indicate_rxpkt(p_cds_sched_context pSchedContext,
 	wake_up_interruptible(&pSchedContext->ol_rx_wait_queue);
 }
 
+/**
+ * cds_close_rx_thread() - close the Rx thread
+ *
+ * This api closes the Rx thread:
+ *
+ * Return: qdf status
+ */
+QDF_STATUS cds_close_rx_thread(void)
+{
+	cds_debug("invoked");
+
+	if (!gp_cds_sched_context) {
+		cds_err("gp_cds_sched_context == NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!gp_cds_sched_context->ol_rx_thread)
+		return QDF_STATUS_SUCCESS;
+
+	/* Shut down Tlshim Rx thread */
+	set_bit(RX_SHUTDOWN_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
+	set_bit(RX_POST_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
+	wake_up_interruptible(&gp_cds_sched_context->ol_rx_wait_queue);
+	wait_for_completion(&gp_cds_sched_context->ol_rx_shutdown);
+	gp_cds_sched_context->ol_rx_thread = NULL;
+	cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
+	cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
+	qdf_cpuhp_unregister(&gp_cds_sched_context->cpuhp_event_handle);
+
+	return QDF_STATUS_SUCCESS;
+} /* cds_close_rx_thread */
+
 /**
  * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta
  * @pSchedContext: Pointer to the global CDS Sched Context
@@ -791,20 +823,7 @@ QDF_STATUS cds_sched_close(void)
 		return QDF_STATUS_E_FAILURE;
 	}
 
-#ifdef QCA_CONFIG_SMP
-	if (!gp_cds_sched_context->ol_rx_thread)
-		return QDF_STATUS_SUCCESS;
-
-	/* Shut down Tlshim Rx thread */
-	set_bit(RX_SHUTDOWN_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
-	set_bit(RX_POST_EVENT, &gp_cds_sched_context->ol_rx_event_flag);
-	wake_up_interruptible(&gp_cds_sched_context->ol_rx_wait_queue);
-	wait_for_completion(&gp_cds_sched_context->ol_rx_shutdown);
-	gp_cds_sched_context->ol_rx_thread = NULL;
-	cds_drop_rxpkt_by_staid(gp_cds_sched_context, WLAN_MAX_STA_COUNT);
-	cds_free_ol_rx_pkt_freeq(gp_cds_sched_context);
-	qdf_cpuhp_unregister(&gp_cds_sched_context->cpuhp_event_handle);
-#endif
+	cds_close_rx_thread();
 	gp_cds_sched_context = NULL;
 	return QDF_STATUS_SUCCESS;
 } /* cds_sched_close() */