Merge branch 'mlxsw-updates'

Ido Schimmel says:

====================
mlxsw: Various updates

Patches #1-#3 add missing topology diagrams in selftests and perform
small cleanups.

Patches #4-#5 make small adjustments in QoS configuration. See detailed
description in the commit messages.

Patches #6-#8 reduce the number of background EMAD transactions. The
driver periodically queries the device (via EMAD transactions) about
updates that cannot happen in certain situations. This can negatively
impact the latency of time critical transactions, as the device is busy
processing other transactions.

Before:

 # perf stat -a -e devlink:devlink_hwmsg -- sleep 10

  Performance counter stats for 'system wide':

                452      devlink:devlink_hwmsg

       10.009736160 seconds time elapsed

After:

 # perf stat -a -e devlink:devlink_hwmsg -- sleep 10

  Performance counter stats for 'system wide':

                  0      devlink:devlink_hwmsg

       10.001726333 seconds time elapsed

====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2022-05-04 11:21:33 +01:00
commit a37f37a2e7
12 changed files with 82 additions and 39 deletions

View file

@ -1827,10 +1827,9 @@ static int
mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
void *rule_priv, bool *activity)
{
struct mlxsw_sp_acl_tcam_mr_rule *rule = rule_priv;
*activity = false;
return mlxsw_sp_acl_tcam_ventry_activity_get(mlxsw_sp, &rule->ventry,
activity);
return 0;
}
static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {

View file

@ -168,8 +168,6 @@ static int mlxsw_sp_dcbnl_ieee_setets(struct net_device *dev,
static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev,
struct dcb_app *app)
{
int prio;
if (app->priority >= IEEE_8021QAZ_MAX_TCS) {
netdev_err(dev, "APP entry with priority value %u is invalid\n",
app->priority);
@ -183,17 +181,6 @@ static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev,
app->protocol);
return -EINVAL;
}
/* Warn about any DSCP APP entries with the same PID. */
prio = fls(dcb_ieee_getapp_mask(dev, app));
if (prio--) {
if (prio < app->priority)
netdev_warn(dev, "Choosing priority %d for DSCP %d in favor of previously-active value of %d\n",
app->priority, app->protocol, prio);
else if (prio > app->priority)
netdev_warn(dev, "Ignoring new priority %d for DSCP %d in favor of current value of %d\n",
app->priority, app->protocol, prio);
}
break;
case IEEE_8021QAZ_APP_SEL_ETHERTYPE:

View file

@ -2360,6 +2360,7 @@ mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
goto err_neigh_entry_insert;
mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry);
atomic_inc(&mlxsw_sp->router->neighs_update.neigh_count);
list_add(&neigh_entry->rif_list_node, &rif->neigh_list);
return neigh_entry;
@ -2374,6 +2375,7 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry)
{
list_del(&neigh_entry->rif_list_node);
atomic_dec(&mlxsw_sp->router->neighs_update.neigh_count);
mlxsw_sp_neigh_counter_free(mlxsw_sp, neigh_entry);
mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
mlxsw_sp_neigh_entry_free(neigh_entry);
@ -2571,6 +2573,9 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
char *rauhtd_pl;
int err;
if (!atomic_read(&mlxsw_sp->router->neighs_update.neigh_count))
return 0;
rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL);
if (!rauhtd_pl)
return -ENOMEM;
@ -2950,6 +2955,7 @@ static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_router_neighs_update_work);
INIT_DELAYED_WORK(&mlxsw_sp->router->nexthop_probe_dw,
mlxsw_sp_router_probe_unresolved_nexthops);
atomic_set(&mlxsw_sp->router->neighs_update.neigh_count, 0);
mlxsw_core_schedule_dw(&mlxsw_sp->router->neighs_update.dw, 0);
mlxsw_core_schedule_dw(&mlxsw_sp->router->nexthop_probe_dw, 0);
return 0;

View file

