This patch moved the flow count APIs to the netdev-offload provider.
Signed-off-by: Eelco Chaudron <[email protected]>
---
lib/dpif-netdev.c | 29 +++++-----------------------
lib/dpif-offload-dpdk.c | 27 ++++++++++++++++++++++++++
lib/dpif-offload-provider.h | 3 +++
lib/dpif-offload-tc.c | 1 +
lib/dpif-offload.c | 20 +++++++++++++++++++
lib/dpif-offload.h | 1 +
lib/dpif.c | 23 ----------------------
lib/dpif.h | 2 --
lib/netdev-offload-dpdk.c | 13 ++++++-------
lib/netdev-offload-dpdk.h | 1 +
lib/netdev-offload-provider.h | 5 -----
lib/netdev-offload-tc.c | 18 ++++++------------
lib/netdev-offload-tc.h | 1 +
lib/netdev-offload.c | 36 -----------------------------------
lib/netdev-offload.h | 3 ---
ofproto/ofproto-dpif-upcall.c | 9 +++------
16 files changed, 74 insertions(+), 118 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 79b05bc0d..82df85823 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -4762,11 +4762,8 @@ dpif_netdev_offload_stats_get(struct dpif *dpif,
[DP_NETDEV_HW_OFFLOADS_STATS_LAT_EMA_STDDEV] =
{ " Exponential Latency stddev (us)", 0 },
};
- struct dp_netdev *dp = get_dp_netdev(dpif);
- struct dp_netdev_port *port;
+
unsigned int nb_thread;
- uint64_t *port_nb_offloads;
- uint64_t *nb_offloads;
unsigned int tid;
size_t i;
@@ -4783,29 +4780,11 @@ dpif_netdev_offload_stats_get(struct dpif *dpif,
stats->size = ARRAY_SIZE(hwol_stats) * (nb_thread + 1);
stats->counters = xcalloc(stats->size, sizeof *stats->counters);
- nb_offloads = xcalloc(nb_thread, sizeof *nb_offloads);
- port_nb_offloads = xcalloc(nb_thread, sizeof *port_nb_offloads);
-
- ovs_rwlock_rdlock(&dp->port_rwlock);
- HMAP_FOR_EACH (port, node, &dp->ports) {
- memset(port_nb_offloads, 0, nb_thread * sizeof *port_nb_offloads);
- /* Do not abort on read error from a port, just report 0. */
- if (!netdev_flow_get_n_flows(port->netdev, port_nb_offloads)) {
- for (i = 0; i < nb_thread; i++) {
- nb_offloads[i] += port_nb_offloads[i];
- }
- }
- }
- ovs_rwlock_unlock(&dp->port_rwlock);
-
- free(port_nb_offloads);
-
for (tid = 0; tid < nb_thread; tid++) {
uint64_t counts[ARRAY_SIZE(hwol_stats)];
size_t idx = ((tid + 1) * ARRAY_SIZE(hwol_stats));
memset(counts, 0, sizeof counts);
- counts[DP_NETDEV_HW_OFFLOADS_STATS_INSERTED] = nb_offloads[tid];
if (dp_offload_threads != NULL) {
atomic_read_relaxed(&dp_offload_threads[tid].enqueued_item,
&counts[DP_NETDEV_HW_OFFLOADS_STATS_ENQUEUED]);
@@ -4830,14 +4809,16 @@ dpif_netdev_offload_stats_get(struct dpif *dpif,
}
}
- free(nb_offloads);
-
/* Do an average of the average for the aggregate. */
hwol_stats[DP_NETDEV_HW_OFFLOADS_STATS_LAT_CMA_MEAN].total /= nb_thread;
hwol_stats[DP_NETDEV_HW_OFFLOADS_STATS_LAT_CMA_STDDEV].total /= nb_thread;
hwol_stats[DP_NETDEV_HW_OFFLOADS_STATS_LAT_EMA_MEAN].total /= nb_thread;
hwol_stats[DP_NETDEV_HW_OFFLOADS_STATS_LAT_EMA_STDDEV].total /= nb_thread;
+ /* Get the total offload count. */
+ hwol_stats[DP_NETDEV_HW_OFFLOADS_STATS_INSERTED].total =
+ dpif_offload_flow_get_n_offloaded(dpif);
+
for (i = 0; i < ARRAY_SIZE(hwol_stats); i++) {
snprintf(stats->counters[i].name, sizeof(stats->counters[i].name),
" Total %s", hwol_stats[i].name);
diff --git a/lib/dpif-offload-dpdk.c b/lib/dpif-offload-dpdk.c
index f231a1c68..76a8946c9 100644
--- a/lib/dpif-offload-dpdk.c
+++ b/lib/dpif-offload-dpdk.c
@@ -253,6 +253,32 @@ dpif_offload_dpdk_can_offload(struct dpif_offload *offload
OVS_UNUSED,
return netdev_dpdk_flow_api_supported(netdev, true);
}
+static bool
+dpif_offload_dpdk_get_n_offloaded_cb(
+ struct dpif_offload_port_mgr_port *port, void *aux)
+{
+ uint64_t *total = aux;
+
+ *total += netdev_offload_dpdk_flow_get_n_offloaded(port->netdev);
+ return false;
+}
+
+static uint64_t
+dpif_offload_dpdk_get_n_offloaded(const struct dpif_offload *offload_)
+{
+ struct dpif_offload_dpdk *offload = dpif_offload_dpdk_cast(offload_);
+ uint64_t total = 0;
+
+ if (!dpif_offload_is_offload_enabled()) {
+ return 0;
+ }
+
+ dpif_offload_port_mgr_traverse_ports(
+ offload->port_mgr, dpif_offload_dpdk_get_n_offloaded_cb, &total);
+
+ return total;
+}
+
static int
dpif_offload_dpdk_netdev_flow_flush(const struct dpif_offload *offload
OVS_UNUSED, struct netdev *netdev)
@@ -272,6 +298,7 @@ struct dpif_offload_class dpif_offload_dpdk_class = {
.can_offload = dpif_offload_dpdk_can_offload,
.port_add = dpif_offload_dpdk_port_add,
.port_del = dpif_offload_dpdk_port_del,
+ .flow_get_n_offloaded = dpif_offload_dpdk_get_n_offloaded,
.netdev_flow_flush = dpif_offload_dpdk_netdev_flow_flush,
};
diff --git a/lib/dpif-offload-provider.h b/lib/dpif-offload-provider.h
index b60b7f17e..60d6c5321 100644
--- a/lib/dpif-offload-provider.h
+++ b/lib/dpif-offload-provider.h
@@ -131,6 +131,9 @@ struct dpif_offload_class {
* successful, otherwise returns a positive errno value. */
int (*flow_flush)(const struct dpif_offload *);
+ /* Returns the number of flows offloaded by the offload provider. */
+ uint64_t (*flow_get_n_offloaded)(const struct dpif_offload *);
+
/* Adds or modifies the meter in 'dpif_offload' with the given 'meter_id'
* and the configuration in 'config'.
*
diff --git a/lib/dpif-offload-tc.c b/lib/dpif-offload-tc.c
index f258c7147..4ac6f359a 100644
--- a/lib/dpif-offload-tc.c
+++ b/lib/dpif-offload-tc.c
@@ -292,6 +292,7 @@ struct dpif_offload_class dpif_offload_tc_class = {
.port_add = dpif_offload_tc_port_add,
.port_del = dpif_offload_tc_port_del,
.flow_flush = dpif_offload_tc_flow_flush,
+ .flow_get_n_offloaded = dpif_offload_tc_flow_get_n_offloaded,
.meter_set = dpif_offload_tc_meter_set,
.meter_get = dpif_offload_tc_meter_get,
.meter_del = dpif_offload_tc_meter_del,
diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c
index a3089aa38..99cfe2aac 100644
--- a/lib/dpif-offload.c
+++ b/lib/dpif-offload.c
@@ -737,6 +737,26 @@ dpif_offload_flow_flush(struct dpif *dpif)
}
}
+uint64_t
+dpif_offload_flow_get_n_offloaded(const struct dpif *dpif)
+{
+ struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif);
+ const struct dpif_offload *offload;
+ uint64_t flow_count = 0;
+
+ if (!dp_offload || !dpif_offload_is_offload_enabled()) {
+ return 0;
+ }
+
+ LIST_FOR_EACH (offload, dpif_list_node, &dp_offload->offload_providers) {
+ if (offload->class->flow_get_n_offloaded) {
+ flow_count += offload->class->flow_get_n_offloaded(offload);
+ }
+ }
+
+ return flow_count;
+}
+
void
dpif_offload_meter_set(const struct dpif *dpif, ofproto_meter_id meter_id,
struct ofputil_meter_config *config)
diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h
index 0485b7e98..fb7edf269 100644
--- a/lib/dpif-offload.h
+++ b/lib/dpif-offload.h
@@ -51,6 +51,7 @@ void dpif_offload_dump_start(struct dpif_offload_dump *,
const struct dpif *);
bool dpif_offload_dump_next(struct dpif_offload_dump *,
struct dpif_offload **);
int dpif_offload_dump_done(struct dpif_offload_dump *);
+uint64_t dpif_offload_flow_get_n_offloaded(const struct dpif *);
void dpif_offload_meter_set(const struct dpif *dpif, ofproto_meter_id meter_id,
struct ofputil_meter_config *);
void dpif_offload_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id,
diff --git a/lib/dpif.c b/lib/dpif.c
index c6a165605..6e8857144 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -2090,29 +2090,6 @@ dpif_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
: EOPNOTSUPP;
}
-int
-dpif_get_n_offloaded_flows(struct dpif *dpif, uint64_t *n_flows)
-{
- const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
- struct dpif_port_dump port_dump;
- struct dpif_port dpif_port;
- int ret, n_devs = 0;
- uint64_t nflows;
-
- *n_flows = 0;
- DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
- ret = netdev_ports_get_n_flows(dpif_type_str, dpif_port.port_no,
- &nflows);
- if (!ret) {
- *n_flows += nflows;
- } else if (ret == EOPNOTSUPP) {
- continue;
- }
- n_devs++;
- }
- return n_devs ? 0 : EOPNOTSUPP;
-}
-
int
dpif_cache_get_supported_levels(struct dpif *dpif, uint32_t *levels)
{
diff --git a/lib/dpif.h b/lib/dpif.h
index 0b685d8df..7fd3c939c 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -441,8 +441,6 @@ int dpif_get_dp_stats(const struct dpif *, struct
dpif_dp_stats *);
int dpif_set_features(struct dpif *, uint32_t new_features);
-int dpif_get_n_offloaded_flows(struct dpif *dpif, uint64_t *n_flows);
-
/* Port operations. */
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 072103596..d1781d8e4 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -2776,24 +2776,24 @@ close_vport_netdev:
return ret;
}
-static int
-netdev_offload_dpdk_get_n_flows(struct netdev *netdev,
- uint64_t *n_flows)
+uint64_t
+netdev_offload_dpdk_flow_get_n_offloaded(struct netdev *netdev)
{
struct netdev_offload_dpdk_data *data;
+ uint64_t total = 0;
unsigned int tid;
data = (struct netdev_offload_dpdk_data *)
ovsrcu_get(void *, &netdev->hw_info.offload_data);
if (!data) {
- return -1;
+ return 0;
}
for (tid = 0; tid < netdev_offload_thread_nb(); tid++) {
- n_flows[tid] = data->rte_flow_counters[tid];
+ total += data->rte_flow_counters[tid];
}
- return 0;
+ return total;
}
const struct netdev_flow_api netdev_offload_dpdk = {
@@ -2804,5 +2804,4 @@ const struct netdev_flow_api netdev_offload_dpdk = {
.uninit_flow_api = netdev_offload_dpdk_uninit_flow_api,
.flow_get = netdev_offload_dpdk_flow_get,
.hw_miss_packet_recover = netdev_offload_dpdk_hw_miss_packet_recover,
- .flow_get_n_flows = netdev_offload_dpdk_get_n_flows,
};
diff --git a/lib/netdev-offload-dpdk.h b/lib/netdev-offload-dpdk.h
index feded432f..d5061b40c 100644
--- a/lib/netdev-offload-dpdk.h
+++ b/lib/netdev-offload-dpdk.h
@@ -23,5 +23,6 @@ struct netdev;
/* Netdev-specific offload functions. These should only be used by the
* associated dpif offload provider. */
int netdev_offload_dpdk_flow_flush(struct netdev *);
+uint64_t netdev_offload_dpdk_flow_get_n_offloaded(struct netdev *);
#endif /* NETDEV_OFFLOAD_DPDK_H */
diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h
index 07068bd82..898df8333 100644
--- a/lib/netdev-offload-provider.h
+++ b/lib/netdev-offload-provider.h
@@ -80,11 +80,6 @@ struct netdev_flow_api {
int (*flow_del)(struct netdev *, const ovs_u128 *ufid,
struct dpif_flow_stats *);
- /* Get the number of flows offloaded to netdev.
- * 'n_flows' is an array of counters, one per offload thread.
- * Return 0 if successful, otherwise returns a positive errno value. */
- int (*flow_get_n_flows)(struct netdev *, uint64_t *n_flows);
-
/* Recover the packet state (contents and data) for continued processing
* in software.
* Return 0 if successful, otherwise returns a positive errno value and
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 264f86381..d92a79afa 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -2794,22 +2794,17 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED,
return del_filter_and_ufid_mapping(&id, ufid, stats);
}
-static int
-netdev_tc_get_n_flows(struct netdev *netdev, uint64_t *n_flows)
+uint64_t
+dpif_offload_tc_flow_get_n_offloaded(const struct dpif_offload *offload
+ OVS_UNUSED)
{
- struct ufid_tc_data *data;
- uint64_t total = 0;
+ uint64_t total;
ovs_mutex_lock(&ufid_lock);
- HMAP_FOR_EACH (data, tc_to_ufid_node, &tc_to_ufid) {
- if (data->netdev == netdev) {
- total++;
- }
- }
+ total = hmap_count(&tc_to_ufid);
ovs_mutex_unlock(&ufid_lock);
- *n_flows = total;
- return 0;
+ return total;
}
static void
@@ -3477,6 +3472,5 @@ const struct netdev_flow_api netdev_offload_tc = {
.flow_put = netdev_tc_flow_put,
.flow_get = netdev_tc_flow_get,
.flow_del = netdev_tc_flow_del,
- .flow_get_n_flows = netdev_tc_get_n_flows,
.init_flow_api = netdev_tc_init_flow_api,
};
diff --git a/lib/netdev-offload-tc.h b/lib/netdev-offload-tc.h
index a6b000852..5002ab00b 100644
--- a/lib/netdev-offload-tc.h
+++ b/lib/netdev-offload-tc.h
@@ -31,5 +31,6 @@ int dpif_offload_tc_meter_get(const struct dpif_offload *,
ofproto_meter_id,
struct ofputil_meter_stats *);
int dpif_offload_tc_meter_del(const struct dpif_offload *, ofproto_meter_id,
struct ofputil_meter_stats *);
+uint64_t dpif_offload_tc_flow_get_n_offloaded(const struct dpif_offload *);
#endif /* NETDEV_OFFLOAD_TC_H */
diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
index abbb930be..0c4209290 100644
--- a/lib/netdev-offload.c
+++ b/lib/netdev-offload.c
@@ -309,17 +309,6 @@ netdev_flow_del(struct netdev *netdev, const ovs_u128
*ufid,
: EOPNOTSUPP;
}
-int
-netdev_flow_get_n_flows(struct netdev *netdev, uint64_t *n_flows)
-{
- const struct netdev_flow_api *flow_api =
- ovsrcu_get(const struct netdev_flow_api *, &netdev->flow_api);
-
- return (flow_api && flow_api->flow_get_n_flows)
- ? flow_api->flow_get_n_flows(netdev, n_flows)
- : EOPNOTSUPP;
-}
-
int
netdev_init_flow_api(struct netdev *netdev)
{
@@ -717,31 +706,6 @@ netdev_ports_remove(odp_port_t port_no, const char
*dpif_type)
return ret;
}
-int
-netdev_ports_get_n_flows(const char *dpif_type, odp_port_t port_no,
- uint64_t *n_flows)
-{
- struct port_to_netdev_data *data;
- int ret = EOPNOTSUPP;
-
- ovs_rwlock_rdlock(&port_to_netdev_rwlock);
- data = netdev_ports_lookup(port_no, dpif_type);
- if (data) {
- uint64_t thread_n_flows[MAX_OFFLOAD_THREAD_NB] = {0};
- unsigned int tid;
-
- ret = netdev_flow_get_n_flows(data->netdev, thread_n_flows);
- *n_flows = 0;
- if (!ret) {
- for (tid = 0; tid < netdev_offload_thread_nb(); tid++) {
- *n_flows += thread_n_flows[tid];
- }
- }
- }
- ovs_rwlock_unlock(&port_to_netdev_rwlock);
- return ret;
-}
-
odp_port_t
netdev_ifindex_to_odp_port(int ifindex)
{
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index 8552b6e0b..2b32179ec 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -123,7 +123,6 @@ int netdev_get_hw_info(struct netdev *, int);
void netdev_set_hw_info(struct netdev *, int, int);
bool netdev_any_oor(void);
void netdev_set_flow_api_enabled(const struct smap *ovs_other_config);
-int netdev_flow_get_n_flows(struct netdev *netdev, uint64_t *n_flows);
struct dpif_port;
int netdev_ports_insert(struct netdev *, struct dpif_port *);
@@ -151,8 +150,6 @@ int netdev_ports_flow_get(const char *dpif_type, struct
match *match,
struct dpif_flow_stats *stats,
struct dpif_flow_attrs *attrs,
struct ofpbuf *buf);
-int netdev_ports_get_n_flows(const char *dpif_type,
- odp_port_t port_no, uint64_t *n_flows);
#ifdef __cplusplus
}
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 4273b3ea6..3fa96b673 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -830,11 +830,7 @@ udpif_get_n_flows(struct udpif *udpif)
if (!dpif_synced_dp_layers(udpif->dpif)) {
/* If the dpif layer does not sync the flows, we need to include
* the hardware offloaded flows separately. */
- uint64_t hw_flows;
-
- if (!dpif_get_n_offloaded_flows(udpif->dpif, &hw_flows)) {
- flow_count += hw_flows;
- }
+ flow_count += dpif_offload_flow_get_n_offloaded(udpif->dpif);
}
atomic_store_relaxed(&udpif->n_flows, flow_count);
@@ -3171,7 +3167,8 @@ upcall_unixctl_show(struct unixctl_conn *conn, int argc
OVS_UNUSED,
ds_put_format(&ds, " flows : (current %lu)"
" (avg %u) (max %u) (limit %u)\n", udpif_get_n_flows(udpif),
udpif->avg_n_flows, udpif->max_n_flows, flow_limit);
- if (!dpif_get_n_offloaded_flows(udpif->dpif, &n_offloaded_flows)) {
+ n_offloaded_flows = dpif_offload_flow_get_n_offloaded(udpif->dpif);
+ if (n_offloaded_flows) {
ds_put_format(&ds, " offloaded flows : %"PRIu64"\n",
n_offloaded_flows);
}
--
2.50.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev