Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dibs: Create class dibs

Create '/sys/class/dibs' to represent multiple kinds of dibs devices in
sysfs. Show s390/ism devices as well as dibs_loopback devices.

Show attribute fabric_id using dibs_ops.get_fabric_id(). This can help
users understand which dibs devices are connected to the same fabric in
different systems and which dibs devices are loopback devices
(fabric_id 0xffff)

Instead of using the same name as the pci device, give the ism devices
their own readable names based on uid or fid from the HW definition.

smc_loopback was never visible in sysfs. dibs_loopback is now represented
as a virtual device.

For the SMC feature "software defined pnet-id" either the ib device name or
the PCI-ID (actually the parent device name) can be used for SMC-R entries.
Mimic this behaviour for SMC-D, and check the parent device name as well.
So device name or PCI-ID can be used for ism and device name can be used
for dibs-loopback. Note that this:
IB_DEVICE_NAME_MAX - 1 == smc_pnet_policy.[SMC_PNETID_IBNAME].len
is the length of smcd_name. Future SW-pnetid cleanup patches to could use a
meaningful define, but that would touch too much unrelated code here.

Examples:
---------
ism before:
> ls /sys/bus/pci/devices/0000:00:00.0/0000:00:00.0
uevent

ism now:
> ls /sys/bus/pci/devices/0000:00:00.0/dibs/ism30
device -> ../../../0000:00:00.0/
fabric_id
subsystem -> ../../../../../class/dibs/
uevent

dibs loopback:
> ls /sys/devices/virtual/dibs/lo/
fabric_id
subsystem -> ../../../../class/dibs/
uevent

dibs class:
> ls -l /sys/class/dibs/
ism30 -> ../../devices/pci0000:00/0000:00:00.0/dibs/ism30/
lo -> ../../devices/virtual/dibs/lo/

For comparison:
> ls -l /sys/class/net/
enc8410 -> ../../devices/qeth/0.0.8410/net/enc8410/
ens1693 -> ../../devices/pci0001:00/0001:00:00.0/net/ens1693/
lo -> ../../devices/virtual/net/lo/

Signed-off-by: Julian Ruess <julianr@linux.ibm.com>
Co-developed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20250918110500.1731261-10-wintera@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Julian Ruess and committed by
Paolo Abeni
80473734 845c334a

