Skip to content

Commit 888bd44

Browse files
author
Mete Durlu
committed
net/smc: compatible with 128-bits extended GID of virtual ISM device
JIRA: https://issues.redhat.com/browse/RHEL-73484 Conflicts: Code changes necessary to adapt to existing differences to upstream - no functional change commit b40584d Author: Wen Gu <guwen@linux.alibaba.com> Date: Tue Dec 19 22:26:13 2023 +0800 net/smc: compatible with 128-bits extended GID of virtual ISM device According to virtual ISM support feature defined by SMCv2.1, GIDs of virtual ISM device are UUIDs defined by RFC4122, which are 128-bits long. So some adaptation work is required. And note that the GIDs of existing platform firmware ISM devices still remain 64-bits long. Signed-off-by: Wen Gu <guwen@linux.alibaba.com> Reviewed-by: Alexandra Winter <wintera@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Mete Durlu <mdurlu@redhat.com>
1 parent 26c596e commit 888bd44

File tree

12 files changed

+167
-68
lines changed

12 files changed

+167
-68
lines changed

drivers/s390/net/ism_drv.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -762,10 +762,10 @@ static int ism_query_rgid(struct ism_dev *ism, u64 rgid, u32 vid_valid,
762762
return ism_cmd(ism, &cmd);
763763
}
764764

765-
static int smcd_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
766-
u32 vid)
765+
static int smcd_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid,
766+
u32 vid_valid, u32 vid)
767767
{
768-
return ism_query_rgid(smcd->priv, rgid, vid_valid, vid);
768+
return ism_query_rgid(smcd->priv, rgid->gid, vid_valid, vid);
769769
}
770770

771771
static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
@@ -816,10 +816,11 @@ static int ism_signal_ieq(struct ism_dev *ism, u64 rgid, u32 trigger_irq,
816816
return ism_cmd(ism, &cmd);
817817
}
818818

819-
static int smcd_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
820-
u32 event_code, u64 info)
819+
static int smcd_signal_ieq(struct smcd_dev *smcd, struct smcd_gid *rgid,
820+
u32 trigger_irq, u32 event_code, u64 info)
821821
{
822-
return ism_signal_ieq(smcd->priv, rgid, trigger_irq, event_code, info);
822+
return ism_signal_ieq(smcd->priv, rgid->gid,
823+
trigger_irq, event_code, info);
823824
}
824825

825826
static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
@@ -840,9 +841,11 @@ static u64 ism_get_local_gid(struct ism_dev *ism)
840841
return ism->local_gid;
841842
}
842843

843-
static u64 smcd_get_local_gid(struct smcd_dev *smcd)
844+
static void smcd_get_local_gid(struct smcd_dev *smcd,
845+
struct smcd_gid *smcd_gid)
844846
{
845-
return ism_get_local_gid(smcd->priv);
847+
smcd_gid->gid = ism_get_local_gid(smcd->priv);
848+
smcd_gid->gid_ext = 0;
846849
}
847850

848851
static u16 ism_get_chid(struct ism_dev *ism)

