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

dibs: Local gid for dibs devices

Define a uuid_t GID attribute to identify a dibs device.

SMC uses 64 Bit and 128 Bit Global Identifiers (GIDs) per device, that
need to be sent via the SMC protocol. Because the smc code uses integers,
network endianness and host endianness need to be considered. Avoid this
in the dibs layer by using uuid_t byte arrays. Future patches could change
SMC to use uuid_t. For now conversion helper functions are introduced.

ISM devices provide 64 Bit GIDs. Map them to dibs uuid_t GIDs like this:
_________________________________________
| 64 Bit ISM-vPCI GID | 00000000_00000000 |
-----------------------------------------
If interpreted as UUID [1], this would be interpreted as the UIID variant,
that is reserved for NCS backward compatibility. So it will not collide
with UUIDs that were generated according to the standard.

smc_loopback already uses version 4 UUIDs as 128 Bit GIDs, move that to
dibs loopback. A temporary change to smc_lo_query_rgid() is required,
that will be moved to dibs_loopback with a follow-on patch.

Provide gid of a dibs device as sysfs read-only attribute.

Link: https://datatracker.ietf.org/doc/html/rfc4122 [1]
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Julian Ruess <julianr@linux.ibm.com>
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Link: https://patch.msgid.link/20250918110500.1731261-11-wintera@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Alexandra Winter and committed by
Paolo Abeni
05e68d8d 80473734