+56 -5
+40
drivers/dibs/dibs_main.c
··· 20 20 MODULE_DESCRIPTION("Direct Internal Buffer Sharing class"); 21 21 MODULE_LICENSE("GPL"); 22 22 23 + static struct class *dibs_class; 24 + 23 25 /* use an array rather a list for fast mapping: */ 24 26 static struct dibs_client *clients[MAX_DIBS_CLIENTS]; 25 27 static u8 max_client; ··· 107 105 if (!dibs) 108 106 return dibs; 109 107 dibs->dev.release = dibs_dev_release; 108 + dibs->dev.class = dibs_class; 110 109 device_initialize(&dibs->dev); 111 110 112 111 return dibs; 113 112 } 114 113 EXPORT_SYMBOL_GPL(dibs_dev_alloc); 114 + 115 + static ssize_t fabric_id_show(struct device *dev, struct device_attribute *attr, 116 + char *buf) 117 + { 118 + struct dibs_dev *dibs; 119 + u16 fabric_id; 120 + 121 + dibs = container_of(dev, struct dibs_dev, dev); 122 + fabric_id = dibs->ops->get_fabric_id(dibs); 123 + 124 + return sysfs_emit(buf, "0x%04x\n", fabric_id); 125 + } 126 + static DEVICE_ATTR_RO(fabric_id); 127 + 128 + static struct attribute *dibs_dev_attrs[] = { 129 + &dev_attr_fabric_id.attr, 130 + NULL, 131 + }; 132 + 133 + static const struct attribute_group dibs_dev_attr_group = { 134 + .attrs = dibs_dev_attrs, 135 + }; 115 136 116 137 int dibs_dev_add(struct dibs_dev *dibs) 117 138 { ··· 144 119 if (ret) 145 120 return ret; 146 121 122 + ret = sysfs_create_group(&dibs->dev.kobj, &dibs_dev_attr_group); 123 + if (ret) { 124 + dev_err(&dibs->dev, "sysfs_create_group failed for dibs_dev\n"); 125 + goto err_device_del; 126 + } 147 127 mutex_lock(&dibs_dev_list.mutex); 148 128 mutex_lock(&clients_lock); 149 129 for (i = 0; i < max_client; ++i) { ··· 160 130 mutex_unlock(&dibs_dev_list.mutex); 161 131 162 132 return 0; 133 + 134 + err_device_del: 135 + device_del(&dibs->dev); 136 + return ret; 137 + 163 138 } 164 139 EXPORT_SYMBOL_GPL(dibs_dev_add); 165 140 ··· 193 158 memset(clients, 0, sizeof(clients)); 194 159 max_client = 0; 195 160 161 + dibs_class = class_create("dibs"); 162 + if (IS_ERR(&dibs_class)) 163 + return PTR_ERR(&dibs_class); 164 + 196 165 rc = dibs_loopback_init(); 197 166 if (rc) 198 167 pr_err("%s fails with %d\n", __func__, rc); ··· 207 168 static void __exit dibs_exit(void) 208 169 { 209 170 dibs_loopback_exit(); 171 + class_destroy(dibs_class); 210 172 } 211 173 212 174 module_init(dibs_init);
+4 -1
drivers/s390/net/ism_drv.c
··· 629 629 static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) 630 630 { 631 631 struct dibs_dev *dibs; 632 + struct zpci_dev *zdev; 632 633 struct ism_dev *ism; 633 634 int ret; 634 635 ··· 673 672 goto err_dibs; 674 673 675 674 dibs->dev.parent = &pdev->dev; 676 - dev_set_name(&dibs->dev, "%s", dev_name(&pdev->dev)); 675 + 676 + zdev = to_zpci(pdev); 677 + dev_set_name(&dibs->dev, "ism%x", zdev->uid ? zdev->uid : zdev->fid); 677 678 678 679 ret = dibs_dev_add(dibs); 679 680 if (ret)
+12 -4
net/smc/smc_pnet.c
··· 332 332 333 333 mutex_lock(&smcd_dev_list.mutex); 334 334 list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) { 335 - if (!strncmp(dev_name(&smcd_dev->dibs->dev), 336 - smcd_name, IB_DEVICE_NAME_MAX - 1)) 335 + if (!strncmp(dev_name(&smcd_dev->dibs->dev), smcd_name, 336 + IB_DEVICE_NAME_MAX - 1) || 337 + (smcd_dev->dibs->dev.parent && 338 + !strncmp(dev_name(smcd_dev->dibs->dev.parent), smcd_name, 339 + IB_DEVICE_NAME_MAX - 1))) 337 340 goto out; 338 341 } 339 342 smcd_dev = NULL; ··· 1193 1190 */ 1194 1191 int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev) 1195 1192 { 1196 - const char *ib_name = dev_name(&smcddev->dibs->dev); 1197 1193 struct smc_pnettable *pnettable; 1198 1194 struct smc_pnetentry *tmp_pe; 1199 1195 struct smc_net *sn; ··· 1205 1203 mutex_lock(&pnettable->lock); 1206 1204 list_for_each_entry(tmp_pe, &pnettable->pnetlist, list) { 1207 1205 if (tmp_pe->type == SMC_PNET_IB && 1208 - !strncmp(tmp_pe->ib_name, ib_name, IB_DEVICE_NAME_MAX)) { 1206 + (!strncmp(tmp_pe->ib_name, 1207 + dev_name(&smcddev->dibs->dev), 1208 + sizeof(tmp_pe->ib_name)) || 1209 + (smcddev->dibs->dev.parent && 1210 + !strncmp(tmp_pe->ib_name, 1211 + dev_name(smcddev->dibs->dev.parent), 1212 + sizeof(tmp_pe->ib_name))))) { 1209 1213 smc_pnet_apply_smcd(smcddev, tmp_pe->pnet_name); 1210 1214 rc = 0; 1211 1215 break;