net/smc: Separate SMC-D and ISM APIs
authorStefan Raspl <raspl@linux.ibm.com>
Mon, 23 Jan 2023 18:17:50 +0000 (19:17 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 25 Jan 2023 09:46:48 +0000 (09:46 +0000)
We separate the code implementing the struct smcd_ops API in the ISM
device driver from the functions that may be used by other exploiters of
ISM devices.
Note: We start out small, and don't offer the whole breadth of the ISM
device for public use, as many functions are specific to or likely only
ever used in the context of SMC-D.
This is the third part of a bigger overhaul of the interfaces between SMC
and ISM.

Signed-off-by: Stefan Raspl <raspl@linux.ibm.com>
Signed-off-by: Jan Karcher <jaka@linux.ibm.com>
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/ism_drv.c
include/linux/ism.h
include/net/smc.h
net/smc/smc_clc.c
net/smc/smc_core.c
net/smc/smc_diag.c

index f35c6077db041df98bcf2ea5fcc37ff9049ab228..e6c810a96b242fbf065e93c279fe1f734785e39f 100644 (file)
@@ -273,10 +273,9 @@ out:
        return ret;
 }
 
-static int ism_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
+static int ism_query_rgid(struct ism_dev *ism, u64 rgid, u32 vid_valid,
                          u32 vid)
 {
-       struct ism_dev *ism = smcd->priv;
        union ism_query_rgid cmd;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -290,6 +289,11 @@ static int ism_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid,
        return ism_cmd(ism, &cmd);
 }
 
+static int smcd_query_rgid(struct smcd_dev *smcd, u64 rgid, u32 vid_valid, u32 vid)
+{
+       return ism_query_rgid(smcd->priv, rgid, vid_valid, vid);
+}
+
 static void ism_free_dmb(struct ism_dev *ism, struct ism_dmb *dmb)
 {
        clear_bit(dmb->sba_idx, ism->sba_bitmap);
@@ -326,9 +330,9 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct ism_dmb *dmb)
        return dmb->cpu_addr ? 0 : -ENOMEM;
 }
 
-static int ism_register_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
+int ism_register_dmb(struct ism_dev *ism, struct ism_dmb *dmb,
+                    struct ism_client *client)
 {
-       struct ism_dev *ism = smcd->priv;
        union ism_reg_dmb cmd;
        int ret;
 
@@ -353,18 +357,19 @@ static int ism_register_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
                goto out;
        }
        dmb->dmb_tok = cmd.response.dmb_tok;
+       ism->sba_client_arr[dmb->sba_idx - ISM_DMB_BIT_OFFSET] = client->id;
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ism_register_dmb);
 
 static int smcd_register_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
 {
-       return ism_register_dmb(smcd, (struct ism_dmb *)dmb);
+       return ism_register_dmb(smcd->priv, (struct ism_dmb *)dmb, NULL);
 }
 
-static int ism_unregister_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
+int ism_unregister_dmb(struct ism_dev *ism, struct ism_dmb *dmb)
 {
-       struct ism_dev *ism = smcd->priv;
        union ism_unreg_dmb cmd;
        int ret;
 
@@ -374,6 +379,8 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
 
        cmd.request.dmb_tok = dmb->dmb_tok;
 
+       ism->sba_client_arr[dmb->sba_idx - ISM_DMB_BIT_OFFSET] = NO_CLIENT;
+
        ret = ism_cmd(ism, &cmd);
        if (ret && ret != ISM_ERROR)
                goto out;
@@ -382,15 +389,15 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct ism_dmb *dmb)
 out:
        return ret;
 }
+EXPORT_SYMBOL_GPL(ism_unregister_dmb);
 
 static int smcd_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb)
 {
-       return ism_unregister_dmb(smcd, (struct ism_dmb *)dmb);
+       return ism_unregister_dmb(smcd->priv, (struct ism_dmb *)dmb);
 }
 
