summaryrefslogtreecommitdiff
path: root/drivers/s390/net/ism_drv.c
diff options
context:
space:
mode:
authorAlexandra Winter <wintera@linux.ibm.com>2025-09-18 13:04:53 +0200
committerPaolo Abeni <pabeni@redhat.com>2025-09-23 11:13:22 +0200
commit69baaac9361edd169713562f088829a1be9c51a9 (patch)
tree6e78c39fa337cf5522a577aef017a1e701299b73 /drivers/s390/net/ism_drv.c
parentcb990a45d7f6eb6dc495d2226a3005b284a5ee4f (diff)
dibs: Define dibs_client_ops and dibs_dev_ops
Move the device add() and remove() functions from ism_client to dibs_client_ops and call add_dev()/del_dev() for ism devices and dibs_loopback devices. dibs_client_ops->add_dev() = smcd_register_dev() for the smc_dibs_client. This is the first step to handle ism and loopback devices alike (as dibs devices) in the smc dibs client. Define dibs_dev->ops and move smcd_ops->get_chid to dibs_dev_ops->get_fabric_id() for ism and loopback devices. See below for why this needs to be in the same patch as dibs_client_ops->add_dev(). The following changes contain intermediate steps, that will be obsoleted by follow-on patches, once more functionality has been moved to dibs: Use different smcd_ops and max_dmbs for ism and loopback. Follow-on patches will change SMC-D to directly use dibs_ops instead of smcd_ops. In smcd_register_dev() it is now necessary to identify a dibs_loopback device before smcd_dev and smcd_ops->get_chid() are available. So provide dibs_dev_ops->get_fabric_id() in this patch and evaluate it in smc_ism_is_loopback(). Call smc_loopback_init() in smcd_register_dev() and call smc_loopback_exit() in smcd_unregister_dev() to handle the functionality that is still in smc_loopback. Follow-on patches will move all smc_loopback code to dibs_loopback. In smcd_[un]register_dev() use only ism device name, this will be replaced by dibs device name by a follow-on patch. End of changes with intermediate parts. Allocate an smcd event workqueue for all dibs devices, although dibs_loopback does not generate events. Use kernel memory instead of devres memory for smcd_dev and smcd->conn. Since commit a72178cfe855 ("net/smc: Fix dependency of SMC on ISM") an ism device and its driver can have a longer lifetime than the smc module, so smc should not rely on devres to free its resources [1]. It is now the responsibility of the smc client to free smcd and smcd->conn for all dibs devices, ism devices as well as loopback. Call client->ops->del_dev() for all existing dibs devices in dibs_unregister_client(), so all device related structures can be freed in the client. When dibs_unregister_client() is called in the context of smc_exit() or smc_core_reboot_event(), these functions have already called smc_lgrs_shutdown() which calls smc_smcd_terminate_all(smcd) and sets going_away. This is done a second time in smcd_unregister_dev(). This is analogous to how smcr is handled in these functions, by calling first smc_lgrs_shutdown() and then smc_ib_unregister_client() > smc_ib_remove_dev(), so leave it that way. It may be worth investigating, whether smc_lgrs_shutdown() is still required or useful. Remove CONFIG_SMC_LO. CONFIG_DIBS_LO now controls whether a dibs loopback device exists or not. Link: https://www.kernel.org/doc/Documentation/driver-model/devres.txt [1] Signed-off-by: Alexandra Winter <wintera@linux.ibm.com> Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com> Link: https://patch.msgid.link/20250918110500.1731261-8-wintera@linux.ibm.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'drivers/s390/net/ism_drv.c')
-rw-r--r--drivers/s390/net/ism_drv.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index 8ecd0cccc7e8..2bd8f64ebb56 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -79,7 +79,6 @@ int ism_register_client(struct ism_client *client)
/* initialize with all devices that we got so far */
list_for_each_entry(ism, &ism_dev_list.list, list) {
ism->priv[i] = NULL;
- client->add(ism);
ism_setup_forwarding(client, ism);
}
}
@@ -465,6 +464,16 @@ int ism_move(struct ism_dev *ism, u64 dmb_tok, unsigned int idx, bool sf,
}
EXPORT_SYMBOL_GPL(ism_move);
+static u16 ism_get_chid(struct dibs_dev *dibs)
+{
+ struct ism_dev *ism = dibs->drv_priv;
+
+ if (!ism || !ism->pdev)
+ return 0;
+
+ return to_zpci(ism->pdev)->pchid;
+}
+
static void ism_handle_event(struct ism_dev *ism)
{
struct ism_event *entry;
@@ -523,6 +532,10 @@ static irqreturn_t ism_handle_irq(int irq, void *data)
return IRQ_HANDLED;
}
+static const struct dibs_dev_ops ism_ops = {
+ .get_fabric_id = ism_get_chid,
+};
+
static int ism_dev_init(struct ism_dev *ism)
{
struct pci_dev *pdev = ism->pdev;
@@ -564,7 +577,6 @@ static int ism_dev_init(struct ism_dev *ism)
mutex_lock(&clients_lock);
for (i = 0; i < max_client; ++i) {
if (clients[i]) {
- clients[i]->add(ism);
ism_setup_forwarding(clients[i], ism);
}
}
@@ -611,12 +623,6 @@ static void ism_dev_exit(struct ism_dev *ism)
spin_unlock_irqrestore(&ism->lock, flags);
mutex_lock(&ism_dev_list.mutex);
- mutex_lock(&clients_lock);
- for (i = 0; i < max_client; ++i) {
- if (clients[i])
- clients[i]->remove(ism);
- }
- mutex_unlock(&clients_lock);
if (ism_v2_capable)
ism_del_vlan_id(ism, ISM_RESERVED_VLANID);
@@ -672,7 +678,10 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = -ENOMEM;
goto err_resource;
}
+ /* set this up before we enable interrupts */
ism->dibs = dibs;
+ dibs->drv_priv = ism;
+ dibs->ops = &ism_ops;
ret = ism_dev_init(ism);
if (ret)
@@ -857,19 +866,6 @@ static void smcd_get_local_gid(struct smcd_dev *smcd,
smcd_gid->gid_ext = 0;
}
-static u16 ism_get_chid(struct ism_dev *ism)
-{
- if (!ism || !ism->pdev)
- return 0;
-
- return to_zpci(ism->pdev)->pchid;
-}
-
-static u16 smcd_get_chid(struct smcd_dev *smcd)
-{
- return ism_get_chid(smcd->priv);
-}
-
static inline struct device *smcd_get_dev(struct smcd_dev *dev)
{
struct ism_dev *ism = dev->priv;
@@ -877,7 +873,7 @@ static inline struct device *smcd_get_dev(struct smcd_dev *dev)
return &ism->dev;
}
-static const struct smcd_ops ism_ops = {
+static const struct smcd_ops ism_smcd_ops = {
.query_remote_gid = smcd_query_rgid,
.register_dmb = smcd_register_dmb,
.unregister_dmb = smcd_unregister_dmb,
@@ -889,13 +885,12 @@ static const struct smcd_ops ism_ops = {
.move_data = smcd_move,
.supports_v2 = smcd_supports_v2,
.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)
{
- return &ism_ops;
+ return &ism_smcd_ops;
}
EXPORT_SYMBOL_GPL(ism_get_smcd_ops);
#endif