qcacmn: Add memory barrier to avoid inconsistent reg write for valid flag

Add memory barrier to avoid inconsistent reg write for valid flag.

Change-Id: Ieb4ed80872961889f29de083a6b1dcdbe6a303d2
CRs-Fixed: 2699549
This commit is contained in:
Tiger Yu
2020-06-12 09:14:22 +08:00
committed by nshrivas
parent e3b05ae8ae
commit 0f08390fa4
3 changed files with 26 additions and 1 deletions

View File

@@ -461,7 +461,10 @@ static void hal_reg_write_work(void *arg)
uint32_t *addr;
q_elem = &hal->reg_write_queue[(hal->read_idx)];
q_elem->work_scheduled_time = qdf_get_log_timestamp();
/* Make sure q_elem consistent in the memory for multi-cores */
qdf_rmb();
if (!q_elem->valid)
return;
@@ -474,7 +477,11 @@ static void hal_reg_write_work(void *arg)
return;
}
while (q_elem->valid) {
while (true) {
qdf_rmb();
if (!q_elem->valid)
break;
q_elem->dequeue_time = qdf_get_log_timestamp();
ring_id = q_elem->srng->ring_id;
addr = q_elem->addr;
@@ -569,6 +576,17 @@ static void hal_reg_write_enqueue(struct hal_soc *hal_soc,
qdf_wmb();
q_elem->valid = true;
/*
* After all other fields in the q_elem has been updated
* in memory successfully, the valid flag needs to be updated
* in memory in time too.
* Else there is a chance that the dequeuing worker thread
* might read stale valid flag and the work will be bypassed
* for this round. And if there is no other work scheduled
* later, this hal register writing won't be updated any more.
*/
qdf_wmb();
srng->reg_write_in_progress = true;
qdf_atomic_inc(&hal_soc->active_work_cnt);