-static int ism_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
+static int ism_add_vlan_id(struct ism_dev *ism, u64 vlan_id)
 {
-       struct ism_dev *ism = smcd->priv;
        union ism_set_vlan_id cmd;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -402,9 +409,13 @@ static int ism_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
        return ism_cmd(ism, &cmd);
 }
 
-static int ism_del_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
+static int smcd_add_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
+{
+       return ism_add_vlan_id(smcd->priv, vlan_id);
+}
+
+static int ism_del_vlan_id(struct ism_dev *ism, u64 vlan_id)
 {
-       struct ism_dev *ism = smcd->priv;
        union ism_set_vlan_id cmd;
 
        memset(&cmd, 0, sizeof(cmd));
@@ -416,6 +427,11 @@ static int ism_del_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
        return ism_cmd(ism, &cmd);
 }
 
+static int smcd_del_vlan_id(struct smcd_dev *smcd, u64 vlan_id)
+{
+       return ism_del_vlan_id(smcd->priv, vlan_id);
+}
+
 static int ism_set_vlan_required(struct smcd_dev *smcd)
 {
        return ism_cmd_simple(smcd->priv, ISM_SET_VLAN);
@@ -426,8 +442,8 @@ static int ism_reset_vlan_required(struct smcd_dev *smcd)
        return ism_cmd_simple(smcd->priv, ISM_RESET_VLAN);
 }
 
-static int ism_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
-                         u32 event_code, u64 info)
+static int smcd_signal_ieq(struct smcd_dev *smcd, u64 rgid, u32 trigger_irq,
+                          u32 event_code, u64 info)
 {
        struct ism_dev *ism = smcd->priv;
        union ism_sig_ieq cmd;
@@ -450,8 +466,9 @@ static unsigned int max_bytes(unsigned int start, unsigned int len,
        return min(boundary - (start & (boundary - 1)), len);
 }
 
-static int ism_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
-                   bool sf, unsigned int offset, void *data, unsigned int size)
+static int smcd_move(struct smcd_dev *smcd, u64 dmb_tok, unsigned int idx,
+                    bool sf, unsigned int offset, void *data,
+                    unsigned int size)
 {
        struct ism_dev *ism = smcd->priv;
        unsigned int bytes;
@@ -495,14 +512,15 @@ static void ism_create_system_eid(void)
        memcpy(&SYSTEM_EID.type, tmp, 4);
 }
 
-static u8 *ism_get_system_eid(void)
+u8 *ism_get_seid(void)
 {
        return SYSTEM_EID.seid_string;
 }
+EXPORT_SYMBOL_GPL(ism_get_seid);
 
