Fix for IOFSwitch/OFSwitchImpl leak
- Fix for ONOS-1765
- OFSwitchImpl.java
Changes TLS bufffer map to WeakHashMap to eliminate buffer for
eliminated switches.
- OFMessageDamper.java
Added a hack to remove cached entries related to disconnected switch
- TimedCache.java
Backdoor acccess to manually invalidate cached entries
- FlowProgrammer.java
Propagate removeSwitch event
FlowPusher -> OFMessageDamper to invalidate cache.
- FlowPusher.java
Switched `assignedQueues` to concurrent version of WeakHashMap
- PlanInstallRuntime.java
Changed FlowModCount map to WeakHashMap and removed
strong reference to IOFSwitch
Change-Id: Idb5014379ebc5658d0ae58ebcdbb2bf03e981df7
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
index 838533d..046d130 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowProgrammer.java
@@ -128,6 +128,7 @@
synchronizer.interrupt(sw);
}
pusher.deleteQueue(sw, true);
+ pusher.invalidate(sw);
}
@Override
diff --git a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
index 98c2f97..37e1b44 100644
--- a/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
+++ b/src/main/java/net/onrc/onos/core/flowprogrammer/FlowPusher.java
@@ -70,6 +70,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.cache.CacheBuilder;
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
@@ -299,8 +301,11 @@
* Main thread that reads messages from queues and sends them to switches.
*/
private class FlowPusherThread extends Thread {
+ // Weak ConncurrentHashMap
private Map<IOFSwitch, SwitchQueue> assignedQueues
- = new ConcurrentHashMap<IOFSwitch, SwitchQueue>();
+ = CacheBuilder.newBuilder()
+ .weakKeys()
+ .<IOFSwitch, SwitchQueue>build().asMap();
final Lock queuingLock = new ReentrantLock();
final Condition messagePushed = queuingLock.newCondition();
@@ -612,6 +617,17 @@
}
}
+ /**
+ * Invalidate.
+ *
+ * @param sw switch
+ *
+ * @see OFMessageDamper#invalidate(IOFSwitch)
+ */
+ public void invalidate(IOFSwitch sw) {
+ messageDamper.invalidate(sw);
+ }
+
@Override
public boolean add(IOFSwitch sw, OFMessage msg) {
return add(sw, msg, MsgPriority.NORMAL);
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
index bd332ac..f942fa8 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanInstallRuntime.java
@@ -1,11 +1,12 @@
package net.onrc.onos.core.intent.runtime;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
import java.util.concurrent.ExecutionException;
import net.floodlightcontroller.core.IFloodlightProviderService;
@@ -50,7 +51,7 @@
* TODO: This class should be wrapped into a more generic debugging framework when available.
*/
private static class FlowModCount {
- IOFSwitch sw;
+ WeakReference<IOFSwitch> sw;
long modFlows = 0;
long delFlows = 0;
long errors = 0;
@@ -61,7 +62,7 @@
* @param sw the switch for FlowMod statistics collection
*/
FlowModCount(IOFSwitch sw) {
- this.sw = sw;
+ this.sw = new WeakReference<>(sw);
}
/**
@@ -92,10 +93,12 @@
*/
@Override
public String toString() {
- return "sw:" + sw.getStringId() + ": modify " + modFlows + " delete " + delFlows + " error " + errors;
+ final IOFSwitch swTemp = sw.get();
+ return "sw:" + ((swTemp == null) ? "disconnected" : swTemp.getStringId())
+ + ": modify " + modFlows + " delete " + delFlows + " error " + errors;
}
- static Map<IOFSwitch, FlowModCount> map = new HashMap<>();
+ static Map<IOFSwitch, FlowModCount> map = new WeakHashMap<>();
/**
* This function is used for collecting statistics information. It should be called for