net/mlx5e: Always query offloaded tc peer rule counter
authorRoi Dayan <roid@mellanox.com>
Mon, 2 Jul 2018 11:06:02 +0000 (14:06 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 1 Mar 2019 20:04:17 +0000 (12:04 -0800)
Under multipath when encap rules are duplicated to HW in the driver,
it's possible for one flow to be currently un-offloaded (e.g. lack of
next-hop route or neigh entry) while the other flow is offloaded. As
such, we move to query the counters of both flows at all times.

Signed-off-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

index 2f0c631847fd1e31ddf2287d41c55adde402e410..c44cb5083d55afbab61b3971587c7ee5ecb77686 100644 (file)
@@ -3078,23 +3078,25 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
        struct mlx5_eswitch *peer_esw;
        struct mlx5e_tc_flow *flow;
        struct mlx5_fc *counter;
-       u64 bytes;
-       u64 packets;
-       u64 lastuse;
+       u64 lastuse = 0;
+       u64 packets = 0;
+       u64 bytes = 0;
 
        flow = rhashtable_lookup_fast(tc_ht, &f->cookie, tc_ht_params);
        if (!flow || !same_flow_direction(flow, flags))
                return -EINVAL;
 
-       if (!(flow->flags & MLX5E_TC_FLOW_OFFLOADED))
-               return 0;
-
-       counter = mlx5e_tc_get_counter(flow);
-       if (!counter)
-               return 0;
+       if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) {
+               counter = mlx5e_tc_get_counter(flow);
+               if (!counter)
+                       return 0;
 
-       mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
+               mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse);
+       }
 
+       /* Under multipath it's possible for one rule to be currently
+        * un-offloaded while the other rule is offloaded.
+        */
        peer_esw = mlx5_devcom_get_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
        if (!peer_esw)
                goto out;
@@ -3106,6 +3108,8 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
                u64 lastuse2;
 
                counter = mlx5e_tc_get_counter(flow->peer_flow);
+               if (!counter)
+                       goto no_peer_counter;
                mlx5_fc_query_cached(counter, &bytes2, &packets2, &lastuse2);
 
                bytes += bytes2;
@@ -3113,8 +3117,8 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
                lastuse = max_t(u64, lastuse, lastuse2);
        }
 
+no_peer_counter:
        mlx5_devcom_release_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
-
 out:
        flow_stats_update(&f->stats, bytes, packets, lastuse);