mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
ksmbd: register ksmbd ib client with ib_register_client()
Register ksmbd ib client with ib_register_client() to find the rdma capable network adapter. If ops.get_netdev(Chelsio NICs) is NULL, ksmbd will find it using ib_device_get_by_netdev in old way. Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
d4eeb82674
commit
31928a001b
@ -79,6 +79,14 @@ static int smb_direct_max_read_write_size = 1024 * 1024;
|
||||
|
||||
static int smb_direct_max_outstanding_rw_ops = 8;
|
||||
|
||||
static LIST_HEAD(smb_direct_device_list);
|
||||
static DEFINE_RWLOCK(smb_direct_device_lock);
|
||||
|
||||
struct smb_direct_device {
|
||||
struct ib_device *ib_dev;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static struct smb_direct_listener {
|
||||
struct rdma_cm_id *cm_id;
|
||||
} smb_direct_listener;
|
||||
@ -2007,12 +2015,61 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int smb_direct_ib_client_add(struct ib_device *ib_dev)
|
||||
{
|
||||
struct smb_direct_device *smb_dev;
|
||||
|
||||
if (!ib_dev->ops.get_netdev ||
|
||||
!rdma_frwr_is_supported(&ib_dev->attrs))
|
||||
return 0;
|
||||
|
||||
smb_dev = kzalloc(sizeof(*smb_dev), GFP_KERNEL);
|
||||
if (!smb_dev)
|
||||
return -ENOMEM;
|
||||
smb_dev->ib_dev = ib_dev;
|
||||
|
||||
write_lock(&smb_direct_device_lock);
|
||||
list_add(&smb_dev->list, &smb_direct_device_list);
|
||||
write_unlock(&smb_direct_device_lock);
|
||||
|
||||
ksmbd_debug(RDMA, "ib device added: name %s\n", ib_dev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smb_direct_ib_client_remove(struct ib_device *ib_dev,
|
||||
void *client_data)
|
||||
{
|
||||
struct smb_direct_device *smb_dev, *tmp;
|
||||
|
||||
write_lock(&smb_direct_device_lock);
|
||||
list_for_each_entry_safe(smb_dev, tmp, &smb_direct_device_list, list) {
|
||||
if (smb_dev->ib_dev == ib_dev) {
|
||||
list_del(&smb_dev->list);
|
||||
kfree(smb_dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_unlock(&smb_direct_device_lock);
|
||||
}
|
||||
|
||||
static struct ib_client smb_direct_ib_client = {
|
||||
.name = "ksmbd_smb_direct_ib",
|
||||
.add = smb_direct_ib_client_add,
|
||||
.remove = smb_direct_ib_client_remove,
|
||||
};
|
||||
|
||||
int ksmbd_rdma_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
smb_direct_listener.cm_id = NULL;
|
||||
|
||||
ret = ib_register_client(&smb_direct_ib_client);
|
||||
if (ret) {
|
||||
pr_err("failed to ib_register_client\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* When a client is running out of send credits, the credits are
|
||||
* granted by the server's sending a packet using this queue.
|
||||
* This avoids the situation that a clients cannot send packets
|
||||
@ -2036,30 +2093,60 @@ int ksmbd_rdma_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ksmbd_rdma_destroy(void)
|
||||
void ksmbd_rdma_destroy(void)
|
||||
{
|
||||
if (smb_direct_listener.cm_id)
|
||||
rdma_destroy_id(smb_direct_listener.cm_id);
|
||||
if (!smb_direct_listener.cm_id)
|
||||
return;
|
||||
|
||||
ib_unregister_client(&smb_direct_ib_client);
|
||||
rdma_destroy_id(smb_direct_listener.cm_id);
|
||||
|
||||
smb_direct_listener.cm_id = NULL;
|
||||
|
||||
if (smb_direct_wq) {
|
||||
destroy_workqueue(smb_direct_wq);
|
||||
smb_direct_wq = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ksmbd_rdma_capable_netdev(struct net_device *netdev)
|
||||
{
|
||||
struct ib_device *ibdev;
|
||||
struct smb_direct_device *smb_dev;
|
||||
int i;
|
||||
bool rdma_capable = false;
|
||||
|
||||
ibdev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_UNKNOWN);
|
||||
if (ibdev) {
|
||||
if (rdma_frwr_is_supported(&ibdev->attrs))
|
||||
rdma_capable = true;
|
||||
ib_device_put(ibdev);
|
||||
read_lock(&smb_direct_device_lock);
|
||||
list_for_each_entry(smb_dev, &smb_direct_device_list, list) {
|
||||
for (i = 0; i < smb_dev->ib_dev->phys_port_cnt; i++) {
|
||||
struct net_device *ndev;
|
||||
|
||||
ndev = smb_dev->ib_dev->ops.get_netdev(smb_dev->ib_dev,
|
||||
i + 1);
|
||||
if (!ndev)
|
||||
continue;
|
||||
|
||||
if (ndev == netdev) {
|
||||
dev_put(ndev);
|
||||
rdma_capable = true;
|
||||
goto out;
|
||||
}
|
||||
dev_put(ndev);
|
||||
}
|
||||
}
|
||||
out:
|
||||
read_unlock(&smb_direct_device_lock);
|
||||
|
||||
if (rdma_capable == false) {
|
||||
struct ib_device *ibdev;
|
||||
|
||||
ibdev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_UNKNOWN);
|
||||
if (ibdev) {
|
||||
if (rdma_frwr_is_supported(&ibdev->attrs))
|
||||
rdma_capable = true;
|
||||
ib_device_put(ibdev);
|
||||
}
|
||||
}
|
||||
|
||||
return rdma_capable;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ struct smb_direct_data_transfer {
|
||||
|
||||
#ifdef CONFIG_SMB_SERVER_SMBDIRECT
|
||||
int ksmbd_rdma_init(void);
|
||||
int ksmbd_rdma_destroy(void);
|
||||
void ksmbd_rdma_destroy(void);
|
||||
bool ksmbd_rdma_capable_netdev(struct net_device *netdev);
|
||||
#else
|
||||
static inline int ksmbd_rdma_init(void) { return 0; }
|
||||
|
Loading…
Reference in New Issue
Block a user