Small extensions in server driver
First extension is the ability to prevent the installation
of a full wildcard rule, when only one rule is present per
NIC. Such a rule will redirect all the system's load on one
core, which is undesirable.
Second, we introduce the ability to detect the duration of
load on a core by converting the boolean field isBusy to
a timestamp busySince.
Addressed code review suggestions.
Change-Id: I631cf322ee3724d9f1f97246d4189b5b2a008a76
Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java b/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
index 3dc7d59..34947cb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/FlowRuleProgrammableServerImpl.java
@@ -251,16 +251,26 @@
rules.forEach(rule -> {
if (!(rule instanceof FlowEntry)) {
- NicFlowRule nicRule = (NicFlowRule) rule;
- String tcId = nicRule.trafficClassId();
+ NicFlowRule nicRule = null;
- // Create a bucket of flow rules for this traffic class
- if (!rulesPerTc.containsKey(tcId)) {
- rulesPerTc.put(tcId, Sets.<FlowRule>newConcurrentHashSet());
+ // Only NicFlowRules are accepted
+ try {
+ nicRule = (NicFlowRule) rule;
+ } catch (ClassCastException cEx) {
+ log.warn("Skipping rule not crafted for NIC: {}", rule);
}
- Set<FlowRule> tcRuleSet = rulesPerTc.get(tcId);
- tcRuleSet.add(nicRule);
+ if (nicRule != null) {
+ String tcId = nicRule.trafficClassId();
+
+ // Create a bucket of flow rules for this traffic class
+ if (!rulesPerTc.containsKey(tcId)) {
+ rulesPerTc.put(tcId, Sets.<FlowRule>newConcurrentHashSet());
+ }
+
+ Set<FlowRule> tcRuleSet = rulesPerTc.get(tcId);
+ tcRuleSet.add(nicRule);
+ }
}
});
@@ -322,6 +332,11 @@
for (FlowRule rule : rules) {
NicFlowRule nicRule = (NicFlowRule) rule;
+ if (nicRule.isFullWildcard() && (rules.size() > 1)) {
+ log.warn("Skipping wildcard rule: {}", nicRule);
+ continue;
+ }
+
long coreIndex = nicRule.cpuCoreIndex();
// Keep the ID of the target NIC
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
index b4440e8..3ff7f05 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/ServerDevicesDiscovery.java
@@ -781,14 +781,14 @@
int cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
float cpuLoad = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
int queueId = cpuObjNode.path(CPU_PARAM_QUEUE).asInt();
- boolean isBusy = cpuObjNode.path(CPU_PARAM_STATUS).booleanValue();
+ int busySince = cpuObjNode.path(CPU_PARAM_STATUS).asInt();
// This is mandatory information
cpuBuilder.setDeviceId(deviceId)
.setId(cpuId)
.setLoad(cpuLoad)
.setQueue(queueId)
- .setIsBusy(isBusy);
+ .setBusySince(busySince);
// We have all the statistics for this CPU core
cpuStats.add(cpuBuilder.build());
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
index 019b875..8f50986 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/DefaultNicFlowRule.java
@@ -169,7 +169,7 @@
}
// This action provides basic rule match counters
- this.actions.add(new NicRuleAction(NicRuleAction.Action.COUNT));
+ // this.actions.add(new NicRuleAction(NicRuleAction.Action.COUNT));
}
@Override
@@ -307,6 +307,16 @@
}
@Override
+ public boolean isFullWildcard() {
+ if (((ipv4SrcAddress() != null) && !ipv4SrcAddress().isZero()) ||
+ ((ipv4DstAddress() != null) && !ipv4DstAddress().isZero()) ||
+ (ipv4Protocol() > 0) || (sourcePort() > 0) || (destinationPort() > 0)) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
public Set<NicRuleAction> actions() {
return actions;
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
index 64c792b..c2430c0 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/FlowRxFilterValue.java
@@ -26,26 +26,29 @@
public final class FlowRxFilterValue extends RxFilterValue
implements Comparable {
- private long cpuCoreId;
+ private long value;
private String flowRule;
/**
* Constructs a flow-based Rx filter.
+ *
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public FlowRxFilterValue() {
- super();
+ public FlowRxFilterValue(int cpuId) {
+ super(cpuId);
setValue(0);
setRule("");
}
/**
- * Constructs a flow-based Rx filter with CPU core ID.
+ * Constructs a flow-based Rx filter with physical CPU core ID.
*
- * @param cpuCoreId a CPU core ID when the flow ends up
+ * @param value Flow tag
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public FlowRxFilterValue(long cpuCoreId) {
- super();
- setValue(cpuCoreId);
+ public FlowRxFilterValue(long value, int cpuId) {
+ super(cpuId);
+ setValue(value);
setRule("");
}
@@ -53,12 +56,13 @@
* Constructs a flow-based Rx filter with CPU core ID
* and an associated rule.
*
- * @param cpuCoreId a CPU core ID
+ * @param value Flow tag
+ * @param cpuId CPU ID of the server this tag will lead to
* @param flowRule a flow rule as a string
*/
- public FlowRxFilterValue(long cpuCoreId, String flowRule) {
- super();
- setValue(cpuCoreId);
+ public FlowRxFilterValue(long value, int cpuId, String flowRule) {
+ super(cpuId);
+ setValue(value);
setRule(flowRule);
}
@@ -68,7 +72,7 @@
* @param other a source FlowRxFilterValue object
*/
public FlowRxFilterValue(FlowRxFilterValue other) {
- super();
+ super(other.cpuId);
setValue(other.value());
setRule(other.rule());
}
@@ -79,18 +83,18 @@
* @return Flow Rx filter value
*/
public long value() {
- return this.cpuCoreId;
+ return this.value;
}
/**
* Sets the value of this Rx filter.
*
- * @param cpuCoreId a CPU core ID for this Rx filter
+ * @param value a CPU core ID for this Rx filter
*/
- public void setValue(long cpuCoreId) {
- checkArgument(cpuCoreId >= 0,
+ private void setValue(long value) {
+ checkArgument(value >= 0,
"NIC flow Rx filter has invalid CPU core ID");
- this.cpuCoreId = cpuCoreId;
+ this.value = value;
}
/**
@@ -115,7 +119,7 @@
@Override
public int hashCode() {
- return Objects.hash(this.cpuCoreId, this.flowRule);
+ return Objects.hash(this.value, this.flowRule, this.cpuId);
}
@Override
@@ -130,8 +134,8 @@
FlowRxFilterValue other = (FlowRxFilterValue) obj;
- return (this.value() == other.value()) &&
- this.rule().equals(other.rule());
+ return this.value() == other.value() &&
+ this.rule().equals(other.rule()) && ((RxFilterValue) this).equals(other);
}
@Override
@@ -147,15 +151,15 @@
if (other instanceof FlowRxFilterValue) {
FlowRxFilterValue otherRxVal = (FlowRxFilterValue) other;
- long thisCoreId = this.value();
- long otherCoreId = otherRxVal.value();
+ long thisCpuId = this.value();
+ long otherCpuId = otherRxVal.value();
- if (thisCoreId > otherCoreId) {
+ if (thisCpuId > otherCpuId) {
return 1;
- } else if (thisCoreId < otherCoreId) {
+ } else if (thisCpuId < otherCpuId) {
return -1;
} else {
- return 0;
+ return this.cpuId - otherRxVal.cpuId;
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
index 2676f65..25b28bb 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MacRxFilterValue.java
@@ -30,9 +30,10 @@
/**
* Constructs a MAC-based Rx filter.
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public MacRxFilterValue() {
- super();
+ public MacRxFilterValue(int cpuId) {
+ super(cpuId);
this.mac = null;
}
@@ -40,9 +41,10 @@
* Constructs a MAC-based Rx filter with specific MAC address.
*
* @param mac a MAC address to use as a filter
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public MacRxFilterValue(MacAddress mac) {
- super();
+ public MacRxFilterValue(MacAddress mac, int cpuId) {
+ super(cpuId);
setValue(mac);
}
@@ -52,7 +54,7 @@
* @param other a source MacRxFilterValue object
*/
public MacRxFilterValue(MacRxFilterValue other) {
- super();
+ super(other.cpuId);
setValue(other.value());
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
index 2b5112f..ddc1930c 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/MplsRxFilterValue.java
@@ -30,9 +30,11 @@
/**
* Constructs an MPLS-based Rx filter.
+ *
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public MplsRxFilterValue() {
- super();
+ public MplsRxFilterValue(int cpuId) {
+ super(cpuId);
this.mplsLabel = null;
}
@@ -40,9 +42,10 @@
* Constructs an MPLS-based Rx filter with specific label.
*
* @param mplsLabel an MPLS label to use as a filter
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public MplsRxFilterValue(MplsLabel mplsLabel) {
- super();
+ public MplsRxFilterValue(MplsLabel mplsLabel, int cpuId) {
+ super(cpuId);
setValue(mplsLabel);
}
@@ -52,7 +55,7 @@
* @param other a source MplsRxFilterValue object
*/
public MplsRxFilterValue(MplsRxFilterValue other) {
- super();
+ super(other.cpuId);
setValue(other.value());
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicFlowRule.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicFlowRule.java
index 1215b6f..9083395 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicFlowRule.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/NicFlowRule.java
@@ -206,6 +206,13 @@
boolean hasTransport();
/**
+ * Returns whether this rule is a full wildcard or not.
+ *
+ * @return boolean full wildcard status
+ */
+ boolean isFullWildcard();
+
+ /**
* Returns the set of actions of this rule.
*
* @return rule's set of actions
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
index 08f2a46..2d54a81 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RssRxFilterValue.java
@@ -28,9 +28,11 @@
/**
* Constructs an RSS-based Rx filter.
+ *
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public RssRxFilterValue() {
- super();
+ public RssRxFilterValue(int cpuId) {
+ super(cpuId);
setValue(0);
}
@@ -38,9 +40,10 @@
* Constructs an RSS-based Rx filter with specific hash.
*
* @param rssHash a hash value
+ * @param cpuId CPU ID of the server this tag will lead to
*/
- public RssRxFilterValue(int rssHash) {
- super();
+ public RssRxFilterValue(int rssHash, int cpuId) {
+ super(cpuId);
setValue(rssHash);
}
@@ -50,7 +53,7 @@
* @param other a source RssRxFilterValue object
*/
public RssRxFilterValue(RssRxFilterValue other) {
- super();
+ super(other.cpuId);
setValue(other.value());
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
index 10ebe04..dceff82 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/RxFilterValue.java
@@ -15,12 +15,50 @@
*/
package org.onosproject.drivers.server.devices.nic;
+import java.util.Objects;
+
/**
* The base class that holds the value of a NIC's Rx filter.
*/
public abstract class RxFilterValue {
- public RxFilterValue() {
+ /* CPU id of the server this tag will lead to */
+ protected int cpuId;
+
+ /**
+ * Constructs an Rx filter value.
+ *
+ * @param cpuId CPU ID of the server this tag will lead to
+ */
+ public RxFilterValue(int cpuId) {
+ this.cpuId = cpuId;
+ }
+
+ /**
+ * Returns the CPU ID that corresponds to this Rx filter value.
+ *
+ * @return CPU ID of the server this tag will lead to
+ */
+ public int cpuId() {
+ return this.cpuId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.cpuId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if ((obj == null) || (!(obj instanceof RxFilterValue))) {
+ return false;
+ }
+
+ return cpuId == ((RxFilterValue) obj).cpuId;
}
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
index 18a99be..8e16321 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/devices/nic/VlanRxFilterValue.java
@@ -30,9 +30,10 @@
/**
* Constructs a VLAN-based Rx filter.
+ * @param cpuId CPU id of the server this tag will lead to
*/
- public VlanRxFilterValue() {
- super();
+ public VlanRxFilterValue(int cpuId) {
+ super(cpuId);
this.vlanId = VlanId.NONE;
}
@@ -40,9 +41,10 @@
* Constructs a VLAN-based Rx filter with specific ID.
*
* @param vlanId a VLAN ID to use as a filter
+ * @param cpuId CPU id of the server this tag will lead to
*/
- public VlanRxFilterValue(VlanId vlanId) {
- super();
+ public VlanRxFilterValue(VlanId vlanId, int cpuId) {
+ super(cpuId);
setValue(vlanId);
}
@@ -52,7 +54,7 @@
* @param other a source VlanRxFilterValue object
*/
public VlanRxFilterValue(VlanRxFilterValue other) {
- super();
+ super(other.cpuId);
setValue(other.value());
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
index 99e6c84..f2b6968 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/impl/stats/DefaultCpuStatistics.java
@@ -48,7 +48,7 @@
private final int id;
private final float load;
private final int queue;
- private final boolean isBusy;
+ private final int busySince;
private final Optional<MonitoringUnit> throughputUnit;
private final Optional<Float> averageThroughput;
private final Optional<MonitoringUnit> latencyUnit;
@@ -56,11 +56,11 @@
private final Optional<Float> averageLatency;
private final Optional<Float> maxLatency;
- private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, boolean isBusy) {
- this(deviceId, id, load, queue, isBusy, null, -1, null, -1, -1, -1);
+ private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, int busySince) {
+ this(deviceId, id, load, queue, busySince, null, -1, null, -1, -1, -1);
}
- private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, boolean isBusy,
+ private DefaultCpuStatistics(DeviceId deviceId, int id, float load, int queue, int busySince,
MonitoringUnit throughputUnit, float averageThroughput, MonitoringUnit latencyUnit,
float minLatency, float averageLatency, float maxLatency) {
checkNotNull(deviceId, "Device ID is NULL");
@@ -69,11 +69,11 @@
checkArgument((load >= MIN_CPU_LOAD) && (load <= MAX_CPU_LOAD),
"Invalid CPU load " + Float.toString(load) + ", not in [" + MIN_CPU_LOAD + ", " + MAX_CPU_LOAD + "]");
- this.deviceId = deviceId;
- this.id = id;
- this.load = load;
- this.queue = queue;
- this.isBusy = isBusy;
+ this.deviceId = deviceId;
+ this.id = id;
+ this.load = load;
+ this.queue = queue;
+ this.busySince = busySince;
this.throughputUnit = (throughputUnit == null) ?
Optional.empty() : Optional.ofNullable(throughputUnit);
@@ -91,11 +91,11 @@
// Constructor for serializer
private DefaultCpuStatistics() {
- this.deviceId = null;
- this.id = 0;
- this.load = 0;
- this.queue = 0;
- this.isBusy = false;
+ this.deviceId = null;
+ this.id = 0;
+ this.load = 0;
+ this.queue = 0;
+ this.busySince = -1;
this.throughputUnit = null;
this.averageThroughput = null;
@@ -131,7 +131,12 @@
@Override
public boolean busy() {
- return this.isBusy;
+ return this.busySince >= 0;
+ }
+
+ @Override
+ public int busySince() {
+ return this.busySince;
}
@Override
@@ -172,7 +177,7 @@
.add("id", id())
.add("load", load())
.add("queue", queue())
- .add("isBusy", busy())
+ .add("busySince", busySince())
.add("throughputUnit", throughputUnit.orElse(null))
.add("averageThroughput", averageThroughput.orElse(null))
.add("latencyUnit", latencyUnit.orElse(null))
@@ -188,7 +193,7 @@
int id;
float load = 0;
int queue = -1;
- boolean isBusy = false;
+ int busySince = -1;
MonitoringUnit throughputUnit = DEF_THROUGHPUT_UNIT;
float averageThroughput = -1;
@@ -250,13 +255,13 @@
}
/**
- * Sets the CPU status (free or busy).
+ * Sets the CPU status (free or busy since some ms).
*
- * @param isBusy CPU status
+ * @param busySince CPU busy time in ms, -1 if not busy
* @return builder object
*/
- public Builder setIsBusy(boolean isBusy) {
- this.isBusy = isBusy;
+ public Builder setBusySince(int busySince) {
+ this.busySince = busySince;
return this;
}
@@ -340,7 +345,7 @@
*/
public DefaultCpuStatistics build() {
return new DefaultCpuStatistics(
- deviceId, id, load, queue, isBusy,
+ deviceId, id, load, queue, busySince,
throughputUnit, averageThroughput,
latencyUnit, minLatency, averageLatency, maxLatency);
}
diff --git a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
index c43b826..5296d57 100644
--- a/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
+++ b/drivers/server/src/main/java/org/onosproject/drivers/server/stats/CpuStatistics.java
@@ -54,6 +54,14 @@
boolean busy();
/**
+ * Returns the amount of time in ms since the CPU has been busy,
+ * or a negative value if the CPU is idle.
+ *
+ * @return int time in ms since the CPU has been busy
+ */
+ int busySince();
+
+ /**
* Returns the unit of throughput values.
*
* @return throughput monitoring unit