Browse Source

qcacmn: Unlock tid_lock after status check

There is a race condition as tid_lock is unlocked early in
dp_rx_defrag_store_fragment and descriptors are replenished
from dp_peer_flush_frags and same descriptor is again
being replenished in fragmented path.
To resolve this, extending lock period till all the operations
on tid.head_frag_desc are done.

Change-Id: I6d2abb2119e3bebf739de9e41334d58ba87ee391
CRs-Fixed: 3068165
Ananya Gupta 3 years ago
parent
commit
182d1268cc
1 changed files with 2 additions and 1 deletions
  1. 2 1
      dp/wifi3.0/dp_rx_defrag.c

+ 2 - 1
dp/wifi3.0/dp_rx_defrag.c

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -1913,7 +1914,6 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
 	/* Re-inject the fragments back to REO for further processing */
 	/* Re-inject the fragments back to REO for further processing */
 	status = dp_rx_defrag_reo_reinject(peer, tid,
 	status = dp_rx_defrag_reo_reinject(peer, tid,
 			rx_reorder_array_elem->head);
 			rx_reorder_array_elem->head);
-	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 	if (QDF_IS_STATUS_SUCCESS(status)) {
 	if (QDF_IS_STATUS_SUCCESS(status)) {
 		rx_reorder_array_elem->head = NULL;
 		rx_reorder_array_elem->head = NULL;
 		rx_reorder_array_elem->tail = NULL;
 		rx_reorder_array_elem->tail = NULL;
@@ -1926,6 +1926,7 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc,
 	}
 	}
 
 
 	dp_rx_defrag_cleanup(peer, tid);
 	dp_rx_defrag_cleanup(peer, tid);
+	qdf_spin_unlock_bh(&rx_tid->tid_lock);
 
 
 	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);
 	dp_peer_unref_delete(peer, DP_MOD_ID_RX_ERR);