aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2020-03-08 21:07:48 -0700
committerDavid S. Miller <davem@davemloft.net>2020-03-08 21:07:48 -0700
commit9d2e4e16484a7639c60ec867f1cba0209cc279dd (patch)
tree91666da01c7c8ae1758342a2261165c5fab6fcf6 /include
parentMerge branch 'ethtool-consolidate-irq-coalescing-other-drivers' (diff)
parentsched: act: allow user to specify type of HW stats for a filter (diff)
Merge branch 'net-allow-user-specify-TC-action-HW-stats-type'
Jiri Pirko says: ==================== net: allow user specify TC action HW stats type Currently, when user adds a TC action and the action gets offloaded, the user expects the HW stats to be counted and included in stats dump. However, since drivers may implement different types of counting, there is no way to specify which one the user is interested in. For example for mlx5, only delayed counters are available as the driver periodically polls for updated stats. In case of mlxsw, the counters are queried on dump time. However, the HW resources for this type of counters is quite limited (couple of thousands). This limits the amount of supported offloaded filters significantly. Without counter assigned, the HW is capable to carry millions of those. On top of that, mlxsw HW is able to support delayed counters as well in greater numbers. That is going to be added in a follow-up patch. This patchset allows user to specify one of the following types of HW stats for added action: immediate - queried during dump time delayed - polled from HW periodically or sent by HW in async manner disabled - no stats needed Note that if "hw_stats" option is not passed, user does not care about the type, just expects any type of stats. Examples: $ tc filter add dev enp0s16np28 ingress proto ip handle 1 pref 1 flower skip_sw dst_ip 192.168.1.1 action drop hw_stats disabled $ tc -s filter show dev enp0s16np28 ingress filter protocol ip pref 1 flower chain 0 filter protocol ip pref 1 flower chain 0 handle 0x1 eth_type ipv4 dst_ip 192.168.1.1 skip_sw in_hw in_hw_count 2 action order 1: gact action drop random type none pass val 0 index 1 ref 1 bind 1 installed 7 sec used 2 sec Action statistics: Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 hw_stats disabled $ tc filter add dev enp0s16np28 ingress proto ip handle 1 pref 1 flower skip_sw dst_ip 192.168.1.1 action drop hw_stats immediate $ tc -s filter show dev enp0s16np28 ingress filter protocol ip pref 1 flower chain 0 filter protocol ip pref 1 flower chain 0 handle 0x1 eth_type ipv4 dst_ip 192.168.1.1 skip_sw in_hw in_hw_count 2 action order 1: gact action drop random type none pass val 0 index 1 ref 1 bind 1 installed 11 sec used 4 sec Action statistics: Sent 102 bytes 1 pkt (dropped 1, overlimits 0 requeues 0) Sent software 0 bytes 0 pkt Sent hardware 102 bytes 1 pkt backlog 0b 0p requeues 0 hw_stats immediate ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/act_api.h4
-rw-r--r--include/net/flow_offload.h68
-rw-r--r--include/uapi/linux/pkt_cls.h22
3 files changed, 94 insertions, 0 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 71347a90a9d1..41337c7fc728 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -41,6 +41,7 @@ struct tc_action {
struct tc_cookie __rcu *act_cookie;
struct tcf_chain __rcu *goto_chain;
u32 tcfa_flags;
+ u8 hw_stats_type;
};
#define tcf_index common.tcfa_index
#define tcf_refcnt common.tcfa_refcnt
@@ -52,6 +53,9 @@ struct tc_action {
#define tcf_rate_est common.tcfa_rate_est
#define tcf_lock common.tcfa_lock
+#define TCA_ACT_HW_STATS_TYPE_ANY (TCA_ACT_HW_STATS_TYPE_IMMEDIATE | \
+ TCA_ACT_HW_STATS_TYPE_DELAYED)
+
/* Update lastuse only if needed, to avoid dirtying a cache line.
* We use a temp variable to avoid fetching jiffies twice.
*/
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index cd3510ac66b0..64807aa03cee 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/list.h>
+#include <linux/netlink.h>
#include <net/flow_dissector.h>
#include <linux/rhashtable.h>
@@ -154,6 +155,12 @@ enum flow_action_mangle_base {
FLOW_ACT_MANGLE_HDR_TYPE_UDP,
};
+#define FLOW_ACTION_HW_STATS_TYPE_IMMEDIATE BIT(0)
+#define FLOW_ACTION_HW_STATS_TYPE_DELAYED BIT(1)
+#define FLOW_ACTION_HW_STATS_TYPE_ANY (FLOW_ACTION_HW_STATS_TYPE_IMMEDIATE | \
+ FLOW_ACTION_HW_STATS_TYPE_DELAYED)
+#define FLOW_ACTION_HW_STATS_TYPE_DISABLED 0
+
typedef void (*action_destr)(void *priv);
struct flow_action_cookie {
@@ -168,6 +175,7 @@ void flow_action_cookie_destroy(struct flow_action_cookie *cookie);
struct flow_action_entry {
enum flow_action_id id;
+ u8 hw_stats_type;
action_destr destructor;
void *destructor_priv;
union {
@@ -248,6 +256,66 @@ static inline bool flow_offload_has_one_action(const struct flow_action *action)
return action->num_entries == 1;
}
+static inline bool
+flow_action_mixed_hw_stats_types_check(const struct flow_action *action,
+ struct netlink_ext_ack *extack)
+{
+ const struct flow_action_entry *action_entry;
+ u8 uninitialized_var(last_hw_stats_type);
+ int i;
+
+ if (flow_offload_has_one_action(action))
+ return true;
+
+ for (i = 0; i < action->num_entries; i++) {
+ action_entry = &action->entries[i];
+ if (i && action_entry->hw_stats_type != last_hw_stats_type) {
+ NL_SET_ERR_MSG_MOD(extack, "Mixing HW stats types for actions is not supported");
+ return false;
+ }
+ last_hw_stats_type = action_entry->hw_stats_type;
+ }
+ return true;
+}
+
+static inline const struct flow_action_entry *
+flow_action_first_entry_get(const struct flow_action *action)
+{
+ WARN_ON(!flow_action_has_entries(action));
+ return &action->entries[0];
+}
+
+static inline bool
+flow_action_hw_stats_types_check(const struct flow_action *action,
+ struct netlink_ext_ack *extack,
+ u8 allowed_hw_stats_type)
+{
+ const struct flow_action_entry *action_entry;
+
+ if (!flow_action_has_entries(action))
+ return true;
+ if (!flow_action_mixed_hw_stats_types_check(action, extack))
+ return false;
+ action_entry = flow_action_first_entry_get(action);
+ if (allowed_hw_stats_type == 0 &&
+ action_entry->hw_stats_type != FLOW_ACTION_HW_STATS_TYPE_ANY) {
+ NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type \"any\"");
+ return false;
+ } else if (allowed_hw_stats_type != 0 &&
+ action_entry->hw_stats_type != allowed_hw_stats_type) {
+ NL_SET_ERR_MSG_MOD(extack, "Driver does not support selected HW stats type");
+ return false;
+ }
+ return true;
+}
+
+static inline bool
+flow_action_basic_hw_stats_types_check(const struct flow_action *action,
+ struct netlink_ext_ack *extack)
+{
+ return flow_action_hw_stats_types_check(action, extack, 0);
+}
+
#define flow_action_for_each(__i, __act, __actions) \
for (__i = 0, __act = &(__actions)->entries[0]; __i < (__actions)->num_entries; __act = &(__actions)->entries[++__i])
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 449a63971451..81cc1a869588 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -17,6 +17,7 @@ enum {
TCA_ACT_PAD,
TCA_ACT_COOKIE,
TCA_ACT_FLAGS,
+ TCA_ACT_HW_STATS_TYPE,
__TCA_ACT_MAX
};
@@ -24,6 +25,27 @@ enum {
* actions stats.
*/
+/* tca HW stats type
+ * When user does not pass the attribute, he does not care.
+ * It is the same as if he would pass the attribute with
+ * all supported bits set.
+ * In case no bits are set, user is not interested in getting any HW statistics.
+ */
+#define TCA_ACT_HW_STATS_TYPE_IMMEDIATE (1 << 0) /* Means that in dump, user
+ * gets the current HW stats
+ * state from the device
+ * queried at the dump time.
+ */
+#define TCA_ACT_HW_STATS_TYPE_DELAYED (1 << 1) /* Means that in dump, user gets
+ * HW stats that might be out
+ * of date for some time, maybe
+ * couple of seconds. This is
+ * the case when driver polls
+ * stats updates periodically
+ * or when it gets async stats update
+ * from the device.
+ */
+
#define TCA_ACT_MAX __TCA_ACT_MAX
#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
#define TCA_ACT_MAX_PRIO 32