2013-07-07 14:25:49 +00:00
|
|
|
/*
|
2015-04-02 14:07:29 +00:00
|
|
|
* Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.
|
2013-07-07 14:25:49 +00:00
|
|
|
*
|
|
|
|
* This software is available to you under a choice of one of two
|
|
|
|
* licenses. You may choose to be licensed under the terms of the GNU
|
|
|
|
* General Public License (GPL) Version 2, available from the file
|
|
|
|
* COPYING in the main directory of this source tree, or the
|
|
|
|
* OpenIB.org BSD license below:
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or
|
|
|
|
* without modification, are permitted provided that the following
|
|
|
|
* conditions are met:
|
|
|
|
*
|
|
|
|
* - Redistributions of source code must retain the above
|
|
|
|
* copyright notice, this list of conditions and the following
|
|
|
|
* disclaimer.
|
|
|
|
*
|
|
|
|
* - Redistributions in binary form must reproduce the above
|
|
|
|
* copyright notice, this list of conditions and the following
|
|
|
|
* disclaimer in the documentation and/or other materials
|
|
|
|
* provided with the distribution.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2015-08-28 07:27:19 +00:00
|
|
|
#include <linux/highmem.h>
|
2013-07-07 14:25:49 +00:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/pci.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
#include <linux/slab.h>
|
2015-05-28 19:28:39 +00:00
|
|
|
#include <linux/interrupt.h>
|
2015-10-14 14:43:47 +00:00
|
|
|
#include <linux/delay.h>
|
2013-07-07 14:25:49 +00:00
|
|
|
#include <linux/mlx5/driver.h>
|
|
|
|
#include <linux/mlx5/cq.h>
|
|
|
|
#include <linux/mlx5/qp.h>
|
|
|
|
#include <linux/debugfs.h>
|
2014-12-02 10:26:11 +00:00
|
|
|
#include <linux/kmod.h>
|
2014-10-02 09:19:44 +00:00
|
|
|
#include <linux/mlx5/mlx5_ifc.h>
|
2017-05-30 06:42:54 +00:00
|
|
|
#include <linux/mlx5/vport.h>
|
2020-10-15 11:52:00 +00:00
|
|
|
#include <linux/version.h>
|
2016-07-01 11:51:02 +00:00
|
|
|
#include <net/devlink.h>
|
2013-07-07 14:25:49 +00:00
|
|
|
#include "mlx5_core.h"
|
2018-11-19 18:52:38 +00:00
|
|
|
#include "lib/eq.h"
|
2018-11-19 18:52:39 +00:00
|
|
|
#include "fs_core.h"
|
2017-06-04 20:11:55 +00:00
|
|
|
#include "lib/mpfs.h"
|
2015-12-01 16:03:18 +00:00
|
|
|
#include "eswitch.h"
|
2018-12-11 14:09:51 +00:00
|
|
|
#include "devlink.h"
|
2020-10-07 06:00:49 +00:00
|
|
|
#include "fw_reset.h"
|
2017-03-26 14:01:57 +00:00
|
|
|
#include "lib/mlx5.h"
|
2021-10-07 15:00:27 +00:00
|
|
|
#include "lib/tout.h"
|
2017-03-13 18:05:45 +00:00
|
|
|
#include "fpga/core.h"
|
2022-03-09 08:35:05 +00:00
|
|
|
#include "en_accel/ipsec.h"
|
2017-08-15 10:46:04 +00:00
|
|
|
#include "lib/clock.h"
|
2018-05-09 20:28:00 +00:00
|
|
|
#include "lib/vxlan.h"
|
2019-01-30 15:21:55 +00:00
|
|
|
#include "lib/geneve.h"
|
2018-12-04 19:24:46 +00:00
|
|
|
#include "lib/devcom.h"
|
2018-06-28 12:05:58 +00:00
|
|
|
#include "lib/pci_vsc.h"
|
2018-02-22 08:01:35 +00:00
|
|
|
#include "diag/fw_tracer.h"
|
2019-02-13 06:55:35 +00:00
|
|
|
#include "ecpf.h"
|
2019-08-22 05:05:51 +00:00
|
|
|
#include "lib/hv_vhca.h"
|
2020-02-11 22:32:43 +00:00
|
|
|
#include "diag/rsc_dump.h"
|
2020-12-12 06:12:16 +00:00
|
|
|
#include "sf/vhca_event.h"
|
2020-12-12 06:12:17 +00:00
|
|
|
#include "sf/dev/dev.h"
|
net/mlx5: SF, Port function state change support
Support changing the state of the SF port's function through devlink.
When activating the SF port's function, enable the hca in the device
followed by adding its auxiliary device.
When deactivating the SF port's function, delete its auxiliary device
followed by disabling the vHCA.
Port function attributes get/set callbacks are invoked with devlink
instance lock held. Such callbacks need to synchronize with sf port
table getting disabled either via sriov sysfs callback. Such callbacks
synchronize with table disable context holding table refcount.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:88:88 state inactive opstate detached
$ devlink port function set pci/0000:06:00.0/32768 hw_addr 00:00:00:00:88:88 state active
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:88:88",
"state": "active",
"opstate": "attached"
}
}
}
}
On port function activation, an auxiliary device is created in below
example.
$ devlink dev show
devlink dev show auxiliary/mlx5_core.sf.4
$ devlink port show auxiliary/mlx5_core.sf.4/1
auxiliary/mlx5_core.sf.4/1: type eth netdev p0sf88 flavour virtual port 0 splittable false
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:22 +00:00
|
|
|
#include "sf/sf.h"
|
2021-04-06 18:42:17 +00:00
|
|
|
#include "mlx5_irq.h"
|
net/mlx5: Expose NIC temperature via hardware monitoring kernel API
Expose NIC temperature by implementing hwmon kernel API, which turns
current thermal zone kernel API to redundant.
For each one of the supported and exposed thermal diode sensors, expose
the following attributes:
1) Input temperature.
2) Highest temperature.
3) Temperature label:
Depends on the firmware capability, if firmware doesn't support
sensors naming, the fallback naming convention would be: "sensorX",
where X is the HW spec (MTMP register) sensor index.
4) Temperature critical max value:
refers to the high threshold of Warning Event. Will be exposed as
`tempY_crit` hwmon attribute (RO attribute). For example for
ConnectX5 HCA's this temperature value will be 105 Celsius, 10
degrees lower than the HW shutdown temperature).
5) Temperature reset history: resets highest temperature.
For example, for dualport ConnectX5 NIC with a single IC thermal diode
sensor will have 2 hwmon directories (one for each PCI function)
under "/sys/class/hwmon/hwmon[X,Y]".
Listing one of the directories above (hwmonX/Y) generates the
corresponding output below:
$ grep -H -d skip . /sys/class/hwmon/hwmon0/*
Output
=======================================================================
/sys/class/hwmon/hwmon0/name:mlx5
/sys/class/hwmon/hwmon0/temp1_crit:105000
/sys/class/hwmon/hwmon0/temp1_highest:48000
/sys/class/hwmon/hwmon0/temp1_input:46000
/sys/class/hwmon/hwmon0/temp1_label:asic
grep: /sys/class/hwmon/hwmon0/temp1_reset_history: Permission denied
In addition, displaying the sensors data via lm_sensors generates the
corresponding output below:
$ sensors
Output
=======================================================================
mlx5-pci-0800
Adapter: PCI adapter
asic: +46.0°C (crit = +105.0°C, highest = +48.0°C)
mlx5-pci-0801
Adapter: PCI adapter
asic: +46.0°C (crit = +105.0°C, highest = +48.0°C)
CC: Jean Delvare <jdelvare@suse.com>
Signed-off-by: Adham Faris <afaris@nvidia.com>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Gal Pressman <gal@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://lore.kernel.org/r/20230807180507.22984-3-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2023-08-07 18:05:07 +00:00
|
|
|
#include "hwmon.h"
|
2023-10-12 19:27:39 +00:00
|
|
|
#include "lag/lag.h"
|
2013-07-07 14:25:49 +00:00
|
|
|
|
|
|
|
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
|
2018-07-17 01:35:37 +00:00
|
|
|
MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver");
|
2013-07-07 14:25:49 +00:00
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|
|
|
|
|
2016-12-06 15:32:43 +00:00
|
|
|
unsigned int mlx5_core_debug_mask;
|
|
|
|
module_param_named(debug_mask, mlx5_core_debug_mask, uint, 0644);
|
2013-07-07 14:25:49 +00:00
|
|
|
MODULE_PARM_DESC(debug_mask, "debug mask: 1 = dump cmd data, 2 = dump cmd exec time, 3 = both. Default=0");
|
|
|
|
|
2016-12-06 15:32:43 +00:00
|
|
|
static unsigned int prof_sel = MLX5_DEFAULT_PROF;
|
|
|
|
module_param_named(prof_sel, prof_sel, uint, 0444);
|
2014-07-28 20:30:22 +00:00
|
|
|
MODULE_PARM_DESC(prof_sel, "profile selector. Valid range 0 - 2");
|
|
|
|
|
2018-01-04 15:25:32 +00:00
|
|
|
static u32 sw_owner_id[4];
|
2022-06-02 09:47:34 +00:00
|
|
|
#define MAX_SW_VHCA_ID (BIT(__mlx5_bit_sz(cmd_hca_cap_2, sw_vhca_id)) - 1)
|
|
|
|
static DEFINE_IDA(sw_vhca_ida);
|
2018-01-04 15:25:32 +00:00
|
|
|
|
2015-12-14 14:34:09 +00:00
|
|
|
enum {
|
|
|
|
MLX5_ATOMIC_REQ_MODE_BE = 0x0,
|
|
|
|
MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS = 0x1,
|
|
|
|
};
|
|
|
|
|
2022-01-05 12:50:11 +00:00
|
|
|
#define LOG_MAX_SUPPORTED_QPS 0xff
|
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
static struct mlx5_profile profile[] = {
|
|
|
|
[0] = {
|
|
|
|
.mask = 0,
|
2020-04-23 13:27:59 +00:00
|
|
|
.num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
|
2014-07-28 20:30:22 +00:00
|
|
|
},
|
|
|
|
[1] = {
|
|
|
|
.mask = MLX5_PROF_MASK_QP_SIZE,
|
|
|
|
.log_max_qp = 12,
|
2020-04-23 13:27:59 +00:00
|
|
|
.num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
|
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
},
|
|
|
|
[2] = {
|
|
|
|
.mask = MLX5_PROF_MASK_QP_SIZE |
|
|
|
|
MLX5_PROF_MASK_MR_CACHE,
|
2022-01-05 12:50:11 +00:00
|
|
|
.log_max_qp = LOG_MAX_SUPPORTED_QPS,
|
2020-04-23 13:27:59 +00:00
|
|
|
.num_cmd_caches = MLX5_NUM_COMMAND_CACHES,
|
2014-07-28 20:30:22 +00:00
|
|
|
.mr_cache[0] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[1] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[2] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[3] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[4] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[5] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[6] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[7] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[8] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[9] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[10] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[11] = {
|
|
|
|
.size = 500,
|
|
|
|
.limit = 250
|
|
|
|
},
|
|
|
|
.mr_cache[12] = {
|
|
|
|
.size = 64,
|
|
|
|
.limit = 32
|
|
|
|
},
|
|
|
|
.mr_cache[13] = {
|
|
|
|
.size = 32,
|
|
|
|
.limit = 16
|
|
|
|
},
|
|
|
|
.mr_cache[14] = {
|
|
|
|
.size = 16,
|
|
|
|
.limit = 8
|
|
|
|
},
|
|
|
|
.mr_cache[15] = {
|
|
|
|
.size = 8,
|
|
|
|
.limit = 4
|
|
|
|
},
|
|
|
|
},
|
2020-04-23 13:27:59 +00:00
|
|
|
[3] = {
|
|
|
|
.mask = MLX5_PROF_MASK_QP_SIZE,
|
|
|
|
.log_max_qp = LOG_MAX_SUPPORTED_QPS,
|
|
|
|
.num_cmd_caches = 0,
|
|
|
|
},
|
2014-07-28 20:30:22 +00:00
|
|
|
};
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2019-06-10 23:38:14 +00:00
|
|
|
static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili,
|
|
|
|
u32 warn_time_mili)
|
2015-10-14 14:43:47 +00:00
|
|
|
{
|
2019-06-10 23:38:14 +00:00
|
|
|
unsigned long warn = jiffies + msecs_to_jiffies(warn_time_mili);
|
2015-10-14 14:43:47 +00:00
|
|
|
unsigned long end = jiffies + msecs_to_jiffies(max_wait_mili);
|
2022-03-22 14:55:58 +00:00
|
|
|
u32 fw_initializing;
|
2015-10-14 14:43:47 +00:00
|
|
|
int err = 0;
|
|
|
|
|
2022-03-22 14:55:58 +00:00
|
|
|
do {
|
|
|
|
fw_initializing = ioread32be(&dev->iseg->initializing);
|
|
|
|
if (!(fw_initializing >> 31))
|
|
|
|
break;
|
2022-03-27 14:45:32 +00:00
|
|
|
if (time_after(jiffies, end) ||
|
2023-03-14 05:42:20 +00:00
|
|
|
test_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state)) {
|
2015-10-14 14:43:47 +00:00
|
|
|
err = -EBUSY;
|
|
|
|
break;
|
|
|
|
}
|
2019-06-10 23:38:14 +00:00
|
|
|
if (warn_time_mili && time_after(jiffies, warn)) {
|
2022-03-22 14:55:58 +00:00
|
|
|
mlx5_core_warn(dev, "Waiting for FW initialization, timeout abort in %ds (0x%x)\n",
|
|
|
|
jiffies_to_msecs(end - warn) / 1000, fw_initializing);
|
2019-06-10 23:38:14 +00:00
|
|
|
warn = jiffies + msecs_to_jiffies(warn_time_mili);
|
|
|
|
}
|
2021-10-07 15:00:27 +00:00
|
|
|
msleep(mlx5_tout_ms(dev, FW_PRE_INIT_WAIT));
|
2022-03-22 14:55:58 +00:00
|
|
|
} while (true);
|
2015-10-14 14:43:47 +00:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2016-11-17 11:46:00 +00:00
|
|
|
static void mlx5_set_driver_version(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
int driver_ver_sz = MLX5_FLD_SZ_BYTES(set_driver_version_in,
|
|
|
|
driver_version);
|
2020-04-09 13:33:38 +00:00
|
|
|
u8 in[MLX5_ST_SZ_BYTES(set_driver_version_in)] = {};
|
2016-11-17 11:46:00 +00:00
|
|
|
char *string;
|
|
|
|
|
|
|
|
if (!MLX5_CAP_GEN(dev, driver_version))
|
|
|
|
return;
|
|
|
|
|
|
|
|
string = MLX5_ADDR_OF(set_driver_version_in, in, driver_version);
|
|
|
|
|
2023-10-11 21:29:57 +00:00
|
|
|
snprintf(string, driver_ver_sz, "Linux,%s,%u.%u.%u",
|
|
|
|
KBUILD_MODNAME, LINUX_VERSION_MAJOR,
|
|
|
|
LINUX_VERSION_PATCHLEVEL, LINUX_VERSION_SUBLEVEL);
|
2016-11-17 11:46:00 +00:00
|
|
|
|
|
|
|
/*Send the command*/
|
|
|
|
MLX5_SET(set_driver_version_in, in, opcode,
|
|
|
|
MLX5_CMD_OP_SET_DRIVER_VERSION);
|
|
|
|
|
2020-04-09 13:33:38 +00:00
|
|
|
mlx5_cmd_exec_in(dev, set_driver_version, in);
|
2016-11-17 11:46:00 +00:00
|
|
|
}
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
static int set_dma_caps(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
net/mellanox: switch from 'pci_' to 'dma_' API
The wrappers in include/linux/pci-dma-compat.h should go away.
The patch has been generated with the coccinelle script below.
It has been hand modified to use 'dma_set_mask_and_coherent()' instead of
'pci_set_dma_mask()/pci_set_consistent_dma_mask()' when applicable.
This is less verbose.
It has been compile tested.
@@
@@
- PCI_DMA_BIDIRECTIONAL
+ DMA_BIDIRECTIONAL
@@
@@
- PCI_DMA_TODEVICE
+ DMA_TO_DEVICE
@@
@@
- PCI_DMA_FROMDEVICE
+ DMA_FROM_DEVICE
@@
@@
- PCI_DMA_NONE
+ DMA_NONE
@@
expression e1, e2, e3;
@@
- pci_alloc_consistent(e1, e2, e3)
+ dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
@@
expression e1, e2, e3;
@@
- pci_zalloc_consistent(e1, e2, e3)
+ dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
@@
expression e1, e2, e3, e4;
@@
- pci_free_consistent(e1, e2, e3, e4)
+ dma_free_coherent(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_map_single(e1, e2, e3, e4)
+ dma_map_single(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_single(e1, e2, e3, e4)
+ dma_unmap_single(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4, e5;
@@
- pci_map_page(e1, e2, e3, e4, e5)
+ dma_map_page(&e1->dev, e2, e3, e4, e5)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_page(e1, e2, e3, e4)
+ dma_unmap_page(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_map_sg(e1, e2, e3, e4)
+ dma_map_sg(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_sg(e1, e2, e3, e4)
+ dma_unmap_sg(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
+ dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_single_for_device(e1, e2, e3, e4)
+ dma_sync_single_for_device(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
+ dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_sg_for_device(e1, e2, e3, e4)
+ dma_sync_sg_for_device(&e1->dev, e2, e3, e4)
@@
expression e1, e2;
@@
- pci_dma_mapping_error(e1, e2)
+ dma_mapping_error(&e1->dev, e2)
@@
expression e1, e2;
@@
- pci_set_dma_mask(e1, e2)
+ dma_set_mask(&e1->dev, e2)
@@
expression e1, e2;
@@
- pci_set_consistent_dma_mask(e1, e2)
+ dma_set_coherent_mask(&e1->dev, e2)
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-22 19:12:41 +00:00
|
|
|
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2014-05-07 19:52:57 +00:00
|
|
|
dev_warn(&pdev->dev, "Warning: couldn't set 64-bit PCI DMA mask\n");
|
net/mellanox: switch from 'pci_' to 'dma_' API
The wrappers in include/linux/pci-dma-compat.h should go away.
The patch has been generated with the coccinelle script below.
It has been hand modified to use 'dma_set_mask_and_coherent()' instead of
'pci_set_dma_mask()/pci_set_consistent_dma_mask()' when applicable.
This is less verbose.
It has been compile tested.
@@
@@
- PCI_DMA_BIDIRECTIONAL
+ DMA_BIDIRECTIONAL
@@
@@
- PCI_DMA_TODEVICE
+ DMA_TO_DEVICE
@@
@@
- PCI_DMA_FROMDEVICE
+ DMA_FROM_DEVICE
@@
@@
- PCI_DMA_NONE
+ DMA_NONE
@@
expression e1, e2, e3;
@@
- pci_alloc_consistent(e1, e2, e3)
+ dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
@@
expression e1, e2, e3;
@@
- pci_zalloc_consistent(e1, e2, e3)
+ dma_alloc_coherent(&e1->dev, e2, e3, GFP_)
@@
expression e1, e2, e3, e4;
@@
- pci_free_consistent(e1, e2, e3, e4)
+ dma_free_coherent(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_map_single(e1, e2, e3, e4)
+ dma_map_single(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_single(e1, e2, e3, e4)
+ dma_unmap_single(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4, e5;
@@
- pci_map_page(e1, e2, e3, e4, e5)
+ dma_map_page(&e1->dev, e2, e3, e4, e5)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_page(e1, e2, e3, e4)
+ dma_unmap_page(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_map_sg(e1, e2, e3, e4)
+ dma_map_sg(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_unmap_sg(e1, e2, e3, e4)
+ dma_unmap_sg(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_single_for_cpu(e1, e2, e3, e4)
+ dma_sync_single_for_cpu(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_single_for_device(e1, e2, e3, e4)
+ dma_sync_single_for_device(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_sg_for_cpu(e1, e2, e3, e4)
+ dma_sync_sg_for_cpu(&e1->dev, e2, e3, e4)
@@
expression e1, e2, e3, e4;
@@
- pci_dma_sync_sg_for_device(e1, e2, e3, e4)
+ dma_sync_sg_for_device(&e1->dev, e2, e3, e4)
@@
expression e1, e2;
@@
- pci_dma_mapping_error(e1, e2)
+ dma_mapping_error(&e1->dev, e2)
@@
expression e1, e2;
@@
- pci_set_dma_mask(e1, e2)
+ dma_set_mask(&e1->dev, e2)
@@
expression e1, e2;
@@
- pci_set_consistent_dma_mask(e1, e2)
+ dma_set_coherent_mask(&e1->dev, e2)
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-08-22 19:12:41 +00:00
|
|
|
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2014-05-07 19:52:57 +00:00
|
|
|
dev_err(&pdev->dev, "Can't set PCI DMA mask, aborting\n");
|
2013-07-07 14:25:49 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dma_set_max_seg_size(&pdev->dev, 2u * 1024 * 1024 * 1024);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2015-10-14 14:43:46 +00:00
|
|
|
static int mlx5_pci_enable_device(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct pci_dev *pdev = dev->pdev;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
mutex_lock(&dev->pci_status_mutex);
|
|
|
|
if (dev->pci_status == MLX5_PCI_STATUS_DISABLED) {
|
|
|
|
err = pci_enable_device(pdev);
|
|
|
|
if (!err)
|
|
|
|
dev->pci_status = MLX5_PCI_STATUS_ENABLED;
|
|
|
|
}
|
|
|
|
mutex_unlock(&dev->pci_status_mutex);
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mlx5_pci_disable_device(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct pci_dev *pdev = dev->pdev;
|
|
|
|
|
|
|
|
mutex_lock(&dev->pci_status_mutex);
|
|
|
|
if (dev->pci_status == MLX5_PCI_STATUS_ENABLED) {
|
|
|
|
pci_disable_device(pdev);
|
|
|
|
dev->pci_status = MLX5_PCI_STATUS_DISABLED;
|
|
|
|
}
|
|
|
|
mutex_unlock(&dev->pci_status_mutex);
|
|
|
|
}
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
static int request_bar(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
|
2014-05-07 19:52:57 +00:00
|
|
|
dev_err(&pdev->dev, "Missing registers BAR, aborting\n");
|
2013-07-07 14:25:49 +00:00
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
2020-10-04 11:30:58 +00:00
|
|
|
err = pci_request_regions(pdev, KBUILD_MODNAME);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err)
|
|
|
|
dev_err(&pdev->dev, "Couldn't get PCI resources, aborting\n");
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void release_bar(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
pci_release_regions(pdev);
|
|
|
|
}
|
|
|
|
|
2017-05-28 12:24:17 +00:00
|
|
|
struct mlx5_reg_host_endianness {
|
2013-07-07 14:25:49 +00:00
|
|
|
u8 he;
|
|
|
|
u8 rsvd[15];
|
|
|
|
};
|
|
|
|
|
2016-07-28 13:43:17 +00:00
|
|
|
static u16 to_fw_pkey_sz(struct mlx5_core_dev *dev, u32 size)
|
2014-10-02 09:19:42 +00:00
|
|
|
{
|
|
|
|
switch (size) {
|
|
|
|
case 128:
|
|
|
|
return 0;
|
|
|
|
case 256:
|
|
|
|
return 1;
|
|
|
|
case 512:
|
|
|
|
return 2;
|
|
|
|
case 1024:
|
|
|
|
return 3;
|
|
|
|
case 2048:
|
|
|
|
return 4;
|
|
|
|
case 4096:
|
|
|
|
return 5;
|
|
|
|
default:
|
2016-07-28 13:43:17 +00:00
|
|
|
mlx5_core_warn(dev, "invalid pkey table size %d\n", size);
|
2014-10-02 09:19:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-01 14:27:43 +00:00
|
|
|
void mlx5_core_uplink_netdev_set(struct mlx5_core_dev *dev, struct net_device *netdev)
|
|
|
|
{
|
|
|
|
mutex_lock(&dev->mlx5e_res.uplink_netdev_lock);
|
|
|
|
dev->mlx5e_res.uplink_netdev = netdev;
|
|
|
|
mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_UPLINK_NETDEV,
|
|
|
|
netdev);
|
|
|
|
mutex_unlock(&dev->mlx5e_res.uplink_netdev_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mlx5_core_uplink_netdev_event_replay(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
mutex_lock(&dev->mlx5e_res.uplink_netdev_lock);
|
|
|
|
mlx5_blocking_notifier_call_chain(dev, MLX5_DRIVER_EVENT_UPLINK_NETDEV,
|
|
|
|
dev->mlx5e_res.uplink_netdev);
|
|
|
|
mutex_unlock(&dev->mlx5e_res.uplink_netdev_lock);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mlx5_core_uplink_netdev_event_replay);
|
|
|
|
|
2023-09-21 12:10:27 +00:00
|
|
|
void mlx5_core_mp_event_replay(struct mlx5_core_dev *dev, u32 event, void *data)
|
|
|
|
{
|
|
|
|
mlx5_blocking_notifier_call_chain(dev, event, data);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mlx5_core_mp_event_replay);
|
|
|
|
|
2023-07-11 12:56:08 +00:00
|
|
|
int mlx5_core_get_caps_mode(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type,
|
|
|
|
enum mlx5_cap_mode cap_mode)
|
2014-10-02 09:19:42 +00:00
|
|
|
{
|
2014-10-02 09:19:44 +00:00
|
|
|
u8 in[MLX5_ST_SZ_BYTES(query_hca_cap_in)];
|
|
|
|
int out_sz = MLX5_ST_SZ_BYTES(query_hca_cap_out);
|
2015-05-28 19:28:41 +00:00
|
|
|
void *out, *hca_caps;
|
|
|
|
u16 opmod = (cap_type << 1) | (cap_mode & 0x01);
|
2013-07-07 14:25:49 +00:00
|
|
|
int err;
|
|
|
|
|
2014-10-02 09:19:44 +00:00
|
|
|
memset(in, 0, sizeof(in));
|
|
|
|
out = kzalloc(out_sz, GFP_KERNEL);
|
2014-10-02 09:19:42 +00:00
|
|
|
if (!out)
|
2013-07-07 14:25:49 +00:00
|
|
|
return -ENOMEM;
|
2015-05-28 19:28:41 +00:00
|
|
|
|
2014-10-02 09:19:44 +00:00
|
|
|
MLX5_SET(query_hca_cap_in, in, opcode, MLX5_CMD_OP_QUERY_HCA_CAP);
|
|
|
|
MLX5_SET(query_hca_cap_in, in, op_mod, opmod);
|
2020-04-09 13:33:38 +00:00
|
|
|
err = mlx5_cmd_exec_inout(dev, query_hca_cap, in, out);
|
2014-10-02 09:19:42 +00:00
|
|
|
if (err) {
|
2015-05-28 19:28:41 +00:00
|
|
|
mlx5_core_warn(dev,
|
|
|
|
"QUERY_HCA_CAP : type(%x) opmode(%x) Failed(%d)\n",
|
|
|
|
cap_type, cap_mode, err);
|
2013-07-07 14:25:49 +00:00
|
|
|
goto query_ex;
|
|
|
|
}
|
2014-10-02 09:19:42 +00:00
|
|
|
|
2015-05-28 19:28:41 +00:00
|
|
|
hca_caps = MLX5_ADDR_OF(query_hca_cap_out, out, capability);
|
|
|
|
|
|
|
|
switch (cap_mode) {
|
|
|
|
case HCA_CAP_OPMOD_GET_MAX:
|
2021-07-13 11:17:03 +00:00
|
|
|
memcpy(dev->caps.hca[cap_type]->max, hca_caps,
|
2015-05-28 19:28:41 +00:00
|
|
|
MLX5_UN_SZ_BYTES(hca_cap_union));
|
|
|
|
break;
|
|
|
|
case HCA_CAP_OPMOD_GET_CUR:
|
2021-07-13 11:17:03 +00:00
|
|
|
memcpy(dev->caps.hca[cap_type]->cur, hca_caps,
|
2015-05-28 19:28:41 +00:00
|
|
|
MLX5_UN_SZ_BYTES(hca_cap_union));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
mlx5_core_warn(dev,
|
|
|
|
"Tried to query dev cap type(%x) with wrong opmode(%x)\n",
|
|
|
|
cap_type, cap_mode);
|
|
|
|
err = -EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
2014-10-02 09:19:42 +00:00
|
|
|
query_ex:
|
|
|
|
kfree(out);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2016-02-23 08:25:22 +00:00
|
|
|
int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = mlx5_core_get_caps_mode(dev, cap_type, HCA_CAP_OPMOD_GET_CUR);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
return mlx5_core_get_caps_mode(dev, cap_type, HCA_CAP_OPMOD_GET_MAX);
|
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
static int set_caps(struct mlx5_core_dev *dev, void *in, int opmod)
|
2014-10-02 09:19:42 +00:00
|
|
|
{
|
2014-10-02 09:19:44 +00:00
|
|
|
MLX5_SET(set_hca_cap_in, in, opcode, MLX5_CMD_OP_SET_HCA_CAP);
|
2015-12-14 14:34:09 +00:00
|
|
|
MLX5_SET(set_hca_cap_in, in, op_mod, opmod << 1);
|
2020-04-09 13:33:38 +00:00
|
|
|
return mlx5_cmd_exec_in(dev, set_hca_cap, in);
|
2014-10-02 09:19:42 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
static int handle_hca_cap_atomic(struct mlx5_core_dev *dev, void *set_ctx)
|
2015-12-14 14:34:09 +00:00
|
|
|
{
|
|
|
|
void *set_hca_cap;
|
|
|
|
int req_endianness;
|
|
|
|
int err;
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
if (!MLX5_CAP_GEN(dev, atomic))
|
2015-12-14 14:34:09 +00:00
|
|
|
return 0;
|
2020-03-19 09:43:59 +00:00
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_ATOMIC);
|
|
|
|
if (err)
|
|
|
|
return err;
|
2015-12-14 14:34:09 +00:00
|
|
|
|
|
|
|
req_endianness =
|
|
|
|
MLX5_CAP_ATOMIC(dev,
|
2017-05-28 12:24:17 +00:00
|
|
|
supported_atomic_req_8B_endianness_mode_1);
|
2015-12-14 14:34:09 +00:00
|
|
|
|
|
|
|
if (req_endianness != MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);
|
|
|
|
|
|
|
|
/* Set requestor to host endianness */
|
2017-05-28 12:24:17 +00:00
|
|
|
MLX5_SET(atomic_caps, set_hca_cap, atomic_req_8B_endianness_mode,
|
2015-12-14 14:34:09 +00:00
|
|
|
MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS);
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ATOMIC);
|
2015-12-14 14:34:09 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
static int handle_hca_cap_odp(struct mlx5_core_dev *dev, void *set_ctx)
|
2019-01-22 06:48:51 +00:00
|
|
|
{
|
|
|
|
void *set_hca_cap;
|
2019-02-25 06:54:39 +00:00
|
|
|
bool do_set = false;
|
2019-01-22 06:48:51 +00:00
|
|
|
int err;
|
|
|
|
|
2019-02-17 11:11:02 +00:00
|
|
|
if (!IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) ||
|
|
|
|
!MLX5_CAP_GEN(dev, pg))
|
2019-01-22 06:48:51 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_ODP);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);
|
2021-07-13 11:17:03 +00:00
|
|
|
memcpy(set_hca_cap, dev->caps.hca[MLX5_CAP_ODP]->cur,
|
2019-01-22 06:48:51 +00:00
|
|
|
MLX5_ST_SZ_BYTES(odp_cap));
|
|
|
|
|
2019-02-25 06:54:39 +00:00
|
|
|
#define ODP_CAP_SET_MAX(dev, field) \
|
|
|
|
do { \
|
|
|
|
u32 _res = MLX5_CAP_ODP_MAX(dev, field); \
|
|
|
|
if (_res) { \
|
|
|
|
do_set = true; \
|
|
|
|
MLX5_SET(odp_cap, set_hca_cap, field, _res); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
ODP_CAP_SET_MAX(dev, ud_odp_caps.srq_receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, rc_odp_caps.srq_receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.srq_receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.send);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.write);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.read);
|
|
|
|
ODP_CAP_SET_MAX(dev, xrc_odp_caps.atomic);
|
2019-08-19 12:08:13 +00:00
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.srq_receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.send);
|
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.receive);
|
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.write);
|
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.read);
|
|
|
|
ODP_CAP_SET_MAX(dev, dc_odp_caps.atomic);
|
2019-02-25 06:54:39 +00:00
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
if (!do_set)
|
|
|
|
return 0;
|
2019-02-25 06:54:39 +00:00
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ODP);
|
2019-01-22 06:48:51 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 10:09:29 +00:00
|
|
|
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;
|
|
|
|
|
2023-01-26 07:58:35 +00:00
|
|
|
err = devl_param_driverinit_value_get(devlink,
|
|
|
|
DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
|
|
|
|
&val);
|
2021-12-09 10:09:29 +00:00
|
|
|
if (!err)
|
|
|
|
return val.vu32;
|
|
|
|
mlx5_core_dbg(dev, "Failed to get param. err = %d\n", err);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-08-29 09:02:27 +00:00
|
|
|
bool mlx5_is_roce_on(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
union devlink_param_value val;
|
|
|
|
int err;
|
|
|
|
|
2023-01-26 07:58:35 +00:00
|
|
|
err = devl_param_driverinit_value_get(devlink,
|
|
|
|
DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
|
|
|
|
&val);
|
2022-08-29 09:02:27 +00:00
|
|
|
|
|
|
|
if (!err)
|
|
|
|
return val.vbool;
|
|
|
|
|
|
|
|
mlx5_core_dbg(dev, "Failed to get param. err = %d\n", err);
|
|
|
|
return MLX5_CAP_GEN(dev, roce);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mlx5_is_roce_on);
|
|
|
|
|
2022-06-02 09:47:34 +00:00
|
|
|
static int handle_hca_cap_2(struct mlx5_core_dev *dev, void *set_ctx)
|
|
|
|
{
|
|
|
|
void *set_hca_cap;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (!MLX5_CAP_GEN_MAX(dev, hca_cap_2))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL_2);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (!MLX5_CAP_GEN_2_MAX(dev, sw_vhca_id_valid) ||
|
|
|
|
!(dev->priv.sw_vhca_id > 0))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx,
|
|
|
|
capability);
|
|
|
|
memcpy(set_hca_cap, dev->caps.hca[MLX5_CAP_GENERAL_2]->cur,
|
|
|
|
MLX5_ST_SZ_BYTES(cmd_hca_cap_2));
|
|
|
|
MLX5_SET(cmd_hca_cap_2, set_hca_cap, sw_vhca_id_valid, 1);
|
|
|
|
|
|
|
|
return set_caps(dev, set_ctx, MLX5_CAP_GENERAL_2);
|
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx)
|
2014-10-02 09:19:42 +00:00
|
|
|
{
|
2021-05-12 10:52:27 +00:00
|
|
|
struct mlx5_profile *prof = &dev->profile;
|
2015-05-28 19:28:41 +00:00
|
|
|
void *set_hca_cap;
|
2021-12-09 10:09:29 +00:00
|
|
|
int max_uc_list;
|
2020-03-19 09:43:59 +00:00
|
|
|
int err;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2016-02-23 08:25:22 +00:00
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err)
|
2020-03-19 09:43:59 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2015-05-28 19:28:41 +00:00
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx,
|
|
|
|
capability);
|
2021-07-13 11:17:03 +00:00
|
|
|
memcpy(set_hca_cap, dev->caps.hca[MLX5_CAP_GENERAL]->cur,
|
2015-05-28 19:28:41 +00:00
|
|
|
MLX5_ST_SZ_BYTES(cmd_hca_cap));
|
|
|
|
|
|
|
|
mlx5_core_dbg(dev, "Current Pkey table size %d Setting new size %d\n",
|
2015-06-04 16:30:41 +00:00
|
|
|
mlx5_to_sw_pkey_sz(MLX5_CAP_GEN(dev, pkey_table_size)),
|
2015-05-28 19:28:41 +00:00
|
|
|
128);
|
2014-10-02 09:19:42 +00:00
|
|
|
/* we limit the size of the pkey table to 128 entries for now */
|
2015-05-28 19:28:41 +00:00
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, pkey_table_size,
|
2016-07-28 13:43:17 +00:00
|
|
|
to_fw_pkey_sz(dev, 128));
|
2014-10-02 09:19:42 +00:00
|
|
|
|
2016-12-28 12:58:32 +00:00
|
|
|
/* Check log_max_qp from HCA caps to set in current profile */
|
2022-01-05 12:50:11 +00:00
|
|
|
if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) {
|
2022-07-24 08:28:21 +00:00
|
|
|
prof->log_max_qp = min_t(u8, 18, MLX5_CAP_GEN_MAX(dev, log_max_qp));
|
2022-01-05 12:50:11 +00:00
|
|
|
} else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) {
|
2016-12-28 12:58:32 +00:00
|
|
|
mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n",
|
2021-05-12 10:52:27 +00:00
|
|
|
prof->log_max_qp,
|
2016-12-28 12:58:32 +00:00
|
|
|
MLX5_CAP_GEN_MAX(dev, log_max_qp));
|
2021-05-12 10:52:27 +00:00
|
|
|
prof->log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp);
|
2016-12-28 12:58:32 +00:00
|
|
|
}
|
2014-10-02 09:19:42 +00:00
|
|
|
if (prof->mask & MLX5_PROF_MASK_QP_SIZE)
|
2015-05-28 19:28:41 +00:00
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_qp,
|
|
|
|
prof->log_max_qp);
|
2014-10-02 09:19:42 +00:00
|
|
|
|
2015-05-28 19:28:41 +00:00
|
|
|
/* disable cmdif checksum */
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
|
2014-10-02 09:19:42 +00:00
|
|
|
|
2017-05-28 11:47:56 +00:00
|
|
|
/* Enable 4K UAR only when HCA supports it and page size is bigger
|
|
|
|
* than 4K.
|
|
|
|
*/
|
|
|
|
if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)
|
2017-01-03 21:55:28 +00:00
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
|
|
|
|
|
2015-08-05 16:05:32 +00:00
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
|
|
|
|
|
2015-11-19 15:12:26 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, cache_line_128byte))
|
|
|
|
MLX5_SET(cmd_hca_cap,
|
|
|
|
set_hca_cap,
|
|
|
|
cache_line_128byte,
|
2018-02-02 15:32:53 +00:00
|
|
|
cache_line_size() >= 128 ? 1 : 0);
|
2015-11-19 15:12:26 +00:00
|
|
|
|
2018-01-02 14:19:29 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, dct))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, dct, 1);
|
|
|
|
|
2020-10-07 06:00:48 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_event))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, pci_sync_for_fw_update_event, 1);
|
2023-05-17 13:07:40 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, pci_sync_for_fw_update_with_driver_unload))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap,
|
|
|
|
pci_sync_for_fw_update_with_driver_unload, 1);
|
2020-10-07 06:00:48 +00:00
|
|
|
|
2018-01-04 15:25:44 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, num_vhca_ports))
|
|
|
|
MLX5_SET(cmd_hca_cap,
|
|
|
|
set_hca_cap,
|
|
|
|
num_vhca_ports,
|
|
|
|
MLX5_CAP_GEN_MAX(dev, num_vhca_ports));
|
|
|
|
|
2020-04-01 07:30:32 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, release_all_pages))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, release_all_pages, 1);
|
|
|
|
|
2020-05-20 10:59:06 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, mkey_by_name))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, mkey_by_name, 1);
|
|
|
|
|
2020-12-12 06:12:16 +00:00
|
|
|
mlx5_vhca_state_cap_handle(dev, set_hca_cap);
|
|
|
|
|
2021-03-14 12:42:55 +00:00
|
|
|
if (MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix))
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, num_total_dynamic_vf_msix,
|
|
|
|
MLX5_CAP_GEN_MAX(dev, num_total_dynamic_vf_msix));
|
|
|
|
|
2022-11-09 12:42:59 +00:00
|
|
|
if (MLX5_CAP_GEN(dev, roce_rw_supported) && MLX5_CAP_GEN_MAX(dev, roce))
|
2022-08-29 09:02:27 +00:00
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, roce,
|
|
|
|
mlx5_is_roce_on(dev));
|
2021-08-18 10:21:30 +00:00
|
|
|
|
2021-12-09 10:09:29 +00:00
|
|
|
max_uc_list = max_uc_list_get_devlink_param(dev);
|
|
|
|
if (max_uc_list > 0)
|
|
|
|
MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_current_uc_list,
|
|
|
|
ilog2(max_uc_list));
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
2014-10-02 09:19:42 +00:00
|
|
|
|
2021-08-18 10:21:30 +00:00
|
|
|
/* Cached MLX5_CAP_GEN(dev, roce) can be out of sync this early in the
|
|
|
|
* boot process.
|
|
|
|
* In case RoCE cap is writable in FW and user/devlink requested to change the
|
|
|
|
* cap, we are yet to query the final state of the above cap.
|
|
|
|
* Hence, the need for this function.
|
|
|
|
*
|
|
|
|
* Returns
|
|
|
|
* True:
|
|
|
|
* 1) RoCE cap is read only in FW and already disabled
|
|
|
|
* OR:
|
|
|
|
* 2) RoCE cap is writable in FW and user/devlink requested it off.
|
|
|
|
*
|
|
|
|
* In any other case, return False.
|
|
|
|
*/
|
|
|
|
static bool is_roce_fw_disabled(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2022-08-29 09:02:27 +00:00
|
|
|
return (MLX5_CAP_GEN(dev, roce_rw_supported) && !mlx5_is_roce_on(dev)) ||
|
2021-08-18 10:21:30 +00:00
|
|
|
(!MLX5_CAP_GEN(dev, roce_rw_supported) && !MLX5_CAP_GEN(dev, roce));
|
|
|
|
}
|
|
|
|
|
2020-01-14 03:06:25 +00:00
|
|
|
static int handle_hca_cap_roce(struct mlx5_core_dev *dev, void *set_ctx)
|
|
|
|
{
|
|
|
|
void *set_hca_cap;
|
|
|
|
int err;
|
|
|
|
|
2021-08-18 10:21:30 +00:00
|
|
|
if (is_roce_fw_disabled(dev))
|
2020-01-14 03:06:25 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_ROCE);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (MLX5_CAP_ROCE(dev, sw_r_roce_src_udp_port) ||
|
|
|
|
!MLX5_CAP_ROCE_MAX(dev, sw_r_roce_src_udp_port))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);
|
2021-07-13 11:17:03 +00:00
|
|
|
memcpy(set_hca_cap, dev->caps.hca[MLX5_CAP_ROCE]->cur,
|
2020-01-14 03:06:25 +00:00
|
|
|
MLX5_ST_SZ_BYTES(roce_cap));
|
|
|
|
MLX5_SET(roce_cap, set_hca_cap, sw_r_roce_src_udp_port, 1);
|
|
|
|
|
2023-03-19 12:59:32 +00:00
|
|
|
if (MLX5_CAP_ROCE_MAX(dev, qp_ooo_transmit_default))
|
|
|
|
MLX5_SET(roce_cap, set_hca_cap, qp_ooo_transmit_default, 1);
|
|
|
|
|
2020-01-14 03:06:25 +00:00
|
|
|
err = set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_ROCE);
|
2013-07-07 14:25:49 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-09-07 23:36:29 +00:00
|
|
|
static int handle_hca_cap_port_selection(struct mlx5_core_dev *dev,
|
|
|
|
void *set_ctx)
|
|
|
|
{
|
|
|
|
void *set_hca_cap;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (!MLX5_CAP_GEN(dev, port_selection_cap))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_PORT_SELECTION);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (MLX5_CAP_PORT_SELECTION(dev, port_select_flow_table_bypass) ||
|
|
|
|
!MLX5_CAP_PORT_SELECTION_MAX(dev, port_select_flow_table_bypass))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
set_hca_cap = MLX5_ADDR_OF(set_hca_cap_in, set_ctx, capability);
|
|
|
|
memcpy(set_hca_cap, dev->caps.hca[MLX5_CAP_PORT_SELECTION]->cur,
|
|
|
|
MLX5_ST_SZ_BYTES(port_selection_cap));
|
|
|
|
MLX5_SET(port_selection_cap, set_hca_cap, port_select_flow_table_bypass, 1);
|
|
|
|
|
2023-03-22 08:21:46 +00:00
|
|
|
err = set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_PORT_SELECTION);
|
2022-09-07 23:36:29 +00:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-02-17 11:11:02 +00:00
|
|
|
static int set_hca_cap(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2020-03-19 09:43:59 +00:00
|
|
|
int set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in);
|
|
|
|
void *set_ctx;
|
2019-02-17 11:11:02 +00:00
|
|
|
int err;
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
set_ctx = kzalloc(set_sz, GFP_KERNEL);
|
|
|
|
if (!set_ctx)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
err = handle_hca_cap(dev, set_ctx);
|
2019-02-17 11:11:02 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "handle_hca_cap failed\n");
|
2019-02-17 11:11:02 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
memset(set_ctx, 0, set_sz);
|
|
|
|
err = handle_hca_cap_atomic(dev, set_ctx);
|
2019-02-17 11:11:02 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "handle_hca_cap_atomic failed\n");
|
2019-02-17 11:11:02 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2020-03-19 09:43:59 +00:00
|
|
|
memset(set_ctx, 0, set_sz);
|
|
|
|
err = handle_hca_cap_odp(dev, set_ctx);
|
2019-02-17 11:11:02 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "handle_hca_cap_odp failed\n");
|
2019-02-17 11:11:02 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2020-01-14 03:06:25 +00:00
|
|
|
memset(set_ctx, 0, set_sz);
|
|
|
|
err = handle_hca_cap_roce(dev, set_ctx);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "handle_hca_cap_roce failed\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2022-06-02 09:47:34 +00:00
|
|
|
memset(set_ctx, 0, set_sz);
|
|
|
|
err = handle_hca_cap_2(dev, set_ctx);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "handle_hca_cap_2 failed\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2022-09-07 23:36:29 +00:00
|
|
|
memset(set_ctx, 0, set_sz);
|
|
|
|
err = handle_hca_cap_port_selection(dev, set_ctx);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "handle_hca_cap_port_selection failed\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2019-02-17 11:11:02 +00:00
|
|
|
out:
|
2020-03-19 09:43:59 +00:00
|
|
|
kfree(set_ctx);
|
2019-02-17 11:11:02 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
static int set_hca_ctrl(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2017-05-28 12:24:17 +00:00
|
|
|
struct mlx5_reg_host_endianness he_in;
|
|
|
|
struct mlx5_reg_host_endianness he_out;
|
2013-07-07 14:25:49 +00:00
|
|
|
int err;
|
|
|
|
|
2015-12-01 16:03:09 +00:00
|
|
|
if (!mlx5_core_is_pf(dev))
|
|
|
|
return 0;
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
memset(&he_in, 0, sizeof(he_in));
|
|
|
|
he_in.he = MLX5_SET_HOST_ENDIANNESS;
|
|
|
|
err = mlx5_core_access_reg(dev, &he_in, sizeof(he_in),
|
|
|
|
&he_out, sizeof(he_out),
|
|
|
|
MLX5_REG_HOST_ENDIANNESS, 0, 1);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2017-05-30 06:42:54 +00:00
|
|
|
static int mlx5_core_set_hca_defaults(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* Disable local_lb by default */
|
2018-01-09 09:41:10 +00:00
|
|
|
if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH)
|
2017-05-30 06:42:54 +00:00
|
|
|
ret = mlx5_nic_vport_update_local_lb(dev, false);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-12-01 16:03:08 +00:00
|
|
|
int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id)
|
2013-07-18 12:31:08 +00:00
|
|
|
{
|
2020-04-09 13:33:38 +00:00
|
|
|
u32 in[MLX5_ST_SZ_DW(enable_hca_in)] = {};
|
2013-07-18 12:31:08 +00:00
|
|
|
|
2015-12-01 16:03:08 +00:00
|
|
|
MLX5_SET(enable_hca_in, in, opcode, MLX5_CMD_OP_ENABLE_HCA);
|
|
|
|
MLX5_SET(enable_hca_in, in, function_id, func_id);
|
2019-02-13 06:55:36 +00:00
|
|
|
MLX5_SET(enable_hca_in, in, embedded_cpu_function,
|
|
|
|
dev->caps.embedded_cpu);
|
2020-04-09 13:33:38 +00:00
|
|
|
return mlx5_cmd_exec_in(dev, enable_hca, in);
|
2013-07-18 12:31:08 +00:00
|
|
|
}
|
|
|
|
|
2015-12-01 16:03:08 +00:00
|
|
|
int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id)
|
2013-07-18 12:31:08 +00:00
|
|
|
{
|
2020-04-09 13:33:38 +00:00
|
|
|
u32 in[MLX5_ST_SZ_DW(disable_hca_in)] = {};
|
2013-07-18 12:31:08 +00:00
|
|
|
|
2015-12-01 16:03:08 +00:00
|
|
|
MLX5_SET(disable_hca_in, in, opcode, MLX5_CMD_OP_DISABLE_HCA);
|
|
|
|
MLX5_SET(disable_hca_in, in, function_id, func_id);
|
2019-02-13 06:55:36 +00:00
|
|
|
MLX5_SET(enable_hca_in, in, embedded_cpu_function,
|
|
|
|
dev->caps.embedded_cpu);
|
2020-04-09 13:33:38 +00:00
|
|
|
return mlx5_cmd_exec_in(dev, disable_hca, in);
|
2013-07-18 12:31:08 +00:00
|
|
|
}
|
|
|
|
|
2015-05-28 19:28:48 +00:00
|
|
|
static int mlx5_core_set_issi(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2020-04-09 13:33:38 +00:00
|
|
|
u32 query_out[MLX5_ST_SZ_DW(query_issi_out)] = {};
|
|
|
|
u32 query_in[MLX5_ST_SZ_DW(query_issi_in)] = {};
|
2015-05-28 19:28:48 +00:00
|
|
|
u32 sup_issi;
|
2016-07-19 17:17:12 +00:00
|
|
|
int err;
|
2015-05-28 19:28:48 +00:00
|
|
|
|
|
|
|
MLX5_SET(query_issi_in, query_in, opcode, MLX5_CMD_OP_QUERY_ISSI);
|
2020-04-09 13:33:38 +00:00
|
|
|
err = mlx5_cmd_exec_inout(dev, query_issi, query_in, query_out);
|
2015-05-28 19:28:48 +00:00
|
|
|
if (err) {
|
2020-04-06 00:50:25 +00:00
|
|
|
u32 syndrome = MLX5_GET(query_issi_out, query_out, syndrome);
|
|
|
|
u8 status = MLX5_GET(query_issi_out, query_out, status);
|
2016-07-19 17:17:12 +00:00
|
|
|
|
2016-12-06 15:32:45 +00:00
|
|
|
if (!status || syndrome == MLX5_DRIVER_SYND) {
|
|
|
|
mlx5_core_err(dev, "Failed to query ISSI err(%d) status(%d) synd(%d)\n",
|
|
|
|
err, status, syndrome);
|
|
|
|
return err;
|
2015-05-28 19:28:48 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 15:32:45 +00:00
|
|
|
mlx5_core_warn(dev, "Query ISSI is not supported by FW, ISSI is 0\n");
|
|
|
|
dev->issi = 0;
|
|
|
|
return 0;
|
2015-05-28 19:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sup_issi = MLX5_GET(query_issi_out, query_out, supported_issi_dw0);
|
|
|
|
|
|
|
|
if (sup_issi & (1 << 1)) {
|
2020-04-09 13:33:38 +00:00
|
|
|
u32 set_in[MLX5_ST_SZ_DW(set_issi_in)] = {};
|
2015-05-28 19:28:48 +00:00
|
|
|
|
|
|
|
MLX5_SET(set_issi_in, set_in, opcode, MLX5_CMD_OP_SET_ISSI);
|
|
|
|
MLX5_SET(set_issi_in, set_in, current_issi, 1);
|
2020-04-09 13:33:38 +00:00
|
|
|
err = mlx5_cmd_exec_in(dev, set_issi, set_in);
|
2015-05-28 19:28:48 +00:00
|
|
|
if (err) {
|
2016-12-06 15:32:45 +00:00
|
|
|
mlx5_core_err(dev, "Failed to set ISSI to 1 err(%d)\n",
|
|
|
|
err);
|
2015-05-28 19:28:48 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
dev->issi = 1;
|
|
|
|
|
|
|
|
return 0;
|
2015-06-04 16:30:39 +00:00
|
|
|
} else if (sup_issi & (1 << 0) || !sup_issi) {
|
2015-05-28 19:28:48 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-11 17:35:41 +00:00
|
|
|
return -EOPNOTSUPP;
|
2015-05-28 19:28:48 +00:00
|
|
|
}
|
|
|
|
|
2019-03-29 22:37:54 +00:00
|
|
|
static int mlx5_pci_init(struct mlx5_core_dev *dev, struct pci_dev *pdev,
|
|
|
|
const struct pci_device_id *id)
|
2015-09-25 07:49:14 +00:00
|
|
|
{
|
|
|
|
int err = 0;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2019-06-28 22:36:00 +00:00
|
|
|
mutex_init(&dev->pci_status_mutex);
|
2019-03-29 22:37:54 +00:00
|
|
|
pci_set_drvdata(dev->pdev, dev);
|
2015-07-23 20:35:57 +00:00
|
|
|
|
2019-03-29 22:38:01 +00:00
|
|
|
dev->bar_addr = pci_resource_start(pdev, 0);
|
2015-07-23 20:35:57 +00:00
|
|
|
|
2015-10-14 14:43:46 +00:00
|
|
|
err = mlx5_pci_enable_device(dev);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Cannot enable PCI device, aborting\n");
|
2019-03-29 22:37:54 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = request_bar(pdev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "error requesting BARs, aborting\n");
|
2013-07-07 14:25:49 +00:00
|
|
|
goto err_disable;
|
|
|
|
}
|
|
|
|
|
|
|
|
pci_set_master(pdev);
|
|
|
|
|
|
|
|
err = set_dma_caps(pdev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed setting DMA capabilities mask, aborting\n");
|
2013-07-07 14:25:49 +00:00
|
|
|
goto err_clr_master;
|
|
|
|
}
|
|
|
|
|
2019-01-19 00:33:11 +00:00
|
|
|
if (pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP32) &&
|
|
|
|
pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP64) &&
|
|
|
|
pci_enable_atomic_ops_to_root(pdev, PCI_EXP_DEVCAP2_ATOMIC_COMP128))
|
|
|
|
mlx5_core_dbg(dev, "Enabling pci atomics failed\n");
|
|
|
|
|
2019-03-29 22:38:01 +00:00
|
|
|
dev->iseg_base = dev->bar_addr;
|
2013-07-07 14:25:49 +00:00
|
|
|
dev->iseg = ioremap(dev->iseg_base, sizeof(*dev->iseg));
|
|
|
|
if (!dev->iseg) {
|
|
|
|
err = -ENOMEM;
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed mapping initialization segment, aborting\n");
|
2013-07-07 14:25:49 +00:00
|
|
|
goto err_clr_master;
|
|
|
|
}
|
2015-09-25 07:49:14 +00:00
|
|
|
|
2018-06-28 12:05:58 +00:00
|
|
|
mlx5_pci_vsc_init(dev);
|
2015-09-25 07:49:14 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_clr_master:
|
|
|
|
release_bar(dev->pdev);
|
|
|
|
err_disable:
|
2015-10-14 14:43:46 +00:00
|
|
|
mlx5_pci_disable_device(dev);
|
2015-09-25 07:49:14 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:37:53 +00:00
|
|
|
static void mlx5_pci_close(struct mlx5_core_dev *dev)
|
2015-09-25 07:49:14 +00:00
|
|
|
{
|
2020-05-06 12:59:48 +00:00
|
|
|
/* health work might still be active, and it needs pci bar in
|
|
|
|
* order to know the NIC state. Therefore, drain the health WQ
|
|
|
|
* before removing the pci bars
|
|
|
|
*/
|
|
|
|
mlx5_drain_health_wq(dev);
|
2015-09-25 07:49:14 +00:00
|
|
|
iounmap(dev->iseg);
|
|
|
|
release_bar(dev->pdev);
|
2015-10-14 14:43:46 +00:00
|
|
|
mlx5_pci_disable_device(dev);
|
2015-09-25 07:49:14 +00:00
|
|
|
}
|
|
|
|
|
2023-10-12 19:27:39 +00:00
|
|
|
static void mlx5_register_hca_devcom_comp(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
/* This component is use to sync adding core_dev to lag_dev and to sync
|
|
|
|
* changes of mlx5_adev_devices between LAG layer and other layers.
|
|
|
|
*/
|
|
|
|
if (!mlx5_lag_is_supported(dev))
|
|
|
|
return;
|
|
|
|
|
|
|
|
dev->priv.hca_devcom_comp =
|
|
|
|
mlx5_devcom_register_component(dev->priv.devc, MLX5_DEVCOM_HCA_PORTS,
|
|
|
|
mlx5_query_nic_system_image_guid(dev),
|
|
|
|
NULL, dev);
|
|
|
|
if (IS_ERR_OR_NULL(dev->priv.hca_devcom_comp))
|
|
|
|
mlx5_core_err(dev, "Failed to register devcom HCA component\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mlx5_unregister_hca_devcom_comp(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
mlx5_devcom_unregister_component(dev->priv.hca_devcom_comp);
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:37:53 +00:00
|
|
|
static int mlx5_init_once(struct mlx5_core_dev *dev)
|
2016-09-09 14:35:20 +00:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2023-05-04 09:14:00 +00:00
|
|
|
dev->priv.devc = mlx5_devcom_register_device(dev);
|
|
|
|
if (IS_ERR(dev->priv.devc))
|
|
|
|
mlx5_core_warn(dev, "failed to register devcom device %ld\n",
|
|
|
|
PTR_ERR(dev->priv.devc));
|
2023-10-12 19:27:39 +00:00
|
|
|
mlx5_register_hca_devcom_comp(dev);
|
2018-12-04 19:24:46 +00:00
|
|
|
|
2016-09-09 14:35:20 +00:00
|
|
|
err = mlx5_query_board_id(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "query board id failed\n");
|
2018-12-04 19:24:46 +00:00
|
|
|
goto err_devcom;
|
2016-09-09 14:35:20 +00:00
|
|
|
}
|
|
|
|
|
2019-06-10 23:38:27 +00:00
|
|
|
err = mlx5_irq_table_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "failed to initialize irq table\n");
|
|
|
|
goto err_devcom;
|
|
|
|
}
|
|
|
|
|
2018-11-19 18:52:38 +00:00
|
|
|
err = mlx5_eq_table_init(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "failed to initialize eq\n");
|
2019-06-10 23:38:27 +00:00
|
|
|
goto err_irq_cleanup;
|
2016-09-09 14:35:20 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 22:12:27 +00:00
|
|
|
err = mlx5_events_init(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "failed to initialize events\n");
|
2018-11-20 22:12:27 +00:00
|
|
|
goto err_eq_cleanup;
|
|
|
|
}
|
|
|
|
|
2020-10-07 06:00:49 +00:00
|
|
|
err = mlx5_fw_reset_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "failed to initialize fw reset events\n");
|
|
|
|
goto err_events_cleanup;
|
|
|
|
}
|
|
|
|
|
2019-08-10 10:17:18 +00:00
|
|
|
mlx5_cq_debugfs_init(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
|
2017-03-26 14:01:57 +00:00
|
|
|
mlx5_init_reserved_gids(dev);
|
|
|
|
|
2017-08-15 10:46:04 +00:00
|
|
|
mlx5_init_clock(dev);
|
|
|
|
|
2018-05-09 20:28:00 +00:00
|
|
|
dev->vxlan = mlx5_vxlan_create(dev);
|
2019-01-30 15:21:55 +00:00
|
|
|
dev->geneve = mlx5_geneve_create(dev);
|
2018-05-09 20:28:00 +00:00
|
|
|
|
2016-09-09 14:35:20 +00:00
|
|
|
err = mlx5_init_rl_table(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init rate limiting\n");
|
2016-09-09 14:35:20 +00:00
|
|
|
goto err_tables_cleanup;
|
|
|
|
}
|
|
|
|
|
2017-06-04 20:11:55 +00:00
|
|
|
err = mlx5_mpfs_init(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init l2 table %d\n", err);
|
2017-06-04 20:11:55 +00:00
|
|
|
goto err_rl_cleanup;
|
|
|
|
}
|
|
|
|
|
2019-06-10 23:38:19 +00:00
|
|
|
err = mlx5_sriov_init(dev);
|
2016-09-09 14:35:23 +00:00
|
|
|
if (err) {
|
2019-06-10 23:38:19 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init sriov %d\n", err);
|
2017-06-04 20:11:55 +00:00
|
|
|
goto err_mpfs_cleanup;
|
2016-09-09 14:35:23 +00:00
|
|
|
}
|
|
|
|
|
2019-06-10 23:38:19 +00:00
|
|
|
err = mlx5_eswitch_init(dev);
|
2016-09-09 14:35:23 +00:00
|
|
|
if (err) {
|
2019-06-10 23:38:19 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init eswitch %d\n", err);
|
|
|
|
goto err_sriov_cleanup;
|
2016-09-09 14:35:23 +00:00
|
|
|
}
|
|
|
|
|
2017-06-14 07:19:54 +00:00
|
|
|
err = mlx5_fpga_init(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init fpga device %d\n", err);
|
2019-06-10 23:38:19 +00:00
|
|
|
goto err_eswitch_cleanup;
|
2017-06-14 07:19:54 +00:00
|
|
|
}
|
|
|
|
|
2020-12-12 06:12:16 +00:00
|
|
|
err = mlx5_vhca_event_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed to init vhca event notifier %d\n", err);
|
|
|
|
goto err_fpga_cleanup;
|
|
|
|
}
|
|
|
|
|
net/mlx5: SF, Add port add delete functionality
To handle SF port management outside of the eswitch as independent
software layer, introduce eswitch notifier APIs so that mlx5 upper
layer who wish to support sf port management in switchdev mode can
perform its task whenever eswitch mode is set to switchdev or before
eswitch is disabled.
Initialize sf port table on such eswitch event.
Add SF port add and delete functionality in switchdev mode.
Destroy all SF ports when eswitch is disabled.
Expose SF port add and delete to user via devlink commands.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
or by its unique port index:
$ devlink port show pci/0000:06:00.0/32768
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:00:00",
"state": "inactive",
"opstate": "detached"
}
}
}
}
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:21 +00:00
|
|
|
err = mlx5_sf_hw_table_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed to init SF HW table %d\n", err);
|
|
|
|
goto err_sf_hw_table_cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = mlx5_sf_table_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed to init SF table %d\n", err);
|
|
|
|
goto err_sf_table_cleanup;
|
|
|
|
}
|
|
|
|
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
err = mlx5_fs_core_alloc(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed to alloc flow steering\n");
|
|
|
|
goto err_fs;
|
|
|
|
}
|
|
|
|
|
2019-08-29 23:42:30 +00:00
|
|
|
dev->dm = mlx5_dm_create(dev);
|
|
|
|
if (IS_ERR(dev->dm))
|
2023-05-01 11:37:56 +00:00
|
|
|
mlx5_core_warn(dev, "Failed to init device memory %ld\n", PTR_ERR(dev->dm));
|
2019-08-29 23:42:30 +00:00
|
|
|
|
2018-02-22 08:01:35 +00:00
|
|
|
dev->tracer = mlx5_fw_tracer_create(dev);
|
2019-08-22 05:05:51 +00:00
|
|
|
dev->hv_vhca = mlx5_hv_vhca_create(dev);
|
2020-02-11 22:32:43 +00:00
|
|
|
dev->rsc_dump = mlx5_rsc_dump_create(dev);
|
2018-02-22 08:01:35 +00:00
|
|
|
|
2016-09-09 14:35:20 +00:00
|
|
|
return 0;
|
|
|
|
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
err_fs:
|
|
|
|
mlx5_sf_table_cleanup(dev);
|
net/mlx5: SF, Add port add delete functionality
To handle SF port management outside of the eswitch as independent
software layer, introduce eswitch notifier APIs so that mlx5 upper
layer who wish to support sf port management in switchdev mode can
perform its task whenever eswitch mode is set to switchdev or before
eswitch is disabled.
Initialize sf port table on such eswitch event.
Add SF port add and delete functionality in switchdev mode.
Destroy all SF ports when eswitch is disabled.
Expose SF port add and delete to user via devlink commands.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
or by its unique port index:
$ devlink port show pci/0000:06:00.0/32768
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:00:00",
"state": "inactive",
"opstate": "detached"
}
}
}
}
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:21 +00:00
|
|
|
err_sf_table_cleanup:
|
|
|
|
mlx5_sf_hw_table_cleanup(dev);
|
|
|
|
err_sf_hw_table_cleanup:
|
|
|
|
mlx5_vhca_event_cleanup(dev);
|
2020-12-12 06:12:16 +00:00
|
|
|
err_fpga_cleanup:
|
|
|
|
mlx5_fpga_cleanup(dev);
|
2016-09-09 14:35:23 +00:00
|
|
|
err_eswitch_cleanup:
|
|
|
|
mlx5_eswitch_cleanup(dev->priv.eswitch);
|
2019-06-10 23:38:19 +00:00
|
|
|
err_sriov_cleanup:
|
|
|
|
mlx5_sriov_cleanup(dev);
|
2017-06-04 20:11:55 +00:00
|
|
|
err_mpfs_cleanup:
|
|
|
|
mlx5_mpfs_cleanup(dev);
|
2016-09-09 14:35:23 +00:00
|
|
|
err_rl_cleanup:
|
|
|
|
mlx5_cleanup_rl_table(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
err_tables_cleanup:
|
2019-01-30 15:21:55 +00:00
|
|
|
mlx5_geneve_destroy(dev->geneve);
|
2018-05-09 20:28:00 +00:00
|
|
|
mlx5_vxlan_destroy(dev->vxlan);
|
2022-10-18 10:51:52 +00:00
|
|
|
mlx5_cleanup_clock(dev);
|
|
|
|
mlx5_cleanup_reserved_gids(dev);
|
net/mlx5: CQ Database per EQ
Before this patch the driver had one CQ database protected via one
spinlock, this spinlock is meant to synchronize between CQ
adding/removing and CQ IRQ interrupt handling.
On a system with large number of CPUs and on a work load that requires
lots of interrupts, this global spinlock becomes a very nasty hotspot
and introduces a contention between the active cores, which will
significantly hurt performance and becomes a bottleneck that prevents
seamless cpu scaling.
To solve this we simply move the CQ database and its spinlock to be per
EQ (IRQ), thus per core.
Tested with:
system: 2 sockets, 14 cores per socket, hyperthreading, 2x14x2=56 cores
netperf command: ./super_netperf 200 -P 0 -t TCP_RR -H <server> -l 30 -- -r 300,300 -o -s 1M,1M -S 1M,1M
WITHOUT THIS PATCH:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 4.32 0.00 36.15 0.09 0.00 34.02 0.00 0.00 0.00 25.41
Samples: 2M of event 'cycles:pp', Event count (approx.): 1554616897271
Overhead Command Shared Object Symbol
+ 14.28% swapper [kernel.vmlinux] [k] intel_idle
+ 12.25% swapper [kernel.vmlinux] [k] queued_spin_lock_slowpath
+ 10.29% netserver [kernel.vmlinux] [k] queued_spin_lock_slowpath
+ 1.32% netserver [kernel.vmlinux] [k] mlx5e_xmit
WITH THIS PATCH:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 4.27 0.00 34.31 0.01 0.00 18.71 0.00 0.00 0.00 42.69
Samples: 2M of event 'cycles:pp', Event count (approx.): 1498132937483
Overhead Command Shared Object Symbol
+ 23.33% swapper [kernel.vmlinux] [k] intel_idle
+ 1.69% netserver [kernel.vmlinux] [k] mlx5e_xmit
Tested-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Gal Pressman <galp@mellanox.com>
2018-01-20 00:13:01 +00:00
|
|
|
mlx5_cq_debugfs_cleanup(dev);
|
2020-10-07 06:00:49 +00:00
|
|
|
mlx5_fw_reset_cleanup(dev);
|
|
|
|
err_events_cleanup:
|
2018-11-20 22:12:27 +00:00
|
|
|
mlx5_events_cleanup(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
err_eq_cleanup:
|
2018-11-19 18:52:38 +00:00
|
|
|
mlx5_eq_table_cleanup(dev);
|
2019-06-10 23:38:27 +00:00
|
|
|
err_irq_cleanup:
|
|
|
|
mlx5_irq_table_cleanup(dev);
|
2018-12-04 19:24:46 +00:00
|
|
|
err_devcom:
|
2023-10-12 19:27:39 +00:00
|
|
|
mlx5_unregister_hca_devcom_comp(dev);
|
2023-05-04 09:14:00 +00:00
|
|
|
mlx5_devcom_unregister_device(dev->priv.devc);
|
2016-09-09 14:35:20 +00:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2020-02-11 22:32:43 +00:00
|
|
|
mlx5_rsc_dump_destroy(dev);
|
2019-08-22 05:05:51 +00:00
|
|
|
mlx5_hv_vhca_destroy(dev->hv_vhca);
|
2018-02-22 08:01:35 +00:00
|
|
|
mlx5_fw_tracer_destroy(dev->tracer);
|
2019-08-29 23:42:30 +00:00
|
|
|
mlx5_dm_cleanup(dev);
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
mlx5_fs_core_free(dev);
|
net/mlx5: SF, Add port add delete functionality
To handle SF port management outside of the eswitch as independent
software layer, introduce eswitch notifier APIs so that mlx5 upper
layer who wish to support sf port management in switchdev mode can
perform its task whenever eswitch mode is set to switchdev or before
eswitch is disabled.
Initialize sf port table on such eswitch event.
Add SF port add and delete functionality in switchdev mode.
Destroy all SF ports when eswitch is disabled.
Expose SF port add and delete to user via devlink commands.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
or by its unique port index:
$ devlink port show pci/0000:06:00.0/32768
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:00:00",
"state": "inactive",
"opstate": "detached"
}
}
}
}
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:21 +00:00
|
|
|
mlx5_sf_table_cleanup(dev);
|
|
|
|
mlx5_sf_hw_table_cleanup(dev);
|
2020-12-12 06:12:16 +00:00
|
|
|
mlx5_vhca_event_cleanup(dev);
|
2017-06-14 07:19:54 +00:00
|
|
|
mlx5_fpga_cleanup(dev);
|
2016-09-09 14:35:23 +00:00
|
|
|
mlx5_eswitch_cleanup(dev->priv.eswitch);
|
2019-06-10 23:38:19 +00:00
|
|
|
mlx5_sriov_cleanup(dev);
|
2017-06-04 20:11:55 +00:00
|
|
|
mlx5_mpfs_cleanup(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
mlx5_cleanup_rl_table(dev);
|
2019-01-30 15:21:55 +00:00
|
|
|
mlx5_geneve_destroy(dev->geneve);
|
2018-05-09 20:28:00 +00:00
|
|
|
mlx5_vxlan_destroy(dev->vxlan);
|
2017-08-15 10:46:04 +00:00
|
|
|
mlx5_cleanup_clock(dev);
|
2017-03-26 14:01:57 +00:00
|
|
|
mlx5_cleanup_reserved_gids(dev);
|
net/mlx5: CQ Database per EQ
Before this patch the driver had one CQ database protected via one
spinlock, this spinlock is meant to synchronize between CQ
adding/removing and CQ IRQ interrupt handling.
On a system with large number of CPUs and on a work load that requires
lots of interrupts, this global spinlock becomes a very nasty hotspot
and introduces a contention between the active cores, which will
significantly hurt performance and becomes a bottleneck that prevents
seamless cpu scaling.
To solve this we simply move the CQ database and its spinlock to be per
EQ (IRQ), thus per core.
Tested with:
system: 2 sockets, 14 cores per socket, hyperthreading, 2x14x2=56 cores
netperf command: ./super_netperf 200 -P 0 -t TCP_RR -H <server> -l 30 -- -r 300,300 -o -s 1M,1M -S 1M,1M
WITHOUT THIS PATCH:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 4.32 0.00 36.15 0.09 0.00 34.02 0.00 0.00 0.00 25.41
Samples: 2M of event 'cycles:pp', Event count (approx.): 1554616897271
Overhead Command Shared Object Symbol
+ 14.28% swapper [kernel.vmlinux] [k] intel_idle
+ 12.25% swapper [kernel.vmlinux] [k] queued_spin_lock_slowpath
+ 10.29% netserver [kernel.vmlinux] [k] queued_spin_lock_slowpath
+ 1.32% netserver [kernel.vmlinux] [k] mlx5e_xmit
WITH THIS PATCH:
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 4.27 0.00 34.31 0.01 0.00 18.71 0.00 0.00 0.00 42.69
Samples: 2M of event 'cycles:pp', Event count (approx.): 1498132937483
Overhead Command Shared Object Symbol
+ 23.33% swapper [kernel.vmlinux] [k] intel_idle
+ 1.69% netserver [kernel.vmlinux] [k] mlx5e_xmit
Tested-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Gal Pressman <galp@mellanox.com>
2018-01-20 00:13:01 +00:00
|
|
|
mlx5_cq_debugfs_cleanup(dev);
|
2020-10-07 06:00:49 +00:00
|
|
|
mlx5_fw_reset_cleanup(dev);
|
2018-11-20 22:12:27 +00:00
|
|
|
mlx5_events_cleanup(dev);
|
2018-11-19 18:52:38 +00:00
|
|
|
mlx5_eq_table_cleanup(dev);
|
2019-06-10 23:38:27 +00:00
|
|
|
mlx5_irq_table_cleanup(dev);
|
2023-10-12 19:27:39 +00:00
|
|
|
mlx5_unregister_hca_devcom_comp(dev);
|
2023-05-04 09:14:00 +00:00
|
|
|
mlx5_devcom_unregister_device(dev->priv.devc);
|
2016-09-09 14:35:20 +00:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:08:48 +00:00
|
|
|
static int mlx5_function_enable(struct mlx5_core_dev *dev, bool boot, u64 timeout)
|
2015-09-25 07:49:14 +00:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_info(dev, "firmware version: %d.%d.%d\n", fw_rev_maj(dev),
|
|
|
|
fw_rev_min(dev), fw_rev_sub(dev));
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2018-03-30 14:01:34 +00:00
|
|
|
/* Only PFs hold the relevant PCIe information for this query */
|
|
|
|
if (mlx5_core_is_pf(dev))
|
|
|
|
pcie_print_link_status(dev->pdev);
|
|
|
|
|
2017-06-08 16:33:16 +00:00
|
|
|
/* wait for firmware to accept initialization segments configurations
|
|
|
|
*/
|
net/mlx5: Increase FW pre-init timeout for health recovery
Currently, health recovery will reload driver to recover it from fatal
errors. During the driver's load process, it would wait for FW to set the
pre-init bit for up to 120 seconds, beyond this threshold it would abort
the load process. In some cases, such as a FW upgrade on the DPU, this
timeout period is insufficient, and the user has no way to recover the
host device.
To solve this issue, introduce a new FW pre-init timeout for health
recovery, which is set to 2 hours.
The timeout for devlink reload and probe will use the original one because
they are user triggered flows, and therefore should not have a
significantly long timeout, during which the user command would hang.
Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-27 14:36:44 +00:00
|
|
|
err = wait_fw_init(dev, timeout,
|
2021-10-07 15:00:27 +00:00
|
|
|
mlx5_tout_ms(dev, FW_PRE_INIT_WARN_MESSAGE_INTERVAL));
|
2017-06-08 16:33:16 +00:00
|
|
|
if (err) {
|
2021-10-07 15:00:27 +00:00
|
|
|
mlx5_core_err(dev, "Firmware over %llu MS in pre-initializing state, aborting\n",
|
net/mlx5: Increase FW pre-init timeout for health recovery
Currently, health recovery will reload driver to recover it from fatal
errors. During the driver's load process, it would wait for FW to set the
pre-init bit for up to 120 seconds, beyond this threshold it would abort
the load process. In some cases, such as a FW upgrade on the DPU, this
timeout period is insufficient, and the user has no way to recover the
host device.
To solve this issue, introduce a new FW pre-init timeout for health
recovery, which is set to 2 hours.
The timeout for devlink reload and probe will use the original one because
they are user triggered flows, and therefore should not have a
significantly long timeout, during which the user command would hang.
Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-27 14:36:44 +00:00
|
|
|
timeout);
|
2021-10-20 09:45:05 +00:00
|
|
|
return err;
|
2017-06-08 16:33:16 +00:00
|
|
|
}
|
|
|
|
|
2023-01-18 18:55:54 +00:00
|
|
|
err = mlx5_cmd_enable(dev);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed initializing command interface, aborting\n");
|
2021-10-20 09:45:05 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2021-10-07 15:00:27 +00:00
|
|
|
mlx5_tout_query_iseg(dev);
|
|
|
|
|
|
|
|
err = wait_fw_init(dev, mlx5_tout_ms(dev, FW_INIT), 0);
|
2015-10-14 14:43:47 +00:00
|
|
|
if (err) {
|
2021-10-07 15:00:27 +00:00
|
|
|
mlx5_core_err(dev, "Firmware over %llu MS in initializing state, aborting\n",
|
|
|
|
mlx5_tout_ms(dev, FW_INIT));
|
2017-03-30 14:00:25 +00:00
|
|
|
goto err_cmd_cleanup;
|
2015-10-14 14:43:47 +00:00
|
|
|
}
|
|
|
|
|
2023-04-28 10:48:13 +00:00
|
|
|
dev->caps.embedded_cpu = mlx5_read_embedded_cpu(dev);
|
2020-03-19 19:43:13 +00:00
|
|
|
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP);
|
|
|
|
|
2022-10-02 04:56:28 +00:00
|
|
|
mlx5_start_health_poll(dev);
|
|
|
|
|
2015-12-01 16:03:08 +00:00
|
|
|
err = mlx5_core_enable_hca(dev, 0);
|
2013-07-18 12:31:08 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "enable hca failed\n");
|
2022-10-02 04:56:28 +00:00
|
|
|
goto stop_health_poll;
|
2013-07-18 12:31:08 +00:00
|
|
|
}
|
|
|
|
|
2015-05-28 19:28:48 +00:00
|
|
|
err = mlx5_core_set_issi(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "failed to set issi\n");
|
2015-05-28 19:28:48 +00:00
|
|
|
goto err_disable_hca;
|
|
|
|
}
|
|
|
|
|
2013-07-18 12:31:08 +00:00
|
|
|
err = mlx5_satisfy_startup_pages(dev, 1);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "failed to allocate boot pages\n");
|
2013-07-18 12:31:08 +00:00
|
|
|
goto err_disable_hca;
|
|
|
|
}
|
|
|
|
|
2021-10-13 06:07:13 +00:00
|
|
|
err = mlx5_tout_query_dtor(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "failed to read dtor\n");
|
|
|
|
goto reclaim_boot_pages;
|
|
|
|
}
|
|
|
|
|
2023-05-03 09:08:48 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
reclaim_boot_pages:
|
|
|
|
mlx5_reclaim_startup_pages(dev);
|
|
|
|
err_disable_hca:
|
|
|
|
mlx5_core_disable_hca(dev, 0);
|
|
|
|
stop_health_poll:
|
|
|
|
mlx5_stop_health_poll(dev, boot);
|
|
|
|
err_cmd_cleanup:
|
|
|
|
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
2023-01-18 18:55:54 +00:00
|
|
|
mlx5_cmd_disable(dev);
|
2023-05-03 09:08:48 +00:00
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void mlx5_function_disable(struct mlx5_core_dev *dev, bool boot)
|
|
|
|
{
|
|
|
|
mlx5_reclaim_startup_pages(dev);
|
|
|
|
mlx5_core_disable_hca(dev, 0);
|
|
|
|
mlx5_stop_health_poll(dev, boot);
|
|
|
|
mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN);
|
2023-01-18 18:55:54 +00:00
|
|
|
mlx5_cmd_disable(dev);
|
2023-05-03 09:08:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int mlx5_function_open(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
err = set_hca_ctrl(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "set_hca_ctrl failed\n");
|
2023-05-03 09:08:48 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2019-02-17 11:11:02 +00:00
|
|
|
err = set_hca_cap(dev);
|
2015-12-14 14:34:09 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "set_hca_cap failed\n");
|
2023-05-03 09:08:48 +00:00
|
|
|
return err;
|
2019-01-22 06:48:51 +00:00
|
|
|
}
|
|
|
|
|
2013-07-18 12:31:08 +00:00
|
|
|
err = mlx5_satisfy_startup_pages(dev, 0);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "failed to allocate init pages\n");
|
2023-05-03 09:08:48 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2018-01-04 15:25:32 +00:00
|
|
|
err = mlx5_cmd_init_hca(dev, sw_owner_id);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "init hca failed\n");
|
2023-05-03 09:08:48 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 11:46:00 +00:00
|
|
|
mlx5_set_driver_version(dev);
|
|
|
|
|
2016-10-25 15:36:25 +00:00
|
|
|
err = mlx5_query_hca_caps(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "query hca failed\n");
|
2023-05-03 09:08:48 +00:00
|
|
|
return err;
|
2016-10-25 15:36:25 +00:00
|
|
|
}
|
2022-10-02 04:56:28 +00:00
|
|
|
mlx5_start_health_fw_log_up(dev);
|
2019-03-29 22:37:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-03 09:08:48 +00:00
|
|
|
static int mlx5_function_close(struct mlx5_core_dev *dev)
|
2019-03-29 22:37:56 +00:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = mlx5_cmd_teardown_hca(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "tear_down_hca failed, skip cleanup\n");
|
2019-03-29 22:37:56 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
2019-03-29 22:37:56 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-05-03 09:08:48 +00:00
|
|
|
static int mlx5_function_setup(struct mlx5_core_dev *dev, bool boot, u64 timeout)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = mlx5_function_enable(dev, boot, timeout);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
err = mlx5_function_open(dev);
|
|
|
|
if (err)
|
|
|
|
mlx5_function_disable(dev, boot);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mlx5_function_teardown(struct mlx5_core_dev *dev, bool boot)
|
|
|
|
{
|
|
|
|
int err = mlx5_function_close(dev);
|
|
|
|
|
|
|
|
if (!err)
|
|
|
|
mlx5_function_disable(dev, boot);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2019-03-29 22:37:57 +00:00
|
|
|
static int mlx5_load(struct mlx5_core_dev *dev)
|
2019-03-29 22:37:56 +00:00
|
|
|
{
|
|
|
|
int err;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2017-01-03 21:55:24 +00:00
|
|
|
dev->priv.uar = mlx5_get_uars_page(dev);
|
2017-11-20 07:58:01 +00:00
|
|
|
if (IS_ERR(dev->priv.uar)) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed allocating uar, aborting\n");
|
2017-11-20 07:58:01 +00:00
|
|
|
err = PTR_ERR(dev->priv.uar);
|
2019-03-29 22:37:57 +00:00
|
|
|
return err;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2018-11-20 22:12:27 +00:00
|
|
|
mlx5_events_start(dev);
|
2018-11-20 22:12:23 +00:00
|
|
|
mlx5_pagealloc_start(dev);
|
|
|
|
|
2019-06-10 23:38:32 +00:00
|
|
|
err = mlx5_irq_table_create(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed to alloc IRQs\n");
|
|
|
|
goto err_irq_table;
|
|
|
|
}
|
|
|
|
|
2018-11-19 18:52:36 +00:00
|
|
|
err = mlx5_eq_table_create(dev);
|
2013-07-07 14:25:49 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to create EQs\n");
|
2018-11-19 18:52:36 +00:00
|
|
|
goto err_eq_table;
|
2013-07-07 14:25:49 +00:00
|
|
|
}
|
|
|
|
|
2018-02-22 08:01:35 +00:00
|
|
|
err = mlx5_fw_tracer_init(dev->tracer);
|
|
|
|
if (err) {
|
2021-08-02 10:33:03 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init FW tracer %d\n", err);
|
|
|
|
mlx5_fw_tracer_destroy(dev->tracer);
|
|
|
|
dev->tracer = NULL;
|
2018-02-22 08:01:35 +00:00
|
|
|
}
|
|
|
|
|
2020-10-07 06:00:49 +00:00
|
|
|
mlx5_fw_reset_events_start(dev);
|
2019-08-22 05:05:51 +00:00
|
|
|
mlx5_hv_vhca_init(dev->hv_vhca);
|
|
|
|
|
2020-02-11 22:32:43 +00:00
|
|
|
err = mlx5_rsc_dump_init(dev);
|
|
|
|
if (err) {
|
2021-08-02 10:33:03 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init Resource dump %d\n", err);
|
|
|
|
mlx5_rsc_dump_destroy(dev);
|
|
|
|
dev->rsc_dump = NULL;
|
2020-02-11 22:32:43 +00:00
|
|
|
}
|
|
|
|
|
2017-11-19 15:51:13 +00:00
|
|
|
err = mlx5_fpga_device_start(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "fpga device start failed %d\n", err);
|
2017-11-19 15:51:13 +00:00
|
|
|
goto err_fpga_start;
|
|
|
|
}
|
|
|
|
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
err = mlx5_fs_core_init(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init flow steering\n");
|
2017-05-30 06:42:54 +00:00
|
|
|
goto err_fs;
|
2016-09-09 14:35:20 +00:00
|
|
|
}
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2017-05-30 06:42:54 +00:00
|
|
|
err = mlx5_core_set_hca_defaults(dev);
|
2015-12-10 15:12:44 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to set hca defaults\n");
|
2021-03-08 13:41:55 +00:00
|
|
|
goto err_set_hca;
|
2015-12-10 15:12:44 +00:00
|
|
|
}
|
2016-06-23 14:02:37 +00:00
|
|
|
|
2020-12-12 06:12:16 +00:00
|
|
|
mlx5_vhca_event_start(dev);
|
|
|
|
|
net/mlx5: SF, Port function state change support
Support changing the state of the SF port's function through devlink.
When activating the SF port's function, enable the hca in the device
followed by adding its auxiliary device.
When deactivating the SF port's function, delete its auxiliary device
followed by disabling the vHCA.
Port function attributes get/set callbacks are invoked with devlink
instance lock held. Such callbacks need to synchronize with sf port
table getting disabled either via sriov sysfs callback. Such callbacks
synchronize with table disable context holding table refcount.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:88:88 state inactive opstate detached
$ devlink port function set pci/0000:06:00.0/32768 hw_addr 00:00:00:00:88:88 state active
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:88:88",
"state": "active",
"opstate": "attached"
}
}
}
}
On port function activation, an auxiliary device is created in below
example.
$ devlink dev show
devlink dev show auxiliary/mlx5_core.sf.4
$ devlink port show auxiliary/mlx5_core.sf.4/1
auxiliary/mlx5_core.sf.4/1: type eth netdev p0sf88 flavour virtual port 0 splittable false
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:22 +00:00
|
|
|
err = mlx5_sf_hw_table_create(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "sf table create failed %d\n", err);
|
|
|
|
goto err_vhca;
|
|
|
|
}
|
|
|
|
|
2019-02-13 06:55:36 +00:00
|
|
|
err = mlx5_ec_init(dev);
|
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "Failed to init embedded CPU\n");
|
2019-02-13 06:55:36 +00:00
|
|
|
goto err_ec;
|
|
|
|
}
|
|
|
|
|
2021-08-03 23:19:56 +00:00
|
|
|
mlx5_lag_add_mdev(dev);
|
2020-11-20 23:03:38 +00:00
|
|
|
err = mlx5_sriov_attach(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "sriov init failed %d\n", err);
|
|
|
|
goto err_sriov;
|
|
|
|
}
|
|
|
|
|
2020-12-12 06:12:17 +00:00
|
|
|
mlx5_sf_dev_table_create(dev);
|
|
|
|
|
2022-08-08 17:02:59 +00:00
|
|
|
err = mlx5_devlink_traps_register(priv_to_devlink(dev));
|
|
|
|
if (err)
|
|
|
|
goto err_traps_reg;
|
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
return 0;
|
|
|
|
|
2022-08-08 17:02:59 +00:00
|
|
|
err_traps_reg:
|
|
|
|
mlx5_sf_dev_table_destroy(dev);
|
|
|
|
mlx5_sriov_detach(dev);
|
2016-09-09 14:35:20 +00:00
|
|
|
err_sriov:
|
2021-08-03 23:19:56 +00:00
|
|
|
mlx5_lag_remove_mdev(dev);
|
2020-11-20 23:03:38 +00:00
|
|
|
mlx5_ec_cleanup(dev);
|
|
|
|
err_ec:
|
net/mlx5: SF, Port function state change support
Support changing the state of the SF port's function through devlink.
When activating the SF port's function, enable the hca in the device
followed by adding its auxiliary device.
When deactivating the SF port's function, delete its auxiliary device
followed by disabling the vHCA.
Port function attributes get/set callbacks are invoked with devlink
instance lock held. Such callbacks need to synchronize with sf port
table getting disabled either via sriov sysfs callback. Such callbacks
synchronize with table disable context holding table refcount.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:88:88 state inactive opstate detached
$ devlink port function set pci/0000:06:00.0/32768 hw_addr 00:00:00:00:88:88 state active
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:88:88",
"state": "active",
"opstate": "attached"
}
}
}
}
On port function activation, an auxiliary device is created in below
example.
$ devlink dev show
devlink dev show auxiliary/mlx5_core.sf.4
$ devlink port show auxiliary/mlx5_core.sf.4/1
auxiliary/mlx5_core.sf.4/1: type eth netdev p0sf88 flavour virtual port 0 splittable false
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:22 +00:00
|
|
|
mlx5_sf_hw_table_destroy(dev);
|
|
|
|
err_vhca:
|
2020-12-12 06:12:16 +00:00
|
|
|
mlx5_vhca_event_stop(dev);
|
2021-03-08 13:41:55 +00:00
|
|
|
err_set_hca:
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
mlx5_fs_core_cleanup(dev);
|
2015-12-10 15:12:44 +00:00
|
|
|
err_fs:
|
2017-11-19 15:51:13 +00:00
|
|
|
mlx5_fpga_device_stop(dev);
|
|
|
|
err_fpga_start:
|
2020-02-11 22:32:43 +00:00
|
|
|
mlx5_rsc_dump_cleanup(dev);
|
2019-08-22 05:05:51 +00:00
|
|
|
mlx5_hv_vhca_cleanup(dev->hv_vhca);
|
2020-10-07 06:00:49 +00:00
|
|
|
mlx5_fw_reset_events_stop(dev);
|
2018-02-22 08:01:35 +00:00
|
|
|
mlx5_fw_tracer_cleanup(dev->tracer);
|
2018-11-19 18:52:36 +00:00
|
|
|
mlx5_eq_table_destroy(dev);
|
|
|
|
err_eq_table:
|
2019-06-10 23:38:32 +00:00
|
|
|
mlx5_irq_table_destroy(dev);
|
|
|
|
err_irq_table:
|
2018-11-20 22:12:23 +00:00
|
|
|
mlx5_pagealloc_stop(dev);
|
2018-11-20 22:12:27 +00:00
|
|
|
mlx5_events_stop(dev);
|
2019-03-29 22:37:53 +00:00
|
|
|
mlx5_put_uars_page(dev, dev->priv.uar);
|
2019-03-29 22:37:57 +00:00
|
|
|
return err;
|
|
|
|
}
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2019-03-29 22:37:57 +00:00
|
|
|
static void mlx5_unload(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2023-09-13 07:12:33 +00:00
|
|
|
mlx5_eswitch_disable(dev->priv.eswitch);
|
2022-08-08 17:02:59 +00:00
|
|
|
mlx5_devlink_traps_unregister(priv_to_devlink(dev));
|
2020-12-12 06:12:17 +00:00
|
|
|
mlx5_sf_dev_table_destroy(dev);
|
2022-10-19 21:13:50 +00:00
|
|
|
mlx5_sriov_detach(dev);
|
2021-08-03 23:19:56 +00:00
|
|
|
mlx5_lag_remove_mdev(dev);
|
2020-11-20 23:03:38 +00:00
|
|
|
mlx5_ec_cleanup(dev);
|
net/mlx5: SF, Port function state change support
Support changing the state of the SF port's function through devlink.
When activating the SF port's function, enable the hca in the device
followed by adding its auxiliary device.
When deactivating the SF port's function, delete its auxiliary device
followed by disabling the vHCA.
Port function attributes get/set callbacks are invoked with devlink
instance lock held. Such callbacks need to synchronize with sf port
table getting disabled either via sriov sysfs callback. Such callbacks
synchronize with table disable context holding table refcount.
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
$ devlink port show
pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false
$ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
$ devlink port show ens2f0npf0sf88
pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false
function:
hw_addr 00:00:00:00:88:88 state inactive opstate detached
$ devlink port function set pci/0000:06:00.0/32768 hw_addr 00:00:00:00:88:88 state active
$ devlink port show ens2f0npf0sf88 -jp
{
"port": {
"pci/0000:06:00.0/32768": {
"type": "eth",
"netdev": "ens2f0npf0sf88",
"flavour": "pcisf",
"controller": 0,
"pfnum": 0,
"sfnum": 88,
"external": false,
"splittable": false,
"function": {
"hw_addr": "00:00:00:00:88:88",
"state": "active",
"opstate": "attached"
}
}
}
}
On port function activation, an auxiliary device is created in below
example.
$ devlink dev show
devlink dev show auxiliary/mlx5_core.sf.4
$ devlink port show auxiliary/mlx5_core.sf.4/1
auxiliary/mlx5_core.sf.4/1: type eth netdev p0sf88 flavour virtual port 0 splittable false
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Vu Pham <vuhuong@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2020-12-12 06:12:22 +00:00
|
|
|
mlx5_sf_hw_table_destroy(dev);
|
2020-12-12 06:12:16 +00:00
|
|
|
mlx5_vhca_event_stop(dev);
|
net/mlx5: Initialize flow steering during driver probe
Currently, software objects of flow steering are created and destroyed
during reload flow. In case a device is unloaded, the following error
is printed during grace period:
mlx5_core 0000:00:0b.0: mlx5_fw_fatal_reporter_err_work:690:(pid 95):
Driver is in error state. Unloading
As a solution to fix use-after-free bugs, where we try to access
these objects, when reading the value of flow_steering_mode devlink
param[1], let's split flow steering creation and destruction into two
routines:
* init and cleanup: memory, cache, and pools allocation/free.
* create and destroy: namespaces initialization and cleanup.
While at it, re-order the cleanup function to mirror the init function.
[1]
Kasan trace:
[ 385.119849 ] BUG: KASAN: use-after-free in mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] Read of size 4 at addr ffff888104b79308 by task bash/291
[ 385.119849 ]
[ 385.119849 ] CPU: 1 PID: 291 Comm: bash Not tainted 5.17.0-rc1+ #2
[ 385.119849 ] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-2.fc32 04/01/2014
[ 385.119849 ] Call Trace:
[ 385.119849 ] <TASK>
[ 385.119849 ] dump_stack_lvl+0x6e/0x91
[ 385.119849 ] print_address_description.constprop.0+0x1f/0x160
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] kasan_report.cold+0x83/0xdf
[ 385.119849 ] ? devlink_param_notify+0x20/0x190
[ 385.119849 ] ? mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] mlx5_devlink_fs_mode_get+0x3b/0xa0
[ 385.119849 ] devlink_nl_param_fill+0x18a/0xa50
[ 385.119849 ] ? _raw_spin_lock_irqsave+0x8d/0xe0
[ 385.119849 ] ? devlink_flash_update_timeout_notify+0xf0/0xf0
[ 385.119849 ] ? __wake_up_common+0x4b/0x1e0
[ 385.119849 ] ? preempt_count_sub+0x14/0xc0
[ 385.119849 ] ? _raw_spin_unlock_irqrestore+0x28/0x40
[ 385.119849 ] ? __wake_up_common_lock+0xe3/0x140
[ 385.119849 ] ? __wake_up_common+0x1e0/0x1e0
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp8+0x27/0x80
[ 385.119849 ] ? __rcu_read_unlock+0x48/0x70
[ 385.119849 ] ? kasan_unpoison+0x23/0x50
[ 385.119849 ] ? __kasan_slab_alloc+0x2c/0x80
[ 385.119849 ] ? memset+0x20/0x40
[ 385.119849 ] ? __sanitizer_cov_trace_const_cmp4+0x25/0x80
[ 385.119849 ] devlink_param_notify+0xce/0x190
[ 385.119849 ] devlink_unregister+0x92/0x2b0
[ 385.119849 ] remove_one+0x41/0x140
[ 385.119849 ] pci_device_remove+0x68/0x140
[ 385.119849 ] ? pcibios_free_irq+0x10/0x10
[ 385.119849 ] __device_release_driver+0x294/0x3f0
[ 385.119849 ] device_driver_detach+0x82/0x130
[ 385.119849 ] unbind_store+0x193/0x1b0
[ 385.119849 ] ? subsys_interface_unregister+0x270/0x270
[ 385.119849 ] drv_attr_store+0x4e/0x70
[ 385.119849 ] ? drv_attr_show+0x60/0x60
[ 385.119849 ] sysfs_kf_write+0xa7/0xc0
[ 385.119849 ] kernfs_fop_write_iter+0x23a/0x2f0
[ 385.119849 ] ? sysfs_kf_bin_read+0x160/0x160
[ 385.119849 ] new_sync_write+0x311/0x430
[ 385.119849 ] ? new_sync_read+0x480/0x480
[ 385.119849 ] ? _raw_spin_lock+0x87/0xe0
[ 385.119849 ] ? __sanitizer_cov_trace_cmp4+0x25/0x80
[ 385.119849 ] ? security_file_permission+0x94/0xa0
[ 385.119849 ] vfs_write+0x4c7/0x590
[ 385.119849 ] ksys_write+0xf6/0x1e0
[ 385.119849 ] ? __x64_sys_read+0x50/0x50
[ 385.119849 ] ? fpregs_assert_state_consistent+0x99/0xa0
[ 385.119849 ] do_syscall_64+0x3d/0x90
[ 385.119849 ] entry_SYSCALL_64_after_hwframe+0x44/0xae
[ 385.119849 ] RIP: 0033:0x7fc36ef38504
[ 385.119849 ] Code: 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b3 0f 1f
80 00 00 00 00 48 8d 05 f9 61 0d 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f
05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 41 54 49 89 d4 55 48 89 f5 53
[ 385.119849 ] RSP: 002b:00007ffde0ff3d08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 385.119849 ] RAX: ffffffffffffffda RBX: 000000000000000c RCX: 00007fc36ef38504
[ 385.119849 ] RDX: 000000000000000c RSI: 00007fc370521040 RDI: 0000000000000001
[ 385.119849 ] RBP: 00007fc370521040 R08: 00007fc36f00b8c0 R09: 00007fc36ee4b740
[ 385.119849 ] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fc36f00a760
[ 385.119849 ] R13: 000000000000000c R14: 00007fc36f005760 R15: 000000000000000c
[ 385.119849 ] </TASK>
[ 385.119849 ]
[ 385.119849 ] Allocated by task 65:
[ 385.119849 ] kasan_save_stack+0x1e/0x40
[ 385.119849 ] __kasan_kmalloc+0x81/0xa0
[ 385.119849 ] mlx5_init_fs+0x11b/0x1160
[ 385.119849 ] mlx5_load+0x13c/0x220
[ 385.119849 ] mlx5_load_one+0xda/0x160
[ 385.119849 ] mlx5_recover_device+0xb8/0x100
[ 385.119849 ] mlx5_health_try_recover+0x2f9/0x3a1
[ 385.119849 ] devlink_health_reporter_recover+0x75/0x100
[ 385.119849 ] devlink_health_report+0x26c/0x4b0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work+0x11e/0x1b0
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] Freed by task 65:
[ 385.275909 ] kasan_save_stack+0x1e/0x40
[ 385.275909 ] kasan_set_track+0x21/0x30
[ 385.275909 ] kasan_set_free_info+0x20/0x30
[ 385.275909 ] __kasan_slab_free+0xfc/0x140
[ 385.275909 ] kfree+0xa5/0x3b0
[ 385.275909 ] mlx5_unload+0x2e/0xb0
[ 385.275909 ] mlx5_unload_one+0x86/0xb0
[ 385.275909 ] mlx5_fw_fatal_reporter_err_work.cold+0xca/0xcf
[ 385.275909 ] process_one_work+0x520/0x970
[ 385.275909 ] worker_thread+0x378/0x950
[ 385.275909 ] kthread+0x1bb/0x200
[ 385.275909 ] ret_from_fork+0x1f/0x30
[ 385.275909 ]
[ 385.275909 ] The buggy address belongs to the object at ffff888104b79300
[ 385.275909 ] which belongs to the cache kmalloc-128 of size 128
[ 385.275909 ] The buggy address is located 8 bytes inside of
[ 385.275909 ] 128-byte region [ffff888104b79300, ffff888104b79380)
[ 385.275909 ] The buggy address belongs to the page:
[ 385.275909 ] page:00000000de44dd39 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x104b78
[ 385.275909 ] head:00000000de44dd39 order:1 compound_mapcount:0
[ 385.275909 ] flags: 0x8000000000010200(slab|head|zone=2)
[ 385.275909 ] raw: 8000000000010200 0000000000000000 dead000000000122 ffff8881000428c0
[ 385.275909 ] raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
[ 385.275909 ] page dumped because: kasan: bad access detected
[ 385.275909 ]
[ 385.275909 ] Memory state around the buggy address:
[ 385.275909 ] ffff888104b79200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc
[ 385.275909 ] ffff888104b79280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] >ffff888104b79300: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ] ^
[ 385.275909 ] ffff888104b79380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 385.275909 ] ffff888104b79400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 385.275909 ]]
Fixes: e890acd5ff18 ("net/mlx5: Add devlink flow_steering_mode parameter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-09 12:45:58 +00:00
|
|
|
mlx5_fs_core_cleanup(dev);
|
2019-03-29 22:37:57 +00:00
|
|
|
mlx5_fpga_device_stop(dev);
|
2020-02-11 22:32:43 +00:00
|
|
|
mlx5_rsc_dump_cleanup(dev);
|
2019-08-22 05:05:51 +00:00
|
|
|
mlx5_hv_vhca_cleanup(dev->hv_vhca);
|
2020-10-07 06:00:49 +00:00
|
|
|
mlx5_fw_reset_events_stop(dev);
|
2019-03-29 22:37:57 +00:00
|
|
|
mlx5_fw_tracer_cleanup(dev->tracer);
|
|
|
|
mlx5_eq_table_destroy(dev);
|
2019-06-10 23:38:32 +00:00
|
|
|
mlx5_irq_table_destroy(dev);
|
2019-03-29 22:37:57 +00:00
|
|
|
mlx5_pagealloc_stop(dev);
|
|
|
|
mlx5_events_stop(dev);
|
|
|
|
mlx5_put_uars_page(dev, dev->priv.uar);
|
|
|
|
}
|
2016-09-09 14:35:20 +00:00
|
|
|
|
2023-05-03 11:18:23 +00:00
|
|
|
int mlx5_init_one_devl_locked(struct mlx5_core_dev *dev)
|
2019-03-29 22:37:57 +00:00
|
|
|
{
|
2023-05-03 11:18:23 +00:00
|
|
|
bool light_probe = mlx5_dev_is_lightweight(dev);
|
2019-03-29 22:37:57 +00:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
mutex_lock(&dev->intf_state_mutex);
|
|
|
|
dev->state = MLX5_DEVICE_STATE_UP;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2022-10-02 04:56:28 +00:00
|
|
|
err = mlx5_function_setup(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT));
|
2019-03-29 22:37:57 +00:00
|
|
|
if (err)
|
2020-05-06 11:52:04 +00:00
|
|
|
goto err_function;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
err = mlx5_init_once(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "sw objs init failed\n");
|
|
|
|
goto function_teardown;
|
2019-03-29 22:37:57 +00:00
|
|
|
}
|
2013-07-18 12:31:08 +00:00
|
|
|
|
2023-05-03 11:18:23 +00:00
|
|
|
/* In case of light_probe, mlx5_devlink is already registered.
|
|
|
|
* Hence, don't register devlink again.
|
|
|
|
*/
|
|
|
|
if (!light_probe) {
|
|
|
|
err = mlx5_devlink_params_register(priv_to_devlink(dev));
|
|
|
|
if (err)
|
|
|
|
goto err_devlink_params_reg;
|
|
|
|
}
|
2023-01-03 06:48:14 +00:00
|
|
|
|
2019-03-29 22:37:57 +00:00
|
|
|
err = mlx5_load(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_load;
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2020-05-15 07:44:06 +00:00
|
|
|
set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
err = mlx5_register_device(dev);
|
2020-10-08 13:06:37 +00:00
|
|
|
if (err)
|
|
|
|
goto err_register;
|
|
|
|
|
2024-04-09 19:08:10 +00:00
|
|
|
err = mlx5_crdump_enable(dev);
|
|
|
|
if (err)
|
|
|
|
mlx5_core_err(dev, "mlx5_crdump_enable failed with error code %d\n", err);
|
|
|
|
|
|
|
|
err = mlx5_hwmon_dev_register(dev);
|
|
|
|
if (err)
|
|
|
|
mlx5_core_err(dev, "mlx5_hwmon_dev_register failed with error code %d\n", err);
|
|
|
|
|
2020-05-01 15:20:01 +00:00
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
|
|
|
return 0;
|
2019-03-29 22:37:57 +00:00
|
|
|
|
2020-10-08 13:06:37 +00:00
|
|
|
err_register:
|
2020-05-15 07:44:06 +00:00
|
|
|
clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
2019-03-29 22:37:57 +00:00
|
|
|
mlx5_unload(dev);
|
|
|
|
err_load:
|
2023-05-03 11:18:23 +00:00
|
|
|
if (!light_probe)
|
|
|
|
mlx5_devlink_params_unregister(priv_to_devlink(dev));
|
2023-01-03 06:48:14 +00:00
|
|
|
err_devlink_params_reg:
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_cleanup_once(dev);
|
2019-03-29 22:37:56 +00:00
|
|
|
function_teardown:
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_function_teardown(dev, true);
|
2020-05-06 11:52:04 +00:00
|
|
|
err_function:
|
2015-10-14 14:43:46 +00:00
|
|
|
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
|
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
2023-05-03 11:18:23 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mlx5_init_one(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
int err;
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_register(devlink);
|
2023-05-03 11:18:23 +00:00
|
|
|
err = mlx5_init_one_devl_locked(dev);
|
2024-04-09 19:08:10 +00:00
|
|
|
if (err)
|
|
|
|
devl_unregister(devlink);
|
2022-07-28 15:53:45 +00:00
|
|
|
devl_unlock(devlink);
|
2013-07-07 14:25:49 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
void mlx5_uninit_one(struct mlx5_core_dev *dev)
|
2013-07-07 14:25:49 +00:00
|
|
|
{
|
2022-07-28 15:53:45 +00:00
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
2020-05-15 07:44:06 +00:00
|
|
|
mutex_lock(&dev->intf_state_mutex);
|
|
|
|
|
2024-04-09 19:08:10 +00:00
|
|
|
mlx5_hwmon_dev_unregister(dev);
|
|
|
|
mlx5_crdump_disable(dev);
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_unregister_device(dev);
|
2016-12-28 12:58:33 +00:00
|
|
|
|
2017-08-08 18:17:00 +00:00
|
|
|
if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_warn(dev, "%s: interface is down, NOP\n",
|
|
|
|
__func__);
|
2023-06-25 08:07:38 +00:00
|
|
|
mlx5_devlink_params_unregister(priv_to_devlink(dev));
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_cleanup_once(dev);
|
2015-10-14 14:43:46 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2016-09-09 14:35:18 +00:00
|
|
|
|
2017-05-25 05:42:07 +00:00
|
|
|
clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_unload(dev);
|
2023-01-03 06:48:14 +00:00
|
|
|
mlx5_devlink_params_unregister(priv_to_devlink(dev));
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_cleanup_once(dev);
|
|
|
|
mlx5_function_teardown(dev, true);
|
|
|
|
out:
|
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_unregister(devlink);
|
2022-07-28 15:53:45 +00:00
|
|
|
devl_unlock(devlink);
|
2020-11-02 14:54:43 +00:00
|
|
|
}
|
|
|
|
|
2022-07-28 15:53:45 +00:00
|
|
|
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery)
|
2020-11-02 14:54:43 +00:00
|
|
|
{
|
|
|
|
int err = 0;
|
net/mlx5: Increase FW pre-init timeout for health recovery
Currently, health recovery will reload driver to recover it from fatal
errors. During the driver's load process, it would wait for FW to set the
pre-init bit for up to 120 seconds, beyond this threshold it would abort
the load process. In some cases, such as a FW upgrade on the DPU, this
timeout period is insufficient, and the user has no way to recover the
host device.
To solve this issue, introduce a new FW pre-init timeout for health
recovery, which is set to 2 hours.
The timeout for devlink reload and probe will use the original one because
they are user triggered flows, and therefore should not have a
significantly long timeout, during which the user command would hang.
Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-27 14:36:44 +00:00
|
|
|
u64 timeout;
|
2020-11-02 14:54:43 +00:00
|
|
|
|
2022-07-28 15:53:45 +00:00
|
|
|
devl_assert_locked(priv_to_devlink(dev));
|
2020-11-02 14:54:43 +00:00
|
|
|
mutex_lock(&dev->intf_state_mutex);
|
|
|
|
if (test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
|
|
|
|
mlx5_core_warn(dev, "interface is up, NOP\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
/* remove any previous indication of internal error */
|
|
|
|
dev->state = MLX5_DEVICE_STATE_UP;
|
|
|
|
|
net/mlx5: Increase FW pre-init timeout for health recovery
Currently, health recovery will reload driver to recover it from fatal
errors. During the driver's load process, it would wait for FW to set the
pre-init bit for up to 120 seconds, beyond this threshold it would abort
the load process. In some cases, such as a FW upgrade on the DPU, this
timeout period is insufficient, and the user has no way to recover the
host device.
To solve this issue, introduce a new FW pre-init timeout for health
recovery, which is set to 2 hours.
The timeout for devlink reload and probe will use the original one because
they are user triggered flows, and therefore should not have a
significantly long timeout, during which the user command would hang.
Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-03-27 14:36:44 +00:00
|
|
|
if (recovery)
|
|
|
|
timeout = mlx5_tout_ms(dev, FW_PRE_INIT_ON_RECOVERY_TIMEOUT);
|
|
|
|
else
|
|
|
|
timeout = mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT);
|
2022-10-02 04:56:28 +00:00
|
|
|
err = mlx5_function_setup(dev, false, timeout);
|
2020-11-02 14:54:43 +00:00
|
|
|
if (err)
|
|
|
|
goto err_function;
|
|
|
|
|
|
|
|
err = mlx5_load(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_load;
|
|
|
|
|
|
|
|
set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
2017-05-25 05:42:07 +00:00
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
err = mlx5_attach_device(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_attach;
|
|
|
|
|
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_attach:
|
|
|
|
clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
2019-03-29 22:37:57 +00:00
|
|
|
mlx5_unload(dev);
|
2020-11-02 14:54:43 +00:00
|
|
|
err_load:
|
|
|
|
mlx5_function_teardown(dev, false);
|
|
|
|
err_function:
|
|
|
|
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
|
|
|
|
out:
|
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
|
|
|
return err;
|
|
|
|
}
|
2019-03-29 22:37:57 +00:00
|
|
|
|
2023-04-09 07:44:31 +00:00
|
|
|
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
|
2020-11-02 14:54:43 +00:00
|
|
|
{
|
2022-07-28 15:53:45 +00:00
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
2023-04-09 07:44:31 +00:00
|
|
|
ret = mlx5_load_one_devl_locked(dev, recovery);
|
2022-07-28 15:53:45 +00:00
|
|
|
devl_unlock(devlink);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2023-01-26 12:39:09 +00:00
|
|
|
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend)
|
2022-07-28 15:53:45 +00:00
|
|
|
{
|
|
|
|
devl_assert_locked(priv_to_devlink(dev));
|
2020-11-02 14:54:43 +00:00
|
|
|
mutex_lock(&dev->intf_state_mutex);
|
|
|
|
|
2023-01-26 12:39:09 +00:00
|
|
|
mlx5_detach_device(dev, suspend);
|
2020-11-02 14:54:43 +00:00
|
|
|
|
|
|
|
if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
|
|
|
|
mlx5_core_warn(dev, "%s: interface is down, NOP\n",
|
|
|
|
__func__);
|
|
|
|
goto out;
|
|
|
|
}
|
2014-07-28 20:30:22 +00:00
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
|
|
|
|
mlx5_unload(dev);
|
|
|
|
mlx5_function_teardown(dev, false);
|
2015-10-08 14:14:00 +00:00
|
|
|
out:
|
2015-10-14 14:43:46 +00:00
|
|
|
mutex_unlock(&dev->intf_state_mutex);
|
2014-07-28 20:30:22 +00:00
|
|
|
}
|
2015-04-02 14:07:34 +00:00
|
|
|
|
2023-01-26 12:39:09 +00:00
|
|
|
void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend)
|
2022-07-28 15:53:45 +00:00
|
|
|
{
|
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
2023-01-26 12:39:09 +00:00
|
|
|
mlx5_unload_one_devl_locked(dev, suspend);
|
2022-07-28 15:53:45 +00:00
|
|
|
devl_unlock(devlink);
|
|
|
|
}
|
|
|
|
|
2023-05-03 11:18:23 +00:00
|
|
|
/* In case of light probe, we don't need a full query of hca_caps, but only the bellow caps.
|
|
|
|
* A full query of hca_caps will be done when the device will reload.
|
|
|
|
*/
|
|
|
|
static int mlx5_query_hca_caps_light(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = mlx5_core_get_caps(dev, MLX5_CAP_GENERAL);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
if (MLX5_CAP_GEN(dev, eth_net_offloads)) {
|
2023-07-11 12:56:08 +00:00
|
|
|
err = mlx5_core_get_caps_mode(dev, MLX5_CAP_ETHERNET_OFFLOADS,
|
|
|
|
HCA_CAP_OPMOD_GET_CUR);
|
2023-05-03 11:18:23 +00:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MLX5_CAP_GEN(dev, nic_flow_table) ||
|
|
|
|
MLX5_CAP_GEN(dev, ipoib_enhanced_offloads)) {
|
2023-07-11 12:56:08 +00:00
|
|
|
err = mlx5_core_get_caps_mode(dev, MLX5_CAP_FLOW_TABLE,
|
|
|
|
HCA_CAP_OPMOD_GET_CUR);
|
2023-05-03 11:18:23 +00:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MLX5_CAP_GEN_64(dev, general_obj_types) &
|
|
|
|
MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q) {
|
2023-07-11 12:56:08 +00:00
|
|
|
err = mlx5_core_get_caps_mode(dev, MLX5_CAP_VDPA_EMULATION,
|
|
|
|
HCA_CAP_OPMOD_GET_CUR);
|
2023-05-03 11:18:23 +00:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mlx5_init_one_light(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
int err;
|
|
|
|
|
|
|
|
dev->state = MLX5_DEVICE_STATE_UP;
|
|
|
|
err = mlx5_function_enable(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT));
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_warn(dev, "mlx5_function_enable err=%d\n", err);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = mlx5_query_hca_caps_light(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_warn(dev, "mlx5_query_hca_caps_light err=%d\n", err);
|
|
|
|
goto query_hca_caps_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_register(devlink);
|
|
|
|
|
2023-05-03 11:18:23 +00:00
|
|
|
err = mlx5_devlink_params_register(priv_to_devlink(dev));
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_warn(dev, "mlx5_devlink_param_reg err = %d\n", err);
|
|
|
|
goto query_hca_caps_err;
|
|
|
|
}
|
|
|
|
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_unlock(devlink);
|
2023-05-03 11:18:23 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
query_hca_caps_err:
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_unregister(devlink);
|
|
|
|
devl_unlock(devlink);
|
2023-05-03 11:18:23 +00:00
|
|
|
mlx5_function_disable(dev, true);
|
|
|
|
out:
|
|
|
|
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mlx5_uninit_one_light(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
|
|
|
|
|
|
|
devl_lock(devlink);
|
|
|
|
mlx5_devlink_params_unregister(priv_to_devlink(dev));
|
2024-04-09 19:08:10 +00:00
|
|
|
devl_unregister(devlink);
|
2023-05-03 11:18:23 +00:00
|
|
|
devl_unlock(devlink);
|
|
|
|
if (dev->state != MLX5_DEVICE_STATE_UP)
|
|
|
|
return;
|
|
|
|
mlx5_function_disable(dev, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* xxx_light() function are used in order to configure the device without full
|
|
|
|
* init (light init). e.g.: There isn't a point in reload a device to light state.
|
|
|
|
* Hence, mlx5_load_one_light() isn't needed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void mlx5_unload_one_light(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
if (dev->state != MLX5_DEVICE_STATE_UP)
|
|
|
|
return;
|
|
|
|
mlx5_function_disable(dev, false);
|
|
|
|
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
|
|
|
|
}
|
|
|
|
|
2021-07-13 11:17:03 +00:00
|
|
|
static const int types[] = {
|
|
|
|
MLX5_CAP_GENERAL,
|
|
|
|
MLX5_CAP_GENERAL_2,
|
|
|
|
MLX5_CAP_ETHERNET_OFFLOADS,
|
|
|
|
MLX5_CAP_IPOIB_ENHANCED_OFFLOADS,
|
|
|
|
MLX5_CAP_ODP,
|
|
|
|
MLX5_CAP_ATOMIC,
|
|
|
|
MLX5_CAP_ROCE,
|
|
|
|
MLX5_CAP_IPOIB_OFFLOADS,
|
|
|
|
MLX5_CAP_FLOW_TABLE,
|
|
|
|
MLX5_CAP_ESWITCH_FLOW_TABLE,
|
|
|
|
MLX5_CAP_ESWITCH,
|
|
|
|
MLX5_CAP_QOS,
|
|
|
|
MLX5_CAP_DEBUG,
|
|
|
|
MLX5_CAP_DEV_MEM,
|
|
|
|
MLX5_CAP_DEV_EVENT,
|
|
|
|
MLX5_CAP_TLS,
|
|
|
|
MLX5_CAP_VDPA_EMULATION,
|
|
|
|
MLX5_CAP_IPSEC,
|
2021-05-23 10:34:28 +00:00
|
|
|
MLX5_CAP_PORT_SELECTION,
|
2022-09-06 05:21:19 +00:00
|
|
|
MLX5_CAP_MACSEC,
|
2022-09-05 10:58:44 +00:00
|
|
|
MLX5_CAP_ADV_VIRTUALIZATION,
|
2022-05-23 04:10:02 +00:00
|
|
|
MLX5_CAP_CRYPTO,
|
2021-07-13 11:17:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void mlx5_hca_caps_free(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
int type;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(types); i++) {
|
|
|
|
type = types[i];
|
|
|
|
kfree(dev->caps.hca[type]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mlx5_hca_caps_alloc(struct mlx5_core_dev *dev)
|
|
|
|
{
|
|
|
|
struct mlx5_hca_cap *cap;
|
|
|
|
int type;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(types); i++) {
|
|
|
|
cap = kzalloc(sizeof(*cap), GFP_KERNEL);
|
|
|
|
if (!cap)
|
|
|
|
goto err;
|
|
|
|
type = types[i];
|
|
|
|
dev->caps.hca[type] = cap;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
mlx5_hca_caps_free(dev);
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2022-09-21 10:33:29 +00:00
|
|
|
static int vhca_id_show(struct seq_file *file, void *priv)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = file->private;
|
|
|
|
|
|
|
|
seq_printf(file, "0x%x\n", MLX5_CAP_GEN(dev, vhca_id));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_SHOW_ATTRIBUTE(vhca_id);
|
|
|
|
|
2020-12-12 06:12:18 +00:00
|
|
|
int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
|
2014-07-28 20:30:22 +00:00
|
|
|
{
|
2019-03-29 22:37:54 +00:00
|
|
|
struct mlx5_priv *priv = &dev->priv;
|
2014-07-28 20:30:22 +00:00
|
|
|
int err;
|
|
|
|
|
2021-05-12 10:52:27 +00:00
|
|
|
memcpy(&dev->profile, &profile[profile_idx], sizeof(dev->profile));
|
net/mlx5: Avoid false positive lockdep warning by adding lock_class_key
Add a lock_class_key per mlx5 device to avoid a false positive
"possible circular locking dependency" warning by lockdep, on flows
which lock more than one mlx5 device, such as adding SF.
kernel log:
======================================================
WARNING: possible circular locking dependency detected
5.19.0-rc8+ #2 Not tainted
------------------------------------------------------
kworker/u20:0/8 is trying to acquire lock:
ffff88812dfe0d98 (&dev->intf_state_mutex){+.+.}-{3:3}, at: mlx5_init_one+0x2e/0x490 [mlx5_core]
but task is already holding lock:
ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&(¬ifier->n_head)->rwsem){++++}-{3:3}:
down_write+0x90/0x150
blocking_notifier_chain_register+0x53/0xa0
mlx5_sf_table_init+0x369/0x4a0 [mlx5_core]
mlx5_init_one+0x261/0x490 [mlx5_core]
probe_one+0x430/0x680 [mlx5_core]
local_pci_probe+0xd6/0x170
work_for_cpu_fn+0x4e/0xa0
process_one_work+0x7c2/0x1340
worker_thread+0x6f6/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
-> #0 (&dev->intf_state_mutex){+.+.}-{3:3}:
__lock_acquire+0x2fc7/0x6720
lock_acquire+0x1c1/0x550
__mutex_lock+0x12c/0x14b0
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
bus_for_each_drv+0x123/0x1a0
__device_attach+0x1a3/0x460
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
__auxiliary_device_add+0x88/0xc0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
process_one_work+0x7c2/0x1340
worker_thread+0x59d/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
*** DEADLOCK ***
4 locks held by kworker/u20:0/8:
#0: ffff888150612938 ((wq_completion)mlx5_events){+.+.}-{0:0}, at: process_one_work+0x6e2/0x1340
#1: ffff888100cafdb8 ((work_completion)(&work->work)#3){+.+.}-{0:0}, at: process_one_work+0x70f/0x1340
#2: ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
#3: ffff88813682d0e8 (&dev->mutex){....}-{3:3}, at:__device_attach+0x76/0x460
stack backtrace:
CPU: 6 PID: 8 Comm: kworker/u20:0 Not tainted 5.19.0-rc8+
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Workqueue: mlx5_events mlx5_vhca_state_work_handler [mlx5_core]
Call Trace:
<TASK>
dump_stack_lvl+0x57/0x7d
check_noncircular+0x278/0x300
? print_circular_bug+0x460/0x460
? lock_chain_count+0x20/0x20
? register_lock_class+0x1880/0x1880
__lock_acquire+0x2fc7/0x6720
? register_lock_class+0x1880/0x1880
? register_lock_class+0x1880/0x1880
lock_acquire+0x1c1/0x550
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? lockdep_hardirqs_on_prepare+0x400/0x400
__mutex_lock+0x12c/0x14b0
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? _raw_read_unlock+0x1f/0x30
? mutex_lock_io_nested+0x1320/0x1320
? __ioremap_caller.constprop.0+0x306/0x490
? mlx5_sf_dev_probe+0x269/0x370 [mlx5_core]
? iounmap+0x160/0x160
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
? mlx5_sf_dev_remove+0x130/0x130 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
? auxiliary_match_id+0xe9/0x140
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
? driver_allows_async_probing+0x140/0x140
bus_for_each_drv+0x123/0x1a0
? bus_for_each_dev+0x1a0/0x1a0
? lockdep_hardirqs_on_prepare+0x286/0x400
? trace_hardirqs_on+0x2d/0x100
__device_attach+0x1a3/0x460
? device_driver_attach+0x1e0/0x1e0
? kobject_uevent_env+0x22d/0xf10
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
? dev_set_name+0xab/0xe0
? __fw_devlink_link_to_suppliers+0x260/0x260
? memset+0x20/0x40
? lockdep_init_map_type+0x21a/0x7d0
__auxiliary_device_add+0x88/0xc0
? auxiliary_device_init+0x86/0xa0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
? mlx5_vhca_event_arm+0x100/0x100 [mlx5_core]
? lock_downgrade+0x6e0/0x6e0
? lockdep_hardirqs_on_prepare+0x286/0x400
process_one_work+0x7c2/0x1340
? lockdep_hardirqs_on_prepare+0x400/0x400
? pwq_dec_nr_in_flight+0x230/0x230
? rwlock_bug.part.0+0x90/0x90
worker_thread+0x59d/0xec0
? process_one_work+0x1340/0x1340
kthread+0x28f/0x330
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x1f/0x30
</TASK>
Fixes: 6a3273217469 ("net/mlx5: SF, Port function state change support")
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-08-03 07:49:23 +00:00
|
|
|
lockdep_register_key(&dev->lock_key);
|
2015-10-14 14:43:46 +00:00
|
|
|
mutex_init(&dev->intf_state_mutex);
|
net/mlx5: Avoid false positive lockdep warning by adding lock_class_key
Add a lock_class_key per mlx5 device to avoid a false positive
"possible circular locking dependency" warning by lockdep, on flows
which lock more than one mlx5 device, such as adding SF.
kernel log:
======================================================
WARNING: possible circular locking dependency detected
5.19.0-rc8+ #2 Not tainted
------------------------------------------------------
kworker/u20:0/8 is trying to acquire lock:
ffff88812dfe0d98 (&dev->intf_state_mutex){+.+.}-{3:3}, at: mlx5_init_one+0x2e/0x490 [mlx5_core]
but task is already holding lock:
ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&(¬ifier->n_head)->rwsem){++++}-{3:3}:
down_write+0x90/0x150
blocking_notifier_chain_register+0x53/0xa0
mlx5_sf_table_init+0x369/0x4a0 [mlx5_core]
mlx5_init_one+0x261/0x490 [mlx5_core]
probe_one+0x430/0x680 [mlx5_core]
local_pci_probe+0xd6/0x170
work_for_cpu_fn+0x4e/0xa0
process_one_work+0x7c2/0x1340
worker_thread+0x6f6/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
-> #0 (&dev->intf_state_mutex){+.+.}-{3:3}:
__lock_acquire+0x2fc7/0x6720
lock_acquire+0x1c1/0x550
__mutex_lock+0x12c/0x14b0
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
bus_for_each_drv+0x123/0x1a0
__device_attach+0x1a3/0x460
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
__auxiliary_device_add+0x88/0xc0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
process_one_work+0x7c2/0x1340
worker_thread+0x59d/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
*** DEADLOCK ***
4 locks held by kworker/u20:0/8:
#0: ffff888150612938 ((wq_completion)mlx5_events){+.+.}-{0:0}, at: process_one_work+0x6e2/0x1340
#1: ffff888100cafdb8 ((work_completion)(&work->work)#3){+.+.}-{0:0}, at: process_one_work+0x70f/0x1340
#2: ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
#3: ffff88813682d0e8 (&dev->mutex){....}-{3:3}, at:__device_attach+0x76/0x460
stack backtrace:
CPU: 6 PID: 8 Comm: kworker/u20:0 Not tainted 5.19.0-rc8+
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Workqueue: mlx5_events mlx5_vhca_state_work_handler [mlx5_core]
Call Trace:
<TASK>
dump_stack_lvl+0x57/0x7d
check_noncircular+0x278/0x300
? print_circular_bug+0x460/0x460
? lock_chain_count+0x20/0x20
? register_lock_class+0x1880/0x1880
__lock_acquire+0x2fc7/0x6720
? register_lock_class+0x1880/0x1880
? register_lock_class+0x1880/0x1880
lock_acquire+0x1c1/0x550
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? lockdep_hardirqs_on_prepare+0x400/0x400
__mutex_lock+0x12c/0x14b0
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? _raw_read_unlock+0x1f/0x30
? mutex_lock_io_nested+0x1320/0x1320
? __ioremap_caller.constprop.0+0x306/0x490
? mlx5_sf_dev_probe+0x269/0x370 [mlx5_core]
? iounmap+0x160/0x160
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
? mlx5_sf_dev_remove+0x130/0x130 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
? auxiliary_match_id+0xe9/0x140
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
? driver_allows_async_probing+0x140/0x140
bus_for_each_drv+0x123/0x1a0
? bus_for_each_dev+0x1a0/0x1a0
? lockdep_hardirqs_on_prepare+0x286/0x400
? trace_hardirqs_on+0x2d/0x100
__device_attach+0x1a3/0x460
? device_driver_attach+0x1e0/0x1e0
? kobject_uevent_env+0x22d/0xf10
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
? dev_set_name+0xab/0xe0
? __fw_devlink_link_to_suppliers+0x260/0x260
? memset+0x20/0x40
? lockdep_init_map_type+0x21a/0x7d0
__auxiliary_device_add+0x88/0xc0
? auxiliary_device_init+0x86/0xa0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
? mlx5_vhca_event_arm+0x100/0x100 [mlx5_core]
? lock_downgrade+0x6e0/0x6e0
? lockdep_hardirqs_on_prepare+0x286/0x400
process_one_work+0x7c2/0x1340
? lockdep_hardirqs_on_prepare+0x400/0x400
? pwq_dec_nr_in_flight+0x230/0x230
? rwlock_bug.part.0+0x90/0x90
worker_thread+0x59d/0xec0
? process_one_work+0x1340/0x1340
kthread+0x28f/0x330
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x1f/0x30
</TASK>
Fixes: 6a3273217469 ("net/mlx5: SF, Port function state change support")
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-08-03 07:49:23 +00:00
|
|
|
lockdep_set_class(&dev->intf_state_mutex, &dev->lock_key);
|
2022-11-01 14:27:43 +00:00
|
|
|
mutex_init(&dev->mlx5e_res.uplink_netdev_lock);
|
2017-01-02 09:37:46 +00:00
|
|
|
|
2017-01-03 21:55:24 +00:00
|
|
|
mutex_init(&priv->bfregs.reg_head.lock);
|
|
|
|
mutex_init(&priv->bfregs.wc_head.lock);
|
|
|
|
INIT_LIST_HEAD(&priv->bfregs.reg_head.list);
|
|
|
|
INIT_LIST_HEAD(&priv->bfregs.wc_head.list);
|
|
|
|
|
2019-03-29 22:37:54 +00:00
|
|
|
mutex_init(&priv->alloc_mutex);
|
|
|
|
mutex_init(&priv->pgdir_mutex);
|
|
|
|
INIT_LIST_HEAD(&priv->pgdir_list);
|
|
|
|
|
2021-06-16 19:23:23 +00:00
|
|
|
priv->numa_node = dev_to_node(mlx5_core_dma_dev(dev));
|
2022-02-18 07:36:20 +00:00
|
|
|
priv->dbg.dbg_root = debugfs_create_dir(dev_name(dev->device),
|
|
|
|
mlx5_debugfs_root);
|
2022-09-21 10:33:29 +00:00
|
|
|
debugfs_create_file("vhca_id", 0400, priv->dbg.dbg_root, dev, &vhca_id_fops);
|
2021-01-26 23:24:07 +00:00
|
|
|
INIT_LIST_HEAD(&priv->traps);
|
|
|
|
|
2023-01-18 18:55:54 +00:00
|
|
|
err = mlx5_cmd_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed initializing cmdif SW structs, aborting\n");
|
|
|
|
goto err_cmd_init;
|
|
|
|
}
|
|
|
|
|
2021-10-20 09:45:05 +00:00
|
|
|
err = mlx5_tout_init(dev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "Failed initializing timeouts, aborting\n");
|
|
|
|
goto err_timeout_init;
|
|
|
|
}
|
|
|
|
|
2015-10-08 14:14:00 +00:00
|
|
|
err = mlx5_health_init(dev);
|
2019-03-29 22:37:55 +00:00
|
|
|
if (err)
|
|
|
|
goto err_health_init;
|
2015-10-08 14:14:00 +00:00
|
|
|
|
2018-11-20 22:12:23 +00:00
|
|
|
err = mlx5_pagealloc_init(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_pagealloc_init;
|
2016-09-09 14:35:20 +00:00
|
|
|
|
2020-10-08 13:06:37 +00:00
|
|
|
err = mlx5_adev_init(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_adev_init;
|
|
|
|
|
2021-07-13 11:17:03 +00:00
|
|
|
err = mlx5_hca_caps_alloc(dev);
|
|
|
|
if (err)
|
|
|
|
goto err_hca_caps;
|
|
|
|
|
2022-06-02 09:47:34 +00:00
|
|
|
/* The conjunction of sw_vhca_id with sw_owner_id will be a global
|
|
|
|
* unique id per function which uses mlx5_core.
|
|
|
|
* Those values are supplied to FW as part of the init HCA command to
|
|
|
|
* be used by both driver and FW when it's applicable.
|
|
|
|
*/
|
|
|
|
dev->priv.sw_vhca_id = ida_alloc_range(&sw_vhca_ida, 1,
|
|
|
|
MAX_SW_VHCA_ID,
|
|
|
|
GFP_KERNEL);
|
|
|
|
if (dev->priv.sw_vhca_id < 0)
|
|
|
|
mlx5_core_err(dev, "failed to allocate sw_vhca_id, err=%d\n",
|
|
|
|
dev->priv.sw_vhca_id);
|
|
|
|
|
2019-03-29 22:37:54 +00:00
|
|
|
return 0;
|
2019-03-29 22:37:55 +00:00
|
|
|
|
2021-07-13 11:17:03 +00:00
|
|
|
err_hca_caps:
|
|
|
|
mlx5_adev_cleanup(dev);
|
2020-10-08 13:06:37 +00:00
|
|
|
err_adev_init:
|
|
|
|
mlx5_pagealloc_cleanup(dev);
|
2019-03-29 22:37:55 +00:00
|
|
|
err_pagealloc_init:
|
|
|
|
mlx5_health_cleanup(dev);
|
|
|
|
err_health_init:
|
2021-10-20 09:45:05 +00:00
|
|
|
mlx5_tout_cleanup(dev);
|
|
|
|
err_timeout_init:
|
2023-01-18 18:55:54 +00:00
|
|
|
mlx5_cmd_cleanup(dev);
|
|
|
|
err_cmd_init:
|
2022-02-18 07:36:20 +00:00
|
|
|
debugfs_remove(dev->priv.dbg.dbg_root);
|
2020-05-15 04:42:45 +00:00
|
|
|
mutex_destroy(&priv->pgdir_mutex);
|
|
|
|
mutex_destroy(&priv->alloc_mutex);
|
|
|
|
mutex_destroy(&priv->bfregs.wc_head.lock);
|
|
|
|
mutex_destroy(&priv->bfregs.reg_head.lock);
|
|
|
|
mutex_destroy(&dev->intf_state_mutex);
|
net/mlx5: Avoid false positive lockdep warning by adding lock_class_key
Add a lock_class_key per mlx5 device to avoid a false positive
"possible circular locking dependency" warning by lockdep, on flows
which lock more than one mlx5 device, such as adding SF.
kernel log:
======================================================
WARNING: possible circular locking dependency detected
5.19.0-rc8+ #2 Not tainted
------------------------------------------------------
kworker/u20:0/8 is trying to acquire lock:
ffff88812dfe0d98 (&dev->intf_state_mutex){+.+.}-{3:3}, at: mlx5_init_one+0x2e/0x490 [mlx5_core]
but task is already holding lock:
ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&(¬ifier->n_head)->rwsem){++++}-{3:3}:
down_write+0x90/0x150
blocking_notifier_chain_register+0x53/0xa0
mlx5_sf_table_init+0x369/0x4a0 [mlx5_core]
mlx5_init_one+0x261/0x490 [mlx5_core]
probe_one+0x430/0x680 [mlx5_core]
local_pci_probe+0xd6/0x170
work_for_cpu_fn+0x4e/0xa0
process_one_work+0x7c2/0x1340
worker_thread+0x6f6/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
-> #0 (&dev->intf_state_mutex){+.+.}-{3:3}:
__lock_acquire+0x2fc7/0x6720
lock_acquire+0x1c1/0x550
__mutex_lock+0x12c/0x14b0
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
bus_for_each_drv+0x123/0x1a0
__device_attach+0x1a3/0x460
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
__auxiliary_device_add+0x88/0xc0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
process_one_work+0x7c2/0x1340
worker_thread+0x59d/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
*** DEADLOCK ***
4 locks held by kworker/u20:0/8:
#0: ffff888150612938 ((wq_completion)mlx5_events){+.+.}-{0:0}, at: process_one_work+0x6e2/0x1340
#1: ffff888100cafdb8 ((work_completion)(&work->work)#3){+.+.}-{0:0}, at: process_one_work+0x70f/0x1340
#2: ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
#3: ffff88813682d0e8 (&dev->mutex){....}-{3:3}, at:__device_attach+0x76/0x460
stack backtrace:
CPU: 6 PID: 8 Comm: kworker/u20:0 Not tainted 5.19.0-rc8+
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Workqueue: mlx5_events mlx5_vhca_state_work_handler [mlx5_core]
Call Trace:
<TASK>
dump_stack_lvl+0x57/0x7d
check_noncircular+0x278/0x300
? print_circular_bug+0x460/0x460
? lock_chain_count+0x20/0x20
? register_lock_class+0x1880/0x1880
__lock_acquire+0x2fc7/0x6720
? register_lock_class+0x1880/0x1880
? register_lock_class+0x1880/0x1880
lock_acquire+0x1c1/0x550
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? lockdep_hardirqs_on_prepare+0x400/0x400
__mutex_lock+0x12c/0x14b0
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? _raw_read_unlock+0x1f/0x30
? mutex_lock_io_nested+0x1320/0x1320
? __ioremap_caller.constprop.0+0x306/0x490
? mlx5_sf_dev_probe+0x269/0x370 [mlx5_core]
? iounmap+0x160/0x160
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
? mlx5_sf_dev_remove+0x130/0x130 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
? auxiliary_match_id+0xe9/0x140
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
? driver_allows_async_probing+0x140/0x140
bus_for_each_drv+0x123/0x1a0
? bus_for_each_dev+0x1a0/0x1a0
? lockdep_hardirqs_on_prepare+0x286/0x400
? trace_hardirqs_on+0x2d/0x100
__device_attach+0x1a3/0x460
? device_driver_attach+0x1e0/0x1e0
? kobject_uevent_env+0x22d/0xf10
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
? dev_set_name+0xab/0xe0
? __fw_devlink_link_to_suppliers+0x260/0x260
? memset+0x20/0x40
? lockdep_init_map_type+0x21a/0x7d0
__auxiliary_device_add+0x88/0xc0
? auxiliary_device_init+0x86/0xa0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
? mlx5_vhca_event_arm+0x100/0x100 [mlx5_core]
? lock_downgrade+0x6e0/0x6e0
? lockdep_hardirqs_on_prepare+0x286/0x400
process_one_work+0x7c2/0x1340
? lockdep_hardirqs_on_prepare+0x400/0x400
? pwq_dec_nr_in_flight+0x230/0x230
? rwlock_bug.part.0+0x90/0x90
worker_thread+0x59d/0xec0
? process_one_work+0x1340/0x1340
kthread+0x28f/0x330
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x1f/0x30
</TASK>
Fixes: 6a3273217469 ("net/mlx5: SF, Port function state change support")
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-08-03 07:49:23 +00:00
|
|
|
lockdep_unregister_key(&dev->lock_key);
|
2019-03-29 22:37:55 +00:00
|
|
|
return err;
|
2019-03-29 22:37:54 +00:00
|
|
|
}
|
|
|
|
|
2020-12-12 06:12:18 +00:00
|
|
|
void mlx5_mdev_uninit(struct mlx5_core_dev *dev)
|
2019-03-29 22:37:54 +00:00
|
|
|
{
|
2020-05-15 04:42:45 +00:00
|
|
|
struct mlx5_priv *priv = &dev->priv;
|
|
|
|
|
2022-06-02 09:47:34 +00:00
|
|
|
if (priv->sw_vhca_id > 0)
|
|
|
|
ida_free(&sw_vhca_ida, dev->priv.sw_vhca_id);
|
|
|
|
|
2021-07-13 11:17:03 +00:00
|
|
|
mlx5_hca_caps_free(dev);
|
2020-10-08 13:06:37 +00:00
|
|
|
mlx5_adev_cleanup(dev);
|
2019-03-29 22:37:55 +00:00
|
|
|
mlx5_pagealloc_cleanup(dev);
|
|
|
|
mlx5_health_cleanup(dev);
|
2021-10-20 09:45:05 +00:00
|
|
|
mlx5_tout_cleanup(dev);
|
2023-01-18 18:55:54 +00:00
|
|
|
mlx5_cmd_cleanup(dev);
|
2022-02-18 07:36:20 +00:00
|
|
|
debugfs_remove_recursive(dev->priv.dbg.dbg_root);
|
2020-05-15 04:42:45 +00:00
|
|
|
mutex_destroy(&priv->pgdir_mutex);
|
|
|
|
mutex_destroy(&priv->alloc_mutex);
|
|
|
|
mutex_destroy(&priv->bfregs.wc_head.lock);
|
|
|
|
mutex_destroy(&priv->bfregs.reg_head.lock);
|
2022-11-01 14:27:43 +00:00
|
|
|
mutex_destroy(&dev->mlx5e_res.uplink_netdev_lock);
|
2020-05-15 04:42:45 +00:00
|
|
|
mutex_destroy(&dev->intf_state_mutex);
|
net/mlx5: Avoid false positive lockdep warning by adding lock_class_key
Add a lock_class_key per mlx5 device to avoid a false positive
"possible circular locking dependency" warning by lockdep, on flows
which lock more than one mlx5 device, such as adding SF.
kernel log:
======================================================
WARNING: possible circular locking dependency detected
5.19.0-rc8+ #2 Not tainted
------------------------------------------------------
kworker/u20:0/8 is trying to acquire lock:
ffff88812dfe0d98 (&dev->intf_state_mutex){+.+.}-{3:3}, at: mlx5_init_one+0x2e/0x490 [mlx5_core]
but task is already holding lock:
ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&(¬ifier->n_head)->rwsem){++++}-{3:3}:
down_write+0x90/0x150
blocking_notifier_chain_register+0x53/0xa0
mlx5_sf_table_init+0x369/0x4a0 [mlx5_core]
mlx5_init_one+0x261/0x490 [mlx5_core]
probe_one+0x430/0x680 [mlx5_core]
local_pci_probe+0xd6/0x170
work_for_cpu_fn+0x4e/0xa0
process_one_work+0x7c2/0x1340
worker_thread+0x6f6/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
-> #0 (&dev->intf_state_mutex){+.+.}-{3:3}:
__lock_acquire+0x2fc7/0x6720
lock_acquire+0x1c1/0x550
__mutex_lock+0x12c/0x14b0
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
bus_for_each_drv+0x123/0x1a0
__device_attach+0x1a3/0x460
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
__auxiliary_device_add+0x88/0xc0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
process_one_work+0x7c2/0x1340
worker_thread+0x59d/0xec0
kthread+0x28f/0x330
ret_from_fork+0x1f/0x30
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
lock(&(¬ifier->n_head)->rwsem);
lock(&dev->intf_state_mutex);
*** DEADLOCK ***
4 locks held by kworker/u20:0/8:
#0: ffff888150612938 ((wq_completion)mlx5_events){+.+.}-{0:0}, at: process_one_work+0x6e2/0x1340
#1: ffff888100cafdb8 ((work_completion)(&work->work)#3){+.+.}-{0:0}, at: process_one_work+0x70f/0x1340
#2: ffff888101aa7898 (&(¬ifier->n_head)->rwsem){++++}-{3:3}, at: blocking_notifier_call_chain+0x5a/0x130
#3: ffff88813682d0e8 (&dev->mutex){....}-{3:3}, at:__device_attach+0x76/0x460
stack backtrace:
CPU: 6 PID: 8 Comm: kworker/u20:0 Not tainted 5.19.0-rc8+
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
Workqueue: mlx5_events mlx5_vhca_state_work_handler [mlx5_core]
Call Trace:
<TASK>
dump_stack_lvl+0x57/0x7d
check_noncircular+0x278/0x300
? print_circular_bug+0x460/0x460
? lock_chain_count+0x20/0x20
? register_lock_class+0x1880/0x1880
__lock_acquire+0x2fc7/0x6720
? register_lock_class+0x1880/0x1880
? register_lock_class+0x1880/0x1880
lock_acquire+0x1c1/0x550
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? lockdep_hardirqs_on_prepare+0x400/0x400
__mutex_lock+0x12c/0x14b0
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? mlx5_init_one+0x2e/0x490 [mlx5_core]
? _raw_read_unlock+0x1f/0x30
? mutex_lock_io_nested+0x1320/0x1320
? __ioremap_caller.constprop.0+0x306/0x490
? mlx5_sf_dev_probe+0x269/0x370 [mlx5_core]
? iounmap+0x160/0x160
mlx5_init_one+0x2e/0x490 [mlx5_core]
mlx5_sf_dev_probe+0x29c/0x370 [mlx5_core]
? mlx5_sf_dev_remove+0x130/0x130 [mlx5_core]
auxiliary_bus_probe+0x9d/0xe0
really_probe+0x1e0/0xaa0
__driver_probe_device+0x219/0x480
? auxiliary_match_id+0xe9/0x140
driver_probe_device+0x49/0x130
__device_attach_driver+0x1b8/0x280
? driver_allows_async_probing+0x140/0x140
bus_for_each_drv+0x123/0x1a0
? bus_for_each_dev+0x1a0/0x1a0
? lockdep_hardirqs_on_prepare+0x286/0x400
? trace_hardirqs_on+0x2d/0x100
__device_attach+0x1a3/0x460
? device_driver_attach+0x1e0/0x1e0
? kobject_uevent_env+0x22d/0xf10
bus_probe_device+0x1a2/0x260
device_add+0x9b1/0x1b40
? dev_set_name+0xab/0xe0
? __fw_devlink_link_to_suppliers+0x260/0x260
? memset+0x20/0x40
? lockdep_init_map_type+0x21a/0x7d0
__auxiliary_device_add+0x88/0xc0
? auxiliary_device_init+0x86/0xa0
mlx5_sf_dev_state_change_handler+0x67e/0x9d0 [mlx5_core]
blocking_notifier_call_chain+0xd5/0x130
mlx5_vhca_state_work_handler+0x2b0/0x3f0 [mlx5_core]
? mlx5_vhca_event_arm+0x100/0x100 [mlx5_core]
? lock_downgrade+0x6e0/0x6e0
? lockdep_hardirqs_on_prepare+0x286/0x400
process_one_work+0x7c2/0x1340
? lockdep_hardirqs_on_prepare+0x400/0x400
? pwq_dec_nr_in_flight+0x230/0x230
? rwlock_bug.part.0+0x90/0x90
worker_thread+0x59d/0xec0
? process_one_work+0x1340/0x1340
kthread+0x28f/0x330
? kthread_complete_and_exit+0x20/0x20
ret_from_fork+0x1f/0x30
</TASK>
Fixes: 6a3273217469 ("net/mlx5: SF, Port function state change support")
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Shay Drory <shayd@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
2022-08-03 07:49:23 +00:00
|
|
|
lockdep_unregister_key(&dev->lock_key);
|
2019-03-29 22:37:54 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
2014-07-28 20:30:22 +00:00
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev;
|
2016-07-01 11:51:02 +00:00
|
|
|
struct devlink *devlink;
|
2014-07-28 20:30:22 +00:00
|
|
|
int err;
|
|
|
|
|
2021-08-08 18:57:43 +00:00
|
|
|
devlink = mlx5_devlink_alloc(&pdev->dev);
|
2016-07-01 11:51:02 +00:00
|
|
|
if (!devlink) {
|
2018-12-11 14:09:51 +00:00
|
|
|
dev_err(&pdev->dev, "devlink alloc failed\n");
|
2014-07-28 20:30:22 +00:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
2016-07-01 11:51:02 +00:00
|
|
|
|
|
|
|
dev = devlink_priv(devlink);
|
2019-04-29 18:14:02 +00:00
|
|
|
dev->device = &pdev->dev;
|
|
|
|
dev->pdev = pdev;
|
2014-07-28 20:30:22 +00:00
|
|
|
|
2019-06-28 22:35:58 +00:00
|
|
|
dev->coredev_type = id->driver_data & MLX5_PCI_DEV_IS_VF ?
|
|
|
|
MLX5_COREDEV_VF : MLX5_COREDEV_PF;
|
|
|
|
|
2020-10-08 13:06:37 +00:00
|
|
|
dev->priv.adev_idx = mlx5_adev_idx_alloc();
|
2021-01-04 08:08:36 +00:00
|
|
|
if (dev->priv.adev_idx < 0) {
|
|
|
|
err = dev->priv.adev_idx;
|
|
|
|
goto adev_init_err;
|
|
|
|
}
|
2020-10-08 13:06:37 +00:00
|
|
|
|
2019-04-29 18:14:02 +00:00
|
|
|
err = mlx5_mdev_init(dev, prof_sel);
|
2019-03-29 22:37:54 +00:00
|
|
|
if (err)
|
|
|
|
goto mdev_init_err;
|
2017-01-03 21:55:24 +00:00
|
|
|
|
2019-03-29 22:37:54 +00:00
|
|
|
err = mlx5_pci_init(dev, pdev, id);
|
2014-07-28 20:30:22 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "mlx5_pci_init failed with error code %d\n",
|
|
|
|
err);
|
2019-03-29 22:37:54 +00:00
|
|
|
goto pci_init_err;
|
2014-07-28 20:30:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
err = mlx5_init_one(dev);
|
2014-07-28 20:30:22 +00:00
|
|
|
if (err) {
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_core_err(dev, "mlx5_init_one failed with error code %d\n",
|
2019-03-29 22:38:00 +00:00
|
|
|
err);
|
2020-11-02 14:54:43 +00:00
|
|
|
goto err_init_one;
|
2014-07-28 20:30:22 +00:00
|
|
|
}
|
2016-09-09 14:35:20 +00:00
|
|
|
|
2017-03-10 12:33:02 +00:00
|
|
|
pci_save_state(pdev);
|
2014-07-28 20:30:22 +00:00
|
|
|
return 0;
|
|
|
|
|
2020-11-02 14:54:43 +00:00
|
|
|
err_init_one:
|
2019-03-29 22:37:53 +00:00
|
|
|
mlx5_pci_close(dev);
|
2019-03-29 22:37:54 +00:00
|
|
|
pci_init_err:
|
|
|
|
mlx5_mdev_uninit(dev);
|
|
|
|
mdev_init_err:
|
2020-10-08 13:06:37 +00:00
|
|
|
mlx5_adev_idx_free(dev->priv.adev_idx);
|
2021-01-04 08:08:36 +00:00
|
|
|
adev_init_err:
|
2018-12-11 14:09:51 +00:00
|
|
|
mlx5_devlink_free(devlink);
|
2015-09-25 07:49:14 +00:00
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
return err;
|
|
|
|
}
|
2015-09-25 07:49:14 +00:00
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
static void remove_one(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
2016-07-01 11:51:02 +00:00
|
|
|
struct devlink *devlink = priv_to_devlink(dev);
|
2014-07-28 20:30:22 +00:00
|
|
|
|
2023-02-28 08:36:19 +00:00
|
|
|
set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
|
2022-04-04 07:47:36 +00:00
|
|
|
mlx5_drain_fw_reset(dev);
|
2023-04-24 09:31:59 +00:00
|
|
|
mlx5_drain_health_wq(dev);
|
2023-03-07 16:52:29 +00:00
|
|
|
mlx5_sriov_disable(pdev, false);
|
2020-11-02 14:54:43 +00:00
|
|
|
mlx5_uninit_one(dev);
|
2019-03-29 22:37:53 +00:00
|
|
|
mlx5_pci_close(dev);
|
2019-03-29 22:37:54 +00:00
|
|
|
mlx5_mdev_uninit(dev);
|
2020-10-08 13:06:37 +00:00
|
|
|
mlx5_adev_idx_free(dev->priv.adev_idx);
|
2018-12-11 14:09:51 +00:00
|
|
|
mlx5_devlink_free(devlink);
|
2014-07-28 20:30:22 +00:00
|
|
|
}
|
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
#define mlx5_pci_trace(dev, fmt, ...) ({ \
|
|
|
|
struct mlx5_core_dev *__dev = (dev); \
|
|
|
|
mlx5_core_info(__dev, "%s Device state = %d health sensors: %d pci_status: %d. " fmt, \
|
|
|
|
__func__, __dev->state, mlx5_health_check_fatal_sensors(__dev), \
|
|
|
|
__dev->pci_status, ##__VA_ARGS__); \
|
|
|
|
})
|
|
|
|
|
|
|
|
static const char *result2str(enum pci_ers_result result)
|
|
|
|
{
|
|
|
|
return result == PCI_ERS_RESULT_NEED_RESET ? "need reset" :
|
|
|
|
result == PCI_ERS_RESULT_DISCONNECT ? "disconnect" :
|
|
|
|
result == PCI_ERS_RESULT_RECOVERED ? "recovered" :
|
|
|
|
"unknown";
|
|
|
|
}
|
|
|
|
|
2015-10-14 14:43:46 +00:00
|
|
|
static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
|
|
|
|
pci_channel_state_t state)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
2021-10-05 01:39:51 +00:00
|
|
|
enum pci_ers_result res;
|
2015-10-14 14:43:46 +00:00
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
mlx5_pci_trace(dev, "Enter, pci channel state = %d\n", state);
|
2016-10-25 15:36:34 +00:00
|
|
|
|
2017-02-09 12:20:12 +00:00
|
|
|
mlx5_enter_error_state(dev, false);
|
2018-11-12 14:40:17 +00:00
|
|
|
mlx5_error_sw_reset(dev);
|
2023-07-23 08:03:01 +00:00
|
|
|
mlx5_unload_one(dev, false);
|
2019-01-27 16:38:39 +00:00
|
|
|
mlx5_drain_health_wq(dev);
|
|
|
|
mlx5_pci_disable_device(dev);
|
2016-10-25 15:36:33 +00:00
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
res = state == pci_channel_io_perm_failure ?
|
2015-10-14 14:43:46 +00:00
|
|
|
PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
|
2021-10-05 01:39:51 +00:00
|
|
|
|
2022-07-24 06:49:07 +00:00
|
|
|
mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
|
|
|
|
__func__, dev->state, dev->pci_status, res, result2str(res));
|
2021-10-05 01:39:51 +00:00
|
|
|
return res;
|
2015-10-14 14:43:46 +00:00
|
|
|
}
|
|
|
|
|
2016-06-30 14:34:41 +00:00
|
|
|
/* wait for the device to show vital signs by waiting
|
|
|
|
* for the health counter to start counting.
|
2015-10-14 14:43:46 +00:00
|
|
|
*/
|
2016-06-30 14:34:41 +00:00
|
|
|
static int wait_vital(struct pci_dev *pdev)
|
2015-10-14 14:43:46 +00:00
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
|
|
|
struct mlx5_core_health *health = &dev->priv.health;
|
|
|
|
const int niter = 100;
|
2016-06-30 14:34:41 +00:00
|
|
|
u32 last_count = 0;
|
2015-10-14 14:43:46 +00:00
|
|
|
u32 count;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < niter; i++) {
|
|
|
|
count = ioread32be(health->health_counter);
|
|
|
|
if (count && count != 0xffffffff) {
|
2016-06-30 14:34:41 +00:00
|
|
|
if (last_count && last_count != count) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_info(dev,
|
|
|
|
"wait vital counter value 0x%x after %d iterations\n",
|
|
|
|
count, i);
|
2016-06-30 14:34:41 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
last_count = count;
|
2015-10-14 14:43:46 +00:00
|
|
|
}
|
|
|
|
msleep(50);
|
|
|
|
}
|
|
|
|
|
2016-06-30 14:34:41 +00:00
|
|
|
return -ETIMEDOUT;
|
2015-10-14 14:43:46 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 18:09:04 +00:00
|
|
|
static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
|
2015-10-14 14:43:46 +00:00
|
|
|
{
|
2021-10-05 01:39:51 +00:00
|
|
|
enum pci_ers_result res = PCI_ERS_RESULT_DISCONNECT;
|
2015-10-14 14:43:46 +00:00
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
|
|
|
int err;
|
|
|
|
|
2022-07-24 06:49:07 +00:00
|
|
|
mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
|
|
|
|
__func__, dev->state, dev->pci_status);
|
2015-10-14 14:43:46 +00:00
|
|
|
|
2016-08-18 18:09:04 +00:00
|
|
|
err = mlx5_pci_enable_device(dev);
|
2016-06-30 14:34:41 +00:00
|
|
|
if (err) {
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_err(dev, "%s: mlx5_pci_enable_device failed with error code: %d\n",
|
|
|
|
__func__, err);
|
2021-10-05 01:39:51 +00:00
|
|
|
goto out;
|
2016-08-18 18:09:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pci_set_master(pdev);
|
|
|
|
pci_restore_state(pdev);
|
2017-03-10 12:33:02 +00:00
|
|
|
pci_save_state(pdev);
|
2016-08-18 18:09:04 +00:00
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
err = wait_vital(pdev);
|
|
|
|
if (err) {
|
|
|
|
mlx5_core_err(dev, "%s: wait vital failed with error code: %d\n",
|
|
|
|
__func__, err);
|
|
|
|
goto out;
|
2016-06-30 14:34:41 +00:00
|
|
|
}
|
2015-10-14 14:43:46 +00:00
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
res = PCI_ERS_RESULT_RECOVERED;
|
|
|
|
out:
|
2022-07-24 06:49:07 +00:00
|
|
|
mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
|
|
|
|
__func__, dev->state, dev->pci_status, err, res, result2str(res));
|
2021-10-05 01:39:51 +00:00
|
|
|
return res;
|
2016-08-18 18:09:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mlx5_pci_resume(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
|
|
|
int err;
|
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
mlx5_pci_trace(dev, "Enter, loading driver..\n");
|
2016-08-18 18:09:04 +00:00
|
|
|
|
2023-04-09 07:44:31 +00:00
|
|
|
err = mlx5_load_one(dev, false);
|
|
|
|
|
2022-10-26 13:51:48 +00:00
|
|
|
if (!err)
|
|
|
|
devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
|
|
|
|
DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
|
|
|
|
|
2021-10-05 01:39:51 +00:00
|
|
|
mlx5_pci_trace(dev, "Done, err = %d, device %s\n", err,
|
|
|
|
!err ? "recovered" : "Failed");
|
2015-10-14 14:43:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct pci_error_handlers mlx5_err_handler = {
|
|
|
|
.error_detected = mlx5_pci_err_detected,
|
|
|
|
.slot_reset = mlx5_pci_slot_reset,
|
|
|
|
.resume = mlx5_pci_resume
|
|
|
|
};
|
|
|
|
|
2017-02-09 12:20:12 +00:00
|
|
|
static int mlx5_try_fast_unload(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2018-08-09 06:55:21 +00:00
|
|
|
bool fast_teardown = false, force_teardown = false;
|
|
|
|
int ret = 1;
|
|
|
|
|
|
|
|
fast_teardown = MLX5_CAP_GEN(dev, fast_teardown);
|
|
|
|
force_teardown = MLX5_CAP_GEN(dev, force_teardown);
|
|
|
|
|
|
|
|
mlx5_core_dbg(dev, "force teardown firmware support=%d\n", force_teardown);
|
|
|
|
mlx5_core_dbg(dev, "fast teardown firmware support=%d\n", fast_teardown);
|
2017-02-09 12:20:12 +00:00
|
|
|
|
2018-08-09 06:55:21 +00:00
|
|
|
if (!fast_teardown && !force_teardown)
|
2017-02-09 12:20:12 +00:00
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) {
|
|
|
|
mlx5_core_dbg(dev, "Device in internal error state, giving up\n");
|
|
|
|
return -EAGAIN;
|
|
|
|
}
|
|
|
|
|
2017-09-26 20:11:56 +00:00
|
|
|
/* Panic tear down fw command will stop the PCI bus communication
|
2022-05-21 11:10:31 +00:00
|
|
|
* with the HCA, so the health poll is no longer needed.
|
2017-09-26 20:11:56 +00:00
|
|
|
*/
|
|
|
|
mlx5_drain_health_wq(dev);
|
2018-08-05 06:19:33 +00:00
|
|
|
mlx5_stop_health_poll(dev, false);
|
2017-09-26 20:11:56 +00:00
|
|
|
|
2018-08-09 06:55:21 +00:00
|
|
|
ret = mlx5_cmd_fast_teardown_hca(dev);
|
|
|
|
if (!ret)
|
|
|
|
goto succeed;
|
|
|
|
|
2017-02-09 12:20:12 +00:00
|
|
|
ret = mlx5_cmd_force_teardown_hca(dev);
|
2018-08-09 06:55:21 +00:00
|
|
|
if (!ret)
|
|
|
|
goto succeed;
|
|
|
|
|
|
|
|
mlx5_core_dbg(dev, "Firmware couldn't do fast unload error: %d\n", ret);
|
|
|
|
mlx5_start_health_poll(dev);
|
|
|
|
return ret;
|
2017-02-09 12:20:12 +00:00
|
|
|
|
2018-08-09 06:55:21 +00:00
|
|
|
succeed:
|
2017-02-09 12:20:12 +00:00
|
|
|
mlx5_enter_error_state(dev, true);
|
|
|
|
|
2018-03-26 18:35:29 +00:00
|
|
|
/* Some platforms requiring freeing the IRQ's in the shutdown
|
|
|
|
* flow. If they aren't freed they can't be allocated after
|
|
|
|
* kexec. There is no need to cleanup the mlx5_core software
|
|
|
|
* contexts.
|
|
|
|
*/
|
|
|
|
mlx5_core_eq_free_irqs(dev);
|
|
|
|
|
2017-02-09 12:20:12 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-21 21:33:07 +00:00
|
|
|
static void shutdown(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
2017-02-09 12:20:12 +00:00
|
|
|
int err;
|
2016-04-21 21:33:07 +00:00
|
|
|
|
2019-03-29 22:38:00 +00:00
|
|
|
mlx5_core_info(dev, "Shutdown was called\n");
|
2022-03-27 14:45:32 +00:00
|
|
|
set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
|
2017-02-09 12:20:12 +00:00
|
|
|
err = mlx5_try_fast_unload(dev);
|
|
|
|
if (err)
|
2023-01-26 12:39:09 +00:00
|
|
|
mlx5_unload_one(dev, false);
|
2016-04-21 21:33:07 +00:00
|
|
|
mlx5_pci_disable_device(dev);
|
|
|
|
}
|
|
|
|
|
2020-05-20 17:32:08 +00:00
|
|
|
static int mlx5_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
|
|
|
|
2023-01-26 12:39:09 +00:00
|
|
|
mlx5_unload_one(dev, true);
|
2020-05-20 17:32:08 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mlx5_resume(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
|
|
|
|
2023-04-09 07:44:31 +00:00
|
|
|
return mlx5_load_one(dev, false);
|
2020-05-20 17:32:08 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
static const struct pci_device_id mlx5_core_pci_table[] = {
|
2017-06-20 17:21:26 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_CONNECTIB) },
|
2015-12-01 16:03:09 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */
|
2017-06-20 17:21:26 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_CONNECTX4) },
|
2015-12-01 16:03:09 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4 VF */
|
2017-06-20 17:21:26 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_CONNECTX4_LX) },
|
2015-12-01 16:03:09 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF}, /* ConnectX-4LX VF */
|
2016-06-27 09:08:33 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1017) }, /* ConnectX-5, PCIe 3.0 */
|
2016-04-21 21:33:02 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1018), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 VF */
|
2017-02-23 08:52:19 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1019) }, /* ConnectX-5 Ex */
|
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101a), MLX5_PCI_DEV_IS_VF}, /* ConnectX-5 Ex VF */
|
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101b) }, /* ConnectX-6 */
|
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101c), MLX5_PCI_DEV_IS_VF}, /* ConnectX-6 VF */
|
2019-01-27 13:01:25 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101d) }, /* ConnectX-6 Dx */
|
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101e), MLX5_PCI_DEV_IS_VF}, /* ConnectX Family mlx5Gen Virtual Function */
|
2019-11-12 13:10:00 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x101f) }, /* ConnectX-6 LX */
|
2019-12-12 14:09:33 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1021) }, /* ConnectX-7 */
|
2022-01-10 08:14:41 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0x1023) }, /* ConnectX-8 */
|
2017-04-19 10:12:23 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */
|
|
|
|
{ PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */
|
2019-08-26 21:34:12 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0xa2d6) }, /* BlueField-2 integrated ConnectX-6 Dx network controller */
|
2020-11-20 23:03:30 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0xa2dc) }, /* BlueField-3 integrated ConnectX-7 network controller */
|
2022-01-10 08:14:41 +00:00
|
|
|
{ PCI_VDEVICE(MELLANOX, 0xa2df) }, /* BlueField-4 integrated ConnectX-8 network controller */
|
2014-07-28 20:30:22 +00:00
|
|
|
{ 0, }
|
|
|
|
};
|
|
|
|
|
|
|
|
MODULE_DEVICE_TABLE(pci, mlx5_core_pci_table);
|
|
|
|
|
2016-10-25 15:36:34 +00:00
|
|
|
void mlx5_disable_device(struct mlx5_core_dev *dev)
|
|
|
|
{
|
2019-01-27 16:38:39 +00:00
|
|
|
mlx5_error_sw_reset(dev);
|
2023-01-26 12:39:09 +00:00
|
|
|
mlx5_unload_one_devl_locked(dev, false);
|
2016-10-25 15:36:34 +00:00
|
|
|
}
|
|
|
|
|
2020-11-03 16:46:31 +00:00
|
|
|
int mlx5_recover_device(struct mlx5_core_dev *dev)
|
2016-10-25 15:36:34 +00:00
|
|
|
{
|
2021-11-23 18:08:13 +00:00
|
|
|
if (!mlx5_core_is_sf(dev)) {
|
|
|
|
mlx5_pci_disable_device(dev);
|
|
|
|
if (mlx5_pci_slot_reset(dev->pdev) != PCI_ERS_RESULT_RECOVERED)
|
|
|
|
return -EIO;
|
|
|
|
}
|
2020-11-03 16:46:31 +00:00
|
|
|
|
2022-07-28 15:53:49 +00:00
|
|
|
return mlx5_load_one_devl_locked(dev, true);
|
2016-10-25 15:36:34 +00:00
|
|
|
}
|
|
|
|
|
2014-07-28 20:30:22 +00:00
|
|
|
static struct pci_driver mlx5_core_driver = {
|
2020-10-04 11:30:58 +00:00
|
|
|
.name = KBUILD_MODNAME,
|
2014-07-28 20:30:22 +00:00
|
|
|
.id_table = mlx5_core_pci_table,
|
2020-11-02 14:54:43 +00:00
|
|
|
.probe = probe_one,
|
2015-10-14 14:43:46 +00:00
|
|
|
.remove = remove_one,
|
2020-05-20 17:32:08 +00:00
|
|
|
.suspend = mlx5_suspend,
|
|
|
|
.resume = mlx5_resume,
|
2016-04-21 21:33:07 +00:00
|
|
|
.shutdown = shutdown,
|
2015-12-01 16:03:09 +00:00
|
|
|
.err_handler = &mlx5_err_handler,
|
|
|
|
.sriov_configure = mlx5_core_sriov_configure,
|
2021-03-14 12:42:56 +00:00
|
|
|
.sriov_get_vf_total_msix = mlx5_sriov_get_vf_total_msix,
|
|
|
|
.sriov_set_msix_vec_count = mlx5_core_sriov_set_msix_vec_count,
|
2014-07-28 20:30:22 +00:00
|
|
|
};
|
2013-07-07 14:25:49 +00:00
|
|
|
|
2022-02-24 14:20:14 +00:00
|
|
|
/**
|
|
|
|
* mlx5_vf_get_core_dev - Get the mlx5 core device from a given VF PCI device if
|
|
|
|
* mlx5_core is its driver.
|
|
|
|
* @pdev: The associated PCI device.
|
|
|
|
*
|
|
|
|
* Upon return the interface state lock stay held to let caller uses it safely.
|
|
|
|
* Caller must ensure to use the returned mlx5 device for a narrow window
|
|
|
|
* and put it back with mlx5_vf_put_core_dev() immediately once usage was over.
|
|
|
|
*
|
|
|
|
* Return: Pointer to the associated mlx5_core_dev or NULL.
|
|
|
|
*/
|
|
|
|
struct mlx5_core_dev *mlx5_vf_get_core_dev(struct pci_dev *pdev)
|
|
|
|
{
|
|
|
|
struct mlx5_core_dev *mdev;
|
|
|
|
|
|
|
|
mdev = pci_iov_get_pf_drvdata(pdev, &mlx5_core_driver);
|
|
|
|
if (IS_ERR(mdev))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
mutex_lock(&mdev->intf_state_mutex);
|
|
|
|
if (!test_bit(MLX5_INTERFACE_STATE_UP, &mdev->intf_state)) {
|
|
|
|
mutex_unlock(&mdev->intf_state_mutex);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mdev;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mlx5_vf_get_core_dev);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* mlx5_vf_put_core_dev - Put the mlx5 core device back.
|
|
|
|
* @mdev: The mlx5 core device.
|
|
|
|
*
|
|
|
|
* Upon return the interface state lock is unlocked and caller should not
|
|
|
|
* access the mdev any more.
|
|
|
|
*/
|
|
|
|
void mlx5_vf_put_core_dev(struct mlx5_core_dev *mdev)
|
|
|
|
{
|
|
|
|
mutex_unlock(&mdev->intf_state_mutex);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mlx5_vf_put_core_dev);
|
|
|
|
|
2016-12-06 15:32:43 +00:00
|
|
|
static void mlx5_core_verify_params(void)
|
|
|
|
{
|
|
|
|
if (prof_sel >= ARRAY_SIZE(profile)) {
|
|
|
|
pr_warn("mlx5_core: WARNING: Invalid module parameter prof_sel %d, valid range 0-%zu, changing back to default(%d)\n",
|
|
|
|
prof_sel,
|
|
|
|
ARRAY_SIZE(profile) - 1,
|
|
|
|
MLX5_DEFAULT_PROF);
|
|
|
|
prof_sel = MLX5_DEFAULT_PROF;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-31 03:12:29 +00:00
|
|
|
static int __init mlx5_init(void)
|
2013-07-07 14:25:49 +00:00
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
2020-10-04 11:30:58 +00:00
|
|
|
WARN_ONCE(strcmp(MLX5_ADEV_NAME, KBUILD_MODNAME),
|
|
|
|
"mlx5_core name not in sync with kernel module name");
|
|
|
|
|
2018-01-04 15:25:32 +00:00
|
|
|
get_random_bytes(&sw_owner_id, sizeof(sw_owner_id));
|
|
|
|
|
2016-12-06 15:32:43 +00:00
|
|
|
mlx5_core_verify_params();
|
2013-07-07 14:25:49 +00:00
|
|
|
mlx5_register_debugfs();
|
|
|
|
|
2022-12-14 20:16:23 +00:00
|
|
|
err = mlx5e_init();
|
2014-07-28 20:30:22 +00:00
|
|
|
if (err)
|
2015-10-08 14:14:00 +00:00
|
|
|
goto err_debug;
|
2014-07-28 20:30:22 +00:00
|
|
|
|
2020-12-12 06:12:18 +00:00
|
|
|
err = mlx5_sf_driver_register();
|
|
|
|
if (err)
|
|
|
|
goto err_sf;
|
|
|
|
|
2022-12-14 20:16:23 +00:00
|
|
|
err = pci_register_driver(&mlx5_core_driver);
|
2021-08-02 13:39:54 +00:00
|
|
|
if (err)
|
2022-12-14 20:16:23 +00:00
|
|
|
goto err_pci;
|
2015-05-28 19:28:48 +00:00
|
|
|
|
2013-07-07 14:25:49 +00:00
|
|
|
return 0;
|
|
|
|
|
2022-12-14 20:16:23 +00:00
|
|
|
err_pci:
|
2021-08-02 13:39:54 +00:00
|
|
|
mlx5_sf_driver_unregister();
|
2020-12-12 06:12:18 +00:00
|
|
|
err_sf:
|
2022-12-14 20:16:23 +00:00
|
|
|
mlx5e_cleanup();
|
2013-07-07 14:25:49 +00:00
|
|
|
err_debug:
|
|
|
|
mlx5_unregister_debugfs();
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2022-08-31 03:12:29 +00:00
|
|
|
static void __exit mlx5_cleanup(void)
|
2013-07-07 14:25:49 +00:00
|
|
|
{
|
2014-07-28 20:30:22 +00:00
|
|
|
pci_unregister_driver(&mlx5_core_driver);
|
2022-12-14 20:16:23 +00:00
|
|
|
mlx5_sf_driver_unregister();
|
|
|
|
mlx5e_cleanup();
|
2013-07-07 14:25:49 +00:00
|
|
|
mlx5_unregister_debugfs();
|
|
|
|
}
|
|
|
|
|
2022-08-31 03:12:29 +00:00
|
|
|
module_init(mlx5_init);
|
|
|
|
module_exit(mlx5_cleanup);
|