net/smc: De-tangle ism and smc device initialization
authorStefan Raspl <raspl@linux.ibm.com>
Mon, 23 Jan 2023 18:17:52 +0000 (19:17 +0100)
committerDavid S. Miller <davem@davemloft.net>
Wed, 25 Jan 2023 09:46:49 +0000 (09:46 +0000)
The struct device for ISM devices was part of struct smcd_dev. Move to
struct ism_dev, provide a new API call in struct smcd_ops, and convert
existing SMCD code accordingly.
Furthermore, remove struct smcd_dev from struct ism_dev.
This is the final 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/af_smc.c
net/smc/smc_core.c
net/smc/smc_ism.c
net/smc/smc_pnet.c

index 73c8f42..eb7e134 100644 (file)
@@ -646,6 +646,12 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        spin_lock_init(&ism->lock);
        dev_set_drvdata(&pdev->dev, ism);
        ism->pdev = pdev;
+       ism->dev.parent = &pdev->dev;
+       device_initialize(&ism->dev);
+       dev_set_name(&ism->dev, dev_name(&pdev->dev));
+       ret = device_add(&ism->dev);
+       if (ret)
+               goto err_dev;
 
        ret = pci_enable_device_mem(pdev);
        if (ret)
@@ -663,30 +669,23 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        dma_set_max_seg_size(&pdev->dev, SZ_1M);
        pci_set_master(pdev);
 
-       ism->smcd = smcd_alloc_dev(&pdev->dev, dev_name(&pdev->dev), &ism_ops,
-                                  ISM_NR_DMBS);
-       if (!ism->smcd) {
-               ret = -ENOMEM;
-               goto err_resource;
-       }
-
-       ism->smcd->priv = ism;
        ret = ism_dev_init(ism);
        if (ret)
-               goto err_free;
+               goto err_resource;
 
        return 0;
 
-err_free:
-       smcd_free_dev(ism->smcd);
 err_resource:
        pci_clear_master(pdev);
        pci_release_mem_regions(pdev);
 err_disable:
        pci_disable_device(pdev);
 err:
-       kfree(ism);
+       device_del(&ism->dev);
+err_dev:
        dev_set_drvdata(&pdev->dev, NULL);
+       kfree(ism);
+
        return ret;
 }
 
@@ -740,7 +739,6 @@ static void ism_remove(struct pci_dev *pdev)
        ism_dev_exit(ism);
        mutex_unlock(&ism_dev_list.mutex);
 
-       smcd_free_dev(ism->smcd);
        pci_clear_master(pdev);
        pci_release_mem_regions(pdev);
        pci_disable_device(pdev);
@@ -874,6 +872,7 @@ static const struct smcd_ops ism_ops = {
        .get_system_eid = ism_get_seid,
        .get_local_gid = smcd_get_local_gid,
        .get_chid = smcd_get_chid,
+       .get_dev = smcd_get_dev,
 };
 
 const struct smcd_ops *ism_get_smcd_ops(void)
