[VOL-4299] R2.8 - OpenOnuAdapter ATT scenario Flow suspension on cookie usage runs into deadlock
Signed-off-by: mpagenko <michael.pagenkopf@adtran.com>
Change-Id: I6348ea5ef51c93bc0a502fd2f81f07737258ba64
diff --git a/internal/pkg/onuadaptercore/omci_vlan_config.go b/internal/pkg/onuadaptercore/omci_vlan_config.go
index 26ecac0..3201150 100644
--- a/internal/pkg/onuadaptercore/omci_vlan_config.go
+++ b/internal/pkg/onuadaptercore/omci_vlan_config.go
@@ -496,7 +496,11 @@
//a delay for adding the cookie to this rule is requested
// take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
oFsm.mutexFlowParams.Unlock()
- oFsm.suspendNewRule(ctx)
+ if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
+ logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
+ "device-id": oFsm.deviceID, "cookie": delayedCookie})
+ return fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
+ }
flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
oFsm.mutexFlowParams.Lock()
} else {
@@ -515,7 +519,12 @@
oFsm.mutexFlowParams.Unlock()
if !flowEntryMatch { //it is (was) a new rule
- delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
+ delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
+ if !deleteSuccess {
+ logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
+ "device-id": oFsm.deviceID, "cookie": delayedCookie})
+ return fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
+ }
requestAppendRule = true //default assumption here is that rule is to be appended
flowCookieModify = true //and that the the flow data base is to be updated
if delayedCookie != 0 { //it was suspended
@@ -713,15 +722,16 @@
}
return 0 //no delay requested
}
-func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
+func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
oFsm.mutexFlowParams.RLock()
logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
"device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
oFsm.mutexFlowParams.RUnlock()
+ cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
select {
- case <-oFsm.chCookieDeleted:
- logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
- "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
+ case cookieDeleted = <-oFsm.chCookieDeleted:
+ logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
+ "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
"device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
@@ -729,16 +739,18 @@
oFsm.mutexFlowParams.Lock()
oFsm.delayNewRuleCookie = 0
oFsm.mutexFlowParams.Unlock()
+ return cookieDeleted
}
-func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
+func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
oFsm.mutexFlowParams.Lock()
delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
oFsm.mutexFlowParams.Unlock()
+ deleteSuccess := true
if delayedCookie != 0 {
- oFsm.suspendNewRule(ctx)
+ deleteSuccess = oFsm.suspendNewRule(ctx)
}
- return delayedCookie
+ return delayedCookie, deleteSuccess
}
//returns flowModified, RuleAppendRequest
@@ -1793,7 +1805,7 @@
if oFsm.delayNewRuleCookie != 0 {
// looks like the waiting AddFlow is stuck
oFsm.mutexFlowParams.RUnlock()
- oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/terminate
+ oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
oFsm.mutexFlowParams.RLock()
}
if len(oFsm.uniRemoveFlowsSlice) > 0 {