History

net/mlx5e: E-switch, Add steering drop counters

Add flow counters to count packets dropped due to drop rules configured in eswitch egress and ingress ACLs. These counters will count VFs violations and incoming traffic drops. Will be presented on hypervisor via standard 'ip -s link show' command. Example: "ip -s link show dev enp5s0f0" 6: enp5s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 24:8a:07:a5:28:f0 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 2 TX: bytes packets errors dropped carrier collsns 1406 17 0 0 0 0 vf 0 MAC 00:00:ca:fe:ca:fe, vlan 5, spoof checking off, link-state auto, trust off, query_rss off RX: bytes packets mcast bcast dropped 1666 29 14 32 0 TX: bytes packets dropped 2880 44 2412

Eugenia Emantayev committed 9 years ago

Commit b8a0dbe1 parent c5a9f6f4 files · +112 −2Browse files

Unified · Split

4 files
  1. drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +97 −2
  2. drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +7 −0
  3. drivers/net/ethernet/mellanox/mlx5/core/fs_core.h +2 −0
  4. drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +6 −0
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c+97−2
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#include <linux/mlx5/fs.h>37#include <linux/mlx5/fs.h>
38#include "mlx5_core.h"38#include "mlx5_core.h"
39#include "eswitch.h"39#include "eswitch.h"
40#include "fs_core.h"
40 41
41#define UPLINK_VPORT 0xFFFF42#define UPLINK_VPORT 0xFFFF
42 43
@@ -1123,8 +1124,12 @@ static void esw_vport_disable_ingress_acl(struct mlx5_eswitch *esw, · 1080 unmodified lines
1123static int esw_vport_ingress_config(struct mlx5_eswitch *esw,1124static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
1124 struct mlx5_vport *vport)1125 struct mlx5_vport *vport)
1125{1126{
1127 struct mlx5_fc *counter = vport->ingress.drop_counter;
1128 struct mlx5_flow_destination drop_ctr_dst = {0};
1129 struct mlx5_flow_destination *dst = NULL;
1126 struct mlx5_flow_act flow_act = {0};1130 struct mlx5_flow_act flow_act = {0};
1127 struct mlx5_flow_spec *spec;1131 struct mlx5_flow_spec *spec;
1132 int dest_num = 0;
1128 int err = 0;1133 int err = 0;
1129 u8 *smac_v;1134 u8 *smac_v;
1130 1135
@@ -1188,9 +1193,18 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw, · 57 unmodified lines
1188 1193
1189 memset(spec, 0, sizeof(*spec));1194 memset(spec, 0, sizeof(*spec));
1190 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;1195 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
1196
1197 /* Attach drop flow counter */
1198 if (counter) {
1199 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
1200 drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1201 drop_ctr_dst.counter = counter;
1202 dst = &drop_ctr_dst;
1203 dest_num++;
1204 }
1191 vport->ingress.drop_rule =1205 vport->ingress.drop_rule =
1192 mlx5_add_flow_rules(vport->ingress.acl, spec,1206 mlx5_add_flow_rules(vport->ingress.acl, spec,
1193 &flow_act, NULL, 0);1207 &flow_act, dst, dest_num);
1194 if (IS_ERR(vport->ingress.drop_rule)) {1208 if (IS_ERR(vport->ingress.drop_rule)) {
1195 err = PTR_ERR(vport->ingress.drop_rule);1209 err = PTR_ERR(vport->ingress.drop_rule);
1196 esw_warn(esw->dev,1210 esw_warn(esw->dev,
@@ -1210,8 +1224,12 @@ out: · 13 unmodified lines
1210static int esw_vport_egress_config(struct mlx5_eswitch *esw,1224static int esw_vport_egress_config(struct mlx5_eswitch *esw,
1211 struct mlx5_vport *vport)1225 struct mlx5_vport *vport)
1212{1226{
1227 struct mlx5_fc *counter = vport->egress.drop_counter;
1228 struct mlx5_flow_destination drop_ctr_dst = {0};
1229 struct mlx5_flow_destination *dst = NULL;
1213 struct mlx5_flow_act flow_act = {0};1230 struct mlx5_flow_act flow_act = {0};
1214 struct mlx5_flow_spec *spec;1231 struct mlx5_flow_spec *spec;
1232 int dest_num = 0;
1215 int err = 0;1233 int err = 0;
1216 1234
1217 esw_vport_cleanup_egress_rules(esw, vport);1235 esw_vport_cleanup_egress_rules(esw, vport);
@@ -1262,9 +1280,18 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw, · 44 unmodified lines
1262 /* Drop others rule (star rule) */1280 /* Drop others rule (star rule) */
1263 memset(spec, 0, sizeof(*spec));1281 memset(spec, 0, sizeof(*spec));
1264 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;1282 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
1283
1284 /* Attach egress drop flow counter */
1285 if (counter) {
1286 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
1287 drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1288 drop_ctr_dst.counter = counter;
1289 dst = &drop_ctr_dst;
1290 dest_num++;
1291 }
1265 vport->egress.drop_rule =1292 vport->egress.drop_rule =
1266 mlx5_add_flow_rules(vport->egress.acl, spec,1293 mlx5_add_flow_rules(vport->egress.acl, spec,
1267 &flow_act, NULL, 0);1294 &flow_act, dst, dest_num);
1268 if (IS_ERR(vport->egress.drop_rule)) {1295 if (IS_ERR(vport->egress.drop_rule)) {
1269 err = PTR_ERR(vport->egress.drop_rule);1296 err = PTR_ERR(vport->egress.drop_rule);
1270 esw_warn(esw->dev,1297 esw_warn(esw->dev,
@@ -1457,6 +1484,41 @@ static void esw_apply_vport_conf(struct mlx5_eswitch *esw, · 186 unmodified lines
1457 }1484 }
1458}1485}
1459 1486
1487static void esw_vport_create_drop_counters(struct mlx5_vport *vport)
1488{
1489 struct mlx5_core_dev *dev = vport->dev;
1490
1491 if (MLX5_CAP_ESW_INGRESS_ACL(dev, flow_counter)) {
1492 vport->ingress.drop_counter = mlx5_fc_create(dev, false);
1493 if (IS_ERR(vport->ingress.drop_counter)) {
1494 esw_warn(dev,
1495 "vport[%d] configure ingress drop rule counter failed\n",
1496 vport->vport);
1497 vport->ingress.drop_counter = NULL;
1498 }
1499 }
1500
1501 if (MLX5_CAP_ESW_EGRESS_ACL(dev, flow_counter)) {
1502 vport->egress.drop_counter = mlx5_fc_create(dev, false);
1503 if (IS_ERR(vport->egress.drop_counter)) {
1504 esw_warn(dev,
1505 "vport[%d] configure egress drop rule counter failed\n",
1506 vport->vport);
1507 vport->egress.drop_counter = NULL;
1508 }
1509 }
1510}
1511
1512static void esw_vport_destroy_drop_counters(struct mlx5_vport *vport)
1513{
1514 struct mlx5_core_dev *dev = vport->dev;
1515
1516 if (vport->ingress.drop_counter)
1517 mlx5_fc_destroy(dev, vport->ingress.drop_counter);
1518 if (vport->egress.drop_counter)
1519 mlx5_fc_destroy(dev, vport->egress.drop_counter);
1520}
1521
1460static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,1522static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
1461 int enable_events)1523 int enable_events)
1462{1524{
@@ -1483,6 +1545,10 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num, · 20 unmodified lines
1483 if (!vport_num)1545 if (!vport_num)
1484 vport->info.trusted = true;1546 vport->info.trusted = true;
1485 1547
1548 /* create steering drop counters for ingress and egress ACLs */
1549 if (vport_num && esw->mode == SRIOV_LEGACY)
1550 esw_vport_create_drop_counters(vport);
1551
1486 esw_vport_change_handle_locked(vport);1552 esw_vport_change_handle_locked(vport);
1487 1553
1488 esw->enabled_vports++;1554 esw->enabled_vports++;
@@ -1521,6 +1587,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num) · 32 unmodified lines
1521 MLX5_ESW_VPORT_ADMIN_STATE_DOWN);1587 MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
1522 esw_vport_disable_egress_acl(esw, vport);1588 esw_vport_disable_egress_acl(esw, vport);
1523 esw_vport_disable_ingress_acl(esw, vport);1589 esw_vport_disable_ingress_acl(esw, vport);
1590 esw_vport_destroy_drop_counters(vport);
1524 }1591 }
1525 esw->enabled_vports--;1592 esw->enabled_vports--;
1526 mutex_unlock(&esw->state_lock);1593 mutex_unlock(&esw->state_lock);
@@ -2016,12 +2083,36 @@ unlock: · 489 unmodified lines
2016 return err;2083 return err;
2017}2084}
2018 2085
2086static void mlx5_eswitch_query_vport_drop_stats(struct mlx5_core_dev *dev,
2087 int vport_idx,
2088 struct mlx5_vport_drop_stats *stats)
2089{
2090 struct mlx5_eswitch *esw = dev->priv.eswitch;
2091 struct mlx5_vport *vport = &esw->vports[vport_idx];
2092 u64 bytes = 0;
2093 u16 idx = 0;
2094
2095 if (!vport->enabled || esw->mode != SRIOV_LEGACY)
2096 return;
2097
2098 if (vport->egress.drop_counter) {
2099 idx = vport->egress.drop_counter->id;
2100 mlx5_fc_query(dev, idx, &stats->rx_dropped, &bytes);
2101 }
2102
2103 if (vport->ingress.drop_counter) {
2104 idx = vport->ingress.drop_counter->id;
2105 mlx5_fc_query(dev, idx, &stats->tx_dropped, &bytes);
2106 }
2107}
2108
2019int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,2109int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
2020 int vport,2110 int vport,
2021 struct ifla_vf_stats *vf_stats)2111 struct ifla_vf_stats *vf_stats)
2022{2112{
2023 int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);2113 int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
2024 u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {0};2114 u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {0};
2115 struct mlx5_vport_drop_stats stats = {0};
2025 int err = 0;2116 int err = 0;
2026 u32 *out;2117 u32 *out;
2027 2118
@@ -2076,6 +2167,10 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, · 48 unmodified lines
2076 vf_stats->broadcast =2167 vf_stats->broadcast =
2077 MLX5_GET_CTR(out, received_eth_broadcast.packets);2168 MLX5_GET_CTR(out, received_eth_broadcast.packets);
2078 2169
2170 mlx5_eswitch_query_vport_drop_stats(esw->dev, vport, &stats);
2171 vf_stats->rx_dropped = stats.rx_dropped;
2172 vf_stats->tx_dropped = stats.tx_dropped;
2173
2079free_out:2174free_out:
2080 kvfree(out);2175 kvfree(out);
2081 return err;2176 return err;
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h+7−0
@@ -73,6 +73,7 @@ struct vport_ingress { · 72 unmodified lines
73 struct mlx5_flow_group *drop_grp;73 struct mlx5_flow_group *drop_grp;
74 struct mlx5_flow_handle *allow_rule;74 struct mlx5_flow_handle *allow_rule;
75 struct mlx5_flow_handle *drop_rule;75 struct mlx5_flow_handle *drop_rule;
76 struct mlx5_fc *drop_counter;
76};77};
77 78
78struct vport_egress {79struct vport_egress {
@@ -81,6 +82,12 @@ struct vport_egress { · 2 unmodified lines
81 struct mlx5_flow_group *drop_grp;82 struct mlx5_flow_group *drop_grp;
82 struct mlx5_flow_handle *allowed_vlan;83 struct mlx5_flow_handle *allowed_vlan;
83 struct mlx5_flow_handle *drop_rule;84 struct mlx5_flow_handle *drop_rule;
85 struct mlx5_fc *drop_counter;
86};
87
88struct mlx5_vport_drop_stats {
89 u64 rx_dropped;
90 u64 tx_dropped;
84};91};
85 92
86struct mlx5_vport_info {93struct mlx5_vport_info {
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h+2−0
@@ -233,6 +233,8 @@ void mlx5_fc_queue_stats_work(struct mlx5_core_dev *dev, · 232 unmodified lines
233 unsigned long delay);233 unsigned long delay);
234void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,234void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
235 unsigned long interval);235 unsigned long interval);
236int mlx5_fc_query(struct mlx5_core_dev *dev, u16 id,
237 u64 *packets, u64 *bytes);
236 238
237int mlx5_init_fs(struct mlx5_core_dev *dev);239int mlx5_init_fs(struct mlx5_core_dev *dev);
238void mlx5_cleanup_fs(struct mlx5_core_dev *dev);240void mlx5_cleanup_fs(struct mlx5_core_dev *dev);
drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c+6−0
@@ -312,6 +312,12 @@ void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev) · 311 unmodified lines
312 }312 }
313}313}
314 314
315int mlx5_fc_query(struct mlx5_core_dev *dev, u16 id,
316 u64 *packets, u64 *bytes)
317{
318 return mlx5_cmd_fc_query(dev, id, packets, bytes);
319}
320
315void mlx5_fc_query_cached(struct mlx5_fc *counter,321void mlx5_fc_query_cached(struct mlx5_fc *counter,
316 u64 *bytes, u64 *packets, u64 *lastuse)322 u64 *bytes, u64 *packets, u64 *lastuse)
317{323{