include/net/smc.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,29 @@ struct smcd_dmb {
5252
struct smcd_dev;
5353
struct ism_client;
5454

55+
struct smcd_gid {
56+
u64 gid;
57+
u64 gid_ext;
58+
};
59+
5560
struct smcd_ops {
56-
int (*query_remote_gid)(struct smcd_dev *dev, u64 rgid, u32 vid_valid,
57-
u32 vid);
61+
int (*query_remote_gid)(struct smcd_dev *dev, struct smcd_gid *rgid,
62+
u32 vid_valid, u32 vid);
5863
int (*register_dmb)(struct smcd_dev *dev, struct smcd_dmb *dmb,
5964
struct ism_client *client);
6065
int (*unregister_dmb)(struct smcd_dev *dev, struct smcd_dmb *dmb);
6166
int (*add_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
6267
int (*del_vlan_id)(struct smcd_dev *dev, u64 vlan_id);
6368
int (*set_vlan_required)(struct smcd_dev *dev);
6469
int (*reset_vlan_required)(struct smcd_dev *dev);
65-
int (*signal_event)(struct smcd_dev *dev, u64 rgid, u32 trigger_irq,
66-
u32 event_code, u64 info);
70+
int (*signal_event)(struct smcd_dev *dev, struct smcd_gid *rgid,
71+
u32 trigger_irq, u32 event_code, u64 info);
6772
int (*move_data)(struct smcd_dev *dev, u64 dmb_tok, unsigned int idx,
6873
bool sf, unsigned int offset, void *data,
6974
unsigned int size);
7075
int (*supports_v2)(void);
7176
u8* (*get_system_eid)(void);
72-
u64 (*get_local_gid)(struct smcd_dev *dev);
77+
void (*get_local_gid)(struct smcd_dev *dev, struct smcd_gid *gid);
7378
u16 (*get_chid)(struct smcd_dev *dev);
7479
struct device* (*get_dev)(struct smcd_dev *dev);
7580
};

net/smc/af_smc.c

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,8 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
10141014
{
10151015
int rc = SMC_CLC_DECL_NOSMCDDEV;
10161016
struct smcd_dev *smcd;
1017-
int i = 1;
1017+
int i = 1, entry = 1;
1018+
bool is_virtual;
10181019
u16 chid;
10191020

10201021
if (smcd_indicated(ini->smc_type_v1))
@@ -1026,14 +1027,23 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
10261027
chid = smc_ism_get_chid(smcd);
10271028
if (!smc_find_ism_v2_is_unique_chid(chid, ini, i))
10281029
continue;
1030+
is_virtual = __smc_ism_is_virtual(chid);
10291031
if (!smc_pnet_is_pnetid_set(smcd->pnetid) ||
10301032
smc_pnet_is_ndev_pnetid(sock_net(&smc->sk), smcd->pnetid)) {
1033+
if (is_virtual && entry == SMCD_CLC_MAX_V2_GID_ENTRIES)
1034+
/* It's the last GID-CHID entry left in CLC
1035+
* Proposal SMC-Dv2 extension, but a virtual
1036+
* ISM device will take two entries. So give
1037+
* up it and try the next potential ISM device.
1038+
*/
1039+
continue;
10311040
ini->ism_dev[i] = smcd;
10321041
ini->ism_chid[i] = chid;
10331042
ini->is_smcd = true;
10341043
rc = 0;
10351044
i++;
1036-
if (i > SMC_MAX_ISM_DEVS)
1045+
entry = is_virtual ? entry + 2 : entry + 1;
1046+
if (entry > SMCD_CLC_MAX_V2_GID_ENTRIES)
10371047
break;
10381048
}
10391049
}
@@ -1375,8 +1385,13 @@ static int smc_connect_ism(struct smc_sock *smc,
13751385
rc = smc_v2_determine_accepted_chid(aclc, ini);
13761386
if (rc)
13771387
return rc;
1388+
1389+
if (__smc_ism_is_virtual(ini->ism_chid[ini->ism_selected]))
1390+
ini->ism_peer_gid[ini->ism_selected].gid_ext =
1391+
ntohll(aclc->d1.gid_ext);
1392+
/* for non-virtual ISM devices, peer gid_ext remains 0. */
13781393
}
1379-
ini->ism_peer_gid[ini->ism_selected] = ntohll(aclc->d0.gid);
1394+
ini->ism_peer_gid[ini->ism_selected].gid = ntohll(aclc->d0.gid);
13801395

13811396
/* there is only one lgr role for SMC-D; use server lock */
13821397
mutex_lock(&smc_server_lgr_pending);
@@ -2061,7 +2076,8 @@ static bool smc_is_already_selected(struct smcd_dev *smcd,
20612076

20622077
/* check for ISM devices matching proposed ISM devices */
20632078
static void smc_check_ism_v2_match(struct smc_init_info *ini,
2064-
u16 proposed_chid, u64 proposed_gid,
2079+
u16 proposed_chid,
2080+
struct smcd_gid *proposed_gid,
20652081
unsigned int *matches)
20662082
{
20672083
struct smcd_dev *smcd;
@@ -2073,7 +2089,11 @@ static void smc_check_ism_v2_match(struct smc_init_info *ini,
20732089
continue;
20742090
if (smc_ism_get_chid(smcd) == proposed_chid &&
20752091
!smc_ism_cantalk(proposed_gid, ISM_RESERVED_VLANID, smcd)) {
2076-
ini->ism_peer_gid[*matches] = proposed_gid;
2092+
ini->ism_peer_gid[*matches].gid = proposed_gid->gid;
2093+
if (__smc_ism_is_virtual(proposed_chid))
2094+
ini->ism_peer_gid[*matches].gid_ext =
2095+
proposed_gid->gid_ext;
2096+
/* non-virtual ISM's peer gid_ext remains 0. */
20772097
ini->ism_dev[*matches] = smcd;
20782098
(*matches)++;
20792099
break;
@@ -2095,9 +2115,11 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
20952115
struct smc_clc_v2_extension *smc_v2_ext;
20962116
struct smc_clc_msg_smcd *pclc_smcd;
20972117
unsigned int matches = 0;
2118+
struct smcd_gid smcd_gid;
20982119
u8 smcd_version;
20992120
u8 *eid = NULL;
21002121
int i, rc;
2122+
u16 chid;
21012123

21022124
if (!(ini->smcd_version & SMC_V2) || !smcd_indicated(ini->smc_type_v2))
21032125
goto not_found;
@@ -2107,18 +2129,35 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
21072129
smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
21082130

21092131
mutex_lock(&smcd_dev_list.mutex);
2110-
if (pclc_smcd->ism.chid)
2132+
if (pclc_smcd->ism.chid) {
21112133
/* check for ISM device matching proposed native ISM device */
2134+
smcd_gid.gid = ntohll(pclc_smcd->ism.gid);
2135+
smcd_gid.gid_ext = 0;
21122136
smc_check_ism_v2_match(ini, ntohs(pclc_smcd->ism.chid),
2113-
ntohll(pclc_smcd->ism.gid), &matches);
2114-
for (i = 1; i <= smc_v2_ext->hdr.ism_gid_cnt; i++) {
2137+
&smcd_gid, &matches);
2138+
}
2139+
for (i = 0; i < smc_v2_ext->hdr.ism_gid_cnt; i++) {
21152140
/* check for ISM devices matching proposed non-native ISM
21162141
* devices
21172142
*/
2118-
smc_check_ism_v2_match(ini,
2119-
ntohs(smcd_v2_ext->gidchid[i - 1].chid),
2120-
ntohll(smcd_v2_ext->gidchid[i - 1].gid),
2121-
&matches);
2143+
smcd_gid.gid = ntohll(smcd_v2_ext->gidchid[i].gid);
2144+
smcd_gid.gid_ext = 0;
2145+
chid = ntohs(smcd_v2_ext->gidchid[i].chid);
2146+
if (__smc_ism_is_virtual(chid)) {
2147+
if ((i + 1) == smc_v2_ext->hdr.ism_gid_cnt ||
2148+
chid != ntohs(smcd_v2_ext->gidchid[i + 1].chid))
2149+
/* each virtual ISM device takes two GID-CHID
2150+
* entries and CHID of the second entry repeats
2151+
* that of the first entry.
2152+
*
2153+
* So check if the next GID-CHID entry exists
2154+
* and both two entries' CHIDs are the same.
2155+
*/
2156+
continue;
2157+
smcd_gid.gid_ext =
2158+
ntohll(smcd_v2_ext->gidchid[++i].gid);
2159+
}
2160+
smc_check_ism_v2_match(ini, chid, &smcd_gid, &matches);
21222161
}
21232162
mutex_unlock(&smcd_dev_list.mutex);
21242163

@@ -2167,7 +2206,8 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
21672206
if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1))
21682207
goto not_found;
21692208
ini->is_smcd = true; /* prepare ISM check */
2170-
ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
2209+
ini->ism_peer_gid[0].gid = ntohll(pclc_smcd->ism.gid);
2210+
ini->ism_peer_gid[0].gid_ext = 0;
21712211
rc = smc_find_ism_device(new_smc, ini);
21722212
if (rc)
21732213
goto not_found;

net/smc/smc.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929
#define SMCPROTO_SMC 0 /* SMC protocol, IPv4 */
3030
#define SMCPROTO_SMC6 1 /* SMC protocol, IPv6 */
3131

32-
#define SMC_MAX_ISM_DEVS 8 /* max # of proposed non-native ISM
33-
* devices
34-
*/
3532
#define SMC_AUTOCORKING_DEFAULT_SIZE 0x10000 /* 64K by default */
3633

3734
extern struct proto smc_proto;

net/smc/smc_clc.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -883,11 +883,13 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
883883
ETH_ALEN);
884884
}
885885
if (smcd_indicated(ini->smc_type_v1)) {
886+
struct smcd_gid smcd_gid;
887+
886888
/* add SMC-D specifics */
887889
if (ini->ism_dev[0]) {
888890
smcd = ini->ism_dev[0];
889-
pclc_smcd->ism.gid =
890-
htonll(smcd->ops->get_local_gid(smcd));
891+
smcd->ops->get_local_gid(smcd, &smcd_gid);
892+
pclc_smcd->ism.gid = htonll(smcd_gid.gid);
891893
pclc_smcd->ism.chid =
892894
htons(smc_ism_get_chid(ini->ism_dev[0]));
893895
}
@@ -920,10 +922,11 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
920922
read_unlock(&smc_clc_eid_table.lock);
921923
}
922924
if (smcd_indicated(ini->smc_type_v2)) {
925+
struct smcd_gid smcd_gid;
923926
u8 *eid = NULL;
927+
int entry = 0;
924928

925929
v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
926-
v2_ext->hdr.ism_gid_cnt = ini->ism_offered_cnt;
927930
v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
928931
offsetofend(struct smc_clnt_opts_area_hdr,
929932
smcd_v2_ext_offset) +
@@ -935,14 +938,26 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
935938
if (ini->ism_offered_cnt) {
936939
for (i = 1; i <= ini->ism_offered_cnt; i++) {
937940
smcd = ini->ism_dev[i];
938-
gidchids[i - 1].gid =
939-
htonll(smcd->ops->get_local_gid(smcd));
940-
gidchids[i - 1].chid =
941+
smcd->ops->get_local_gid(smcd, &smcd_gid);
942+
gidchids[entry].chid =
941943
htons(smc_ism_get_chid(ini->ism_dev[i]));
944+
gidchids[entry].gid = htonll(smcd_gid.gid);
945+
if (smc_ism_is_virtual(smcd)) {
946+
/* a virtual ISM device takes two
947+
* entries. CHID of the second entry
948+
* repeats that of the first entry.
949+
*/
950+
gidchids[entry + 1].chid =
951+
gidchids[entry].chid;
952+
gidchids[entry + 1].gid =
953+
htonll(smcd_gid.gid_ext);
954+
entry++;
955+
}
956+
entry++;
942957
}
943-
plen += ini->ism_offered_cnt *
944-
sizeof(struct smc_clc_smcd_gid_chid);
958+
plen += entry * sizeof(struct smc_clc_smcd_gid_chid);
945959
}
960+
v2_ext->hdr.ism_gid_cnt = entry;
946961
}
947962
if (smcr_indicated(ini->smc_type_v2)) {
948963
memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
@@ -978,7 +993,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
978993
vec[i++].iov_len = sizeof(*smcd_v2_ext);
979994
if (ini->ism_offered_cnt) {
980995
vec[i].iov_base = gidchids;
981-
vec[i++].iov_len = ini->ism_offered_cnt *
996+
vec[i++].iov_len = v2_ext->hdr.ism_gid_cnt *
982997
sizeof(struct smc_clc_smcd_gid_chid);
983998
}
984999
}
@@ -1009,23 +1024,29 @@ smcd_clc_prep_confirm_accept(struct smc_connection *conn,
10091024
struct smc_clc_msg_trail *trl)
10101025
{
10111026
struct smcd_dev *smcd = conn->lgr->smcd;
1027+
struct smcd_gid smcd_gid;
1028+
u16 chid;
10121029
int len;
10131030

10141031
/* SMC-D specific settings */
10151032
memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
10161033
sizeof(SMCD_EYECATCHER));
1034+
smcd->ops->get_local_gid(smcd, &smcd_gid);
10171035
clc->hdr.typev1 = SMC_TYPE_D;
1018-
clc->d0.gid = htonll(smcd->ops->get_local_gid(smcd));
1036+
clc->d0.gid = htonll(smcd_gid.gid);
10191037
clc->d0.token = htonll(conn->rmb_desc->token);
10201038
clc->d0.dmbe_size = conn->rmbe_size_short;
10211039
clc->d0.dmbe_idx = 0;
10221040
memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
10231041
if (version == SMC_V1) {
10241042
clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
10251043
} else {
1026-
clc->d1.chid = htons(smc_ism_get_chid(smcd));
1044+
chid = smc_ism_get_chid(smcd);
1045+
clc->d1.chid = htons(chid);
10271046
if (eid && eid[0])
10281047
memcpy(clc->d1.eid, eid, SMC_MAX_EID_LEN);
1048+
if (__smc_ism_is_virtual(chid))
1049+
clc->d1.gid_ext = htonll(smcd_gid.gid_ext);
10291050
len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
10301051
if (first_contact) {
10311052
*fce_len = smc_clc_fill_fce_v2x(fce_v2x, ini);

net/smc/smc_clc.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
172172

173173
#define SMC_CLC_MAX_V6_PREFIX 8
174174
#define SMC_CLC_MAX_UEID 8
175+
#define SMCD_CLC_MAX_V2_GID_ENTRIES 8 /* max # of CHID-GID entries in CLC
176+
* proposal SMC-Dv2 extension.
177+
* each ISM device takes one entry and
178+
* each virtual ISM takes two entries.
179+
*/
175180

176181
struct smc_clc_msg_proposal_area {
177182
struct smc_clc_msg_proposal pclc_base;
@@ -181,7 +186,8 @@ struct smc_clc_msg_proposal_area {
181186
struct smc_clc_v2_extension pclc_v2_ext;
182187
u8 user_eids[SMC_CLC_MAX_UEID][SMC_MAX_EID_LEN];
183188
struct smc_clc_smcd_v2_extension pclc_smcd_v2_ext;
184-
struct smc_clc_smcd_gid_chid pclc_gidchids[SMC_MAX_ISM_DEVS];
189+
struct smc_clc_smcd_gid_chid
190+
pclc_gidchids[SMCD_CLC_MAX_V2_GID_ENTRIES];
185191
struct smc_clc_msg_trail pclc_trl;
186192
};
187193

@@ -277,7 +283,7 @@ struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */
277283
struct { /* v2 only, but 12 bytes reserved in v1 */
278284
__be16 chid;
279285
u8 eid[SMC_MAX_EID_LEN];
280-
u8 reserved5[8];
286+
__be64 gid_ext;
281287
} __packed d1;
282288
};
283289
};

0 commit comments

Comments
 (0)