Commit 8c81ba20 authored by Stefan Raspl's avatar Stefan Raspl Committed by David S. Miller

net/smc: De-tangle ism and smc device initialization

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: default avatarStefan Raspl <raspl@linux.ibm.com>
Signed-off-by: default avatarJan Karcher <jaka@linux.ibm.com>
Signed-off-by: default avatarWenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 820f2100
...@@ -646,6 +646,12 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -646,6 +646,12 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&ism->lock); spin_lock_init(&ism->lock);
dev_set_drvdata(&pdev->dev, ism); dev_set_drvdata(&pdev->dev, ism);
ism->pdev = pdev; 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); ret = pci_enable_device_mem(pdev);
if (ret) if (ret)
...@@ -663,30 +669,23 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -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); dma_set_max_seg_size(&pdev->dev, SZ_1M);
pci_set_master(pdev); 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); ret = ism_dev_init(ism);
if (ret) if (ret)
goto err_free; goto err_resource;
return 0; return 0;
err_free:
smcd_free_dev(ism->smcd);
err_resource: err_resource:
pci_clear_master(pdev); pci_clear_master(pdev);
pci_release_mem_regions(pdev); pci_release_mem_regions(pdev);
err_disable: err_disable:
pci_disable_device(pdev); pci_disable_device(pdev);
err: err:
kfree(ism); device_del(&ism->dev);
err_dev:
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
kfree(ism);
return ret; return ret;
} }
...@@ -740,7 +739,6 @@ static void ism_remove(struct pci_dev *pdev) ...@@ -740,7 +739,6 @@ static void ism_remove(struct pci_dev *pdev)
ism_dev_exit(ism); ism_dev_exit(ism);
mutex_unlock(&ism_dev_list.mutex); mutex_unlock(&ism_dev_list.mutex);
smcd_free_dev(ism->smcd);
pci_clear_master(pdev); pci_clear_master(pdev);
pci_release_mem_regions(pdev); pci_release_mem_regions(pdev);
pci_disable_device(pdev); pci_disable_device(pdev);
...@@ -874,6 +872,7 @@ static const struct smcd_ops ism_ops = { ...@@ -874,6 +872,7 @@ static const struct smcd_ops ism_ops = {
.get_system_eid = ism_get_seid, .get_system_eid = ism_get_seid,
.get_local_gid = smcd_get_local_gid, .get_local_gid = smcd_get_local_gid,
.get_chid = smcd_get_chid, .get_chid = smcd_get_chid,
.get_dev = smcd_get_dev,
}; };
const struct smcd_ops *ism_get_smcd_ops(void) const struct smcd_ops *ism_get_smcd_ops(void)
......
...@@ -30,7 +30,6 @@ struct ism_dev { ...@@ -30,7 +30,6 @@ struct ism_dev {
spinlock_t lock; /* protects the ism device */ spinlock_t lock; /* protects the ism device */
struct list_head list; struct list_head list;
struct pci_dev *pdev; struct pci_dev *pdev;
struct smcd_dev *smcd;
struct ism_sba *sba; struct ism_sba *sba;
dma_addr_t sba_dma_addr; dma_addr_t sba_dma_addr;
......
...@@ -70,11 +70,11 @@ struct smcd_ops { ...@@ -70,11 +70,11 @@ struct smcd_ops {
u8* (*get_system_eid)(void); u8* (*get_system_eid)(void);
u64 (*get_local_gid)(struct smcd_dev *dev); u64 (*get_local_gid)(struct smcd_dev *dev);
u16 (*get_chid)(struct smcd_dev *dev); u16 (*get_chid)(struct smcd_dev *dev);
struct device* (*get_dev)(struct smcd_dev *dev);
}; };
struct smcd_dev { struct smcd_dev {
const struct smcd_ops *ops; const struct smcd_ops *ops;
struct device dev;
void *priv; void *priv;
struct list_head list; struct list_head list;
spinlock_t lock; spinlock_t lock;
...@@ -90,8 +90,4 @@ struct smcd_dev { ...@@ -90,8 +90,4 @@ struct smcd_dev {
u8 going_away : 1; 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 */ #endif /* _SMC_H */
...@@ -3499,6 +3499,7 @@ static void __exit smc_exit(void) ...@@ -3499,6 +3499,7 @@ static void __exit smc_exit(void)
sock_unregister(PF_SMC); sock_unregister(PF_SMC);
smc_core_exit(); smc_core_exit();
smc_ib_unregister_client(); smc_ib_unregister_client();
smc_ism_exit();
destroy_workqueue(smc_close_wq); destroy_workqueue(smc_close_wq);
destroy_workqueue(smc_tcp_ls_wq); destroy_workqueue(smc_tcp_ls_wq);
destroy_workqueue(smc_hs_wq); destroy_workqueue(smc_hs_wq);
......
...@@ -822,6 +822,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) ...@@ -822,6 +822,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
{ {
struct smc_link_group *lgr; struct smc_link_group *lgr;
struct list_head *lgr_list; struct list_head *lgr_list;
struct smcd_dev *smcd;
struct smc_link *lnk; struct smc_link *lnk;
spinlock_t *lgr_lock; spinlock_t *lgr_lock;
u8 link_idx; u8 link_idx;
...@@ -868,7 +869,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) ...@@ -868,7 +869,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
lgr->conns_all = RB_ROOT; lgr->conns_all = RB_ROOT;
if (ini->is_smcd) { if (ini->is_smcd) {
/* SMC-D specific settings */ /* 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->peer_gid = ini->ism_peer_gid[ini->ism_selected];
lgr->smcd = ini->ism_dev[ini->ism_selected]; lgr->smcd = ini->ism_dev[ini->ism_selected];
lgr_list = &ini->ism_dev[ini->ism_selected]->lgr_list; lgr_list = &ini->ism_dev[ini->ism_selected]->lgr_list;
...@@ -1387,7 +1389,7 @@ static void smc_lgr_free(struct smc_link_group *lgr) ...@@ -1387,7 +1389,7 @@ static void smc_lgr_free(struct smc_link_group *lgr)
destroy_workqueue(lgr->tx_wq); destroy_workqueue(lgr->tx_wq);
if (lgr->is_smcd) { if (lgr->is_smcd) {
smc_ism_put_vlan(lgr->smcd, lgr->vlan_id); 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 */ smc_lgr_put(lgr); /* theoretically last lgr_put */
} }
......
...@@ -231,9 +231,11 @@ static int smc_nl_handle_smcd_dev(struct smcd_dev *smcd, ...@@ -231,9 +231,11 @@ static int smc_nl_handle_smcd_dev(struct smcd_dev *smcd,
struct smc_pci_dev smc_pci_dev; struct smc_pci_dev smc_pci_dev;
struct nlattr *port_attrs; struct nlattr *port_attrs;
struct nlattr *attrs; struct nlattr *attrs;
struct ism_dev *ism;
int use_cnt = 0; int use_cnt = 0;
void *nlh; void *nlh;
ism = smcd->priv;
nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
&smc_gen_nl_family, NLM_F_MULTI, &smc_gen_nl_family, NLM_F_MULTI,
SMC_NETLINK_GET_DEV_SMCD); SMC_NETLINK_GET_DEV_SMCD);
...@@ -248,7 +250,7 @@ static int smc_nl_handle_smcd_dev(struct smcd_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)) if (nla_put_u8(skb, SMC_NLA_DEV_IS_CRIT, use_cnt > 0))
goto errattr; goto errattr;
memset(&smc_pci_dev, 0, sizeof(smc_pci_dev)); 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)) if (nla_put_u32(skb, SMC_NLA_DEV_PCI_FID, smc_pci_dev.pci_fid))
goto errattr; goto errattr;
if (nla_put_u16(skb, SMC_NLA_DEV_PCI_CHID, smc_pci_dev.pci_pchid)) 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) ...@@ -377,41 +379,24 @@ static void smc_ism_event_work(struct work_struct *work)
kfree(wrk); kfree(wrk);
} }
static void smcd_release(struct device *dev) 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 = 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)
{ {
struct smcd_dev *smcd; struct smcd_dev *smcd;
smcd = kzalloc(sizeof(*smcd), GFP_KERNEL); smcd = devm_kzalloc(parent, sizeof(*smcd), GFP_KERNEL);
if (!smcd) if (!smcd)
return NULL; return NULL;
smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *), smcd->conn = devm_kcalloc(parent, max_dmbs,
GFP_KERNEL); sizeof(struct smc_connection *), GFP_KERNEL);
if (!smcd->conn) { if (!smcd->conn)
kfree(smcd);
return NULL; return NULL;
}
smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)", smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)",
WQ_MEM_RECLAIM, name); WQ_MEM_RECLAIM, name);
if (!smcd->event_wq) { if (!smcd->event_wq)
kfree(smcd->conn);
kfree(smcd);
return NULL; return NULL;
}
smcd->dev.parent = parent;
smcd->dev.release = smcd_release;
device_initialize(&smcd->dev);
dev_set_name(&smcd->dev, name);
smcd->ops = ops; smcd->ops = ops;
spin_lock_init(&smcd->lock); spin_lock_init(&smcd->lock);
...@@ -421,13 +406,6 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name, ...@@ -421,13 +406,6 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name,
init_waitqueue_head(&smcd->lgrs_deleted); init_waitqueue_head(&smcd->lgrs_deleted);
return smcd; 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) static void smcd_register_dev(struct ism_dev *ism)
{ {
...@@ -465,16 +443,9 @@ 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); mutex_unlock(&smcd_dev_list.mutex);
pr_warn_ratelimited("smc: adding smcd device %s with pnetid %.16s%s\n", 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)" : ""); 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; return;
} }
...@@ -483,15 +454,13 @@ static void smcd_unregister_dev(struct ism_dev *ism) ...@@ -483,15 +454,13 @@ static void smcd_unregister_dev(struct ism_dev *ism)
struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client); struct smcd_dev *smcd = ism_get_priv(ism, &smc_ism_client);
pr_warn_ratelimited("smc: removing smcd device %s\n", pr_warn_ratelimited("smc: removing smcd device %s\n",
dev_name(&smcd->dev)); dev_name(&ism->dev));
smcd->going_away = 1; smcd->going_away = 1;
smc_smcd_terminate_all(smcd); smc_smcd_terminate_all(smcd);
mutex_lock(&smcd_dev_list.mutex); mutex_lock(&smcd_dev_list.mutex);
list_del_init(&smcd->list); list_del_init(&smcd->list);
mutex_unlock(&smcd_dev_list.mutex); mutex_unlock(&smcd_dev_list.mutex);
destroy_workqueue(smcd->event_wq); destroy_workqueue(smcd->event_wq);
device_del(&smcd->dev);
} }
/* SMCD Device event handler. Called from ISM device interrupt handler. /* SMCD Device event handler. Called from ISM device interrupt handler.
......
...@@ -103,7 +103,7 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name) ...@@ -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_pnetentry *pnetelem, *tmp_pe;
struct smc_pnettable *pnettable; struct smc_pnettable *pnettable;
struct smc_ib_device *ibdev; struct smc_ib_device *ibdev;
struct smcd_dev *smcd_dev; struct smcd_dev *smcd;
struct smc_net *sn; struct smc_net *sn;
int rc = -ENOENT; int rc = -ENOENT;
int ibport; int ibport;
...@@ -162,16 +162,17 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name) ...@@ -162,16 +162,17 @@ static int smc_pnet_remove_by_pnetid(struct net *net, char *pnet_name)
mutex_unlock(&smc_ib_devices.mutex); mutex_unlock(&smc_ib_devices.mutex);
/* remove smcd devices */ /* remove smcd devices */
mutex_lock(&smcd_dev_list.mutex); mutex_lock(&smcd_dev_list.mutex);
list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) { list_for_each_entry(smcd, &smcd_dev_list.list, list) {
if (smcd_dev->pnetid_by_user && if (smcd->pnetid_by_user &&
(!pnet_name || (!pnet_name ||
smc_pnet_match(pnet_name, smcd_dev->pnetid))) { smc_pnet_match(pnet_name, smcd->pnetid))) {
pr_warn_ratelimited("smc: smcd device %s " pr_warn_ratelimited("smc: smcd device %s "
"erased user defined pnetid " "erased user defined pnetid "
"%.16s\n", dev_name(&smcd_dev->dev), "%.16s\n",
smcd_dev->pnetid); dev_name(smcd->ops->get_dev(smcd)),
memset(smcd_dev->pnetid, 0, SMC_MAX_PNETID_LEN); smcd->pnetid);
smcd_dev->pnetid_by_user = false; memset(smcd->pnetid, 0, SMC_MAX_PNETID_LEN);
smcd->pnetid_by_user = false;
rc = 0; rc = 0;
} }
} }
...@@ -331,8 +332,8 @@ static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name) ...@@ -331,8 +332,8 @@ static struct smcd_dev *smc_pnet_find_smcd(char *smcd_name)
mutex_lock(&smcd_dev_list.mutex); mutex_lock(&smcd_dev_list.mutex);
list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) { list_for_each_entry(smcd_dev, &smcd_dev_list.list, list) {
if (!strncmp(dev_name(&smcd_dev->dev), smcd_name, if (!strncmp(dev_name(smcd_dev->ops->get_dev(smcd_dev)),
IB_DEVICE_NAME_MAX - 1)) smcd_name, IB_DEVICE_NAME_MAX - 1))
goto out; goto out;
} }
smcd_dev = NULL; smcd_dev = NULL;
...@@ -411,7 +412,8 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name, ...@@ -411,7 +412,8 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
struct smc_ib_device *ib_dev; struct smc_ib_device *ib_dev;
bool smcddev_applied = true; bool smcddev_applied = true;
bool ibdev_applied = true; bool ibdev_applied = true;
struct smcd_dev *smcd_dev; struct smcd_dev *smcd;
struct device *dev;
bool new_ibdev; bool new_ibdev;
/* try to apply the pnetid to active devices */ /* 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, ...@@ -425,14 +427,16 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name,
ib_port, ib_port,
ib_dev->pnetid[ib_port - 1]); ib_dev->pnetid[ib_port - 1]);
} }
smcd_dev = smc_pnet_find_smcd(ib_name); smcd = smc_pnet_find_smcd(ib_name);
if (smcd_dev) { if (smcd) {
smcddev_applied = smc_pnet_apply_smcd(smcd_dev, pnet_name); smcddev_applied = smc_pnet_apply_smcd(smcd, pnet_name);
if (smcddev_applied) if (smcddev_applied) {
dev = smcd->ops->get_dev(smcd);
pr_warn_ratelimited("smc: smcd device %s " pr_warn_ratelimited("smc: smcd device %s "
"applied user defined pnetid " "applied user defined pnetid "
"%.16s\n", dev_name(&smcd_dev->dev), "%.16s\n", dev_name(dev),
smcd_dev->pnetid); smcd->pnetid);
}
} }
/* Apply fails when a device has a hardware-defined pnetid set, do not /* Apply fails when a device has a hardware-defined pnetid set, do not
* add a pnet table entry in that case. * 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) ...@@ -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) 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_pnettable *pnettable;
struct smc_pnetentry *tmp_pe; struct smc_pnetentry *tmp_pe;
struct smc_net *sn; struct smc_net *sn;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment