For this reason allow manually setting the number of
handlers via n-handler-threads
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2106570
Signed-off-by: Michael Santana <[email protected]>
---
lib/dpif-netlink.c | 20 +++++++++++---------
lib/dpif-provider.h | 2 +-
lib/dpif.c | 4 ++--
lib/dpif.h | 2 +-
ofproto/ofproto-dpif-upcall.c | 3 +++
ofproto/ofproto-dpif.c | 5 +++--
6 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index a620a6ec5..641c9ff99 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -264,7 +264,8 @@ static void dpif_netlink_handler_uninit(struct dpif_handler
*handler);
static int dpif_netlink_refresh_handlers_vport_dispatch(struct dpif_netlink *,
uint32_t n_handlers);
static void destroy_all_channels(struct dpif_netlink *);
-static int dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *);
+static int dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *,
+ uint32_t n_handlers);
static void destroy_all_handlers(struct dpif_netlink *);
static void dpif_netlink_vport_to_ofpbuf(const struct dpif_netlink_vport *,
@@ -2586,15 +2587,14 @@ dpif_netlink_calculate_n_handlers(void)
}
static int
-dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *dpif)
+dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *dpif,
+ uint32_t n_handlers)
OVS_REQ_WRLOCK(dpif->upcall_lock)
{
int handler_id;
int error = 0;
- uint32_t n_handlers;
uint32_t *upcall_pids;
- n_handlers = dpif_netlink_calculate_n_handlers();
if (dpif->n_handlers != n_handlers) {
VLOG_DBG("Dispatch mode(per-cpu): initializing %d handlers",
n_handlers);
@@ -2770,7 +2770,8 @@ dpif_netlink_recv_set_vport_dispatch(struct dpif_netlink
*dpif, bool enable)
}
static int
-dpif_netlink_recv_set_cpu_dispatch(struct dpif_netlink *dpif, bool enable)
+dpif_netlink_recv_set_cpu_dispatch(struct dpif_netlink *dpif, bool enable,
+ uint32_t handler)
OVS_REQ_WRLOCK(dpif->upcall_lock)
{
if ((dpif->handlers != NULL) == enable) {
@@ -2779,19 +2780,19 @@ dpif_netlink_recv_set_cpu_dispatch(struct dpif_netlink
*dpif, bool enable)
destroy_all_handlers(dpif);
return 0;
} else {
- return dpif_netlink_refresh_handlers_cpu_dispatch(dpif);
+ return dpif_netlink_refresh_handlers_cpu_dispatch(dpif, handler);
}
}
static int
-dpif_netlink_recv_set(struct dpif *dpif_, bool enable)
+dpif_netlink_recv_set(struct dpif *dpif_, bool enable, uint32_t handlers)
{
struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
int error;
fat_rwlock_wrlock(&dpif->upcall_lock);
if (dpif_netlink_upcall_per_cpu(dpif)) {
- error = dpif_netlink_recv_set_cpu_dispatch(dpif, enable);
+ error = dpif_netlink_recv_set_cpu_dispatch(dpif, enable, handlers);
} else {
error = dpif_netlink_recv_set_vport_dispatch(dpif, enable);
}
@@ -2817,7 +2818,8 @@ dpif_netlink_handlers_set(struct dpif *dpif_, uint32_t
n_handlers)
fat_rwlock_wrlock(&dpif->upcall_lock);
if (dpif->handlers) {
if (dpif_netlink_upcall_per_cpu(dpif)) {
- error = dpif_netlink_refresh_handlers_cpu_dispatch(dpif);
+ error = dpif_netlink_refresh_handlers_cpu_dispatch(dpif,
+ n_handlers);
} else {
error = dpif_netlink_refresh_handlers_vport_dispatch(dpif,
n_handlers);
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 12477a24f..91be767a8 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -342,7 +342,7 @@ struct dpif_class {
* Turning packet receive off and then back on is allowed to change
Netlink
* PID assignments (see ->port_get_pid()). The client is responsible for
* updating flows as necessary if it does this. */
- int (*recv_set)(struct dpif *dpif, bool enable);
+ int (*recv_set)(struct dpif *dpif, bool enable, uint32_t n_handlers);
/* Attempts to refresh the poll loops and Netlink sockets used for handling
* upcalls when the number of upcall handlers (upcall receiving thread) is
diff --git a/lib/dpif.c b/lib/dpif.c
index 40f5fe446..6fc553ad4 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1459,12 +1459,12 @@ dpif_upcall_type_to_string(enum dpif_upcall_type type)
* must update all of the flows that have OVS_ACTION_ATTR_USERSPACE actions
* using the new PID assignment. */
int
-dpif_recv_set(struct dpif *dpif, bool enable)
+dpif_recv_set(struct dpif *dpif, bool enable, uint32_t n_handlers)
{
int error = 0;
if (dpif->dpif_class->recv_set) {
- error = dpif->dpif_class->recv_set(dpif, enable);
+ error = dpif->dpif_class->recv_set(dpif, enable, n_handlers);
log_operation(dpif, "recv_set", error);
}
return error;
diff --git a/lib/dpif.h b/lib/dpif.h
index 6cb4dae6d..96dc88237 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -882,7 +882,7 @@ typedef int upcall_callback(const struct dp_packet *packet,
void dpif_register_upcall_cb(struct dpif *, upcall_callback *, void *aux);
-int dpif_recv_set(struct dpif *, bool enable);
+int dpif_recv_set(struct dpif *, bool enable, uint32_t n_handlers);
int dpif_handlers_set(struct dpif *, uint32_t n_handlers);
bool dpif_number_handlers_required(struct dpif *, uint32_t *n_handlers);
int dpif_set_config(struct dpif *, const struct smap *cfg);
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 7ad728adf..734eaac5c 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -655,6 +655,9 @@ udpif_set_threads(struct udpif *udpif, uint32_t n_handlers_,
} else {
n_revalidators_requested = n_revalidators_;
}
+ if (n_handlers_) {
+ n_handlers_requested = n_handlers_;
+ }
} else {
int threads = MAX(count_cpu_cores(), 2);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index f9562dee8..cdbd25000 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -377,7 +377,8 @@ type_run(const char *type)
backer->recv_set_enable = true;
- error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
+ error = dpif_recv_set(backer->dpif, backer->recv_set_enable,
+ n_handlers);
if (error) {
VLOG_ERR("Failed to enable receiving packets in dpif.");
return error;
@@ -816,7 +817,7 @@ open_dpif_backer(const char *type, struct dpif_backer
**backerp)
check_support(backer);
atomic_count_init(&backer->tnl_count, 0);
- error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
+ error = dpif_recv_set(backer->dpif, backer->recv_set_enable, n_handlers);
if (error) {
VLOG_ERR("failed to listen on datapath of type %s: %s",
type, ovs_strerror(error));