Commit 4900a769 authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-updates-2021-10-25' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2021-10-25

Misc updates for mlx5 driver:

1) Misc updates and cleanups:
 - Don't write directly to netdev->dev_addr, From Jakub Kicinski
 - Remove unnecessary checks for slow path flag in tc module
 - Fix unused function warning of mlx5i_flow_type_mask
 - Bridge, support replacing existing FDB entry

2) Sub Functions, Reduction in memory usage:
 - Reduce flow counters bulk query buffer size
 - Implement max_macs devlink parameter
 - Add devlink vendor params to control Event Queue sizes
 - Added SF life cycle trace points by Parav/

3) From Aya, Firmware health buffer reporting improvements
 - Print health buffer by log level and more missing information
 - Periodic update of host time to firmware
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cf12e6f9 d67ab0a8
......@@ -543,6 +543,8 @@ The CR-space dump uses vsc interface which is valid even if the FW command
interface is not functional, which is the case in most FW fatal errors.
The recover function runs recover flow which reloads the driver and triggers fw
reset if needed.
On firmware error, the health buffer is dumped into the dmesg. The log
level is derived from the error's severity (given in health buffer).
User commands examples:
......@@ -700,3 +702,61 @@ Eswitch QoS tracepoints:
$ cat /sys/kernel/debug/tracing/trace
...
<...>-27418 [006] .... 76547.187258: mlx5_esw_group_qos_destroy: (0000:82:00.0) group=000000007b576bb3 tsar_ix=1
SF tracepoints:
- mlx5_sf_add: trace addition of the SF port::
$ echo mlx5:mlx5_sf_add >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
devlink-9363 [031] ..... 24610.188722: mlx5_sf_add: (0000:06:00.0) port_index=32768 controller=0 hw_id=0x8000 sfnum=88
- mlx5_sf_free: trace freeing of the SF port::
$ echo mlx5:mlx5_sf_free >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
devlink-9830 [038] ..... 26300.404749: mlx5_sf_free: (0000:06:00.0) port_index=32768 controller=0 hw_id=0x8000
- mlx5_sf_hwc_alloc: trace allocating of the hardware SF context::
$ echo mlx5:mlx5_sf_hwc_alloc >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
devlink-9775 [031] ..... 26296.385259: mlx5_sf_hwc_alloc: (0000:06:00.0) controller=0 hw_id=0x8000 sfnum=88
- mlx5_sf_hwc_free: trace freeing of the hardware SF context::
$ echo mlx5:mlx5_sf_hwc_free >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u128:3-9093 [046] ..... 24625.365771: mlx5_sf_hwc_free: (0000:06:00.0) hw_id=0x8000
- mlx5_sf_hwc_deferred_free : trace deferred freeing of the hardware SF context::
$ echo mlx5:mlx5_sf_hwc_deferred_free >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
devlink-9519 [046] ..... 24624.400271: mlx5_sf_hwc_deferred_free: (0000:06:00.0) hw_id=0x8000
- mlx5_sf_vhca_event: trace SF vhca event and state::
$ echo mlx5:mlx5_sf_vhca_event >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u128:3-9093 [046] ..... 24625.365525: mlx5_sf_vhca_event: (0000:06:00.0) hw_id=0x8000 sfnum=88 vhca_state=1
- mlx5_sf_dev_add : trace SF device add event::
$ echo mlx5:mlx5_sf_dev_add>> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u128:3-9093 [000] ..... 24616.524495: mlx5_sf_dev_add: (0000:06:00.0) sfdev=00000000fc5d96fd aux_id=4 hw_id=0x8000 sfnum=88
- mlx5_sf_dev_del : trace SF device delete event::
$ echo mlx5:mlx5_sf_dev_del >> /sys/kernel/debug/tracing/set_event
$ cat /sys/kernel/debug/tracing/trace
...
kworker/u128:3-9093 [044] ..... 24624.400749: mlx5_sf_dev_del: (0000:06:00.0) sfdev=00000000fc5d96fd aux_id=4 hw_id=0x8000 sfnum=88
......@@ -14,8 +14,12 @@ Parameters
* - Name
- Mode
- Validation
* - ``enable_roce``
- driverinit
* - ``max_macs``
- driverinit
- The range is between 1 and 2^31. Only power of 2 values are supported.
The ``mlx5`` driver also implements the following driver-specific
parameters.
......@@ -46,6 +50,22 @@ parameters.
The ``mlx5`` driver supports reloading via ``DEVLINK_CMD_RELOAD``
Resources
=========
.. list-table:: Driver-specific resources implemented
:widths: 5 5 5 85
* - Name
- Description
* - ``comp_eq_size``
- Control the size of I/O completion EQs.
* The default value is 1024, and the range is between 64 and 4096.
* - ``event_eq_size``
- Control the size of the asynchronous control events EQ.
* The default value is 4096, and the range is between 64 and 4096.
Info versions
=============
......
......@@ -16,7 +16,7 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
transobj.o vport.o sriov.o fs_cmd.o fs_core.o pci_irq.o \
fs_counters.o fs_ft_pool.o rl.o lag/lag.o dev.o events.o wq.o lib/gid.o \
lib/devcom.o lib/pci_vsc.o lib/dm.o lib/fs_ttc.o diag/fs_tracepoint.o \
diag/fw_tracer.o diag/crdump.o devlink.o diag/rsc_dump.o \
diag/fw_tracer.o diag/crdump.o devlink.o devlink_res.o diag/rsc_dump.o \
fw_reset.o qos.o lib/tout.o
#
......
......@@ -752,6 +752,68 @@ static void mlx5_devlink_auxdev_params_unregister(struct devlink *devlink)
mlx5_devlink_eth_param_unregister(devlink);
}
static int mlx5_devlink_max_uc_list_validate(struct devlink *devlink, u32 id,
union devlink_param_value val,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
/* At least one unicast mac is needed */
if (val.vu32 == 0) {
NL_SET_ERR_MSG_MOD(extack, "max_macs value must be greater than 0");
return -EINVAL;
}
/* Check if its power of 2 or not */
if (!is_power_of_2(val.vu32)) {
NL_SET_ERR_MSG_MOD(extack,
"Only power of 2 values are supported for max_macs");
return -EOPNOTSUPP;
}
if (ilog2(val.vu32) >
MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list)) {
NL_SET_ERR_MSG_MOD(extack, "max_macs value is out of the supported range");
return -EOPNOTSUPP;
}
return 0;
}
static const struct devlink_param max_uc_list_param =
DEVLINK_PARAM_GENERIC(MAX_MACS, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT),
NULL, NULL, mlx5_devlink_max_uc_list_validate);
static int mlx5_devlink_max_uc_list_param_register(struct devlink *devlink)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
union devlink_param_value value;
int err;
if (!MLX5_CAP_GEN(dev, log_max_current_uc_list_wr_supported))
return 0;
err = devlink_param_register(devlink, &max_uc_list_param);
if (err)
return err;
value.vu32 = 1 << MLX5_CAP_GEN(dev, log_max_current_uc_list);
devlink_param_driverinit_value_set(devlink,
DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
value);
return 0;
}
static void
mlx5_devlink_max_uc_list_param_unregister(struct devlink *devlink)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
if (!MLX5_CAP_GEN(dev, log_max_current_uc_list_wr_supported))
return;
devlink_param_unregister(devlink, &max_uc_list_param);
}
#define MLX5_TRAP_DROP(_id, _group_id) \
DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
......@@ -815,11 +877,17 @@ int mlx5_devlink_register(struct devlink *devlink)
if (err)
goto traps_reg_err;
err = mlx5_devlink_max_uc_list_param_register(devlink);
if (err)
goto uc_list_reg_err;
if (!mlx5_core_is_mp_slave(dev))
devlink_set_features(devlink, DEVLINK_F_RELOAD);
return 0;
uc_list_reg_err:
mlx5_devlink_traps_unregister(devlink);
traps_reg_err:
mlx5_devlink_auxdev_params_unregister(devlink);
auxdev_reg_err:
......@@ -830,6 +898,7 @@ int mlx5_devlink_register(struct devlink *devlink)
void mlx5_devlink_unregister(struct devlink *devlink)
{
mlx5_devlink_max_uc_list_param_unregister(devlink);
mlx5_devlink_traps_unregister(devlink);
mlx5_devlink_auxdev_params_unregister(devlink);
devlink_params_unregister(devlink, mlx5_devlink_params,
......
......@@ -6,6 +6,14 @@
#include <net/devlink.h>
enum mlx5_devlink_resource_id {
MLX5_DL_RES_COMP_EQ = 1,
MLX5_DL_RES_ASYNC_EQ,
__MLX5_ID_RES_MAX,
MLX5_ID_RES_MAX = __MLX5_ID_RES_MAX - 1,
};
enum mlx5_devlink_param_id {
MLX5_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
MLX5_DEVLINK_PARAM_ID_FLOW_STEERING_MODE,
......@@ -31,6 +39,10 @@ int mlx5_devlink_trap_get_num_active(struct mlx5_core_dev *dev);
int mlx5_devlink_traps_get_action(struct mlx5_core_dev *dev, int trap_id,
enum devlink_trap_action *action);
void mlx5_devlink_res_register(struct mlx5_core_dev *dev);
void mlx5_devlink_res_unregister(struct mlx5_core_dev *dev);
size_t mlx5_devlink_res_size(struct mlx5_core_dev *dev, enum mlx5_devlink_resource_id id);
struct devlink *mlx5_devlink_alloc(struct device *dev);
void mlx5_devlink_free(struct devlink *devlink);
int mlx5_devlink_register(struct devlink *devlink);
......
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. */
#include "devlink.h"
#include "mlx5_core.h"
enum {
MLX5_EQ_MIN_SIZE = 64,
MLX5_EQ_MAX_SIZE = 4096,
MLX5_NUM_ASYNC_EQE = 4096,
MLX5_COMP_EQ_SIZE = 1024,
};
static int comp_eq_res_register(struct mlx5_core_dev *dev)
{
struct devlink_resource_size_params comp_eq_size;
struct devlink *devlink = priv_to_devlink(dev);
devlink_resource_size_params_init(&comp_eq_size, MLX5_EQ_MIN_SIZE,
MLX5_EQ_MAX_SIZE, 1, DEVLINK_RESOURCE_UNIT_ENTRY);
return devlink_resource_register(devlink, "io_eq_size", MLX5_COMP_EQ_SIZE,
MLX5_DL_RES_COMP_EQ,
DEVLINK_RESOURCE_ID_PARENT_TOP,
&comp_eq_size);
}
static int async_eq_resource_register(struct mlx5_core_dev *dev)
{
struct devlink_resource_size_params async_eq_size;
struct devlink *devlink = priv_to_devlink(dev);
devlink_resource_size_params_init(&async_eq_size, MLX5_EQ_MIN_SIZE,
MLX5_EQ_MAX_SIZE, 1, DEVLINK_RESOURCE_UNIT_ENTRY);
return devlink_resource_register(devlink, "event_eq_size",
MLX5_NUM_ASYNC_EQE, MLX5_DL_RES_ASYNC_EQ,
DEVLINK_RESOURCE_ID_PARENT_TOP,
&async_eq_size);
}
void mlx5_devlink_res_register(struct mlx5_core_dev *dev)
{
int err;
err = comp_eq_res_register(dev);
if (err)
goto err_msg;
err = async_eq_resource_register(dev);
if (err)
goto err;
return;
err:
devlink_resources_unregister(priv_to_devlink(dev), NULL);
err_msg:
mlx5_core_err(dev, "Failed to register resources, err = %d\n", err);
}
void mlx5_devlink_res_unregister(struct mlx5_core_dev *dev)
{
devlink_resources_unregister(priv_to_devlink(dev), NULL);
}
static const size_t default_vals[MLX5_ID_RES_MAX + 1] = {
[MLX5_DL_RES_COMP_EQ] = MLX5_COMP_EQ_SIZE,
[MLX5_DL_RES_ASYNC_EQ] = MLX5_NUM_ASYNC_EQE,
};
size_t mlx5_devlink_res_size(struct mlx5_core_dev *dev, enum mlx5_devlink_resource_id id)
{
struct devlink *devlink = priv_to_devlink(dev);
u64 size;
int err;
err = devlink_resource_size_get(devlink, id, &size);
if (!err)
return size;
mlx5_core_err(dev, "Failed to get param. using default. err = %d, id = %u\n",
err, id);
return default_vals[id];
}
......@@ -509,13 +509,6 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
if (IS_ERR_OR_NULL(tc_psample))
return ERR_PTR(-EOPNOTSUPP);
/* If slow path flag is set, eg. when the neigh is invalid for encap,
* don't offload sample action.
*/
esw = tc_psample->esw;
if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH)
return mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
sample_flow = kzalloc(sizeof(*sample_flow), GFP_KERNEL);
if (!sample_flow)
return ERR_PTR(-ENOMEM);
......@@ -527,6 +520,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
* Only match the fte id instead of the same match in the
* original flow table.
*/
esw = tc_psample->esw;
if (MLX5_CAP_GEN(esw->dev, reg_c_preserve) ||
attr->action & MLX5_FLOW_CONTEXT_ACTION_DECAP) {
struct mlx5_flow_table *ft;
......@@ -634,15 +628,6 @@ mlx5e_tc_sample_unoffload(struct mlx5e_tc_psample *tc_psample,
if (IS_ERR_OR_NULL(tc_psample))
return;
/* If slow path flag is set, sample action is not offloaded.
* No need to delete sample rule.
*/
esw = tc_psample->esw;
if (attr->flags & MLX5_ESW_ATTR_FLAG_SLOW_PATH) {
mlx5_eswitch_del_offloaded_rule(esw, rule, attr);
return;
}
/* The following delete order can't be changed, otherwise,
* will hit fw syndromes.
*/
......
......@@ -4432,13 +4432,17 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16
static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
u8 addr[ETH_ALEN];
mlx5_query_mac_address(priv->mdev, netdev->dev_addr);
if (is_zero_ether_addr(netdev->dev_addr) &&
mlx5_query_mac_address(priv->mdev, addr);
if (is_zero_ether_addr(addr) &&
!MLX5_CAP_GEN(priv->mdev, vport_group_manager)) {
eth_hw_addr_random(netdev);
mlx5_core_info(priv->mdev, "Assigned random MAC address %pM\n", netdev->dev_addr);
return;
}
eth_hw_addr_set(netdev, addr);
}
static int mlx5e_vxlan_set_port(struct net_device *netdev, unsigned int table,
......
......@@ -19,6 +19,7 @@
#include "lib/clock.h"
#include "diag/fw_tracer.h"
#include "mlx5_irq.h"
#include "devlink.h"
enum {
MLX5_EQE_OWNER_INIT_VAL = 0x1,
......@@ -646,7 +647,7 @@ static int create_async_eqs(struct mlx5_core_dev *dev)
param = (struct mlx5_eq_param) {
.irq_index = MLX5_IRQ_EQ_CTRL,
.nent = MLX5_NUM_ASYNC_EQE,
.nent = mlx5_devlink_res_size(dev, MLX5_DL_RES_ASYNC_EQ),
};
gather_async_events_mask(dev, param.mask);
......@@ -807,7 +808,7 @@ static int create_comp_eqs(struct mlx5_core_dev *dev)
INIT_LIST_HEAD(&table->comp_eqs_list);
ncomp_eqs = table->num_comp_eqs;
nent = MLX5_COMP_EQ_SIZE;
nent = mlx5_devlink_res_size(dev, MLX5_DL_RES_COMP_EQ);
for (i = 0; i < ncomp_eqs; i++) {
struct mlx5_eq_param param = {};
int vecidx = i;
......
......@@ -888,14 +888,20 @@ mlx5_esw_bridge_fdb_entry_cleanup(struct mlx5_esw_bridge_fdb_entry *entry,
kvfree(entry);
}
static void
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(struct mlx5_esw_bridge_fdb_entry *entry,
struct mlx5_esw_bridge *bridge)
{
mlx5_esw_bridge_fdb_del_notify(entry);
mlx5_esw_bridge_fdb_entry_cleanup(entry, bridge);
}
static void mlx5_esw_bridge_fdb_flush(struct mlx5_esw_bridge *bridge)
{
struct mlx5_esw_bridge_fdb_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) {
mlx5_esw_bridge_fdb_del_notify(entry);
mlx5_esw_bridge_fdb_entry_cleanup(entry, bridge);
}
list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list)
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge);
}
static struct mlx5_esw_bridge_vlan *
......@@ -1065,10 +1071,8 @@ static void mlx5_esw_bridge_vlan_flush(struct mlx5_esw_bridge_vlan *vlan,
struct mlx5_eswitch *esw = bridge->br_offloads->esw;
struct mlx5_esw_bridge_fdb_entry *entry, *tmp;
list_for_each_entry_safe(entry, tmp, &vlan->fdb_list, vlan_list) {
mlx5_esw_bridge_fdb_del_notify(entry);
mlx5_esw_bridge_fdb_entry_cleanup(entry, bridge);
}
list_for_each_entry_safe(entry, tmp, &vlan->fdb_list, vlan_list)
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge);
if (vlan->pkt_reformat_pop)
mlx5_esw_bridge_vlan_pop_cleanup(vlan, esw);
......@@ -1127,6 +1131,17 @@ mlx5_esw_bridge_port_vlan_lookup(u16 vid, u16 vport_num, u16 esw_owner_vhca_id,
return vlan;
}
static struct mlx5_esw_bridge_fdb_entry *
mlx5_esw_bridge_fdb_lookup(struct mlx5_esw_bridge *bridge,
const unsigned char *addr, u16 vid)
{
struct mlx5_esw_bridge_fdb_key key = {};
ether_addr_copy(key.addr, addr);
key.vid = vid;
return rhashtable_lookup_fast(&bridge->fdb_ht, &key, fdb_ht_params);
}
static struct mlx5_esw_bridge_fdb_entry *
mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_owner_vhca_id,
const unsigned char *addr, u16 vid, bool added_by_user, bool peer,
......@@ -1145,6 +1160,10 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow
return ERR_CAST(vlan);
}
entry = mlx5_esw_bridge_fdb_lookup(bridge, addr, vid);
if (entry)
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge);
entry = kvzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return ERR_PTR(-ENOMEM);
......@@ -1444,7 +1463,6 @@ void mlx5_esw_bridge_fdb_update_used(struct net_device *dev, u16 vport_num, u16
struct switchdev_notifier_fdb_info *fdb_info)
{
struct mlx5_esw_bridge_fdb_entry *entry;
struct mlx5_esw_bridge_fdb_key key;
struct mlx5_esw_bridge_port *port;
struct mlx5_esw_bridge *bridge;
......@@ -1453,13 +1471,11 @@ void mlx5_esw_bridge_fdb_update_used(struct net_device *dev, u16 vport_num, u16
return;
bridge = port->bridge;
ether_addr_copy(key.addr, fdb_info->addr);
key.vid = fdb_info->vid;
entry = rhashtable_lookup_fast(&bridge->fdb_ht, &key, fdb_ht_params);
entry = mlx5_esw_bridge_fdb_lookup(bridge, fdb_info->addr, fdb_info->vid);
if (!entry) {
esw_debug(br_offloads->esw->dev,
"FDB entry with specified key not found (MAC=%pM,vid=%u,vport=%u)\n",
key.addr, key.vid, vport_num);
fdb_info->addr, fdb_info->vid, vport_num);
return;
}
......@@ -1501,7 +1517,6 @@ void mlx5_esw_bridge_fdb_remove(struct net_device *dev, u16 vport_num, u16 esw_o
{
struct mlx5_eswitch *esw = br_offloads->esw;
struct mlx5_esw_bridge_fdb_entry *entry;
struct mlx5_esw_bridge_fdb_key key;
struct mlx5_esw_bridge_port *port;
struct mlx5_esw_bridge *bridge;
......@@ -1510,18 +1525,15 @@ void mlx5_esw_bridge_fdb_remove(struct net_device *dev, u16 vport_num, u16 esw_o
return;
bridge = port->bridge;
ether_addr_copy(key.addr, fdb_info->addr);
key.vid = fdb_info->vid;
entry = rhashtable_lookup_fast(&bridge->fdb_ht, &key, fdb_ht_params);
entry = mlx5_esw_bridge_fdb_lookup(bridge, fdb_info->addr, fdb_info->vid);
if (!entry) {
esw_warn(esw->dev,
"FDB entry with specified key not found (MAC=%pM,vid=%u,vport=%u)\n",
key.addr, key.vid, vport_num);
fdb_info->addr, fdb_info->vid, vport_num);
return;
}
mlx5_esw_bridge_fdb_del_notify(entry);
mlx5_esw_bridge_fdb_entry_cleanup(entry, bridge);
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge);
}
void mlx5_esw_bridge_update(struct mlx5_esw_bridge_offloads *br_offloads)
......@@ -1537,13 +1549,11 @@ void mlx5_esw_bridge_update(struct mlx5_esw_bridge_offloads *br_offloads)
if (entry->flags & MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER)
continue;
if (time_after(lastuse, entry->lastuse)) {
if (time_after(lastuse, entry->lastuse))
mlx5_esw_bridge_fdb_entry_refresh(entry);
} else if (!(entry->flags & MLX5_ESW_BRIDGE_FLAG_PEER) &&
time_is_before_jiffies(entry->lastuse + bridge->ageing_time)) {
mlx5_esw_bridge_fdb_del_notify(entry);
mlx5_esw_bridge_fdb_entry_cleanup(entry, bridge);
}
else if (!(entry->flags & MLX5_ESW_BRIDGE_FLAG_PEER) &&
time_is_before_jiffies(entry->lastuse + bridge->ageing_time))
mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge);
}
}
}
......
......@@ -40,6 +40,7 @@
#define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000)
/* Max number of counters to query in bulk read is 32K */
#define MLX5_SW_MAX_COUNTERS_BULK BIT(15)
#define MLX5_SF_NUM_COUNTERS_BULK 6
#define MLX5_FC_POOL_MAX_THRESHOLD BIT(18)
#define MLX5_FC_POOL_USED_BUFF_RATIO 10
......@@ -146,8 +147,12 @@ static void mlx5_fc_stats_remove(struct mlx5_core_dev *dev,
static int get_max_bulk_query_len(struct mlx5_core_dev *dev)
{
return min_t(int, MLX5_SW_MAX_COUNTERS_BULK,
(1 << MLX5_CAP_GEN(dev, log_max_flow_counter_bulk)));
int num_counters_bulk = mlx5_core_is_sf(dev) ?
MLX5_SF_NUM_COUNTERS_BULK :
MLX5_SW_MAX_COUNTERS_BULK;
return min_t(int, num_counters_bulk,
(1 << MLX5_CAP_GEN(dev, log_max_flow_counter_bulk)));
}
static void update_counter_cache(int index, u32 *bulk_raw_data,
......
......@@ -36,6 +36,7 @@
#include <linux/vmalloc.h>
#include <linux/hardirq.h>
#include <linux/mlx5/driver.h>
#include <linux/kern_levels.h>
#include "mlx5_core.h"
#include "lib/eq.h"
#include "lib/mlx5.h"
......@@ -74,6 +75,11 @@ enum {
MLX5_SENSOR_FW_SYND_RFR = 5,
};
enum {
MLX5_SEVERITY_MASK = 0x7,
MLX5_SEVERITY_VALID_MASK = 0x8,
};
u8 mlx5_get_nic_state(struct mlx5_core_dev *dev)
{
return (ioread32be(&dev->iseg->cmdq_addr_l_sz) >> 8) & 7;
......@@ -98,12 +104,19 @@ static bool sensor_pci_not_working(struct mlx5_core_dev *dev)
return (ioread32be(&h->fw_ver) == 0xffffffff);
}
static int mlx5_health_get_rfr(u8 rfr_severity)
{
return rfr_severity >> MLX5_RFR_BIT_OFFSET;
}
static bool sensor_fw_synd_rfr(struct mlx5_core_dev *dev)
{
struct mlx5_core_health *health = &dev->priv.health;
struct health_buffer __iomem *h = health->health;
u32 rfr = ioread32be(&h->rfr) >> MLX5_RFR_OFFSET;
u8 synd = ioread8(&h->synd);
u8 rfr;
rfr = mlx5_health_get_rfr(ioread8(&h->rfr_severity));
if (rfr && synd)
mlx5_core_dbg(dev, "FW requests reset, synd: %d\n", synd);
......@@ -366,35 +379,69 @@ static const char *hsynd_str(u8 synd)
}
}
static const char *mlx5_loglevel_str(int level)
{
switch (level) {
case LOGLEVEL_EMERG:
return "EMERGENCY";
case LOGLEVEL_ALERT:
return "ALERT";
case LOGLEVEL_CRIT:
return "CRITICAL";
case LOGLEVEL_ERR:
return "ERROR";
case LOGLEVEL_WARNING:
return "WARNING";
case LOGLEVEL_NOTICE:
return "NOTICE";
case LOGLEVEL_INFO:
return "INFO";
case LOGLEVEL_DEBUG:
return "DEBUG";
}
return "Unknown log level";
}
static int mlx5_health_get_severity(u8 rfr_severity)
{
return rfr_severity & MLX5_SEVERITY_VALID_MASK ?
rfr_severity & MLX5_SEVERITY_MASK : LOGLEVEL_ERR;
}
static void print_health_info(struct mlx5_core_dev *dev)
{
struct mlx5_core_health *health = &dev->priv.health;
struct health_buffer __iomem *h = health->health;
char fw_str[18];
u32 fw;
u8 rfr_severity;
int severity;
int i;
/* If the syndrome is 0, the device is OK and no need to print buffer */
if (!ioread8(&h->synd))
return;
rfr_severity = ioread8(&h->rfr_severity);
severity = mlx5_health_get_severity(rfr_severity);
mlx5_log(dev, severity, "Health issue observed, %s, severity(%d) %s:\n",
hsynd_str(ioread8(&h->synd)), severity, mlx5_loglevel_str(severity));
for (i = 0; i < ARRAY_SIZE(h->assert_var); i++)
mlx5_core_err(dev, "assert_var[%d] 0x%08x\n", i,
ioread32be(h->assert_var + i));
mlx5_core_err(dev, "assert_exit_ptr 0x%08x\n",
ioread32be(&h->assert_exit_ptr));
mlx5_core_err(dev, "assert_callra 0x%08x\n",
ioread32be(&h->assert_callra));
sprintf(fw_str, "%d.%d.%d", fw_rev_maj(dev), fw_rev_min(dev), fw_rev_sub(dev));
mlx5_core_err(dev, "fw_ver %s\n", fw_str);
mlx5_core_err(dev, "hw_id 0x%08x\n", ioread32be(&h->hw_id));
mlx5_core_err(dev, "irisc_index %d\n", ioread8(&h->irisc_index));
mlx5_core_err(dev, "synd 0x%x: %s\n", ioread8(&h->synd),
hsynd_str(ioread8(&h->synd)));
mlx5_core_err(dev, "ext_synd 0x%04x\n", ioread16be(&h->ext_synd));
fw = ioread32be(&h->fw_ver);
mlx5_core_err(dev, "raw fw_ver 0x%08x\n", fw);
mlx5_log(dev, severity, "assert_var[%d] 0x%08x\n", i,
ioread32be(h->assert_var + i));
mlx5_log(dev, severity, "assert_exit_ptr 0x%08x\n", ioread32be(&h->assert_exit_ptr));
mlx5_log(dev, severity, "assert_callra 0x%08x\n", ioread32be(&h->assert_callra));
mlx5_log(dev, severity, "fw_ver %d.%d.%d", fw_rev_maj(dev), fw_rev_min(dev),
fw_rev_sub(dev));
mlx5_log(dev, severity, "time %u\n", ioread32be(&h->time));
mlx5_log(dev, severity, "hw_id 0x%08x\n", ioread32be(&h->hw_id));
mlx5_log(dev, severity, "rfr %d\n", mlx5_health_get_rfr(rfr_severity));
mlx5_log(dev, severity, "severity %d (%s)\n", severity, mlx5_loglevel_str(severity));
mlx5_log(dev, severity, "irisc_index %d\n", ioread8(&h->irisc_index));
mlx5_log(dev, severity, "synd 0x%x: %s\n", ioread8(&h->synd),
hsynd_str(ioread8(&h->synd)));
mlx5_log(dev, severity, "ext_synd 0x%04x\n", ioread16be(&h->ext_synd));
mlx5_log(dev, severity, "raw fw_ver 0x%08x\n", ioread32be(&h->fw_ver));
}
static int
......@@ -443,6 +490,7 @@ mlx5_fw_reporter_heath_buffer_data_put(struct mlx5_core_dev *dev,
{
struct mlx5_core_health *health = &dev->priv.health;
struct health_buffer __iomem *h = health->health;
u8 rfr_severity;
int err;
int i;
......@@ -473,9 +521,19 @@ mlx5_fw_reporter_heath_buffer_data_put(struct mlx5_core_dev *dev,
return err;
err = devlink_fmsg_u32_pair_put(fmsg, "assert_callra",
ioread32be(&h->assert_callra));
if (err)
return err;
err = devlink_fmsg_u32_pair_put(fmsg, "time", ioread32be(&h->time));
if (err)
return err;
err = devlink_fmsg_u32_pair_put(fmsg, "hw_id", ioread32be(&h->hw_id));
if (err)
return err;
rfr_severity = ioread8(&h->rfr_severity);
err = devlink_fmsg_u8_pair_put(fmsg, "rfr", mlx5_health_get_rfr(rfr_severity));
if (err)
return err;
err = devlink_fmsg_u8_pair_put(fmsg, "severity", mlx5_health_get_severity(rfr_severity));
if (err)
return err;
err = devlink_fmsg_u8_pair_put(fmsg, "irisc_index",
......@@ -694,6 +752,31 @@ void mlx5_trigger_health_work(struct mlx5_core_dev *dev)
spin_unlock_irqrestore(&health->wq_lock, flags);
}
#define MLX5_MSEC_PER_HOUR (MSEC_PER_SEC * 60 * 60)
static void mlx5_health_log_ts_update(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
u32 out[MLX5_ST_SZ_DW(mrtc_reg)] = {};
u32 in[MLX5_ST_SZ_DW(mrtc_reg)] = {};
struct mlx5_core_health *health;
struct mlx5_core_dev *dev;
struct mlx5_priv *priv;
u64 now_us;
health = container_of(dwork, struct mlx5_core_health, update_fw_log_ts_work);
priv = container_of(health, struct mlx5_priv, health);
dev = container_of(priv, struct mlx5_core_dev, priv);
now_us = ktime_to_us(ktime_get_real());
MLX5_SET(mrtc_reg, in, time_h, now_us >> 32);
MLX5_SET(mrtc_reg, in, time_l, now_us & 0xFFFFFFFF);
mlx5_core_access_reg(dev, in, sizeof(in), out, sizeof(out), MLX5_REG_MRTC, 0, 1);
queue_delayed_work(health->wq, &health->update_fw_log_ts_work,
msecs_to_jiffies(MLX5_MSEC_PER_HOUR));
}
static void poll_health(struct timer_list *t)
{
struct mlx5_core_dev *dev = from_timer(dev, t, priv.health.timer);
......@@ -776,6 +859,7 @@ void mlx5_drain_health_wq(struct mlx5_core_dev *dev)
spin_lock_irqsave(&health->wq_lock, flags);
set_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags);
spin_unlock_irqrestore(&health->wq_lock, flags);
cancel_delayed_work_sync(&health->update_fw_log_ts_work);
cancel_work_sync(&health->report_work);
cancel_work_sync(&health->fatal_report_work);
}
......@@ -791,6 +875,7 @@ void mlx5_health_cleanup(struct mlx5_core_dev *dev)
{
struct mlx5_core_health *health = &dev->priv.health;
cancel_delayed_work_sync(&health->update_fw_log_ts_work);
destroy_workqueue(health->wq);
mlx5_fw_reporters_destroy(dev);
}
......@@ -816,6 +901,9 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
spin_lock_init(&health->wq_lock);
INIT_WORK(&health->fatal_report_work, mlx5_fw_fatal_reporter_err_work);
INIT_WORK(&health->report_work, mlx5_fw_reporter_err_work);
INIT_DELAYED_WORK(&health->update_fw_log_ts_work, mlx5_health_log_ts_update);
if (mlx5_core_is_pf(dev))
queue_delayed_work(health->wq, &health->update_fw_log_ts_work, 0);
return 0;
......
......@@ -33,11 +33,6 @@
#include "en.h"
#include "ipoib.h"
static u32 mlx5i_flow_type_mask(u32 flow_type)
{
return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
}
static void mlx5i_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
......@@ -223,6 +218,11 @@ static int mlx5i_get_link_ksettings(struct net_device *netdev,
}
#ifdef CONFIG_MLX5_EN_RXNFC
static u32 mlx5i_flow_type_mask(u32 flow_type)
{
return flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS);
}
static int mlx5i_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
{
struct mlx5e_priv *priv = mlx5i_epriv(dev);
......
......@@ -484,10 +484,23 @@ static int handle_hca_cap_odp(struct mlx5_core_dev *dev, void *set_ctx)
return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ODP);
}
static int max_uc_list_get_devlink_param(struct mlx5_core_dev *dev)
{
struct devlink *devlink = priv_to_devlink(dev);
union devlink_param_value val;
int err;
err = devlink_param_driverinit_value_get(devlink,
DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
&val);
return err ? 0 : val.vu32;
}
static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
{
struct mlx5_profile *prof = &dev->profile;
void *set_hca_cap;
u32 max_uc_list;
int err;
err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL);
......@@ -561,6 +574,11 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
if (MLX5_CAP_GEN(dev, roce_rw_supported))
MLX5_SET(cmd_hca_cap, set_hca_cap, roce, mlx5_is_roce_init_enabled(dev));
max_uc_list = max_uc_list_get_devlink_param(dev);
if (max_uc_list)
MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_current_uc_list,
ilog2(max_uc_list));
return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
}
......@@ -922,6 +940,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
dev->hv_vhca = mlx5_hv_vhca_create(dev);
dev->rsc_dump = mlx5_rsc_dump_create(dev);
mlx5_devlink_res_register(dev);
return 0;
err_sf_table_cleanup:
......@@ -957,6 +977,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
{
mlx5_devlink_res_unregister(dev);
mlx5_rsc_dump_destroy(dev);
mlx5_hv_vhca_destroy(dev->hv_vhca);
mlx5_fw_tracer_destroy(dev->tracer);
......
......@@ -97,6 +97,30 @@ do { \
__func__, __LINE__, current->pid, \
##__VA_ARGS__)
static inline void mlx5_printk(struct mlx5_core_dev *dev, int level, const char *format, ...)
{
struct device *device = dev->device;
struct va_format vaf;
va_list args;
if (WARN_ONCE(level < LOGLEVEL_EMERG || level > LOGLEVEL_DEBUG,
"Level %d is out of range, set to default level\n", level))
level = LOGLEVEL_DEFAULT;
va_start(args, format);
vaf.fmt = format;
vaf.va = &args;
dev_printk_emit(level, device, "%s %s: %pV", dev_driver_string(device), dev_name(device),
&vaf);
va_end(args);
}
#define mlx5_log(__dev, level, format, ...) \
mlx5_printk(__dev, level, "%s:%d:(pid %d): " format, \
__func__, __LINE__, current->pid, \
##__VA_ARGS__)
static inline struct device *mlx5_core_dma_dev(struct mlx5_core_dev *dev)
{
return &dev->pdev->dev;
......
......@@ -9,6 +9,8 @@
#include "sf/sf.h"
#include "sf/mlx5_ifc_vhca_event.h"
#include "ecpf.h"
#define CREATE_TRACE_POINTS
#include "diag/dev_tracepoint.h"
struct mlx5_sf_dev_table {
struct xarray devices;
......@@ -66,13 +68,18 @@ static void mlx5_sf_dev_release(struct device *device)
kfree(sf_dev);
}
static void mlx5_sf_dev_remove(struct mlx5_sf_dev *sf_dev)
static void mlx5_sf_dev_remove(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_dev)
{
int id;
id = sf_dev->adev.id;
trace_mlx5_sf_dev_del(dev, sf_dev, id);
auxiliary_device_delete(&sf_dev->adev);
auxiliary_device_uninit(&sf_dev->adev);
}
static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u32 sfnum)
static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u16 fn_id, u32 sfnum)
{
struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;
struct mlx5_sf_dev *sf_dev;
......@@ -100,6 +107,7 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u32 sfnum)
sf_dev->adev.dev.groups = sf_attr_groups;
sf_dev->sfnum = sfnum;
sf_dev->parent_mdev = dev;
sf_dev->fn_id = fn_id;
if (!table->max_sfs) {
mlx5_adev_idx_free(id);
......@@ -109,6 +117,8 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u32 sfnum)
}
sf_dev->bar_base_addr = table->base_address + (sf_index * table->sf_bar_length);
trace_mlx5_sf_dev_add(dev, sf_dev, id);
err = auxiliary_device_init(&sf_dev->adev);
if (err) {
mlx5_adev_idx_free(id);
......@@ -128,7 +138,7 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u32 sfnum)
return;
xa_err:
mlx5_sf_dev_remove(sf_dev);
mlx5_sf_dev_remove(dev, sf_dev);
add_err:
mlx5_core_err(dev, "SF DEV: fail device add for index=%d sfnum=%d err=%d\n",
sf_index, sfnum, err);
......@@ -139,7 +149,7 @@ static void mlx5_sf_dev_del(struct mlx5_core_dev *dev, struct mlx5_sf_dev *sf_de
struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;
xa_erase(&table->devices, sf_index);
mlx5_sf_dev_remove(sf_dev);
mlx5_sf_dev_remove(dev, sf_dev);
}
static int
......@@ -178,7 +188,8 @@ mlx5_sf_dev_state_change_handler(struct notifier_block *nb, unsigned long event_
break;
case MLX5_VHCA_STATE_ACTIVE:
if (!sf_dev)
mlx5_sf_dev_add(table->dev, sf_index, event->sw_function_id);
mlx5_sf_dev_add(table->dev, sf_index, event->function_id,
event->sw_function_id);
break;
default:
break;
......@@ -260,7 +271,7 @@ static void mlx5_sf_dev_destroy_all(struct mlx5_sf_dev_table *table)
xa_for_each(&table->devices, index, sf_dev) {
xa_erase(&table->devices, index);
mlx5_sf_dev_remove(sf_dev);
mlx5_sf_dev_remove(table->dev, sf_dev);
}
}
......
......@@ -16,6 +16,7 @@ struct mlx5_sf_dev {
struct mlx5_core_dev *mdev;
phys_addr_t bar_base_addr;
u32 sfnum;
u16 fn_id;
};
void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev);
......
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mlx5
#if !defined(_MLX5_SF_DEV_TP_) || defined(TRACE_HEADER_MULTI_READ)
#define _MLX5_SF_DEV_TP_
#include <linux/tracepoint.h>
#include <linux/mlx5/driver.h>
#include "../../dev/dev.h"
DECLARE_EVENT_CLASS(mlx5_sf_dev_template,
TP_PROTO(const struct mlx5_core_dev *dev,
const struct mlx5_sf_dev *sfdev,
int aux_id),
TP_ARGS(dev, sfdev, aux_id),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(const struct mlx5_sf_dev*, sfdev)
__field(int, aux_id)
__field(u16, hw_fn_id)
__field(u32, sfnum)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->sfdev = sfdev;
__entry->aux_id = aux_id;
__entry->hw_fn_id = sfdev->fn_id;
__entry->sfnum = sfdev->sfnum;
),
TP_printk("(%s) sfdev=%pK aux_id=%d hw_id=0x%x sfnum=%u\n",
__get_str(devname), __entry->sfdev,
__entry->aux_id, __entry->hw_fn_id,
__entry->sfnum)
);
DEFINE_EVENT(mlx5_sf_dev_template, mlx5_sf_dev_add,
TP_PROTO(const struct mlx5_core_dev *dev,
const struct mlx5_sf_dev *sfdev,
int aux_id),
TP_ARGS(dev, sfdev, aux_id)
);
DEFINE_EVENT(mlx5_sf_dev_template, mlx5_sf_dev_del,
TP_PROTO(const struct mlx5_core_dev *dev,
const struct mlx5_sf_dev *sfdev,
int aux_id),
TP_ARGS(dev, sfdev, aux_id)
);
#endif /* _MLX5_SF_DEV_TP_ */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH sf/dev/diag
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE dev_tracepoint
#include <trace/define_trace.h>
......@@ -8,6 +8,8 @@
#include "mlx5_ifc_vhca_event.h"
#include "vhca_event.h"
#include "ecpf.h"
#define CREATE_TRACE_POINTS
#include "diag/sf_tracepoint.h"
struct mlx5_sf {
struct devlink_port dl_port;
......@@ -112,6 +114,7 @@ static void mlx5_sf_free(struct mlx5_sf_table *table, struct mlx5_sf *sf)
{
mlx5_sf_id_erase(table, sf);
mlx5_sf_hw_table_sf_free(table->dev, sf->controller, sf->id);
trace_mlx5_sf_free(table->dev, sf->port_index, sf->controller, sf->hw_fn_id);
kfree(sf);
}
......@@ -209,6 +212,7 @@ static int mlx5_sf_activate(struct mlx5_core_dev *dev, struct mlx5_sf *sf,
return err;
sf->hw_state = MLX5_VHCA_STATE_ACTIVE;
trace_mlx5_sf_activate(dev, sf->port_index, sf->controller, sf->hw_fn_id);
return 0;
}
......@@ -224,6 +228,7 @@ static int mlx5_sf_deactivate(struct mlx5_core_dev *dev, struct mlx5_sf *sf)
return err;
sf->hw_state = MLX5_VHCA_STATE_TEARDOWN_REQUEST;
trace_mlx5_sf_deactivate(dev, sf->port_index, sf->controller, sf->hw_fn_id);
return 0;
}
......@@ -293,6 +298,7 @@ static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
if (err)
goto esw_err;
*new_port_index = sf->port_index;
trace_mlx5_sf_add(dev, sf->port_index, sf->controller, sf->hw_fn_id, new_attr->sfnum);
return 0;
esw_err:
......@@ -442,6 +448,8 @@ static int mlx5_sf_vhca_event(struct notifier_block *nb, unsigned long opcode, v
update = mlx5_sf_state_update_check(sf, event->new_vhca_state);
if (update)
sf->hw_state = event->new_vhca_state;
trace_mlx5_sf_update_state(table->dev, sf->port_index, sf->controller,
sf->hw_fn_id, sf->hw_state);
sf_err:
mutex_unlock(&table->sf_state_lock);
mlx5_sf_table_put(table);
......
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mlx5
#if !defined(_MLX5_SF_TP_) || defined(TRACE_HEADER_MULTI_READ)
#define _MLX5_SF_TP_
#include <linux/tracepoint.h>
#include <linux/mlx5/driver.h>
#include "sf/vhca_event.h"
TRACE_EVENT(mlx5_sf_add,
TP_PROTO(const struct mlx5_core_dev *dev,
unsigned int port_index,
u32 controller,
u16 hw_fn_id,
u32 sfnum),
TP_ARGS(dev, port_index, controller, hw_fn_id, sfnum),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(unsigned int, port_index)
__field(u32, controller)
__field(u16, hw_fn_id)
__field(u32, sfnum)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->port_index = port_index;
__entry->controller = controller;
__entry->hw_fn_id = hw_fn_id;
__entry->sfnum = sfnum;
),
TP_printk("(%s) port_index=%u controller=%u hw_id=0x%x sfnum=%u\n",
__get_str(devname), __entry->port_index, __entry->controller,
__entry->hw_fn_id, __entry->sfnum)
);
TRACE_EVENT(mlx5_sf_free,
TP_PROTO(const struct mlx5_core_dev *dev,
unsigned int port_index,
u32 controller,
u16 hw_fn_id),
TP_ARGS(dev, port_index, controller, hw_fn_id),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(unsigned int, port_index)
__field(u32, controller)
__field(u16, hw_fn_id)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->port_index = port_index;
__entry->controller = controller;
__entry->hw_fn_id = hw_fn_id;
),
TP_printk("(%s) port_index=%u controller=%u hw_id=0x%x\n",
__get_str(devname), __entry->port_index, __entry->controller,
__entry->hw_fn_id)
);
TRACE_EVENT(mlx5_sf_hwc_alloc,
TP_PROTO(const struct mlx5_core_dev *dev,
u32 controller,
u16 hw_fn_id,
u32 sfnum),
TP_ARGS(dev, controller, hw_fn_id, sfnum),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(u32, controller)
__field(u16, hw_fn_id)
__field(u32, sfnum)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->controller = controller;
__entry->hw_fn_id = hw_fn_id;
__entry->sfnum = sfnum;
),
TP_printk("(%s) controller=%u hw_id=0x%x sfnum=%u\n",
__get_str(devname), __entry->controller, __entry->hw_fn_id,
__entry->sfnum)
);
TRACE_EVENT(mlx5_sf_hwc_free,
TP_PROTO(const struct mlx5_core_dev *dev,
u16 hw_fn_id),
TP_ARGS(dev, hw_fn_id),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(u16, hw_fn_id)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->hw_fn_id = hw_fn_id;
),
TP_printk("(%s) hw_id=0x%x\n", __get_str(devname), __entry->hw_fn_id)
);
TRACE_EVENT(mlx5_sf_hwc_deferred_free,
TP_PROTO(const struct mlx5_core_dev *dev,
u16 hw_fn_id),
TP_ARGS(dev, hw_fn_id),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(u16, hw_fn_id)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->hw_fn_id = hw_fn_id;
),
TP_printk("(%s) hw_id=0x%x\n", __get_str(devname), __entry->hw_fn_id)
);
DECLARE_EVENT_CLASS(mlx5_sf_state_template,
TP_PROTO(const struct mlx5_core_dev *dev,
u32 port_index,
u32 controller,
u16 hw_fn_id),
TP_ARGS(dev, port_index, controller, hw_fn_id),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(unsigned int, port_index)
__field(u32, controller)
__field(u16, hw_fn_id)),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->port_index = port_index;
__entry->controller = controller;
__entry->hw_fn_id = hw_fn_id;
),
TP_printk("(%s) port_index=%u controller=%u hw_id=0x%x\n",
__get_str(devname), __entry->port_index, __entry->controller,
__entry->hw_fn_id)
);
DEFINE_EVENT(mlx5_sf_state_template, mlx5_sf_activate,
TP_PROTO(const struct mlx5_core_dev *dev,
u32 port_index,
u32 controller,
u16 hw_fn_id),
TP_ARGS(dev, port_index, controller, hw_fn_id)
);
DEFINE_EVENT(mlx5_sf_state_template, mlx5_sf_deactivate,
TP_PROTO(const struct mlx5_core_dev *dev,
u32 port_index,
u32 controller,
u16 hw_fn_id),
TP_ARGS(dev, port_index, controller, hw_fn_id)
);
TRACE_EVENT(mlx5_sf_update_state,
TP_PROTO(const struct mlx5_core_dev *dev,
unsigned int port_index,
u32 controller,
u16 hw_fn_id,
u8 state),
TP_ARGS(dev, port_index, controller, hw_fn_id, state),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(unsigned int, port_index)
__field(u32, controller)
__field(u16, hw_fn_id)
__field(u8, state)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->port_index = port_index;
__entry->controller = controller;
__entry->hw_fn_id = hw_fn_id;
__entry->state = state;
),
TP_printk("(%s) port_index=%u controller=%u hw_id=0x%x state=%u\n",
__get_str(devname), __entry->port_index, __entry->controller,
__entry->hw_fn_id, __entry->state)
);
#endif /* _MLX5_SF_TP_ */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH sf/diag
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE sf_tracepoint
#include <trace/define_trace.h>
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mlx5
#if !defined(_MLX5_SF_VHCA_TP_) || defined(TRACE_HEADER_MULTI_READ)
#define _MLX5_SF_VHCA_TP_
#include <linux/tracepoint.h>
#include <linux/mlx5/driver.h>
#include "sf/vhca_event.h"
TRACE_EVENT(mlx5_sf_vhca_event,
TP_PROTO(const struct mlx5_core_dev *dev,
const struct mlx5_vhca_state_event *event),
TP_ARGS(dev, event),
TP_STRUCT__entry(__string(devname, dev_name(dev->device))
__field(u16, hw_fn_id)
__field(u32, sfnum)
__field(u8, vhca_state)
),
TP_fast_assign(__assign_str(devname, dev_name(dev->device));
__entry->hw_fn_id = event->function_id;
__entry->sfnum = event->sw_function_id;
__entry->vhca_state = event->new_vhca_state;
),
TP_printk("(%s) hw_id=0x%x sfnum=%u vhca_state=%d\n",
__get_str(devname), __entry->hw_fn_id,
__entry->sfnum, __entry->vhca_state)
);
#endif /* _MLX5_SF_VHCA_TP_ */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH sf/diag
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_FILE vhca_tracepoint
#include <trace/define_trace.h>
......@@ -8,6 +8,7 @@
#include "ecpf.h"
#include "mlx5_core.h"
#include "eswitch.h"
#include "diag/sf_tracepoint.h"
struct mlx5_sf_hw {
u32 usr_sfnum;
......@@ -142,6 +143,7 @@ int mlx5_sf_hw_table_sf_alloc(struct mlx5_core_dev *dev, u32 controller, u32 usr
goto vhca_err;
}
trace_mlx5_sf_hwc_alloc(dev, controller, hw_fn_id, usr_sfnum);
mutex_unlock(&table->table_lock);
return sw_id;
......@@ -172,6 +174,7 @@ static void mlx5_sf_hw_table_hwc_sf_free(struct mlx5_core_dev *dev,
mlx5_cmd_dealloc_sf(dev, hwc->start_fn_id + idx);
hwc->sfs[idx].allocated = false;
hwc->sfs[idx].pending_delete = false;
trace_mlx5_sf_hwc_free(dev, hwc->start_fn_id + idx);
}
void mlx5_sf_hw_table_sf_deferred_free(struct mlx5_core_dev *dev, u32 controller, u16 id)
......@@ -195,6 +198,7 @@ void mlx5_sf_hw_table_sf_deferred_free(struct mlx5_core_dev *dev, u32 controller
hwc->sfs[id].allocated = false;
} else {
hwc->sfs[id].pending_delete = true;
trace_mlx5_sf_hwc_deferred_free(dev, hw_fn_id);
}
err:
mutex_unlock(&table->table_lock);
......
......@@ -6,6 +6,8 @@
#include "mlx5_core.h"
#include "vhca_event.h"
#include "ecpf.h"
#define CREATE_TRACE_POINTS
#include "diag/vhca_tracepoint.h"
struct mlx5_vhca_state_notifier {
struct mlx5_core_dev *dev;
......@@ -82,6 +84,7 @@ mlx5_vhca_event_notify(struct mlx5_core_dev *dev, struct mlx5_vhca_state_event *
vhca_state_context.vhca_state);
mlx5_vhca_event_arm(dev, event->function_id);
trace_mlx5_sf_vhca_event(dev, event);
blocking_notifier_call_chain(&dev->priv.vhca_state_notifier->n_head, 0, event);
}
......
......@@ -541,19 +541,21 @@ struct mlx5_cmd_layout {
u8 status_own;
};
enum mlx5_fatal_assert_bit_offsets {
MLX5_RFR_OFFSET = 31,
enum mlx5_rfr_severity_bit_offsets {
MLX5_RFR_BIT_OFFSET = 0x7,
};
struct health_buffer {
__be32 assert_var[5];
__be32 rsvd0[3];
__be32 assert_var[6];
__be32 rsvd0[2];
__be32 assert_exit_ptr;
__be32 assert_callra;
__be32 rsvd1[2];
__be32 rsvd1[1];
__be32 time;
__be32 fw_ver;
__be32 hw_id;
__be32 rfr;
u8 rfr_severity;
u8 rsvd2[3];
u8 irisc_index;
u8 synd;
__be16 ext_synd;
......
......@@ -134,6 +134,7 @@ enum {
MLX5_REG_MCIA = 0x9014,
MLX5_REG_MFRL = 0x9028,
MLX5_REG_MLCR = 0x902b,
MLX5_REG_MRTC = 0x902d,
MLX5_REG_MTRC_CAP = 0x9040,
MLX5_REG_MTRC_CONF = 0x9041,
MLX5_REG_MTRC_STDB = 0x9042,
......@@ -440,6 +441,7 @@ struct mlx5_core_health {
struct work_struct report_work;
struct devlink_health_reporter *fw_reporter;
struct devlink_health_reporter *fw_fatal_reporter;
struct delayed_work update_fw_log_ts_work;
};
struct mlx5_qp_table {
......@@ -795,10 +797,6 @@ struct mlx5_db {
int index;
};
enum {
MLX5_COMP_EQ_SIZE = 1024,
};
enum {
MLX5_PTYS_IB = 1 << 0,
MLX5_PTYS_EN = 1 << 2,
......
......@@ -5,7 +5,6 @@
#define MLX5_CORE_EQ_H
#define MLX5_NUM_CMD_EQE (32)
#define MLX5_NUM_ASYNC_EQE (0x1000)
#define MLX5_NUM_SPARE_EQE (0x80)
struct mlx5_eq;
......
......@@ -1603,7 +1603,7 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 ext_stride_num_range[0x1];
u8 roce_rw_supported[0x1];
u8 reserved_at_3a2[0x1];
u8 log_max_current_uc_list_wr_supported[0x1];
u8 log_max_stride_sz_rq[0x5];
u8 reserved_at_3a8[0x3];
u8 log_min_stride_sz_rq[0x5];
......@@ -4149,13 +4149,19 @@ struct mlx5_ifc_health_buffer_bits {
u8 assert_callra[0x20];
u8 reserved_at_140[0x40];
u8 reserved_at_140[0x20];
u8 time[0x20];
u8 fw_version[0x20];
u8 hw_id[0x20];
u8 reserved_at_1c0[0x20];
u8 rfr[0x1];
u8 reserved_at_1c1[0x3];
u8 valid[0x1];
u8 severity[0x3];
u8 reserved_at_1c8[0x18];
u8 irisc_index[0x8];
u8 synd[0x8];
......@@ -10352,6 +10358,17 @@ struct mlx5_ifc_pddr_reg_bits {
union mlx5_ifc_pddr_reg_page_data_auto_bits page_data;
};
struct mlx5_ifc_mrtc_reg_bits {
u8 time_synced[0x1];
u8 reserved_at_1[0x1f];
u8 reserved_at_20[0x20];
u8 time_h[0x20];
u8 time_l[0x20];
};
union mlx5_ifc_ports_control_registers_document_bits {
struct mlx5_ifc_bufferx_reg_bits bufferx_reg;
struct mlx5_ifc_eth_2819_cntrs_grp_data_layout_bits eth_2819_cntrs_grp_data_layout;
......@@ -10413,6 +10430,7 @@ union mlx5_ifc_ports_control_registers_document_bits {
struct mlx5_ifc_mirc_reg_bits mirc_reg;
struct mlx5_ifc_mfrl_reg_bits mfrl_reg;
struct mlx5_ifc_mtutc_reg_bits mtutc_reg;
struct mlx5_ifc_mrtc_reg_bits mrtc_reg;
u8 reserved_at_0[0x60e0];
};
......
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