net/mlx5e: Act on delay probe time updates
authorHadar Hen Zion <hadarh@mellanox.com>
Tue, 14 Feb 2017 09:20:24 +0000 (11:20 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Sun, 30 Apr 2017 13:03:15 +0000 (16:03 +0300)
The user can change delay_first_probe_time parameter through sysctl.
Listen to NETEVENT_DELAY_PROBE_TIME_UPDATE notifications and update the
intervals for updating the neighbours 'used' value periodic task and
for flow HW counters query periodic task.
Both of the intervals will be update only in case the new delay prob
time value is lower the current interval.

Since the driver saves only one min interval value and not per device,
the users will be able to set lower interval value for updating
neighbour 'used' value periodic task but they won't be able to schedule
a higher interval for this periodic task.
The used interval for scheduling neighbour 'used' value periodic task is
the minimal delay prob time parameter ever seen by the driver.

Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c

index af61b10b85bf7c3ae6640200dc24678452c27d24..79462c0368a0781ca7a38354726ed628097c0c89 100644 (file)
@@ -358,7 +358,9 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
        struct mlx5e_priv *priv = netdev_priv(netdev);
        struct mlx5e_neigh_hash_entry *nhe = NULL;
        struct mlx5e_neigh m_neigh = {};
+       struct neigh_parms *p;
        struct neighbour *n;
+       bool found = false;
 
        switch (event) {
        case NETEVENT_NEIGH_UPDATE:
@@ -403,6 +405,43 @@ static int mlx5e_rep_netevent_event(struct notifier_block *nb,
                }
                spin_unlock_bh(&neigh_update->encap_lock);
                break;
+
+       case NETEVENT_DELAY_PROBE_TIME_UPDATE:
+               p = ptr;
+
+               /* We check the device is present since we don't care about
+                * changes in the default table, we only care about changes
+                * done per device delay prob time parameter.
+                */
+#if IS_ENABLED(CONFIG_IPV6)
+               if (!p->dev || (p->tbl != ipv6_stub->nd_tbl && p->tbl != &arp_tbl))
+#else
+               if (!p->dev || p->tbl != &arp_tbl)
+#endif
+                       return NOTIFY_DONE;
+
+               /* We are in atomic context and can't take RTNL mutex,
+                * so use spin_lock_bh to walk the neigh list and look for
+                * the relevant device. bh is used since netevent can be
+                * called from a softirq context.
+                */
+               spin_lock_bh(&neigh_update->encap_lock);
+               list_for_each_entry(nhe, &neigh_update->neigh_list, neigh_list) {
+                       if (p->dev == nhe->m_neigh.dev) {
+                               found = true;
+                               break;
+                       }
+               }
+               spin_unlock_bh(&neigh_update->encap_lock);
+               if (!found)
+                       return NOTIFY_DONE;
+
+               neigh_update->min_interval = min_t(unsigned long,
+                                                  NEIGH_VAR(p, DELAY_PROBE_TIME),
+                                                  neigh_update->min_interval);
+               mlx5_fc_update_sampling_interval(priv->mdev,
+                                                neigh_update->min_interval);
+               break;
        }
        return NOTIFY_DONE;
 }