index 104ce2f..ea2bcda 100644 (file)
@@ -30,7 +30,6 @@ struct ism_dev {
        spinlock_t lock; /* protects the ism device */
        struct list_head list;
        struct pci_dev *pdev;
-       struct smcd_dev *smcd;
 
        struct ism_sba *sba;
        dma_addr_t sba_dma_addr;
index 556b96c..597cb93 100644 (file)
@@ -70,11 +70,11 @@ struct smcd_ops {
        u8* (*get_system_eid)(void);
        u64 (*get_local_gid)(struct smcd_dev *dev);
        u16 (*get_chid)(struct smcd_dev *dev);
+       struct device* (*get_dev)(struct smcd_dev *dev);
 };
 
 struct smcd_dev {
        const struct smcd_ops *ops;
-       struct device dev;
        void *priv;
        struct list_head list;
        spinlock_t lock;
@@ -90,8 +90,4 @@ struct smcd_dev {
        u8 going_away : 1;
 };
 
-struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
-                               const struct smcd_ops *ops, int max_dmbs);
-void smcd_free_dev(struct smcd_dev *smcd);
-
 #endif /* _SMC_H */
index 5d03771..036532c 100644 (file)
@@ -3499,6 +3499,7 @@ static void __exit smc_exit(void)
        sock_unregister(PF_SMC);
        smc_core_exit();
        smc_ib_unregister_client();
+       smc_ism_exit();
        destroy_workqueue(smc_close_wq);
        destroy_workqueue(smc_tcp_ls_wq);
        destroy_workqueue(smc_hs_wq);
index ec04966..7642b16 100644 (file)
@@ -822,6 +822,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
 {
        struct smc_link_group *lgr;
        struct list_head *lgr_list;
+       struct smcd_dev *smcd;
        struct smc_link *lnk;
        spinlock_t *lgr_lock;
        u8 link_idx;
@@ -868,7 +869,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
        lgr->conns_all = RB_ROOT;
        if (ini->is_smcd) {
                /* SMC-D specific settings */
-               get_device(&ini->ism_dev[ini->ism_selected]->dev);
+               smcd = ini->ism_dev[ini->ism_selected];
+               get_device(smcd->ops->get_dev(smcd));
                lgr->peer_gid = ini->ism_peer_gid[ini->ism_selected];
                lgr->smcd = ini->ism_dev[ini->ism_selected];
                lgr_list = &ini->ism_dev[ini->ism_selected]->lgr_list;
@@ -1387,7 +1389,7 @@ static void smc_lgr_free(struct smc_link_group *lgr)
        destroy_workqueue(lgr->tx_wq);
        if (lgr->is_smcd) {
                smc_ism_put_vlan(lgr->smcd, lgr->vlan_id);
-               put_device(&lgr->smcd->dev);
+               put_device(lgr->smcd->ops->get_dev(lgr->smcd));
        }
        smc_lgr_put(lgr); /* theoretically last lgr_put */
 }
index 6196b30..3b0b771 100644 (file)
@@ -231,9 +231,11 @@ static int smc_nl_handle_smcd_dev(struct smcd_dev *smcd,
        struct smc_pci_dev smc_pci_dev;
        struct nlattr *port_attrs;
        struct nlattr *attrs;
+       struct ism_dev *ism;
        int use_cnt = 0;
        void *nlh;
 
+       ism = smcd->priv;
        nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &smc_gen_nl_family, NLM_F_MULTI,
                          SMC_NETLINK_GET_DEV_SMCD);
@@ -248,7 +250,7 @@ static int smc_nl_handle_smcd_dev(struct smcd_dev *smcd,
        if (nla_put_u8(skb, SMC_NLA_DEV_IS_CRIT, use_cnt > 0))
                goto errattr;
        memset(&smc_pci_dev, 0, sizeof(smc_pci_dev));
-       smc_set_pci_values(to_pci_dev(smcd->dev.parent), &smc_pci_dev);
+       smc_set_pci_values(to_pci_dev(ism->dev.parent), &smc_pci_dev);
        if (nla_put_u32(skb, SMC_NLA_DEV_PCI_FID, smc_pci_dev.pci_fid))
                goto errattr;
        if (nla_put_u16(skb, SMC_NLA_DEV_PCI_CHID, smc_pci_dev.pci_pchid))
@@ -377,41 +379,24 @@ static void smc_ism_event_work(struct work_struct *work)
        kfree(wrk);
 }
 
-static void smcd_release(struct device *dev)
-{
-       struct smcd_dev *smcd = container_of(dev, struct smcd_dev, dev);
-
-       kfree(smcd->conn);
-       kfree(smcd);
-}
-
-struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
-                               const struct smcd_ops *ops, int max_dmbs)
+static struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
+                                      const struct smcd_ops *ops, int max_dmbs)
 {
        struct smcd_dev *smcd;
 
-       smcd = kzalloc(sizeof(*smcd), GFP_KERNEL);
+       smcd = devm_kzalloc(parent, sizeof(*smcd), GFP_KERNEL);
        if (!smcd)
                return NULL;
-       smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *),
-                            GFP_KERNEL);
-       if (!smcd->conn) {
-               kfree(smcd);
+       smcd->conn = devm_kcalloc(parent, max_dmbs,
+                                 sizeof(struct smc_connection *), GFP_KERNEL);
+       if (!smcd->conn)
                return NULL;
-       }
 
        smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)",
                                                 WQ_MEM_RECLAIM, name);
-       if (!smcd->event_wq) {
-               kfree(smcd->conn);
-               kfree(smcd);
+       if (!smcd->event_wq)
                return NULL;
-       }
 
-       smcd->dev.parent = parent;
-       smcd->dev.release = smcd_release;
-       device_initialize(&smcd->dev);
-       dev_set_name(&smcd->dev, name);
        smcd->ops = ops;
 
        spin_lock_init(&smcd->lock);
@@ -421,13 +406,6 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
        init_waitqueue_head(&smcd->lgrs_deleted);
        return smcd;
 }
-EXPORT_SYMBOL_GPL(smcd_alloc_dev);
-
-void smcd_free_dev(struct smcd_dev *smcd)
-{
-       put_device(&smcd->dev);
-}
-EXPORT_SYMBOL_GPL(smcd_free_dev);
 
 static void smcd_register_dev(struct ism_dev *ism)
 {
@@ -465,16 +443,9 @@ static void smcd_register_dev(struct ism_dev *ism)
        mutex_unlock(&smcd_dev_list.mutex);
 
        pr_warn_ratelimited("smc: adding smcd device %s with pnetid %.16s%s\n",
-                           dev_name(&smcd->dev), smcd->pnetid,
+                           dev_name(&ism->dev), smcd->pnetid,
                            smcd->pnetid_by_user ? " (user defined)" : "");
 
-       if (device_add(&smcd->dev)) {
-               mutex_lock(&smcd_dev_list.mutex);
-               list_del(&smcd->list);
-               mutex_unlock(&smcd_dev_list.mutex);
-               smcd_free_dev(smcd);
-       }
-
        return;
 }
 
@@ -483,15 +454,13 @@ static void smcd_unregister_dev(struct ism_dev *ism)
        struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client);
 
        pr_warn_ratelimited("smc: removing smcd device %s\n",
-                           dev_name(&smcd->dev));
+                           dev_name(&ism->dev));
        smcd->going_away = 1;
        smc_smcd_terminate_all(smcd);
        mutex_lock(&smcd_dev_list.mutex);
        list_del_init(&smcd->list);
        mutex_unlock(&smcd_dev_list.mutex);
        destroy_workqueue(smcd->event_wq);
-
-       device_del(&smcd->dev);
 }
 
 /* SMCD Device event handler. Called from ISM device interrupt handler.
index 25fb2fd..1177540 100644 (file)
@@ -103,7 +103,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
        struct smc_pnetentry *pnetelem, *tmp_pe;
        struct smc_pnettable *pnettable;
        struct smc_ib_device *ibdev;
-       struct smcd_dev *smcd_dev;
+       struct smcd_dev *smcd;
        struct smc_net *sn;
        int rc = -ENOENT;
        int ibport;
@@ -162,16 +162,17 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
        mutex_unlock(&smc_ib_devices.mutex);
        /* remove smcd devices */
        mutex_lock(&smcd_dev_list.mutex);
-       list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
-               if (smcd_dev->pnetid_by_user &&
+       list_for_each_entry(smcd, &smcd_dev_list.list, list) {
+               if (smcd->pnetid_by_user &&
                    (!pnet_name ||
-                    smc_pnet_match(pnet_name, smcd_dev->pnetid))) {
+                    smc_pnet_match(pnet_name, smcd->pnetid))) {
                        pr_warn_ratelimited("smc: smcd device %s "
                                            "erased user defined pnetid "
-                                           "%.16s\n", dev_name(&smcd_dev->dev),
-                                           smcd_dev->pnetid);
-                       memset(smcd_dev->pnetid, 0, SMC_MAX_PNETID_LEN);
-                       smcd_dev->pnetid_by_user = false;
+                                           "%.16s\n",
+                                           dev_name(smcd->ops->get_dev(smcd)),
+                                           smcd->pnetid);
+                       memset(smcd->pnetid, 0, SMC_MAX_PNETID_LEN);
+                       smcd->pnetid_by_user = false;
                        rc = 0;
                }
        }
@@ -331,8 +332,8 @@ static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)
 
        mutex_lock(&smcd_dev_list.mutex);
        list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
-               if (!strncmp(dev_name(&smcd_dev->dev), smcd_name,
-                            IB_DEVICE_NAME_MAX - 1))
+               if (!strncmp(dev_name(smcd_dev->ops->get_dev(smcd_dev)),
+                            smcd_name, IB_DEVICE_NAME_MAX - 1))
                        goto out;
        }
        smcd_dev = NULL;
@@ -411,7 +412,8 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
        struct smc_ib_device *ib_dev;
        bool smcddev_applied = true;
        bool ibdev_applied = true;
-       struct smcd_dev *smcd_dev;
+       struct smcd_dev *smcd;
+       struct device *dev;
        bool new_ibdev;
 
        /* try to apply the pnetid to active devices */
@@ -425,14 +427,16 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
                                            ib_port,
                                            ib_dev->pnetid[ib_port - 1]);
        }
-       smcd_dev = smc_pnet_find_smcd(ib_name);
-       if (smcd_dev) {
-               smcddev_applied = smc_pnet_apply_smcd(smcd_dev, pnet_name);
-               if (smcddev_applied)
+       smcd = smc_pnet_find_smcd(ib_name);
+       if (smcd) {
+               smcddev_applied = smc_pnet_apply_smcd(smcd, pnet_name);
+               if (smcddev_applied) {
+                       dev = smcd->ops->get_dev(smcd);
                        pr_warn_ratelimited("smc: smcd device %s "
                                            "applied user defined pnetid "
-                                           "%.16s\n", dev_name(&smcd_dev->dev),
-                                           smcd_dev->pnetid);
+                                           "%.16s\n", dev_name(dev),
+                                           smcd->pnetid);
+               }
        }
        /* Apply fails when a device has a hardware-defined pnetid set, do not
         * add a pnet table entry in that case.
@@ -1181,7 +1185,7 @@ int smc_pnetid_by_table_ib(struct smc_ib_device *smcibdev, u8 ib_port)
  */
 int smc_pnetid_by_table_smcd(struct smcd_dev *smcddev)
 {
-       const char *ib_name = dev_name(&smcddev->dev);
+       const char *ib_name = dev_name(smcddev->ops->get_dev(smcddev));
        struct smc_pnettable *pnettable;
        struct smc_pnetentry *tmp_pe;
        struct smc_net *sn;