tc: m_action: introduce support for hw stats type
Introduce support for per-action hw stats type config.
This patch 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: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
25091a761f
commit
341903dd3b
|
|
@ -49,6 +49,8 @@ actions \- independently defined actions in tc
|
|||
] [
|
||||
.I FLAGS
|
||||
] [
|
||||
.I HWSTATSSPEC
|
||||
] [
|
||||
.I CONTROL
|
||||
]
|
||||
|
||||
|
|
@ -77,6 +79,12 @@ ACTNAME
|
|||
:=
|
||||
.I no_percpu
|
||||
|
||||
.I HWSTATSSPEC
|
||||
:=
|
||||
.BR hw_stats " {"
|
||||
.IR immediate " | " delayed " | " disabled
|
||||
.R }
|
||||
|
||||
.I ACTDETAIL
|
||||
:=
|
||||
.I ACTNAME ACTPARAMS
|
||||
|
|
@ -200,6 +208,29 @@ which indicates that action is expected to have minimal software data-path
|
|||
traffic and doesn't need to allocate stat counters with percpu allocator.
|
||||
This option is intended to be used by hardware-offloaded actions.
|
||||
|
||||
.TP
|
||||
.BI hw_stats " HW_STATS"
|
||||
Specifies the type of HW stats of new action. If omitted, any stats counter type
|
||||
is going to be used, according to driver and its resources.
|
||||
The
|
||||
.I HW_STATS
|
||||
indicates the type. Any of the following are valid:
|
||||
.RS
|
||||
.TP
|
||||
.B immediate
|
||||
Means that in dump, user gets the current HW stats state from the device
|
||||
queried at the dump time.
|
||||
.TP
|
||||
.B delayed
|
||||
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.
|
||||
.TP
|
||||
.B disabled
|
||||
No HW stats are going to be available in dump.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.BI since " MSTIME"
|
||||
When dumping large number of actions, a millisecond time-filter can be
|
||||
|
|
|
|||
|
|
@ -51,8 +51,9 @@ static void act_usage(void)
|
|||
" FL := ls | list | flush | <ACTNAMESPEC>\n"
|
||||
" ACTNAMESPEC := action <ACTNAME>\n"
|
||||
" ACTISPEC := <ACTNAMESPEC> <INDEXSPEC>\n"
|
||||
" ACTSPEC := action <ACTDETAIL> [INDEXSPEC]\n"
|
||||
" ACTSPEC := action <ACTDETAIL> [INDEXSPEC] [HWSTATSSPEC]\n"
|
||||
" INDEXSPEC := index <32 bit indexvalue>\n"
|
||||
" HWSTATSSPEC := hw_stats [ immediate | delayed | disabled ]\n"
|
||||
" ACTDETAIL := <ACTNAME> <ACTPARAMS>\n"
|
||||
" Example ACTNAME is gact, mirred, bpf, etc\n"
|
||||
" Each action has its own parameters (ACTPARAMS)\n"
|
||||
|
|
@ -149,6 +150,59 @@ new_cmd(char **argv)
|
|||
(matches(*argv, "add") == 0);
|
||||
}
|
||||
|
||||
static const struct hw_stats_type_item {
|
||||
const char *str;
|
||||
__u8 type;
|
||||
} hw_stats_type_items[] = {
|
||||
{ "immediate", TCA_ACT_HW_STATS_TYPE_IMMEDIATE },
|
||||
{ "delayed", TCA_ACT_HW_STATS_TYPE_DELAYED },
|
||||
{ "disabled", 0 }, /* no bit set */
|
||||
};
|
||||
|
||||
static void print_hw_stats(const struct rtattr *arg)
|
||||
{
|
||||
struct nla_bitfield32 *hw_stats_type_bf = RTA_DATA(arg);
|
||||
__u8 hw_stats_type;
|
||||
int i;
|
||||
|
||||
hw_stats_type = hw_stats_type_bf->value & hw_stats_type_bf->selector;
|
||||
print_string(PRINT_FP, NULL, "\t", NULL);
|
||||
open_json_array(PRINT_ANY, "hw_stats");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hw_stats_type_items); i++) {
|
||||
const struct hw_stats_type_item *item;
|
||||
|
||||
item = &hw_stats_type_items[i];
|
||||
if ((!hw_stats_type && !item->type) ||
|
||||
hw_stats_type & item->type)
|
||||
print_string(PRINT_ANY, NULL, " %s", item->str);
|
||||
}
|
||||
close_json_array(PRINT_JSON, NULL);
|
||||
}
|
||||
|
||||
static int parse_hw_stats(const char *str, struct nlmsghdr *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hw_stats_type_items); i++) {
|
||||
const struct hw_stats_type_item *item;
|
||||
|
||||
item = &hw_stats_type_items[i];
|
||||
if (matches(str, item->str) == 0) {
|
||||
struct nla_bitfield32 hw_stats_type_bf = {
|
||||
.value = item->type,
|
||||
.selector = item->type
|
||||
};
|
||||
|
||||
addattr_l(n, MAX_MSG, TCA_ACT_HW_STATS_TYPE,
|
||||
&hw_stats_type_bf, sizeof(hw_stats_type_bf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
|
||||
{
|
||||
int argc = *argc_p;
|
||||
|
|
@ -250,6 +304,14 @@ done0:
|
|||
addattr_l(n, MAX_MSG, TCA_ACT_COOKIE,
|
||||
&act_ck, act_ck_len);
|
||||
|
||||
if (*argv && matches(*argv, "hw_stats") == 0) {
|
||||
NEXT_ARG();
|
||||
ret = parse_hw_stats(*argv, n);
|
||||
if (ret < 0)
|
||||
invarg("value is invalid\n", *argv);
|
||||
NEXT_ARG_FWD();
|
||||
}
|
||||
|
||||
if (*argv && strcmp(*argv, "no_percpu") == 0) {
|
||||
struct nla_bitfield32 flags =
|
||||
{ TCA_ACT_FLAGS_NO_PERCPU_STATS,
|
||||
|
|
@ -337,6 +399,8 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
|
|||
TCA_ACT_FLAGS_NO_PERCPU_STATS);
|
||||
print_string(PRINT_FP, NULL, "%s", _SL_);
|
||||
}
|
||||
if (tb[TCA_ACT_HW_STATS_TYPE])
|
||||
print_hw_stats(tb[TCA_ACT_HW_STATS_TYPE]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue