net/smc: support SMCv2.x supplemental features negotiation
authorWen Gu <guwen@linux.alibaba.com>
Tue, 19 Dec 2023 14:26:10 +0000 (22:26 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 26 Dec 2023 20:24:33 +0000 (20:24 +0000)
This patch adds SMCv2.x supplemental features negotiation. Supported
SMCv2.x supplemental features are represented by feature_mask in FCE
field. The negotiation process is as follows.

 Server                                        Client
            Proposal(features(c-mask bits))
      <-----------------------------------------
            Accept(features(s-mask bits))
      ----------------------------------------->
           Confirm(features(s&c-mask bits))
      <-----------------------------------------

Signed-off-by: Wen Gu <guwen@linux.alibaba.com>
Reviewed-and-tested-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/smc/smc.h
net/smc/smc_clc.c
net/smc/smc_clc.h
net/smc/smc_core.h

index cd51261b7d9e2839f930438c3c5b77a9d1279aa9..95f56c712b0a1a62b77d4e752829677922db84dc 100644 (file)
@@ -58,6 +58,10 @@ enum smc_state {             /* possible states of an SMC socket */
        SMC_PROCESSABORT        = 27,
 };
 
+#define SMC_FEATURE_MASK       0       /* bitmask of
+                                        * supported supplemental features
+                                        */
+
 struct smc_link_group;
 
 struct smc_wr_rx_hdr { /* common prefix part of LLC and CDC to demultiplex */
index 64733335b6ca66f5002bcfe3a4961c9bc9c2e118..900d307c17a975e7d2bfb92bddfcb8e47d88207f 100644 (file)
@@ -438,6 +438,7 @@ static int smc_clc_fill_fce_v2x(struct smc_clc_first_contact_ext_v2x *fce_v2x,
                        fce_v2x->max_conns = ini->max_conns;
                        fce_v2x->max_links = ini->max_links;
                }
+               fce_v2x->feature_mask = htons(ini->feature_mask);
        }
 
 out:
@@ -907,6 +908,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
                pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
                plen += sizeof(*v2_ext);
 
+               v2_ext->feature_mask = htons(SMC_FEATURE_MASK);
                read_lock(&smc_clc_eid_table.lock);
                v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
                plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
@@ -1208,6 +1210,7 @@ int smc_clc_srv_v2x_features_validate(struct smc_sock *smc,
 
        ini->max_conns = SMC_CONN_PER_LGR_MAX;
        ini->max_links = SMC_LINKS_ADD_LNK_MAX;
+       ini->feature_mask = SMC_FEATURE_MASK;
 
        if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) ||
            ini->release_nr < SMC_RELEASE_1)
@@ -1251,6 +1254,8 @@ int smc_clc_clnt_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
                        return SMC_CLC_DECL_MAXLINKERR;
                ini->max_links = fce_v2x->max_links;
        }
+       /* common supplemental features of server and client */
+       ini->feature_mask = ntohs(fce_v2x->feature_mask) & SMC_FEATURE_MASK;
 
        return 0;
 }
@@ -1279,6 +1284,8 @@ int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
                if (fce_v2x->max_links != ini->max_links)
                        return SMC_CLC_DECL_MAXLINKERR;
        }
+       /* common supplemental features returned by client */
+       ini->feature_mask = ntohs(fce_v2x->feature_mask);
 
        return 0;
 }
index 03f9ccea8c5e73760ea6082c68176ce69dfe70de..c187d5f09d0241ed249bf5e866bc5d93bd920d60 100644 (file)
@@ -138,7 +138,8 @@ struct smc_clc_v2_extension {
        u8 roce[16];            /* RoCEv2 GID */
        u8 max_conns;
        u8 max_links;
-       u8 reserved[14];
+       __be16 feature_mask;
+       u8 reserved[12];
        u8 user_eids[][SMC_MAX_EID_LEN];
 };
 
@@ -240,9 +241,14 @@ struct smc_clc_first_contact_ext {
 
 struct smc_clc_first_contact_ext_v2x {
        struct smc_clc_first_contact_ext fce_v2_base;
-       u8 max_conns; /* for SMC-R only */
-       u8 max_links; /* for SMC-R only */
-       u8 reserved3[2];
+       union {
+               struct {
+                       u8 max_conns; /* for SMC-R only */
+                       u8 max_links; /* for SMC-R only */
+               };
+               u8 reserved3[2];        /* for SMC-D only */
+       };
+       __be16 feature_mask;
        __be32 vendor_exp_options;
        u8 reserved4[8];
 } __packed;            /* format defined in
index 120027d404692bd464092ba4c3832997e6444c14..9f656780d46c5a2aa1c6cbbadebbbc35353640e9 100644 (file)
@@ -401,6 +401,7 @@ struct smc_init_info {
        u8                      max_links;
        u8                      first_contact_peer;
        u8                      first_contact_local;
+       u16                     feature_mask;
        unsigned short          vlan_id;
        u32                     rc;
        u8                      negotiated_eid[SMC_MAX_EID_LEN];