Commit a37f37a2 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 39e85fe0 cff94376
...@@ -1827,10 +1827,9 @@ static int ...@@ -1827,10 +1827,9 @@ static int
mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_tcam_mr_rule_activity_get(struct mlxsw_sp *mlxsw_sp,
void *rule_priv, bool *activity) 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, return 0;
activity);
} }
static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = { static const struct mlxsw_sp_acl_profile_ops mlxsw_sp_acl_tcam_mr_ops = {
......
...@@ -168,8 +168,6 @@ static int mlxsw_sp_dcbnl_ieee_setets(struct net_device *dev, ...@@ -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, static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev,
struct dcb_app *app) struct dcb_app *app)
{ {
int prio;
if (app->priority >= IEEE_8021QAZ_MAX_TCS) { if (app->priority >= IEEE_8021QAZ_MAX_TCS) {
netdev_err(dev, "APP entry with priority value %u is invalid\n", netdev_err(dev, "APP entry with priority value %u is invalid\n",
app->priority); app->priority);
...@@ -183,17 +181,6 @@ static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev, ...@@ -183,17 +181,6 @@ static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev,
app->protocol); app->protocol);
return -EINVAL; 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; break;
case IEEE_8021QAZ_APP_SEL_ETHERTYPE: case IEEE_8021QAZ_APP_SEL_ETHERTYPE:
......
...@@ -2360,6 +2360,7 @@ mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n) ...@@ -2360,6 +2360,7 @@ mlxsw_sp_neigh_entry_create(struct mlxsw_sp *mlxsw_sp, struct neighbour *n)
goto err_neigh_entry_insert; goto err_neigh_entry_insert;
mlxsw_sp_neigh_counter_alloc(mlxsw_sp, neigh_entry); 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); list_add(&neigh_entry->rif_list_node, &rif->neigh_list);
return neigh_entry; return neigh_entry;
...@@ -2374,6 +2375,7 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp, ...@@ -2374,6 +2375,7 @@ mlxsw_sp_neigh_entry_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry) struct mlxsw_sp_neigh_entry *neigh_entry)
{ {
list_del(&neigh_entry->rif_list_node); 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_counter_free(mlxsw_sp, neigh_entry);
mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry); mlxsw_sp_neigh_entry_remove(mlxsw_sp, neigh_entry);
mlxsw_sp_neigh_entry_free(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) ...@@ -2571,6 +2573,9 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
char *rauhtd_pl; char *rauhtd_pl;
int err; int err;
if (!atomic_read(&mlxsw_sp->router->neighs_update.neigh_count))
return 0;
rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL); rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL);
if (!rauhtd_pl) if (!rauhtd_pl)
return -ENOMEM; return -ENOMEM;
...@@ -2950,6 +2955,7 @@ static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp) ...@@ -2950,6 +2955,7 @@ static int mlxsw_sp_neigh_init(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_router_neighs_update_work); mlxsw_sp_router_neighs_update_work);
INIT_DELAYED_WORK(&mlxsw_sp->router->nexthop_probe_dw, INIT_DELAYED_WORK(&mlxsw_sp->router->nexthop_probe_dw,
mlxsw_sp_router_probe_unresolved_nexthops); 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->neighs_update.dw, 0);
mlxsw_core_schedule_dw(&mlxsw_sp->router->nexthop_probe_dw, 0); mlxsw_core_schedule_dw(&mlxsw_sp->router->nexthop_probe_dw, 0);
return 0; return 0;
......
...@@ -56,6 +56,7 @@ struct mlxsw_sp_router { ...@@ -56,6 +56,7 @@ struct mlxsw_sp_router {
struct { struct {
struct delayed_work dw; struct delayed_work dw;
unsigned long interval; /* ms */ unsigned long interval; /* ms */
atomic_t neigh_count;
} neighs_update; } neighs_update;
struct delayed_work nexthop_probe_dw; struct delayed_work nexthop_probe_dw;
#define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */ #define MLXSW_SP_UNRESOLVED_NH_PROBE_INTERVAL 5000 /* ms */
......
...@@ -207,6 +207,16 @@ static void mlxsw_sp_bridge_device_vxlan_fini(struct mlxsw_sp_bridge *bridge, ...@@ -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 * static struct mlxsw_sp_bridge_device *
mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge, mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
struct net_device *br_dev, struct net_device *br_dev,
...@@ -245,6 +255,8 @@ mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge, ...@@ -245,6 +255,8 @@ mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
bridge_device->ops = bridge->bridge_8021d_ops; bridge_device->ops = bridge->bridge_8021d_ops;
} }
INIT_LIST_HEAD(&bridge_device->mids_list); 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); list_add(&bridge_device->list, &bridge->bridges_list);
/* It is possible we already have VXLAN devices enslaved to the bridge. /* 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, ...@@ -273,6 +285,8 @@ mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp, mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
bridge_device->dev); bridge_device->dev);
list_del(&bridge_device->list); list_del(&bridge_device->list);
if (list_empty(&bridge->bridges_list))
cancel_delayed_work(&bridge->fdb_notify.dw);
if (bridge_device->vlan_enabled) if (bridge_device->vlan_enabled)
bridge->vlan_enabled_exists = false; bridge->vlan_enabled_exists = false;
WARN_ON(!list_empty(&bridge_device->ports_list)); 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, ...@@ -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 #define MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION 10
static void mlxsw_sp_fdb_notify_work(struct work_struct *work) static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
{ {
struct mlxsw_sp_bridge *bridge; struct mlxsw_sp_bridge *bridge;
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
bool reschedule = false;
char *sfn_pl; char *sfn_pl;
int queries; int queries;
u8 num_rec; u8 num_rec;
...@@ -2916,6 +2921,9 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work) ...@@ -2916,6 +2921,9 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
mlxsw_sp = bridge->mlxsw_sp; mlxsw_sp = bridge->mlxsw_sp;
rtnl_lock(); rtnl_lock();
if (list_empty(&bridge->bridges_list))
goto out;
reschedule = true;
queries = MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION; queries = MLXSW_SP_FDB_SFN_QUERIES_PER_SESSION;
while (queries > 0) { while (queries > 0) {
mlxsw_reg_sfn_pack(sfn_pl); mlxsw_reg_sfn_pack(sfn_pl);
...@@ -2935,6 +2943,8 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work) ...@@ -2935,6 +2943,8 @@ static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
out: out:
rtnl_unlock(); rtnl_unlock();
kfree(sfn_pl); kfree(sfn_pl);
if (!reschedule)
return;
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, !queries); mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, !queries);
} }
...@@ -3665,7 +3675,6 @@ static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp) ...@@ -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); INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL; bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp, false);
return 0; return 0;
err_register_switchdev_blocking_notifier: err_register_switchdev_blocking_notifier:
......
...@@ -864,7 +864,7 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = { ...@@ -864,7 +864,7 @@ static const struct mlxsw_sp_trap_item mlxsw_sp_trap_items_arr[] = {
.trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP), .trap = MLXSW_SP_TRAP_CONTROL(LLDP, LLDP, TRAP),
.listeners_arr = { .listeners_arr = {
MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU, MLXSW_RXL(mlxsw_sp_rx_ptp_listener, LLDP, TRAP_TO_CPU,
false, SP_LLDP, DISCARD), true, SP_LLDP, DISCARD),
}, },
}, },
{ {
......
...@@ -371,9 +371,9 @@ test_tc_int_buf() ...@@ -371,9 +371,9 @@ test_tc_int_buf()
tc qdisc delete dev $swp root tc qdisc delete dev $swp root
} }
trap cleanup EXIT
bail_on_lldpad bail_on_lldpad
trap cleanup EXIT
setup_wait setup_wait
tests_run tests_run
......
...@@ -393,9 +393,9 @@ test_qos_pfc() ...@@ -393,9 +393,9 @@ test_qos_pfc()
log_test "PFC" log_test "PFC"
} }
trap cleanup EXIT
bail_on_lldpad bail_on_lldpad
trap cleanup EXIT
setup_prepare setup_prepare
setup_wait setup_wait
tests_run tests_run
......
...@@ -166,12 +166,11 @@ ecn_mirror_test() ...@@ -166,12 +166,11 @@ ecn_mirror_test()
uninstall_qdisc uninstall_qdisc
} }
trap cleanup EXIT bail_on_lldpad
trap cleanup EXIT
setup_prepare setup_prepare
setup_wait setup_wait
bail_on_lldpad
tests_run tests_run
exit $EXIT_STATUS exit $EXIT_STATUS
...@@ -73,12 +73,11 @@ red_mirror_test() ...@@ -73,12 +73,11 @@ red_mirror_test()
uninstall_qdisc uninstall_qdisc
} }
trap cleanup EXIT bail_on_lldpad
trap cleanup EXIT
setup_prepare setup_prepare
setup_wait setup_wait
bail_on_lldpad
tests_run tests_run
exit $EXIT_STATUS exit $EXIT_STATUS
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: GPL-2.0 # 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=" ALL_TESTS="
ping_ipv4 ping_ipv4
ping_ipv6 ping_ipv6
......
#!/bin/bash #!/bin/bash
# SPDX-License-Identifier: GPL-2.0 # 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 NUM_NETIFS=4
source lib.sh source lib.sh
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment