Skip to content

Commit dd3cd3c

Browse files
committed
Merge tag 'aux-sysfs-irqs' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux
Saeed Mahameed says: ==================== aux-sysfs-irqs Shay Says: ========== Introduce auxiliary bus IRQs sysfs Today, PCI PFs and VFs, which are anchored on the PCI bus, display their IRQ information in the <pci_device>/msi_irqs/<irq_num> sysfs files. PCI subfunctions (SFs) are similar to PFs and VFs and these SFs are anchored on the auxiliary bus. However, these PCI SFs lack such IRQ information on the auxiliary bus, leaving users without visibility into which IRQs are used by the SFs. This absence makes it impossible to debug situations and to understand the source of interrupts/SFs for performance tuning and debug. Additionally, the SFs are multifunctional devices supporting RDMA, network devices, clocks, and more, similar to their peer PCI PFs and VFs. Therefore, it is desirable to have SFs' IRQ information available at the bus/device level. To overcome the above limitations, this short series extends the auxiliary bus to display IRQ information in sysfs, similar to that of PFs and VFs. It adds an 'irqs' directory under the auxiliary device and includes an <irq_num> sysfs file within it. For example: $ ls /sys/bus/auxiliary/devices/mlx5_core.sf.1/irqs/ 50 51 52 53 54 55 56 57 58 Patch summary: patch-1 adds auxiliary bus to support irqs used by auxiliary device patch-2 mlx5 driver using exposing irqs for PCI SF devices via auxiliary bus ========== * tag 'aux-sysfs-irqs' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux: net/mlx5: Expose SFs IRQs driver core: auxiliary bus: show auxiliary device IRQs RDMA/mlx5: Add Qcounters req_transport_retries_exceeded/req_rnr_retries_exceeded net/mlx5: Reimplement write combining test ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents e7afb95 + 0477d51 commit dd3cd3c

File tree

20 files changed

+651
-246
lines changed

20 files changed

+651
-246
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
What: /sys/bus/auxiliary/devices/.../irqs/
2+
Date: April, 2024
3+
Contact: Shay Drory <[email protected]>
4+
Description:
5+
The /sys/devices/.../irqs directory contains a variable set of
6+
files, with each file is named as irq number similar to PCI PF
7+
or VF's irq number located in msi_irqs directory.
8+
These irq files are added and removed dynamically when an IRQ
9+
is requested and freed respectively for the PCI SF.

drivers/base/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ obj-$(CONFIG_NUMA) += node.o
1616
obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
1717
ifeq ($(CONFIG_SYSFS),y)
1818
obj-$(CONFIG_MODULES) += module.o
19+
obj-$(CONFIG_AUXILIARY_BUS) += auxiliary_sysfs.o
1920
endif
2021
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
2122
obj-$(CONFIG_REGMAP) += regmap/

drivers/base/auxiliary.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ int auxiliary_device_init(struct auxiliary_device *auxdev)
287287

288288
dev->bus = &auxiliary_bus_type;
289289
device_initialize(&auxdev->dev);
290+
mutex_init(&auxdev->sysfs.lock);
290291
return 0;
291292
}
292293
EXPORT_SYMBOL_GPL(auxiliary_device_init);

drivers/base/auxiliary_sysfs.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
4+
*/
5+
6+
#include <linux/auxiliary_bus.h>
7+
#include <linux/slab.h>
8+
9+
#define AUXILIARY_MAX_IRQ_NAME 11
10+
11+
struct auxiliary_irq_info {
12+
struct device_attribute sysfs_attr;
13+
char name[AUXILIARY_MAX_IRQ_NAME];
14+
};
15+
16+
static struct attribute *auxiliary_irq_attrs[] = {
17+
NULL
18+
};
19+
20+
static const struct attribute_group auxiliary_irqs_group = {
21+
.name = "irqs",
22+
.attrs = auxiliary_irq_attrs,
23+
};
24+
25+
static int auxiliary_irq_dir_prepare(struct auxiliary_device *auxdev)
26+
{
27+
int ret = 0;
28+
29+
guard(mutex)(&auxdev->sysfs.lock);
30+
if (auxdev->sysfs.irq_dir_exists)
31+
return 0;
32+
33+
ret = devm_device_add_group(&auxdev->dev, &auxiliary_irqs_group);
34+
if (ret)
35+
return ret;
36+
37+
auxdev->sysfs.irq_dir_exists = true;
38+
xa_init(&auxdev->sysfs.irqs);
39+
return 0;
40+
}
41+
42+
/**
43+
* auxiliary_device_sysfs_irq_add - add a sysfs entry for the given IRQ
44+
* @auxdev: auxiliary bus device to add the sysfs entry.
45+
* @irq: The associated interrupt number.
46+
*
47+
* This function should be called after auxiliary device have successfully
48+
* received the irq.
49+
* The driver is responsible to add a unique irq for the auxiliary device. The
50+
* driver can invoke this function from multiple thread context safely for
51+
* unique irqs of the auxiliary devices. The driver must not invoke this API
52+
* multiple times if the irq is already added previously.
53+
*
54+
* Return: zero on success or an error code on failure.
55+
*/
56+
int auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq)
57+
{
58+
struct auxiliary_irq_info *info __free(kfree) = NULL;
59+
struct device *dev = &auxdev->dev;
60+
int ret;
61+
62+
ret = auxiliary_irq_dir_prepare(auxdev);
63+
if (ret)
64+
return ret;
65+
66+
info = kzalloc(sizeof(*info), GFP_KERNEL);
67+
if (!info)
68+
return -ENOMEM;
69+
70+
sysfs_attr_init(&info->sysfs_attr.attr);
71+
snprintf(info->name, AUXILIARY_MAX_IRQ_NAME, "%d", irq);
72+
73+
ret = xa_insert(&auxdev->sysfs.irqs, irq, info, GFP_KERNEL);
74+
if (ret)
75+
return ret;
76+
77+
info->sysfs_attr.attr.name = info->name;
78+
ret = sysfs_add_file_to_group(&dev->kobj, &info->sysfs_attr.attr,
79+
auxiliary_irqs_group.name);
80+
if (ret)
81+
goto sysfs_add_err;
82+
83+
xa_store(&auxdev->sysfs.irqs, irq, no_free_ptr(info), GFP_KERNEL);
84+
return 0;
85+
86+
sysfs_add_err:
87+
xa_erase(&auxdev->sysfs.irqs, irq);
88+
return ret;
89+
}
90+
EXPORT_SYMBOL_GPL(auxiliary_device_sysfs_irq_add);
91+
92+
/**
93+
* auxiliary_device_sysfs_irq_remove - remove a sysfs entry for the given IRQ
94+
* @auxdev: auxiliary bus device to add the sysfs entry.
95+
* @irq: the IRQ to remove.
96+
*
97+
* This function should be called to remove an IRQ sysfs entry.
98+
* The driver must invoke this API when IRQ is released by the device.
99+
*/
100+
void auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev, int irq)
101+
{
102+
struct auxiliary_irq_info *info __free(kfree) = xa_load(&auxdev->sysfs.irqs, irq);
103+
struct device *dev = &auxdev->dev;
104+
105+
if (!info) {
106+
dev_err(&auxdev->dev, "IRQ %d doesn't exist\n", irq);
107+
return;
108+
}
109+
sysfs_remove_file_from_group(&dev->kobj, &info->sysfs_attr.attr,
110+
auxiliary_irqs_group.name);
111+
xa_erase(&auxdev->sysfs.irqs, irq);
112+
}
113+
EXPORT_SYMBOL_GPL(auxiliary_device_sysfs_irq_remove);

drivers/infiniband/hw/mlx5/counters.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ static const struct mlx5_ib_counter extended_err_cnts[] = {
8383
INIT_Q_COUNTER(resp_remote_access_errors),
8484
INIT_Q_COUNTER(resp_cqe_flush_error),
8585
INIT_Q_COUNTER(req_cqe_flush_error),
86+
INIT_Q_COUNTER(req_transport_retries_exceeded),
87+
INIT_Q_COUNTER(req_rnr_retries_exceeded),
8688
};
8789

8890
static const struct mlx5_ib_counter roce_accl_cnts[] = {
@@ -102,6 +104,8 @@ static const struct mlx5_ib_counter vport_extended_err_cnts[] = {
102104
INIT_VPORT_Q_COUNTER(resp_remote_access_errors),
103105
INIT_VPORT_Q_COUNTER(resp_cqe_flush_error),
104106
INIT_VPORT_Q_COUNTER(req_cqe_flush_error),
107+
INIT_VPORT_Q_COUNTER(req_transport_retries_exceeded),
108+
INIT_VPORT_Q_COUNTER(req_rnr_retries_exceeded),
105109
};
106110

107111
static const struct mlx5_ib_counter vport_roce_accl_cnts[] = {

drivers/infiniband/hw/mlx5/main.c

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,7 +1810,7 @@ static int set_ucontext_resp(struct ib_ucontext *uctx,
18101810
}
18111811

18121812
resp->qp_tab_size = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp);
1813-
if (dev->wc_support)
1813+
if (mlx5_wc_support_get(dev->mdev))
18141814
resp->bf_reg_size = 1 << MLX5_CAP_GEN(dev->mdev,
18151815
log_bf_reg_size);
18161816
resp->cache_line_size = cache_line_size();
@@ -2337,7 +2337,7 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
23372337
switch (command) {
23382338
case MLX5_IB_MMAP_WC_PAGE:
23392339
case MLX5_IB_MMAP_ALLOC_WC:
2340-
if (!dev->wc_support)
2340+
if (!mlx5_wc_support_get(dev->mdev))
23412341
return -EPERM;
23422342
fallthrough;
23432343
case MLX5_IB_MMAP_NC_PAGE:
@@ -3612,7 +3612,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_UAR_OBJ_ALLOC)(
36123612
alloc_type != MLX5_IB_UAPI_UAR_ALLOC_TYPE_NC)
36133613
return -EOPNOTSUPP;
36143614

3615-
if (!to_mdev(c->ibucontext.device)->wc_support &&
3615+
if (!mlx5_wc_support_get(to_mdev(c->ibucontext.device)->mdev) &&
36163616
alloc_type == MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF)
36173617
return -EOPNOTSUPP;
36183618

@@ -3766,18 +3766,6 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
37663766
return err;
37673767
}
37683768

3769-
static int mlx5_ib_enable_driver(struct ib_device *dev)
3770-
{
3771-
struct mlx5_ib_dev *mdev = to_mdev(dev);
3772-
int ret;
3773-
3774-
ret = mlx5_ib_test_wc(mdev);
3775-
mlx5_ib_dbg(mdev, "Write-Combining %s",
3776-
mdev->wc_support ? "supported" : "not supported");
3777-
3778-
return ret;
3779-
}
3780-
37813769
static const struct ib_device_ops mlx5_ib_dev_ops = {
37823770
.owner = THIS_MODULE,
37833771
.driver_id = RDMA_DRIVER_MLX5,
@@ -3808,7 +3796,6 @@ static const struct ib_device_ops mlx5_ib_dev_ops = {
38083796
.drain_rq = mlx5_ib_drain_rq,
38093797
.drain_sq = mlx5_ib_drain_sq,
38103798
.device_group = &mlx5_attr_group,
3811-
.enable_driver = mlx5_ib_enable_driver,
38123799
.get_dev_fw_str = get_dev_fw_str,
38133800
.get_dma_mr = mlx5_ib_get_dma_mr,
38143801
.get_link_layer = mlx5_ib_port_link_layer,

0 commit comments

Comments
 (0)