This is a note to let you know that I've just added the patch titled ksmbd: register ksmbd ib client with ib_register_client() to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ksmbd-register-ksmbd-ib-client-with-ib_register_client.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From stable+bounces-7645-greg=kroah.com@xxxxxxxxxxxxxxx Mon Dec 18 16:37:48 2023 From: Namjae Jeon <linkinjeon@xxxxxxxxxx> Date: Tue, 19 Dec 2023 00:32:36 +0900 Subject: ksmbd: register ksmbd ib client with ib_register_client() To: gregkh@xxxxxxxxxxxxxxxxxxx, stable@xxxxxxxxxxxxxxx Cc: smfrench@xxxxxxxxx, Hyunchul Lee <hyc.lee@xxxxxxxxx>, Namjae Jeon <linkinjeon@xxxxxxxxxx>, Steve French <stfrench@xxxxxxxxxxxxx> Message-ID: <20231218153454.8090-17-linkinjeon@xxxxxxxxxx> From: Hyunchul Lee <hyc.lee@xxxxxxxxx> [ Upstream commit 31928a001bed0d9642711d2eba520fc46d41c376 ] 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@xxxxxxxxx> Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx> Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/ksmbd/transport_rdma.c | 107 +++++++++++++++++++++++++++++++++++++++++----- fs/ksmbd/transport_rdma.h | 2 2 files changed, 98 insertions(+), 11 deletions(-) --- a/fs/ksmbd/transport_rdma.c +++ b/fs/ksmbd/transport_rdma.c @@ -79,6 +79,14 @@ static int smb_direct_max_read_write_siz 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; @@ -2013,12 +2021,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 @@ -2042,30 +2099,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; } --- a/fs/ksmbd/transport_rdma.h +++ b/fs/ksmbd/transport_rdma.h @@ -56,7 +56,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); void init_smbd_max_io_size(unsigned int sz); #else Patches currently in stable-queue which might be from kroah.com@xxxxxxxxxxxxxxx are queue-5.15/ksmbd-remove-unused-parameter-from-smb2_get_name.patch queue-5.15/ksmbd-smbd-handle-multiple-buffer-descriptors.patch queue-5.15/ksmbd-add-mnt_want_write-to-ksmbd-vfs-functions.patch queue-5.15/ksmbd-delete-an-invalid-argument-description-in-smb2_populate_readdir_entry.patch queue-5.15/ksmbd-remove-smb2_buf_length-in-smb2_transform_hdr.patch queue-5.15/ksmbd-fix-smb2_set_info_file-kernel-doc-comment.patch queue-5.15/ksmbd-remove-unused-fields-from-ksmbd_file-struct-definition.patch queue-5.15/ksmbd-set-445-port-to-smbdirect-port-by-default.patch queue-5.15/ksmbd-use-ksmbd_req_buf_next-in-ksmbd_verify_smb_message.patch queue-5.15/ksmbd-set-both-ipv4-and-ipv6-in-fsctl_query_network_interface_info.patch queue-5.15/ksmbd-reduce-descriptor-size-if-remaining-bytes-is-less-than-request-size.patch queue-5.15/ksmbd-fix-smb2_get_name-kernel-doc-comment.patch queue-5.15/ksmbd-register-ksmbd-ib-client-with-ib_register_client.patch queue-5.15/ksmbd-smbd-fix-missing-client-s-memory-region-invalidation.patch queue-5.15/ksmbd-fix-parameter-name-and-comment-mismatch.patch queue-5.15/ksmbd-smbd-call-rdma_accept-under-cm-handler.patch queue-5.15/ksmdb-use-cmd-helper-variable-in-smb2_get_ksmbd_tcon.patch queue-5.15/ksmbd-smbd-change-the-default-maximum-read-write-receive-size.patch queue-5.15/ksmbd-smbd-remove-useless-license-text-when-spdx-license-identifier-is-already-used.patch queue-5.15/ksmbd-check-the-validation-of-pdu_size-in-ksmbd_conn_handler_loop.patch queue-5.15/ksmbd-fix-buffer_check_err-kernel-doc-comment.patch queue-5.15/ksmbd-remove-redundant-flush_workqueue-calls.patch queue-5.15/ksmbd-smbd-create-mr-pool.patch queue-5.15/ksmbd-remove-smb2_buf_length-in-smb2_hdr.patch queue-5.15/ksmbd-remove-md4-leftovers.patch queue-5.15/ksmbd-add-smb-direct-shutdown.patch