@ -56,6 +56,7 @@ struct mlxsw_sp_router {
struct {
struct delayed_work dw;
unsigned long interval; /* ms */
atomic_t neigh_count;
} neighs_update;
struct delayed_work nexthop_probe_dw;
#define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */

View file

@ -207,6 +207,16 @@ static void mlxsw_sp_bridge_device_vxlan_fini(struct mlxsw_sp_bridge *bridge,
}
}
static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp,
bool no_delay)
{
struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
unsigned int interval = no_delay ? 0 : bridge->fdb_notify.interval;
mlxsw_core_schedule_dw(&bridge->fdb_notify.dw,
msecs_to_jiffies(interval));
}
static struct mlxsw_sp_bridge_device *
mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
struct net_device *br_dev,
@ -245,6 +255,8 @@ mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
bridge_device->ops = bridge->bridge_8021d_ops;
}
INIT_LIST_HEAD(&bridge_device->mids_list);
if (list_empty(&bridge->bridges_list))
mlxsw_sp_fdb_notify_work_schedule(bridge->mlxsw_sp, false);
list_add(&bridge_device->list, &bridge->bridges_list);
/* It is possible we already have VXLAN devices enslaved to the bridge.
@ -273,6 +285,8 @@ mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
bridge_device->dev);
list_del(&bridge_device->list);
if (list_empty(&bridge->bridges_list))
cancel_delayed_work(&bridge->fdb_notify.dw);
if (bridge_device->vlan_enabled)
bridge->vlan_enabled_exists = false;
WARN_ON(!list_empty(&bridge_device->ports_list));
@ -2886,22 +2900,13 @@ static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
}
}
static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp,
bool no_delay)
{
struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
unsigned int interval = no_delay ? 0 : bridge->fdb_notify.interval;
mlxsw_core_schedule_dw(&bridge->fdb_notify.dw,
msecs_to_jiffies(interval));
}
#define MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION 10
static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
{
struct mlxsw_sp_bridge *bridge;
struct mlxsw_sp *mlxsw_sp;
bool reschedule = false;
char *sfn_pl;
int queries;
u8 num_rec;
@ -2916,6 +2921,9 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
mlxsw_sp = bridge->mlxsw_sp;
rtnl_lock();
if (list_empty(&bridge->bridges_list))
goto out;
reschedule = true;
queries = MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION;
while (queries > 0) {
mlxsw_reg_sfn_pack(sfn_pl);
@ -2935,6 +2943,8 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
out:
rtnl_unlock();
kfree(sfn_pl);
if (!reschedule)
return;
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, !queries);
}
@ -3665,7 +3675,6 @@ static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, false);
return 0;
err_register_switchdev_blocking_notifier:

View file

@ -864,7 +864,7 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
.trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP),
.listeners_arr = {
MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU,
false, SP_LLDP, DISCARD),
true, SP_LLDP, DISCARD),
},
},
{

View file

@ -371,9 +371,9 @@ test_tc_int_buf()
tc qdisc delete dev $swp root
}
trap cleanup EXIT
bail_on_lldpad
trap cleanup EXIT
setup_wait
tests_run

View file

@ -393,9 +393,9 @@ test_qos_pfc()
log_test "PFC"
}
trap cleanup EXIT
bail_on_lldpad
trap cleanup EXIT
setup_prepare
setup_wait
tests_run

View file

@ -166,12 +166,11 @@ ecn_mirror_test()
uninstall_qdisc
}
trap cleanup EXIT
bail_on_lldpad
trap cleanup EXIT
setup_prepare
setup_wait
bail_on_lldpad
tests_run
exit $EXIT_STATUS

View file

@ -73,12 +73,11 @@ red_mirror_test()
uninstall_qdisc
}
trap cleanup EXIT
bail_on_lldpad
trap cleanup EXIT
setup_prepare
setup_wait
bail_on_lldpad
tests_run
exit $EXIT_STATUS

View file

@ -1,6 +1,24 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# +--------------------+ +----------------------+
# | H1 | | H2 |
# | | | |
# | $h1 + | | + $h2 |
# | 192.0.2.2/24 | | | | 198.51.100.2/24 |
# | 2001:db8:1::2/64 | | | | 2001:db8:2::2/64 |
# | | | | | |
# +------------------|-+ +-|--------------------+
# | |
# +------------------|-------------------------|--------------------+
# | SW | | |
# | | | |
# | $rp1 + + $rp2 |
# | 192.0.2.1/24 198.51.100.1/24 |
# | 2001:db8:1::1/64 2001:db8:2::1/64 |
# | |
# +-----------------------------------------------------------------+
ALL_TESTS="
ping_ipv4
ping_ipv6

View file

@ -1,7 +1,32 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
ALL_TESTS="ping_ipv4 ping_ipv6"
# +--------------------+ +----------------------+
# | H1 | | H2 |
# | | | |
# | $h1.1 + | | + $h2.1 |
# | 192.0.2.2/24 | | | | 198.51.100.2/24 |
# | 2001:db8:1::2/64 | | | | 2001:db8:2::2/64 |
# | | | | | |
# | $h1 + | | + $h2 |
# | | | | | |
# +------------------|-+ +-|--------------------+
# | |
# +------------------|-------------------------|--------------------+
# | SW | | |
# | | | |
# | $rp1 + + $rp2 |
# | | | |
# | $rp1.1 + + $rp2.1 |
# | 192.0.2.1/24 198.51.100.1/24 |
# | 2001:db8:1::1/64 2001:db8:2::1/64 |
# | |
# +-----------------------------------------------------------------+
ALL_TESTS="
ping_ipv4
ping_ipv6
"
NUM_NETIFS=4
source lib.sh