COVERAGE_DEFINE(packet_in_overflow);
COVERAGE_DEFINE(flow_mod_overflow);
-#define N_THREADS 16
-
/* Number of implemented OpenFlow tables. */
enum { N_TABLES = 255 };
enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */
/* Number of subfacets added or deleted from 'created' to 'last_minute.' */
unsigned long long int total_subfacet_add_count;
unsigned long long int total_subfacet_del_count;
+
+ /* Number of upcall handling threads. */
+ unsigned int n_handler_threads;
};
/* All existing ofproto_backer instances, indexed by ofproto->up.type. */
VLOG_ERR("Failed to enable receiving packets in dpif.");
return error;
}
- udpif_recv_set(backer->udpif, N_THREADS, backer->recv_set_enable);
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
dpif_flow_flush(backer->dpif);
backer->need_revalidate = REV_RECONFIGURE;
}
+ /* If the n_handler_threads is reconfigured, call udpif_recv_set()
+ * to reset the handler threads. */
+ if (backer->n_handler_threads != n_handler_threads) {
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
+ backer->n_handler_threads = n_handler_threads;
+ }
+
if (backer->need_revalidate) {
struct ofproto_dpif *ofproto;
struct simap_node *node;
close_dpif_backer(backer);
return error;
}
- udpif_recv_set(backer->udpif, N_THREADS, backer->recv_set_enable);
+ udpif_recv_set(backer->udpif, n_handler_threads,
+ backer->recv_set_enable);
+ backer->n_handler_threads = n_handler_threads;
backer->max_n_subfacet = 0;
backer->created = time_msec();
* ofproto-dpif implementation */
extern unsigned flow_eviction_threshold;
+/* Number of upcall handler threads. Only affects the ofproto-dpif
+ * implementation. */
+extern unsigned n_handler_threads;
+
/* Determines which model to use for handling misses in the ofproto-dpif
* implementation */
extern enum ofproto_flow_miss_model flow_miss_model;
#include <inttypes.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <unistd.h>
#include "bitmap.h"
#include "byte-order.h"
#include "classifier.h"
static size_t allocated_ofproto_classes;
unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
+unsigned n_handler_threads;
enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO;
/* Map from datapath name to struct ofproto, for use by unixctl commands. */
}
}
+/* Sets number of upcall handler threads. The default is
+ * (number of online cores - 1). */
+void
+ofproto_set_n_handler_threads(unsigned limit)
+{
+ if (limit) {
+ n_handler_threads = limit;
+ } else {
+ n_handler_threads = MAX(1, sysconf(_SC_NPROCESSORS_ONLN) - 1);
+ }
+}
+
void
ofproto_set_dp_desc(struct ofproto *p, const char *dp_desc)
{
void ofproto_set_forward_bpdu(struct ofproto *, bool forward_bpdu);
void ofproto_set_mac_table_config(struct ofproto *, unsigned idle_time,
size_t max_entries);
+void ofproto_set_n_handler_threads(unsigned limit);
void ofproto_set_dp_desc(struct ofproto *, const char *dp_desc);
int ofproto_set_snoops(struct ofproto *, const struct sset *snoops);
int ofproto_set_netflow(struct ofproto *,
smap_get_int(&ovs_cfg->other_config, "flow-eviction-threshold",
OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT));
+ ofproto_set_n_handler_threads(
+ smap_get_int(&ovs_cfg->other_config, "n-handler-threads", 0));
+
bridge_configure_flow_miss_model(smap_get(&ovs_cfg->other_config,
"force-miss-model"));
</dl>
</p>
</column>
+
+ <column name="other_config" key="n-handler-threads"
+ type='{"type": "integer", "minInteger": 1}'>
+ <p>
+ Specifies the number of threads for software datapaths to use for
+ handling new flows. The default is one less than the number of
+ online CPU cores (but at least 1).
+ </p>
+ <p>
+ This configuration is per datapath. If you have more than one
+ software datapath (e.g. some <code>system</code> bridges and some
+ <code>netdev</code> bridges), then the total number of threads is
+ <code>n-handler-threads</code> times the number of software
+ datapaths.
+ </p>
+ </column>
</group>
<group title="Status">