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
3737 #include <linux/mlx5/fs.h>
3838 #include "mlx5_core.h"
3939 #include "eswitch.h"
40+#include "fs_core.h"
4041
4142 #define UPLINK_VPORT 0xFFFF
4243
@@ -1123,8 +1124,12 @@ static void esw_vport_disable_ingress_acl(struct mlx5_eswitch *esw, · 1080 unmodified lines
11231124 static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
11241125 struct mlx5_vport *vport)
11251126 {
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;
11261130 struct mlx5_flow_act flow_act = {0};
11271131 struct mlx5_flow_spec *spec;
1132+ int dest_num = 0;
11281133 int err = 0;
11291134 u8 *smac_v;
11301135
@@ -1188,9 +1193,18 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw, · 57 unmodified lines
11881193
11891194 memset(spec, 0, sizeof(*spec));
11901195 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+ }
11911205 vport->ingress.drop_rule =
11921206 mlx5_add_flow_rules(vport->ingress.acl, spec,
1193− &flow_act, NULL, 0);
1207+ &flow_act, dst, dest_num);
11941208 if (IS_ERR(vport->ingress.drop_rule)) {
11951209 err = PTR_ERR(vport->ingress.drop_rule);
11961210 esw_warn(esw->dev,
@@ -1210,8 +1224,12 @@ out: · 13 unmodified lines
12101224 static int esw_vport_egress_config(struct mlx5_eswitch *esw,
12111225 struct mlx5_vport *vport)
12121226 {
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;
12131230 struct mlx5_flow_act flow_act = {0};
12141231 struct mlx5_flow_spec *spec;
1232+ int dest_num = 0;
12151233 int err = 0;
12161234
12171235 esw_vport_cleanup_egress_rules(esw, vport);
@@ -1262,9 +1280,18 @@ static int esw_vport_egress_config(struct mlx5_eswitch *esw, · 44 unmodified lines
12621280 /* Drop others rule (star rule) */
12631281 memset(spec, 0, sizeof(*spec));
12641282 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+ }
12651292 vport->egress.drop_rule =
12661293 mlx5_add_flow_rules(vport->egress.acl, spec,
1267− &flow_act, NULL, 0);
1294+ &flow_act, dst, dest_num);
12681295 if (IS_ERR(vport->egress.drop_rule)) {
12691296 err = PTR_ERR(vport->egress.drop_rule);
12701297 esw_warn(esw->dev,
@@ -1457,6 +1484,41 @@ static void esw_apply_vport_conf(struct mlx5_eswitch *esw, · 186 unmodified lines
14571484 }
14581485 }
14591486
1487+static 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+
1512+static 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+
14601522 static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num,
14611523 int enable_events)
14621524 {
@@ -1483,6 +1545,10 @@ static void esw_enable_vport(struct mlx5_eswitch *esw, int vport_num, · 20 unmodified lines
14831545 if (!vport_num)
14841546 vport->info.trusted = true;
14851547
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+
14861552 esw_vport_change_handle_locked(vport);
14871553
14881554 esw->enabled_vports++;
@@ -1521,6 +1587,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num) · 32 unmodified lines
15211587 MLX5_ESW_VPORT_ADMIN_STATE_DOWN);
15221588 esw_vport_disable_egress_acl(esw, vport);
15231589 esw_vport_disable_ingress_acl(esw, vport);
1590+ esw_vport_destroy_drop_counters(vport);
15241591 }
15251592 esw->enabled_vports--;
15261593 mutex_unlock(&esw->state_lock);
@@ -2016,12 +2083,36 @@ unlock: · 489 unmodified lines
20162083 return err;
20172084 }
20182085
2086+static 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+
20192109 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
20202110 int vport,
20212111 struct ifla_vf_stats *vf_stats)
20222112 {
20232113 int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
20242114 u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {0};
2115+ struct mlx5_vport_drop_stats stats = {0};
20252116 int err = 0;
20262117 u32 *out;
20272118
@@ -2076,6 +2167,10 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, · 48 unmodified lines
20762167 vf_stats->broadcast =
20772168 MLX5_GET_CTR(out, received_eth_broadcast.packets);
20782169
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+
20792174 free_out:
20802175 kvfree(out);
20812176 return err;
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h+7−0
@@ -73,6 +73,7 @@ struct vport_ingress { · 72 unmodified lines
7373 struct mlx5_flow_group *drop_grp;
7474 struct mlx5_flow_handle *allow_rule;
7575 struct mlx5_flow_handle *drop_rule;
76+ struct mlx5_fc *drop_counter;
7677 };
7778
7879 struct vport_egress {
@@ -81,6 +82,12 @@ struct vport_egress { · 2 unmodified lines
8182 struct mlx5_flow_group *drop_grp;
8283 struct mlx5_flow_handle *allowed_vlan;
8384 struct mlx5_flow_handle *drop_rule;
85+ struct mlx5_fc *drop_counter;
86+};
87+
88+struct mlx5_vport_drop_stats {
89+ u64 rx_dropped;
90+ u64 tx_dropped;
8491 };
8592
8693 struct 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
233233 unsigned long delay);
234234 void mlx5_fc_update_sampling_interval(struct mlx5_core_dev *dev,
235235 unsigned long interval);
236+int mlx5_fc_query(struct mlx5_core_dev *dev, u16 id,
237+ u64 *packets, u64 *bytes);
236238
237239 int mlx5_init_fs(struct mlx5_core_dev *dev);
238240 void 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
312312 }
313313 }
314314
315+int 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+
315321 void mlx5_fc_query_cached(struct mlx5_fc *counter,
316322 u64 *bytes, u64 *packets, u64 *lastuse)
317323 {