Skip to content

Commit b40584d

Browse files
Wen Gudavem330
authored andcommitted
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 <[email protected]> Reviewed-by: Alexandra Winter <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8dd512d commit b40584d

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
@@ -743,10 +743,10 @@ static int ism_query_rgid(struct ism_dev *ism, u64 rgid, u32 vid_valid,
743743
return ism_cmd(ism, &cmd);
744744
}
745745

746-
static int smcd_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
747-
u32 vid)
746+
static int smcd_query_rgid(struct smcd_dev *smcd, struct smcd_gid *rgid,
747+
u32 vid_valid, u32 vid)
748748
{
749-
return ism_query_rgid(smcd->priv, rgid, vid_valid, vid);
749+
return ism_query_rgid(smcd->priv, rgid->gid, vid_valid, vid);
750750
}
751751

752752
static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb,
@@ -797,10 +797,11 @@ static int ism_signal_ieq(struct ism_dev *ism, u64 rgid, u32 trigger_irq,
797797
return ism_cmd(ism, &cmd);
798798
}
799799

800-
static int smcd_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
801-
u32 event_code, u64 info)
800+
static int smcd_signal_ieq(struct smcd_dev *smcd, struct smcd_gid *rgid,
801+
u32 trigger_irq, u32 event_code, u64 info)
802802
{
803-
return ism_signal_ieq(smcd->priv, rgid, trigger_irq, event_code, info);
803+
return ism_signal_ieq(smcd->priv, rgid->gid,
804+
trigger_irq, event_code, info);
804805
}
805806

806807
static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
@@ -821,9 +822,11 @@ static u64 ism_get_local_gid(struct ism_dev *ism)
821822
return ism->local_gid;
822823
}
823824

824-
static u64 smcd_get_local_gid(struct smcd_dev *smcd)
825+
static void smcd_get_local_gid(struct smcd_dev *smcd,
826+
struct smcd_gid *smcd_gid)
825827
{
826-
return ism_get_local_gid(smcd->priv);
828+
smcd_gid->gid = ism_get_local_gid(smcd->priv);
829+
smcd_gid->gid_ext = 0;
827830
}
828831

