mirror of
https://github.com/openvswitch/ovs
synced 2025-08-29 13:27:59 +00:00
ofproto-dpif: Set flow-eviction-threshold globally.
With the single datapath, it no longer makes sense to have a per ofproto flow eviction threshold. This patch moves the flow eviction threshold to the Open_vSwitch table making the setting global, though still treated separately for each ofproto. A future patch will unify flow eviction on a per datapath basis. Signed-off-by: Ethan Jackson <ethan@nicira.com>
This commit is contained in:
parent
dc54ef36cb
commit
380f49c4a1
1
NEWS
1
NEWS
@ -6,6 +6,7 @@ post-v1.11.0
|
|||||||
added "remote_ip=flow" and "local_ip=flow" options.
|
added "remote_ip=flow" and "local_ip=flow" options.
|
||||||
- New "check-oftest" Makefile target for running OFTest against Open
|
- New "check-oftest" Makefile target for running OFTest against Open
|
||||||
vSwitch. See README-OFTest for details.
|
vSwitch. See README-OFTest for details.
|
||||||
|
- The flow eviction threshold has been moved to the Open_vSwitch table.
|
||||||
|
|
||||||
|
|
||||||
v1.11.0 - xx xxx xxxx
|
v1.11.0 - xx xxx xxxx
|
||||||
|
@ -1645,7 +1645,7 @@ run(struct ofproto *ofproto_)
|
|||||||
* For hysteresis, the number of subfacets to drop the governor is
|
* For hysteresis, the number of subfacets to drop the governor is
|
||||||
* smaller than the number needed to trigger its creation. */
|
* smaller than the number needed to trigger its creation. */
|
||||||
n_subfacets = hmap_count(&ofproto->subfacets);
|
n_subfacets = hmap_count(&ofproto->subfacets);
|
||||||
if (n_subfacets * 4 < ofproto->up.flow_eviction_threshold
|
if (n_subfacets * 4 < flow_eviction_threshold
|
||||||
&& governor_is_idle(ofproto->governor)) {
|
&& governor_is_idle(ofproto->governor)) {
|
||||||
governor_destroy(ofproto->governor);
|
governor_destroy(ofproto->governor);
|
||||||
ofproto->governor = NULL;
|
ofproto->governor = NULL;
|
||||||
@ -3675,7 +3675,7 @@ flow_miss_should_make_facet(struct ofproto_dpif *ofproto,
|
|||||||
size_t n_subfacets;
|
size_t n_subfacets;
|
||||||
|
|
||||||
n_subfacets = hmap_count(&ofproto->subfacets);
|
n_subfacets = hmap_count(&ofproto->subfacets);
|
||||||
if (n_subfacets * 2 <= ofproto->up.flow_eviction_threshold) {
|
if (n_subfacets * 2 <= flow_eviction_threshold) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4501,7 +4501,7 @@ subfacet_max_idle(const struct ofproto_dpif *ofproto)
|
|||||||
* that is installed in the kernel gets dropped in the appropriate bucket.
|
* that is installed in the kernel gets dropped in the appropriate bucket.
|
||||||
* After the histogram has been built, we compute the cutoff so that only
|
* After the histogram has been built, we compute the cutoff so that only
|
||||||
* the most-recently-used 1% of subfacets (but at least
|
* the most-recently-used 1% of subfacets (but at least
|
||||||
* ofproto->up.flow_eviction_threshold flows) are kept cached. At least
|
* flow_eviction_threshold flows) are kept cached. At least
|
||||||
* the most-recently-used bucket of subfacets is kept, so actually an
|
* the most-recently-used bucket of subfacets is kept, so actually an
|
||||||
* arbitrary number of subfacets can be kept in any given expiration run
|
* arbitrary number of subfacets can be kept in any given expiration run
|
||||||
* (though the next run will delete most of those unless they receive
|
* (though the next run will delete most of those unless they receive
|
||||||
@ -4520,7 +4520,7 @@ subfacet_max_idle(const struct ofproto_dpif *ofproto)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
total = hmap_count(&ofproto->subfacets);
|
total = hmap_count(&ofproto->subfacets);
|
||||||
if (total <= ofproto->up.flow_eviction_threshold) {
|
if (total <= flow_eviction_threshold) {
|
||||||
return N_BUCKETS * BUCKET_WIDTH;
|
return N_BUCKETS * BUCKET_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4539,7 +4539,7 @@ subfacet_max_idle(const struct ofproto_dpif *ofproto)
|
|||||||
do {
|
do {
|
||||||
subtotal += buckets[bucket++];
|
subtotal += buckets[bucket++];
|
||||||
} while (bucket < N_BUCKETS &&
|
} while (bucket < N_BUCKETS &&
|
||||||
subtotal < MAX(ofproto->up.flow_eviction_threshold, total / 100));
|
subtotal < MAX(flow_eviction_threshold, total / 100));
|
||||||
|
|
||||||
if (VLOG_IS_DBG_ENABLED()) {
|
if (VLOG_IS_DBG_ENABLED()) {
|
||||||
struct ds s;
|
struct ds s;
|
||||||
|
@ -48,9 +48,6 @@ struct ofproto {
|
|||||||
/* Settings. */
|
/* Settings. */
|
||||||
uint64_t fallback_dpid; /* Datapath ID if no better choice found. */
|
uint64_t fallback_dpid; /* Datapath ID if no better choice found. */
|
||||||
uint64_t datapath_id; /* Datapath ID. */
|
uint64_t datapath_id; /* Datapath ID. */
|
||||||
unsigned flow_eviction_threshold; /* Threshold at which to begin flow
|
|
||||||
* table eviction. Only affects the
|
|
||||||
* ofproto-dpif implementation */
|
|
||||||
bool forward_bpdu; /* Option to allow forwarding of BPDU frames
|
bool forward_bpdu; /* Option to allow forwarding of BPDU frames
|
||||||
* when NORMAL action is invoked. */
|
* when NORMAL action is invoked. */
|
||||||
char *mfr_desc; /* Manufacturer (NULL for default)b. */
|
char *mfr_desc; /* Manufacturer (NULL for default)b. */
|
||||||
@ -233,6 +230,10 @@ struct rule {
|
|||||||
* is expirable, otherwise empty. */
|
* is expirable, otherwise empty. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Threshold at which to begin flow table eviction. Only affects the
|
||||||
|
* ofproto-dpif implementation */
|
||||||
|
extern unsigned flow_eviction_threshold;
|
||||||
|
|
||||||
static inline struct rule *
|
static inline struct rule *
|
||||||
rule_from_cls_rule(const struct cls_rule *cls_rule)
|
rule_from_cls_rule(const struct cls_rule *cls_rule)
|
||||||
{
|
{
|
||||||
|
@ -220,6 +220,8 @@ static const struct ofproto_class **ofproto_classes;
|
|||||||
static size_t n_ofproto_classes;
|
static size_t n_ofproto_classes;
|
||||||
static size_t allocated_ofproto_classes;
|
static size_t allocated_ofproto_classes;
|
||||||
|
|
||||||
|
unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
|
||||||
|
|
||||||
/* Map from datapath name to struct ofproto, for use by unixctl commands. */
|
/* Map from datapath name to struct ofproto, for use by unixctl commands. */
|
||||||
static struct hmap all_ofprotos = HMAP_INITIALIZER(&all_ofprotos);
|
static struct hmap all_ofprotos = HMAP_INITIALIZER(&all_ofprotos);
|
||||||
|
|
||||||
@ -408,8 +410,6 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
|
|||||||
hmap_insert(&all_ofprotos, &ofproto->hmap_node,
|
hmap_insert(&all_ofprotos, &ofproto->hmap_node,
|
||||||
hash_string(ofproto->name, 0));
|
hash_string(ofproto->name, 0));
|
||||||
ofproto->datapath_id = 0;
|
ofproto->datapath_id = 0;
|
||||||
ofproto_set_flow_eviction_threshold(ofproto,
|
|
||||||
OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT);
|
|
||||||
ofproto->forward_bpdu = false;
|
ofproto->forward_bpdu = false;
|
||||||
ofproto->fallback_dpid = pick_fallback_dpid();
|
ofproto->fallback_dpid = pick_fallback_dpid();
|
||||||
ofproto->mfr_desc = NULL;
|
ofproto->mfr_desc = NULL;
|
||||||
@ -566,13 +566,10 @@ ofproto_set_in_band_queue(struct ofproto *ofproto, int queue_id)
|
|||||||
/* Sets the number of flows at which eviction from the kernel flow table
|
/* Sets the number of flows at which eviction from the kernel flow table
|
||||||
* will occur. */
|
* will occur. */
|
||||||
void
|
void
|
||||||
ofproto_set_flow_eviction_threshold(struct ofproto *ofproto, unsigned threshold)
|
ofproto_set_flow_eviction_threshold(unsigned threshold)
|
||||||
{
|
{
|
||||||
if (threshold < OFPROTO_FLOW_EVICTION_THRESHOLD_MIN) {
|
flow_eviction_threshold = MAX(OFPROTO_FLOW_EVICTION_THRESHOLD_MIN,
|
||||||
ofproto->flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_MIN;
|
threshold);
|
||||||
} else {
|
|
||||||
ofproto->flow_eviction_threshold = threshold;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If forward_bpdu is true, the NORMAL action will forward frames with
|
/* If forward_bpdu is true, the NORMAL action will forward frames with
|
||||||
|
@ -236,7 +236,7 @@ void ofproto_reconnect_controllers(struct ofproto *);
|
|||||||
void ofproto_set_extra_in_band_remotes(struct ofproto *,
|
void ofproto_set_extra_in_band_remotes(struct ofproto *,
|
||||||
const struct sockaddr_in *, size_t n);
|
const struct sockaddr_in *, size_t n);
|
||||||
void ofproto_set_in_band_queue(struct ofproto *, int queue_id);
|
void ofproto_set_in_band_queue(struct ofproto *, int queue_id);
|
||||||
void ofproto_set_flow_eviction_threshold(struct ofproto *, unsigned threshold);
|
void ofproto_set_flow_eviction_threshold(unsigned threshold);
|
||||||
void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu);
|
void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu);
|
||||||
void ofproto_set_mac_table_config(struct ofproto *, unsigned idle_time,
|
void ofproto_set_mac_table_config(struct ofproto *, unsigned idle_time,
|
||||||
size_t max_entries);
|
size_t max_entries);
|
||||||
|
@ -197,7 +197,6 @@ static void bridge_add_del_ports(struct bridge *,
|
|||||||
const unsigned long int *splinter_vlans);
|
const unsigned long int *splinter_vlans);
|
||||||
static void bridge_refresh_ofp_port(struct bridge *);
|
static void bridge_refresh_ofp_port(struct bridge *);
|
||||||
static void bridge_configure_datapath_id(struct bridge *);
|
static void bridge_configure_datapath_id(struct bridge *);
|
||||||
static void bridge_configure_flow_eviction_threshold(struct bridge *);
|
|
||||||
static void bridge_configure_netflow(struct bridge *);
|
static void bridge_configure_netflow(struct bridge *);
|
||||||
static void bridge_configure_forward_bpdu(struct bridge *);
|
static void bridge_configure_forward_bpdu(struct bridge *);
|
||||||
static void bridge_configure_mac_table(struct bridge *);
|
static void bridge_configure_mac_table(struct bridge *);
|
||||||
@ -495,6 +494,10 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
|
|||||||
ovs_assert(!reconfiguring);
|
ovs_assert(!reconfiguring);
|
||||||
reconfiguring = true;
|
reconfiguring = true;
|
||||||
|
|
||||||
|
ofproto_set_flow_eviction_threshold(
|
||||||
|
smap_get_int(&ovs_cfg->other_config, "flow-eviction-threshold",
|
||||||
|
OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT));
|
||||||
|
|
||||||
/* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according
|
/* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according
|
||||||
* to 'ovs_cfg' while update the "if_cfg_queue", with only very minimal
|
* to 'ovs_cfg' while update the "if_cfg_queue", with only very minimal
|
||||||
* configuration otherwise.
|
* configuration otherwise.
|
||||||
@ -613,7 +616,6 @@ bridge_reconfigure_continue(const struct ovsrec_open_vswitch *ovs_cfg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bridge_configure_mirrors(br);
|
bridge_configure_mirrors(br);
|
||||||
bridge_configure_flow_eviction_threshold(br);
|
|
||||||
bridge_configure_forward_bpdu(br);
|
bridge_configure_forward_bpdu(br);
|
||||||
bridge_configure_mac_table(br);
|
bridge_configure_mac_table(br);
|
||||||
bridge_configure_remotes(br, managers, n_managers);
|
bridge_configure_remotes(br, managers, n_managers);
|
||||||
@ -623,6 +625,13 @@ bridge_reconfigure_continue(const struct ovsrec_open_vswitch *ovs_cfg)
|
|||||||
bridge_configure_stp(br);
|
bridge_configure_stp(br);
|
||||||
bridge_configure_tables(br);
|
bridge_configure_tables(br);
|
||||||
bridge_configure_dp_desc(br);
|
bridge_configure_dp_desc(br);
|
||||||
|
|
||||||
|
if (smap_get(&br->cfg->other_config, "flow-eviction-threshold")) {
|
||||||
|
/* XXX: Remove this warning message eventually. */
|
||||||
|
VLOG_WARN_ONCE("As of June 2013, flow-eviction-threshold has been"
|
||||||
|
" moved to the Open_vSwitch table. Ignoring its"
|
||||||
|
" setting in the bridge table.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(managers);
|
free(managers);
|
||||||
|
|
||||||
@ -1559,23 +1568,6 @@ done:
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Flow eviction threshold */
|
|
||||||
static void
|
|
||||||
bridge_configure_flow_eviction_threshold(struct bridge *br)
|
|
||||||
{
|
|
||||||
const char *threshold_str;
|
|
||||||
unsigned threshold;
|
|
||||||
|
|
||||||
threshold_str = smap_get(&br->cfg->other_config,
|
|
||||||
"flow-eviction-threshold");
|
|
||||||
if (threshold_str) {
|
|
||||||
threshold = strtoul(threshold_str, NULL, 10);
|
|
||||||
} else {
|
|
||||||
threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
|
|
||||||
}
|
|
||||||
ofproto_set_flow_eviction_threshold(br->ofproto, threshold);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set forward BPDU option. */
|
/* Set forward BPDU option. */
|
||||||
static void
|
static void
|
||||||
bridge_configure_forward_bpdu(struct bridge *br)
|
bridge_configure_forward_bpdu(struct bridge *br)
|
||||||
|
@ -122,6 +122,20 @@
|
|||||||
functions use the above config option during hot upgrades.
|
functions use the above config option during hot upgrades.
|
||||||
</p>
|
</p>
|
||||||
</column>
|
</column>
|
||||||
|
|
||||||
|
<column name="other_config" key="flow-eviction-threshold"
|
||||||
|
type='{"type": "integer", "minInteger": 0}'>
|
||||||
|
<p>
|
||||||
|
A number of flows as a nonnegative integer. This sets number of
|
||||||
|
flows at which eviction from the datapath flow table will be
|
||||||
|
triggered. If there are a large number of flows then increasing this
|
||||||
|
value to around the number of flows present can result in reduced CPU
|
||||||
|
usage and packet loss.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The default is 1000. Values below 100 will be rounded up to 100.
|
||||||
|
</p>
|
||||||
|
</column>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<group title="Status">
|
<group title="Status">
|
||||||
@ -598,20 +612,6 @@
|
|||||||
datapath ID.
|
datapath ID.
|
||||||
</column>
|
</column>
|
||||||
|
|
||||||
<column name="other_config" key="flow-eviction-threshold"
|
|
||||||
type='{"type": "integer", "minInteger": 0}'>
|
|
||||||
<p>
|
|
||||||
A number of flows as a nonnegative integer. This sets number of
|
|
||||||
flows at which eviction from the kernel flow table will be triggered.
|
|
||||||
If there are a large number of flows then increasing this value to
|
|
||||||
around the number of flows present can result in reduced CPU usage
|
|
||||||
and packet loss.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The default is 1000. Values below 100 will be rounded up to 100.
|
|
||||||
</p>
|
|
||||||
</column>
|
|
||||||
|
|
||||||
<column name="other_config" key="forward-bpdu"
|
<column name="other_config" key="forward-bpdu"
|
||||||
type='{"type": "boolean"}'>
|
type='{"type": "boolean"}'>
|
||||||
Option to allow forwarding of BPDU frames when NORMAL action is
|
Option to allow forwarding of BPDU frames when NORMAL action is
|
||||||
|
Loading…
x
Reference in New Issue
Block a user