<p>pespin has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-trx/+/19206">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Transceiver: Fix race condition obtaining Dl burst from Upper layer<br><br>The queue was being accessed sequentially obtaining and releasing the<br>mutual exclusion zone twice. First in getStaleBurst() dropping all<br>FN<currTime, then in getCurrentBurst() trying to obtain FN=currTime.<br><br>However, since in between the mutex is released, it could happen that<br>for instance upper layer would introduce currTime-1 in the queue, which<br>would make then getCurrentBurst() detect that one instead of potential<br>currTime in the queue and return NULL.<br><br>By holding the mutex during the call to both functions we make sure the<br>state is kept during the whole transaction.<br><br>Related: OS#4487 (comment #7)<br>Change-Id: If1fd8d7fc5f21ee2894192ef1ac2a3cdda6bbb98<br>---<br>M Transceiver52M/Transceiver.cpp<br>M Transceiver52M/radioVector.cpp<br>M Transceiver52M/radioVector.h<br>3 files changed, 17 insertions(+), 24 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/06/19206/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp</span><br><span>index e8e025d..ac2d142 100644</span><br><span>--- a/Transceiver52M/Transceiver.cpp</span><br><span>+++ b/Transceiver52M/Transceiver.cpp</span><br><span>@@ -431,9 +431,15 @@</span><br><span>   std::vector<bool> filler(mChans, true);</span><br><span>   bool stale_bursts_changed;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  TN = nowTime.TN();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   for (size_t i = 0; i < mChans; i ++) {</span><br><span>     state = &mStates[i];</span><br><span>     stale_bursts_changed = false;</span><br><span style="color: hsl(120, 100%, 40%);">+    zeros[i] = state->chanType[TN] == NONE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    Mutex *mtx = mTxPriorityQueues[i].getMutex();</span><br><span style="color: hsl(120, 100%, 40%);">+    mtx->lock();</span><br><span> </span><br><span>     while ((burst = mTxPriorityQueues[i].getStaleBurst(nowTime))) {</span><br><span>       LOGCHAN(i, DTRXDDL, NOTICE) << "dumping STALE burst in TRX->SDR interface ("</span><br><span>@@ -445,15 +451,6 @@</span><br><span>       delete burst;</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (stale_bursts_changed)</span><br><span style="color: hsl(0, 100%, 40%);">-      dispatch_trx_rate_ctr_change(state, i);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    TN = nowTime.TN();</span><br><span style="color: hsl(0, 100%, 40%);">-    modFN = nowTime.FN() % state->fillerModulus[TN];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bursts[i] = state->fillerTable[modFN][TN];</span><br><span style="color: hsl(0, 100%, 40%);">-    zeros[i] = state->chanType[TN] == NONE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>     if ((burst = mTxPriorityQueues[i].getCurrentBurst(nowTime))) {</span><br><span>       bursts[i] = burst->getVector();</span><br><span> </span><br><span>@@ -463,9 +460,16 @@</span><br><span>         burst->setVector(NULL);</span><br><span>         filler[i] = false;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>       delete burst;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+      modFN = nowTime.FN() % state->fillerModulus[TN];</span><br><span style="color: hsl(120, 100%, 40%);">+      bursts[i] = state->fillerTable[modFN][TN];</span><br><span>     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    mtx->unlock();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (stale_bursts_changed)</span><br><span style="color: hsl(120, 100%, 40%);">+      dispatch_trx_rate_ctr_change(state, i);</span><br><span>   }</span><br><span> </span><br><span>   mRadioInterface->driveTransmitRadio(bursts, zeros);</span><br><span>diff --git a/Transceiver52M/radioVector.cpp b/Transceiver52M/radioVector.cpp</span><br><span>index ad40a11..68e42c5 100644</span><br><span>--- a/Transceiver52M/radioVector.cpp</span><br><span>+++ b/Transceiver52M/radioVector.cpp</span><br><span>@@ -120,38 +120,26 @@</span><br><span> </span><br><span> radioVector* VectorQueue::getStaleBurst(const GSM::Time& targTime)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-       mLock.lock();</span><br><span style="color: hsl(0, 100%, 40%);">-   if ((mQ.size()==0)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           mLock.unlock();</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((mQ.size()==0))</span><br><span>          return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span> </span><br><span>        if (mQ.top()->getTime() < targTime) {</span><br><span>          radioVector* retVal = mQ.top();</span><br><span>              mQ.pop();</span><br><span style="color: hsl(0, 100%, 40%);">-               mLock.unlock();</span><br><span>              return retVal;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       mLock.unlock();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      return NULL;</span><br><span> }</span><br><span> </span><br><span> radioVector* VectorQueue::getCurrentBurst(const GSM::Time& targTime)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-  mLock.lock();</span><br><span style="color: hsl(0, 100%, 40%);">-   if ((mQ.size()==0)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           mLock.unlock();</span><br><span style="color: hsl(120, 100%, 40%);">+       if ((mQ.size()==0))</span><br><span>          return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span> </span><br><span>        if (mQ.top()->getTime() == targTime) {</span><br><span>            radioVector* retVal = mQ.top();</span><br><span>              mQ.pop();</span><br><span style="color: hsl(0, 100%, 40%);">-               mLock.unlock();</span><br><span>              return retVal;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       mLock.unlock();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>      return NULL;</span><br><span> }</span><br><span>diff --git a/Transceiver52M/radioVector.h b/Transceiver52M/radioVector.h</span><br><span>index 0a14a4d..84e3987 100644</span><br><span>--- a/Transceiver52M/radioVector.h</span><br><span>+++ b/Transceiver52M/radioVector.h</span><br><span>@@ -65,6 +65,7 @@</span><br><span>   GSM::Time nextTime() const;</span><br><span>  radioVector* getStaleBurst(const GSM::Time& targTime);</span><br><span>   radioVector* getCurrentBurst(const GSM::Time& targTime);</span><br><span style="color: hsl(120, 100%, 40%);">+  Mutex *getMutex() const { return &mLock; };</span><br><span> };</span><br><span> </span><br><span> #endif /* RADIOVECTOR_H */</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-trx/+/19206">change 19206</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/osmo-trx/+/19206"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: If1fd8d7fc5f21ee2894192ef1ac2a3cdda6bbb98 </div>
<div style="display:none"> Gerrit-Change-Number: 19206 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>