-static u16 ism_get_chid(struct smcd_dev *smcd)
+static u16 smcd_get_chid(struct smcd_dev *smcd)
 {
-       struct ism_dev *ism = (struct ism_dev *)smcd->priv;
+       struct ism_dev *ism = smcd->priv;
 
        if (!ism || !ism->pdev)
                return 0;
@@ -565,18 +583,26 @@ static irqreturn_t ism_handle_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static u64 smcd_get_local_gid(struct smcd_dev *smcd)
+{
+       struct ism_dev *ism = smcd->priv;
+
+       return ism->local_gid;
+}
+
 static const struct smcd_ops ism_ops = {
-       .query_remote_gid = ism_query_rgid,
+       .query_remote_gid = smcd_query_rgid,
        .register_dmb = smcd_register_dmb,
        .unregister_dmb = smcd_unregister_dmb,
-       .add_vlan_id = ism_add_vlan_id,
-       .del_vlan_id = ism_del_vlan_id,
+       .add_vlan_id = smcd_add_vlan_id,
+       .del_vlan_id = smcd_del_vlan_id,
        .set_vlan_required = ism_set_vlan_required,
        .reset_vlan_required = ism_reset_vlan_required,
-       .signal_event = ism_signal_ieq,
-       .move_data = ism_move,
-       .get_system_eid = ism_get_system_eid,
-       .get_chid = ism_get_chid,
+       .signal_event = smcd_signal_ieq,
+       .move_data = smcd_move,
+       .get_system_eid = ism_get_seid,
+       .get_local_gid = smcd_get_local_gid,
+       .get_chid = smcd_get_chid,
 };
 
 static void ism_dev_add_work_func(struct work_struct *work)
@@ -599,10 +625,15 @@ static int ism_dev_init(struct ism_dev *ism)
        if (ret <= 0)
                goto out;
 
+       ism->sba_client_arr = kzalloc(ISM_NR_DMBS, GFP_KERNEL);
+       if (!ism->sba_client_arr)
+               goto free_vectors;
+       memset(ism->sba_client_arr, NO_CLIENT, ISM_NR_DMBS);
+
        ret = request_irq(pci_irq_vector(pdev, 0), ism_handle_irq, 0,
                          pci_name(pdev), ism);
        if (ret)
-               goto free_vectors;
+               goto free_client_arr;
 
        ret = register_sba(ism);
        if (ret)
@@ -616,7 +647,7 @@ static int ism_dev_init(struct ism_dev *ism)
        if (ret)
                goto unreg_ieq;
 
-       if (!ism_add_vlan_id(ism->smcd, ISM_RESERVED_VLANID))
+       if (!ism_add_vlan_id(ism, ISM_RESERVED_VLANID))
                /* hardware is V2 capable */
                ism_create_system_eid();
 
@@ -651,6 +682,8 @@ unreg_sba:
        unregister_sba(ism);
 free_irq:
        free_irq(pci_irq_vector(pdev, 0), ism);
+free_client_arr:
+       kfree(ism->sba_client_arr);
 free_vectors:
        pci_free_irq_vectors(pdev);
 out:
@@ -746,10 +779,11 @@ static void ism_dev_exit(struct ism_dev *ism)
 
        if (SYSTEM_EID.serial_number[0] != '0' ||
            SYSTEM_EID.type[0] != '0')
-               ism_del_vlan_id(ism->smcd, ISM_RESERVED_VLANID);
+               ism_del_vlan_id(ism, ISM_RESERVED_VLANID);
        unregister_ieq(ism);
        unregister_sba(ism);
        free_irq(pci_irq_vector(pdev, 0), ism);
+       kfree(ism->sba_client_arr);
        pci_free_irq_vectors(pdev);
        list_del_init(&ism->list);
 }
index 55c8ad306928a4035b1567daa55c3c4b15a631ec..bdd29e08d4fe2c2f228d5eb4f9981dbf9f49d4dd 100644 (file)
@@ -87,4 +87,11 @@ static inline void ism_set_priv(struct ism_dev *dev, struct ism_client *client,
        dev->priv[client->id] = priv;
 }
 
+int  ism_register_dmb(struct ism_dev *dev, struct ism_dmb *dmb,
+                     struct ism_client *client);
+int  ism_unregister_dmb(struct ism_dev *dev, struct ism_dmb *dmb);
+int  ism_move(struct ism_dev *dev, u64 dmb_tok, unsigned int idx, bool sf,
+             unsigned int offset, void *data, unsigned int size);
+u8  *ism_get_seid(void);
+
 #endif /* _ISM_H */
index 151aa54d9ad2d539b54df4ca6451cc95b3d2e830..d5f8f18169d7135a9645d6c77a1b9da30b068499 100644 (file)
@@ -66,14 +66,15 @@ struct smcd_ops {
                         bool sf, unsigned int offset, void *data,
                         unsigned int size);
        u8* (*get_system_eid)(void);
+       u64 (*get_local_gid)(struct smcd_dev *dev);
        u16 (*get_chid)(struct smcd_dev *dev);
 };
 
 struct smcd_dev {
        const struct smcd_ops *ops;
        struct device dev;
+       struct ism_dev *ism;
        void *priv;
-       u64 local_gid;
        struct list_head list;
        spinlock_t lock;
        struct smc_connection **conn;
index dfb9797f7bc63981eaa3dba55fd3d18e89e80ab7..b9b8b07aa7023f899a4a8d627f2c809e7c14c0fe 100644 (file)
@@ -813,6 +813,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
        struct smc_clc_v2_extension *v2_ext;
        struct smc_clc_msg_smcd *pclc_smcd;
        struct smc_clc_msg_trail *trl;
+       struct smcd_dev *smcd;
        int len, i, plen, rc;
        int reason_code = 0;
        struct kvec vec[8];
@@ -868,7 +869,9 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
        if (smcd_indicated(ini->smc_type_v1)) {
                /* add SMC-D specifics */
                if (ini->ism_dev[0]) {
-                       pclc_smcd->ism.gid = htonll(ini->ism_dev[0]->local_gid);
+                       smcd = ini->ism_dev[0];
+                       pclc_smcd->ism.gid =
+                               htonll(smcd->ops->get_local_gid(smcd));
                        pclc_smcd->ism.chid =
                                htons(smc_ism_get_chid(ini->ism_dev[0]));
                }
@@ -914,8 +917,9 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
                plen += sizeof(*smcd_v2_ext);
                if (ini->ism_offered_cnt) {
                        for (i = 1; i <= ini->ism_offered_cnt; i++) {
+                               smcd = ini->ism_dev[i];
                                gidchids[i - 1].gid =
-                                       htonll(ini->ism_dev[i]->local_gid);
+                                       htonll(smcd->ops->get_local_gid(smcd));
                                gidchids[i - 1].chid =
                                        htons(smc_ism_get_chid(ini->ism_dev[i]));
                        }
@@ -1000,7 +1004,8 @@ static int smc_clc_send_confirm_accept(struct smc_sock *smc,
                memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
                       sizeof(SMCD_EYECATCHER));
                clc->hdr.typev1 = SMC_TYPE_D;
-               clc->d0.gid = conn->lgr->smcd->local_gid;
+               clc->d0.gid =
+                       conn->lgr->smcd->ops->get_local_gid(conn->lgr->smcd);
                clc->d0.token = conn->rmb_desc->token;
                clc->d0.dmbe_size = conn->rmbe_size_short;
                clc->d0.dmbe_idx = 0;
index e15ee084cc5abad1e68185dc50cfd688d4bf2c3f..ec04966e9bf9ebd5463320997804c2e5fe777e71 100644 (file)
@@ -500,6 +500,7 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
                                struct netlink_callback *cb)
 {
        char smc_pnet[SMC_MAX_PNETID_LEN + 1];
+       struct smcd_dev *smcd = lgr->smcd;
        struct nlattr *attrs;
        void *nlh;
 
@@ -515,8 +516,9 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
 
        if (nla_put_u32(skb, SMC_NLA_LGR_D_ID, *((u32 *)&lgr->id)))
                goto errattr;
-       if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_GID, lgr->smcd->local_gid,
-                             SMC_NLA_LGR_D_PAD))
+       if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_GID,
+                             smcd->ops->get_local_gid(smcd),
+                                 SMC_NLA_LGR_D_PAD))
                goto errattr;
        if (nla_put_u64_64bit(skb, SMC_NLA_LGR_D_PEER_GID, lgr->peer_gid,
                              SMC_NLA_LGR_D_PAD))
index 80ea7d954eceb830265b4f93e50e87857334f078..7ff2152971a5b8a57ab746bf8ed2cc006b9546e9 100644 (file)
@@ -167,12 +167,13 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
            !list_empty(&smc->conn.lgr->list)) {
                struct smc_connection *conn = &smc->conn;
                struct smcd_diag_dmbinfo dinfo;
+               struct smcd_dev *smcd = conn->lgr->smcd;
 
                memset(&dinfo, 0, sizeof(dinfo));
 
                dinfo.linkid = *((u32 *)conn->lgr->id);
                dinfo.peer_gid = conn->lgr->peer_gid;
-               dinfo.my_gid = conn->lgr->smcd->local_gid;
+               dinfo.my_gid = smcd->ops->get_local_gid(smcd);
                dinfo.token = conn->rmb_desc->token;
                dinfo.peer_token = conn->peer_token;