From: Stefan Metzmacher Date: Fri, 12 Sep 2025 22:10:06 +0000 (+0200) Subject: smb: client: make use of smbdirect_connection_{create,destroy}_mem_pools() X-Git-Tag: v7.1-rc1~128^2~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=116f3eed365143dd8c31a50fe62726966d047577;p=thirdparty%2Fkernel%2Flinux.git smb: client: make use of smbdirect_connection_{create,destroy}_mem_pools() The main logical differences are the following: We now don't use smbdirect_connection_get_recv_io() on cleanup, instead it uses list_for_each_entry_safe()... For the smbdirect_recv_io payload we expose the whole payload including the smbdirect_data_transfer header as documentation says data_offset = 0 and data_length != 0 would be valid, while the existing client code requires data_offset >= 24. The smbdirect_send_io cache includes header space for sizeof(struct smbdirect_negotiate_resp) = 32 bytes instead of sizeof(struct smbdirect_data_transfer) = 24 bytes. If this ever becomes a problem, we can allocate separate space for the smbdirect_negotiate_resp in the server. Cc: Steve French Cc: Tom Talpey Cc: Long Li Cc: Namjae Jeon Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher Acked-by: Namjae Jeon Signed-off-by: Steve French --- diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 41baa403063b7..28fb77b2661b4 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -23,9 +23,6 @@ const struct smbdirect_socket_parameters *smbd_get_parameters(struct smbd_connec return &sc->parameters; } -static int allocate_receive_buffers(struct smbdirect_socket *sc, int num_buf); -static void destroy_receive_buffers(struct smbdirect_socket *sc); - static int smbd_post_send(struct smbdirect_socket *sc, struct smbdirect_send_batch *batch, struct smbdirect_send_io *request); @@ -1473,44 +1470,6 @@ static int smbd_negotiate(struct smbdirect_socket *sc) return rc; } -/* Preallocate all receive buffer on transport establishment */ -static int allocate_receive_buffers(struct smbdirect_socket *sc, int num_buf) -{ - struct smbdirect_recv_io *response; - int i; - - for (i = 0; i < num_buf; i++) { - response = mempool_alloc(sc->recv_io.mem.pool, GFP_KERNEL); - if (!response) - goto allocate_failed; - - response->socket = sc; - response->sge.length = 0; - list_add_tail(&response->list, &sc->recv_io.free.list); - } - - return 0; - -allocate_failed: - while (!list_empty(&sc->recv_io.free.list)) { - response = list_first_entry( - &sc->recv_io.free.list, - struct smbdirect_recv_io, list); - list_del(&response->list); - - mempool_free(response, sc->recv_io.mem.pool); - } - return -ENOMEM; -} - -static void destroy_receive_buffers(struct smbdirect_socket *sc) -{ - struct smbdirect_recv_io *response; - - while ((response = smbdirect_connection_get_recv_io(sc))) - mempool_free(response, sc->recv_io.mem.pool); -} - static void send_immediate_empty_message(struct work_struct *work) { struct smbdirect_socket *sc = @@ -1591,9 +1550,6 @@ void smbd_destroy(struct TCP_Server_Info *server) } while (response); sc->recv_io.reassembly.data_length = 0; - log_rdma_event(INFO, "free receive buffers\n"); - destroy_receive_buffers(sc); - log_rdma_event(INFO, "freeing mr list\n"); destroy_mr_list(sc); @@ -1603,11 +1559,7 @@ void smbd_destroy(struct TCP_Server_Info *server) rdma_destroy_id(sc->rdma.cm_id); /* free mempools */ - mempool_destroy(sc->send_io.mem.pool); - kmem_cache_destroy(sc->send_io.mem.cache); - - mempool_destroy(sc->recv_io.mem.pool); - kmem_cache_destroy(sc->recv_io.mem.cache); + smbdirect_connection_destroy_mem_pools(sc); sc->status = SMBDIRECT_SOCKET_DESTROYED; @@ -1653,81 +1605,6 @@ create_conn: return -ENOENT; } -static void destroy_caches(struct smbdirect_socket *sc) -{ - destroy_receive_buffers(sc); - mempool_destroy(sc->recv_io.mem.pool); - kmem_cache_destroy(sc->recv_io.mem.cache); - mempool_destroy(sc->send_io.mem.pool); - kmem_cache_destroy(sc->send_io.mem.cache); -} - -#define MAX_NAME_LEN 80 -static int allocate_caches(struct smbdirect_socket *sc) -{ - struct smbdirect_socket_parameters *sp = &sc->parameters; - char name[MAX_NAME_LEN]; - int rc; - - if (WARN_ON_ONCE(sp->max_recv_size < sizeof(struct smbdirect_data_transfer))) - return -ENOMEM; - - scnprintf(name, MAX_NAME_LEN, "smbdirect_send_io_%p", sc); - sc->send_io.mem.cache = - kmem_cache_create( - name, - sizeof(struct smbdirect_send_io) + - sizeof(struct smbdirect_data_transfer), - 0, SLAB_HWCACHE_ALIGN, NULL); - if (!sc->send_io.mem.cache) - return -ENOMEM; - - sc->send_io.mem.pool = - mempool_create(sp->send_credit_target, mempool_alloc_slab, - mempool_free_slab, sc->send_io.mem.cache); - if (!sc->send_io.mem.pool) - goto out1; - - scnprintf(name, MAX_NAME_LEN, "smbdirect_recv_io_%p", sc); - - struct kmem_cache_args response_args = { - .align = __alignof__(struct smbdirect_recv_io), - .useroffset = (offsetof(struct smbdirect_recv_io, packet) + - sizeof(struct smbdirect_data_transfer)), - .usersize = sp->max_recv_size - sizeof(struct smbdirect_data_transfer), - }; - sc->recv_io.mem.cache = - kmem_cache_create(name, - sizeof(struct smbdirect_recv_io) + sp->max_recv_size, - &response_args, SLAB_HWCACHE_ALIGN); - if (!sc->recv_io.mem.cache) - goto out2; - - sc->recv_io.mem.pool = - mempool_create(sp->recv_credit_max, mempool_alloc_slab, - mempool_free_slab, sc->recv_io.mem.cache); - if (!sc->recv_io.mem.pool) - goto out3; - - rc = allocate_receive_buffers(sc, sp->recv_credit_max); - if (rc) { - log_rdma_event(ERR, "failed to allocate receive buffers\n"); - goto out4; - } - - return 0; - -out4: - mempool_destroy(sc->recv_io.mem.pool); -out3: - kmem_cache_destroy(sc->recv_io.mem.cache); -out2: - mempool_destroy(sc->send_io.mem.pool); -out1: - kmem_cache_destroy(sc->send_io.mem.cache); - return -ENOMEM; -} - /* Create a SMBD connection, called by upper layer */ static struct smbd_connection *_smbd_get_connection( struct TCP_Server_Info *server, struct sockaddr *dstaddr, int port) @@ -1919,7 +1796,7 @@ static struct smbd_connection *_smbd_get_connection( log_rdma_event(INFO, "rdma_connect connected\n"); - rc = allocate_caches(sc); + rc = smbdirect_connection_create_mem_pools(sc); if (rc) { log_rdma_event(ERR, "cache allocation failed\n"); goto allocate_cache_failed; @@ -1958,7 +1835,7 @@ allocate_mr_failed: negotiation_failed: disable_delayed_work_sync(&sc->idle.timer_work); - destroy_caches(sc); + smbdirect_connection_destroy_mem_pools(sc); sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED; rdma_disconnect(sc->rdma.cm_id); wait_event(sc->status_wait,