+65 -54
+1
drivers/dibs/dibs_loopback.c
··· 46 46 47 47 ldev->dibs = dibs; 48 48 dibs->drv_priv = ldev; 49 + uuid_gen(&dibs->gid); 49 50 dibs->ops = &dibs_lo_ops; 50 51 51 52 dibs->dev.parent = NULL;
+12
drivers/dibs/dibs_main.c
··· 114 114 } 115 115 EXPORT_SYMBOL_GPL(dibs_dev_alloc); 116 116 117 + static ssize_t gid_show(struct device *dev, struct device_attribute *attr, 118 + char *buf) 119 + { 120 + struct dibs_dev *dibs; 121 + 122 + dibs = container_of(dev, struct dibs_dev, dev); 123 + 124 + return sysfs_emit(buf, "%pUb\n", &dibs->gid); 125 + } 126 + static DEVICE_ATTR_RO(gid); 127 + 117 128 static ssize_t fabric_id_show(struct device *dev, struct device_attribute *attr, 118 129 char *buf) 119 130 { ··· 139 128 static DEVICE_ATTR_RO(fabric_id); 140 129 141 130 static struct attribute *dibs_dev_attrs[] = { 131 + &dev_attr_gid.attr, 142 132 &dev_attr_fabric_id.attr, 143 133 NULL, 144 134 };
+9
drivers/s390/net/ism.h
··· 67 67 } response; 68 68 } __aligned(16); 69 69 70 + /* ISM-vPCI devices provide 64 Bit GIDs 71 + * Map them to ISM UUID GIDs like this: 72 + * _________________________________________ 73 + * | 64 Bit ISM-vPCI GID | 00000000_00000000 | 74 + * ----------------------------------------- 75 + * This will be interpreted as a UIID variant, that is reserved 76 + * for NCS backward compatibility. So it will not collide with 77 + * proper UUIDs. 78 + */ 70 79 union ism_read_gid { 71 80 struct { 72 81 struct ism_req_hdr hdr;
+9 -21
drivers/s390/net/ism_drv.c
··· 272 272 return 0; 273 273 } 274 274 275 - static int ism_read_local_gid(struct ism_dev *ism) 275 + static int ism_read_local_gid(struct dibs_dev *dibs) 276 276 { 277 + struct ism_dev *ism = dibs->drv_priv; 277 278 union ism_read_gid cmd; 278 279 int ret; 279 280 ··· 286 285 if (ret) 287 286 goto out; 288 287 289 - ism->local_gid = cmd.response.gid; 288 + memset(&dibs->gid, 0, sizeof(dibs->gid)); 289 + memcpy(&dibs->gid, &cmd.response.gid, sizeof(cmd.response.gid)); 290 290 out: 291 291 return ret; 292 292 } ··· 565 563 if (ret) 566 564 goto unreg_sba; 567 565 568 - ret = ism_read_local_gid(ism); 569 - if (ret) 570 - goto unreg_ieq; 571 - 572 566 if (!ism_add_vlan_id(ism, ISM_RESERVED_VLANID)) 573 567 /* hardware is V2 capable */ 574 568 ism_v2_capable = true; ··· 586 588 query_info(ism); 587 589 return 0; 588 590 589 - unreg_ieq: 590 - unregister_ieq(ism); 591 591 unreg_sba: 592 592 unregister_sba(ism); 593 593 free_irq: ··· 667 671 ret = ism_dev_init(ism); 668 672 if (ret) 669 673 goto err_dibs; 674 + 675 + /* after ism_dev_init() we can call ism function to set gid */ 676 + ret = ism_read_local_gid(dibs); 677 + if (ret) 678 + goto err_ism; 670 679 671 680 dibs->dev.parent = &pdev->dev; 672 681 ··· 842 841 return ism_v2_capable; 843 842 } 844 843 845 - static u64 ism_get_local_gid(struct ism_dev *ism) 846 - { 847 - return ism->local_gid; 848 - } 849 - 850 - static void smcd_get_local_gid(struct smcd_dev *smcd, 851 - struct smcd_gid *smcd_gid) 852 - { 853 - smcd_gid->gid = ism_get_local_gid(smcd->priv); 854 - smcd_gid->gid_ext = 0; 855 - } 856 - 857 844 static const struct smcd_ops ism_smcd_ops = { 858 845 .query_remote_gid = smcd_query_rgid, 859 846 .register_dmb = smcd_register_dmb, ··· 853 864 .signal_event = smcd_signal_ieq, 854 865 .move_data = smcd_move, 855 866 .supports_v2 = smcd_supports_v2, 856 - .get_local_gid = smcd_get_local_gid, 857 867 }; 858 868 859 869 const struct smcd_ops *ism_get_smcd_ops(void)
+3
include/linux/dibs.h
··· 10 10 #define _DIBS_H 11 11 12 12 #include <linux/device.h> 13 + #include <linux/uuid.h> 14 + 13 15 /* DIBS - Direct Internal Buffer Sharing - concept 14 16 * ----------------------------------------------- 15 17 * In the case of multiple system sharing the same hardware, dibs fabrics can ··· 140 138 struct device dev; 141 139 /* To be filled by device driver, before calling dibs_dev_add(): */ 142 140 const struct dibs_dev_ops *ops; 141 + uuid_t gid; 143 142 /* priv pointer for device driver */ 144 143 void *drv_priv; 145 144
-1
include/linux/ism.h
··· 42 42 struct ism_eq *ieq; 43 43 dma_addr_t ieq_dma_addr; 44 44 45 - u64 local_gid; 46 45 int ieq_idx; 47 46 48 47 struct ism_client *subs[MAX_CLIENTS];
-1
include/net/smc.h
··· 62 62 bool sf, unsigned int offset, void *data, 63 63 unsigned int size); 64 64 int (*supports_v2)(void); 65 - void (*get_local_gid)(struct smcd_dev *dev, struct smcd_gid *gid); 66 65 67 66 /* optional operations */ 68 67 int (*add_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
+3 -3
net/smc/smc_clc.c
··· 916 916 /* add SMC-D specifics */ 917 917 if (ini->ism_dev[0]) { 918 918 smcd = ini->ism_dev[0]; 919 - smcd->ops->get_local_gid(smcd, &smcd_gid); 919 + copy_to_smcdgid(&smcd_gid, &smcd->dibs->gid); 920 920 pclc_smcd->ism.gid = htonll(smcd_gid.gid); 921 921 pclc_smcd->ism.chid = 922 922 htons(smc_ism_get_chid(ini->ism_dev[0])); ··· 966 966 if (ini->ism_offered_cnt) { 967 967 for (i = 1; i <= ini->ism_offered_cnt; i++) { 968 968 smcd = ini->ism_dev[i]; 969 - smcd->ops->get_local_gid(smcd, &smcd_gid); 969 + copy_to_smcdgid(&smcd_gid, &smcd->dibs->gid); 970 970 gidchids[entry].chid = 971 971 htons(smc_ism_get_chid(ini->ism_dev[i])); 972 972 gidchids[entry].gid = htonll(smcd_gid.gid); ··· 1059 1059 /* SMC-D specific settings */ 1060 1060 memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER, 1061 1061 sizeof(SMCD_EYECATCHER)); 1062 - smcd->ops->get_local_gid(smcd, &smcd_gid); 1062 + copy_to_smcdgid(&smcd_gid, &smcd->dibs->gid); 1063 1063 clc->hdr.typev1 = SMC_TYPE_D; 1064 1064 clc->d0.gid = htonll(smcd_gid.gid); 1065 1065 clc->d0.token = htonll(conn->rmb_desc->token);
+1 -1
net/smc/smc_core.c
··· 555 555 556 556 if (nla_put_u32(skb, SMC_NLA_LGR_D_ID, *((u32 *)&lgr->id))) 557 557 goto errattr; 558 - smcd->ops->get_local_gid(smcd, &smcd_gid); 558 + copy_to_smcdgid(&smcd_gid, &smcd->dibs->gid); 559 559 if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_GID, 560 560 smcd_gid.gid, SMC_NLA_LGR_D_PAD)) 561 561 goto errattr;
+1 -1
net/smc/smc_diag.c
··· 175 175 dinfo.linkid = *((u32 *)conn->lgr->id); 176 176 dinfo.peer_gid = conn->lgr->peer_gid.gid; 177 177 dinfo.peer_gid_ext = conn->lgr->peer_gid.gid_ext; 178 - smcd->ops->get_local_gid(smcd, &smcd_gid); 178 + copy_to_smcdgid(&smcd_gid, &smcd->dibs->gid); 179 179 dinfo.my_gid = smcd_gid.gid; 180 180 dinfo.my_gid_ext = smcd_gid.gid_ext; 181 181 dinfo.token = conn->rmb_desc->token;
+22
net/smc/smc_ism.h
··· 96 96 return (dibs->ops->get_fabric_id(dibs) == DIBS_LOOPBACK_FABRIC); 97 97 } 98 98 99 + static inline void copy_to_smcdgid(struct smcd_gid *sgid, uuid_t *dibs_gid) 100 + { 101 + __be64 temp; 102 + 103 + memcpy(&temp, dibs_gid, sizeof(sgid->gid)); 104 + sgid->gid = ntohll(temp); 105 + memcpy(&temp, (uint8_t *)dibs_gid + sizeof(sgid->gid), 106 + sizeof(sgid->gid_ext)); 107 + sgid->gid_ext = ntohll(temp); 108 + } 109 + 110 + static inline void copy_to_dibsgid(uuid_t *dibs_gid, struct smcd_gid *sgid) 111 + { 112 + __be64 temp; 113 + 114 + temp = htonll(sgid->gid); 115 + memcpy(dibs_gid, &temp, sizeof(sgid->gid)); 116 + temp = htonll(sgid->gid_ext); 117 + memcpy((uint8_t *)dibs_gid + sizeof(sgid->gid), &temp, 118 + sizeof(sgid->gid_ext)); 119 + } 120 + 99 121 #endif
+4 -25
net/smc/smc_loopback.c
··· 13 13 14 14 #include <linux/device.h> 15 15 #include <linux/types.h> 16 + #include <linux/dibs.h> 16 17 #include <net/smc.h> 17 18 18 19 #include "smc_cdc.h" ··· 26 25 27 26 static struct smc_lo_dev *lo_dev; 28 27 29 - static void smc_lo_generate_ids(struct smc_lo_dev *ldev) 30 - { 31 - struct smcd_gid *lgid = &ldev->local_gid; 32 - uuid_t uuid; 33 - 34 - uuid_gen(&uuid); 35 - memcpy(&lgid->gid, &uuid, sizeof(lgid->gid)); 36 - memcpy(&lgid->gid_ext, (u8 *)&uuid + sizeof(lgid->gid), 37 - sizeof(lgid->gid_ext)); 38 - } 39 - 40 28 static int smc_lo_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid, 41 29 u32 vid_valid, u32 vid) 42 30 { 43 - struct smc_lo_dev *ldev = smcd->priv; 31 + uuid_t temp; 44 32 33 + copy_to_dibsgid(&temp, rgid); 45 34 /* rgid should be the same as lgid */ 46 - if (!ldev || rgid->gid != ldev->local_gid.gid || 47 - rgid->gid_ext != ldev->local_gid.gid_ext) 35 + if (!uuid_equal(&temp, &smcd->dibs->gid)) 48 36 return -ENETUNREACH; 49 37 return 0; 50 38 } ··· 235 245 return 0; 236 246 } 237 247 238 - static void smc_lo_get_local_gid(struct smcd_dev *smcd, 239 - struct smcd_gid *smcd_gid) 240 - { 241 - struct smc_lo_dev *ldev = smcd->priv; 242 - 243 - smcd_gid->gid = ldev->local_gid.gid; 244 - smcd_gid->gid_ext = ldev->local_gid.gid_ext; 245 - } 246 - 247 248 static const struct smcd_ops lo_ops = { 248 249 .query_remote_gid = smc_lo_query_rgid, 249 250 .register_dmb = smc_lo_register_dmb, ··· 248 267 .reset_vlan_required = NULL, 249 268 .signal_event = NULL, 250 269 .move_data = smc_lo_move_data, 251 - .get_local_gid = smc_lo_get_local_gid, 252 270 }; 253 271 254 272 const struct smcd_ops *smc_lo_get_smcd_ops(void) ··· 257 277 258 278 static void smc_lo_dev_init(struct smc_lo_dev *ldev) 259 279 { 260 - smc_lo_generate_ids(ldev); 261 280 rwlock_init(&ldev->dmb_ht_lock); 262 281 hash_init(ldev->dmb_ht); 263 282 atomic_set(&ldev->dmb_cnt, 0);
-1
net/smc/smc_loopback.h
··· 32 32 33 33 struct smc_lo_dev { 34 34 struct smcd_dev *smcd; 35 - struct smcd_gid local_gid; 36 35 atomic_t dmb_cnt; 37 36 rwlock_t dmb_ht_lock; 38 37 DECLARE_BITMAP(sba_idx_mask, SMC_LO_MAX_DMBS);