829832
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
@@ -1044,7 +1044,8 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
10441044
{
10451045
int rc = SMC_CLC_DECL_NOSMCDDEV;
10461046
struct smcd_dev *smcd;
1047-
int i = 1;
1047+
int i = 1, entry = 1;
1048+
bool is_virtual;
10481049
u16 chid;
10491050

10501051
if (smcd_indicated(ini->smc_type_v1))
@@ -1056,14 +1057,23 @@ static int smc_find_ism_v2_device_clnt(struct smc_sock *smc,
10561057
chid = smc_ism_get_chid(smcd);
10571058
if (!smc_find_ism_v2_is_unique_chid(chid, ini, i))
10581059
continue;
1060+
is_virtual = __smc_ism_is_virtual(chid);
10591061
if (!smc_pnet_is_pnetid_set(smcd->pnetid) ||
10601062
smc_pnet_is_ndev_pnetid(sock_net(&smc->sk), smcd->pnetid)) {
1063+
if (is_virtual && entry == SMCD_CLC_MAX_V2_GID_ENTRIES)
1064+
/* It's the last GID-CHID entry left in CLC
1065+
* Proposal SMC-Dv2 extension, but a virtual
1066+
* ISM device will take two entries. So give
1067+
* up it and try the next potential ISM device.
1068+
*/
1069+
continue;
10611070
ini->ism_dev[i] = smcd;
10621071
ini->ism_chid[i] = chid;
10631072
ini->is_smcd = true;
10641073
rc = 0;
10651074
i++;
1066-
if (i > SMC_MAX_ISM_DEVS)
1075+
entry = is_virtual ? entry + 2 : entry + 1;
1076+
if (entry > SMCD_CLC_MAX_V2_GID_ENTRIES)
10671077
break;
10681078
}
10691079
}
@@ -1402,8 +1412,13 @@ static int smc_connect_ism(struct smc_sock *smc,
14021412
rc = smc_v2_determine_accepted_chid(aclc, ini);
14031413
if (rc)
14041414
return rc;
1415+
1416+
if (__smc_ism_is_virtual(ini->ism_chid[ini->ism_selected]))
1417+
ini->ism_peer_gid[ini->ism_selected].gid_ext =
1418+
ntohll(aclc->d1.gid_ext);
1419+
/* for non-virtual ISM devices, peer gid_ext remains 0. */
14051420
}
1406-
ini->ism_peer_gid[ini->ism_selected] = ntohll(aclc->d0.gid);
1421+
ini->ism_peer_gid[ini->ism_selected].gid = ntohll(aclc->d0.gid);
14071422

14081423
/* there is only one lgr role for SMC-D; use server lock */
14091424
mutex_lock(&smc_server_lgr_pending);
@@ -2088,7 +2103,8 @@ static bool smc_is_already_selected(struct smcd_dev *smcd,
20882103

20892104
/* check for ISM devices matching proposed ISM devices */
20902105
static void smc_check_ism_v2_match(struct smc_init_info *ini,
2091-
u16 proposed_chid, u64 proposed_gid,
2106+
u16 proposed_chid,
2107+
struct smcd_gid *proposed_gid,
20922108
unsigned int *matches)
20932109
{
20942110
struct smcd_dev *smcd;
@@ -2100,7 +2116,11 @@ static void smc_check_ism_v2_match(struct smc_init_info *ini,
21002116
continue;
21012117
if (smc_ism_get_chid(smcd) == proposed_chid &&
21022118
!smc_ism_cantalk(proposed_gid, ISM_RESERVED_VLANID, smcd)) {
2103-
ini->ism_peer_gid[*matches] = proposed_gid;
2119+
ini->ism_peer_gid[*matches].gid = proposed_gid->gid;
2120+
if (__smc_ism_is_virtual(proposed_chid))
2121+
ini->ism_peer_gid[*matches].gid_ext =
2122+
proposed_gid->gid_ext;
2123+
/* non-virtual ISM's peer gid_ext remains 0. */
21042124
ini->ism_dev[*matches] = smcd;
21052125
(*matches)++;
21062126
break;
@@ -2122,9 +2142,11 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
21222142
struct smc_clc_v2_extension *smc_v2_ext;
21232143
struct smc_clc_msg_smcd *pclc_smcd;
21242144
unsigned int matches = 0;
2145+
struct smcd_gid smcd_gid;
21252146
u8 smcd_version;
21262147
u8 *eid = NULL;
21272148
int i, rc;
2149+
u16 chid;
21282150

21292151
if (!(ini->smcd_version & SMC_V2) || !smcd_indicated(ini->smc_type_v2))
21302152
goto not_found;
@@ -2134,18 +2156,35 @@ static void smc_find_ism_v2_device_serv(struct smc_sock *new_smc,
21342156
smcd_v2_ext = smc_get_clc_smcd_v2_ext(smc_v2_ext);
21352157

21362158
mutex_lock(&smcd_dev_list.mutex);
2137-
if (pclc_smcd->ism.chid)
2159+
if (pclc_smcd->ism.chid) {
21382160
/* check for ISM device matching proposed native ISM device */
2161+
smcd_gid.gid = ntohll(pclc_smcd->ism.gid);
2162+
smcd_gid.gid_ext = 0;
21392163
smc_check_ism_v2_match(ini, ntohs(pclc_smcd->ism.chid),
2140-
ntohll(pclc_smcd->ism.gid), &matches);
2141-
for (i = 1; i <= smc_v2_ext->hdr.ism_gid_cnt; i++) {
2164+
&smcd_gid, &matches);
2165+
}
2166+
for (i = 0; i < smc_v2_ext->hdr.ism_gid_cnt; i++) {
21422167
/* check for ISM devices matching proposed non-native ISM
21432168
* devices
21442169
*/
2145-
smc_check_ism_v2_match(ini,
2146-
ntohs(smcd_v2_ext->gidchid[i - 1].chid),
2147-
ntohll(smcd_v2_ext->gidchid[i - 1].gid),
2148-
&matches);
2170+
smcd_gid.gid = ntohll(smcd_v2_ext->gidchid[i].gid);
2171+
smcd_gid.gid_ext = 0;
2172+
chid = ntohs(smcd_v2_ext->gidchid[i].chid);
2173+
if (__smc_ism_is_virtual(chid)) {
2174+
if ((i + 1) == smc_v2_ext->hdr.ism_gid_cnt ||
2175+
chid != ntohs(smcd_v2_ext->gidchid[i + 1].chid))
2176+
/* each virtual ISM device takes two GID-CHID
2177+
* entries and CHID of the second entry repeats
2178+
* that of the first entry.
2179+
*
2180+
* So check if the next GID-CHID entry exists
2181+
* and both two entries' CHIDs are the same.
2182+
*/
2183+
continue;
2184+
smcd_gid.gid_ext =
2185+
ntohll(smcd_v2_ext->gidchid[++i].gid);
2186+
}
2187+
smc_check_ism_v2_match(ini, chid, &smcd_gid, &matches);
21492188
}
21502189
mutex_unlock(&smcd_dev_list.mutex);
21512190

@@ -2194,7 +2233,8 @@ static void smc_find_ism_v1_device_serv(struct smc_sock *new_smc,
21942233
if (!(ini->smcd_version & SMC_V1) || !smcd_indicated(ini->smc_type_v1))
21952234
goto not_found;
21962235
ini->is_smcd = true; /* prepare ISM check */
2197-
ini->ism_peer_gid[0] = ntohll(pclc_smcd->ism.gid);
2236+
ini->ism_peer_gid[0].gid = ntohll(pclc_smcd->ism.gid);
2237+
ini->ism_peer_gid[0].gid_ext = 0;
21982238
rc = smc_find_ism_device(new_smc, ini);
21992239
if (rc)
22002240
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_comp;
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)