mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2026-01-27 12:47:24 +01:00
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 a72178cfe8 ("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>
93 lines
2.1 KiB
C
93 lines
2.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Internal Shared Memory
|
|
*
|
|
* Definitions for the ISM module
|
|
*
|
|
* Copyright IBM Corp. 2022
|
|
*/
|
|
#ifndef _ISM_H
|
|
#define _ISM_H
|
|
|
|
#include <linux/workqueue.h>
|
|
|
|
struct ism_dmb {
|
|
u64 dmb_tok;
|
|
u64 rgid;
|
|
u32 dmb_len;
|
|
u32 sba_idx;
|
|
u32 vlan_valid;
|
|
u32 vlan_id;
|
|
void *cpu_addr;
|
|
dma_addr_t dma_addr;
|
|
};
|
|
|
|
/* Unless we gain unexpected popularity, this limit should hold for a while */
|
|
#define MAX_CLIENTS 8
|
|
#define ISM_NR_DMBS 1920
|
|
|
|
struct ism_dev {
|
|
spinlock_t lock; /* protects the ism device */
|
|
spinlock_t cmd_lock; /* serializes cmds */
|
|
struct list_head list;
|
|
struct dibs_dev *dibs;
|
|
struct pci_dev *pdev;
|
|
|
|
struct ism_sba *sba;
|
|
dma_addr_t sba_dma_addr;
|
|
DECLARE_BITMAP(sba_bitmap, ISM_NR_DMBS);
|
|
u8 *sba_client_arr; /* entries are indices into 'clients' array */
|
|
void *priv[MAX_CLIENTS];
|
|
|
|
struct ism_eq *ieq;
|
|
dma_addr_t ieq_dma_addr;
|
|
|
|
struct device dev;
|
|
u64 local_gid;
|
|
int ieq_idx;
|
|
|
|
struct ism_client *subs[MAX_CLIENTS];
|
|
};
|
|
|
|
struct ism_event {
|
|
u32 type;
|
|
u32 code;
|
|
u64 tok;
|
|
u64 time;
|
|
u64 info;
|
|
};
|
|
|
|
struct ism_client {
|
|
const char *name;
|
|
void (*handle_event)(struct ism_dev *dev, struct ism_event *event);
|
|
/* Parameter dmbemask contains a bit vector with updated DMBEs, if sent
|
|
* via ism_move_data(). Callback function must handle all active bits
|
|
* indicated by dmbemask.
|
|
*/
|
|
void (*handle_irq)(struct ism_dev *dev, unsigned int bit, u16 dmbemask);
|
|
/* Private area - don't touch! */
|
|
u8 id;
|
|
};
|
|
|
|
int ism_register_client(struct ism_client *client);
|
|
int ism_unregister_client(struct ism_client *client);
|
|
static inline void *ism_get_priv(struct ism_dev *dev,
|
|
struct ism_client *client) {
|
|
return dev->priv[client->id];
|
|
}
|
|
|
|
static inline void ism_set_priv(struct ism_dev *dev, struct ism_client *client,
|
|
void *priv) {
|
|
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);
|
|
|
|
const struct smcd_ops *ism_get_smcd_ops(void);
|
|
|
|
#endif /* _ISM_H */
|