mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
fourteen smb3 client fixes, most smbdirect related
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmhEsJkACgkQiiy9cAdy T1Gjlgv+P1I4uD8iDbkJvyrh7mVcnIDnjttbgN1pTZZnpcX7JIyMPR9YPUn+QTKf 3GStGgLHqKtnXYYCdrkpPipsH/fjt7kjVLUC/YMhUGEr5dSFKzygOVaRTo4LDgNO sSlOxTPyTaPgxdvIXriU5CeJGtm95GqowLDG29We9ubX1P5GLjIjGlMbAisAk4/Q ek478D0qBSO5u6FkMYUFuSbjGwOYWAlabMxeOVHpjgEH/36tVtDKOc/bORnVZtHB 6bRjhymn9CZQOE2P+gDSqF6pZwHWhU7uYJYW+kbDbmDIgWDk9xl5/kbbqZ6RR3t5 joPWzZkO1I58avmJ31aauhvRpYIOXfOhx2dHB6VM/7bSHTvE6CW60RIlpXo1xbO6 d30pTy7ICqP/RWNZlt5ZgoPTDB1hPmVDdMXoELp7uZzChhrAz4qc/2BSD0Y5fCjE e/U0bPfsyjscB7NtpcrQYVMbOsrweQ4qKUgolEk1klLolsKxDGE176wbPmLNAzo4 C9SzyxU3 =RvlW -----END PGP SIGNATURE----- Merge tag '6.16-rc-part2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull more smb client updates from Steve French: - multichannel/reconnect fixes - move smbdirect (smb over RDMA) defines to fs/smb/common so they will be able to be used in the future more broadly, and a documentation update explaining setting up smbdirect mounts - update email address for Paulo * tag '6.16-rc-part2-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: update internal version number MAINTAINERS, mailmap: Update Paulo Alcantara's email address cifs: add documentation for smbdirect setup cifs: do not disable interface polling on failure cifs: serialize other channels when query server interfaces is pending cifs: deal with the channel loading lag while picking channels smb: client: make use of common smbdirect_socket_parameters smb: smbdirect: introduce smbdirect_socket_parameters smb: client: make use of common smbdirect_socket smb: smbdirect: add smbdirect_socket.h smb: client: make use of common smbdirect.h smb: smbdirect: add smbdirect.h with public structures smb: client: make use of common smbdirect_pdu.h smb: smbdirect: add smbdirect_pdu.h with protocol definitions
This commit is contained in:
commit
522cd6acd2
16 changed files with 532 additions and 287 deletions
6
.mailmap
6
.mailmap
|
@ -602,6 +602,12 @@ Paul Mackerras <paulus@ozlabs.org> <paulus@samba.org>
|
|||
Paul Mackerras <paulus@ozlabs.org> <paulus@au1.ibm.com>
|
||||
Paul Moore <paul@paul-moore.com> <paul.moore@hp.com>
|
||||
Paul Moore <paul@paul-moore.com> <pmoore@redhat.com>
|
||||
Paulo Alcantara <pc@manguebit.org> <pcacjr@zytor.com>
|
||||
Paulo Alcantara <pc@manguebit.org> <paulo@paulo.ac>
|
||||
Paulo Alcantara <pc@manguebit.org> <pc@cjr.nz>
|
||||
Paulo Alcantara <pc@manguebit.org> <palcantara@suse.de>
|
||||
Paulo Alcantara <pc@manguebit.org> <palcantara@suse.com>
|
||||
Paulo Alcantara <pc@manguebit.org> <pc@manguebit.com>
|
||||
Pavankumar Kondeti <quic_pkondeti@quicinc.com> <pkondeti@codeaurora.org>
|
||||
Peter A Jonsson <pj@ludd.ltu.se>
|
||||
Peter Oruba <peter.oruba@amd.com>
|
||||
|
|
|
@ -8,3 +8,4 @@ CIFS
|
|||
|
||||
ksmbd
|
||||
cifsroot
|
||||
smbdirect
|
||||
|
|
103
Documentation/filesystems/smb/smbdirect.rst
Normal file
103
Documentation/filesystems/smb/smbdirect.rst
Normal file
|
@ -0,0 +1,103 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========================
|
||||
SMB Direct - SMB3 over RDMA
|
||||
===========================
|
||||
|
||||
This document describes how to set up the Linux SMB client and server to
|
||||
use RDMA.
|
||||
|
||||
Overview
|
||||
========
|
||||
The Linux SMB kernel client supports SMB Direct, which is a transport
|
||||
scheme for SMB3 that uses RDMA (Remote Direct Memory Access) to provide
|
||||
high throughput and low latencies by bypassing the traditional TCP/IP
|
||||
stack.
|
||||
SMB Direct on the Linux SMB client can be tested against KSMBD - a
|
||||
kernel-space SMB server.
|
||||
|
||||
Installation
|
||||
=============
|
||||
- Install an RDMA device. As long as the RDMA device driver is supported
|
||||
by the kernel, it should work. This includes both software emulators (soft
|
||||
RoCE, soft iWARP) and hardware devices (InfiniBand, RoCE, iWARP).
|
||||
|
||||
- Install a kernel with SMB Direct support. The first kernel release to
|
||||
support SMB Direct on both the client and server side is 5.15. Therefore,
|
||||
a distribution compatible with kernel 5.15 or later is required.
|
||||
|
||||
- Install cifs-utils, which provides the `mount.cifs` command to mount SMB
|
||||
shares.
|
||||
|
||||
- Configure the RDMA stack
|
||||
|
||||
Make sure that your kernel configuration has RDMA support enabled. Under
|
||||
Device Drivers -> Infiniband support, update the kernel configuration to
|
||||
enable Infiniband support.
|
||||
|
||||
Enable the appropriate IB HCA support or iWARP adapter support,
|
||||
depending on your hardware.
|
||||
|
||||
If you are using InfiniBand, enable IP-over-InfiniBand support.
|
||||
|
||||
For soft RDMA, enable either the soft iWARP (`RDMA _SIW`) or soft RoCE
|
||||
(`RDMA_RXE`) module. Install the `iproute2` package and use the
|
||||
`rdma link add` command to load the module and create an
|
||||
RDMA interface.
|
||||
|
||||
e.g. if your local ethernet interface is `eth0`, you can use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo rdma link add siw0 type siw netdev eth0
|
||||
|
||||
- Enable SMB Direct support for both the server and the client in the kernel
|
||||
configuration.
|
||||
|
||||
Server Setup
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Network File Systems --->
|
||||
<M> SMB3 server support
|
||||
[*] Support for SMB Direct protocol
|
||||
|
||||
Client Setup
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Network File Systems --->
|
||||
<M> SMB3 and CIFS support (advanced network filesystem)
|
||||
[*] SMB Direct support
|
||||
|
||||
- Build and install the kernel. SMB Direct support will be enabled in the
|
||||
cifs.ko and ksmbd.ko modules.
|
||||
|
||||
Setup and Usage
|
||||
================
|
||||
|
||||
- Set up and start a KSMBD server as described in the `KSMBD documentation
|
||||
<https://www.kernel.org/doc/Documentation/filesystems/smb/ksmbd.rst>`_.
|
||||
Also add the "server multi channel support = yes" parameter to ksmbd.conf.
|
||||
|
||||
- On the client, mount the share with `rdma` mount option to use SMB Direct
|
||||
(specify a SMB version 3.0 or higher using `vers`).
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
mount -t cifs //server/share /mnt/point -o vers=3.1.1,rdma
|
||||
|
||||
- To verify that the mount is using SMB Direct, you can check dmesg for the
|
||||
following log line after mounting:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
CIFS: VFS: RDMA transport established
|
||||
|
||||
Or, verify `rdma` mount option for the share in `/proc/mounts`:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cat /proc/mounts | grep cifs
|
|
@ -5986,7 +5986,7 @@ X: drivers/clk/clkdev.c
|
|||
COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
|
||||
M: Steve French <sfrench@samba.org>
|
||||
M: Steve French <smfrench@gmail.com>
|
||||
R: Paulo Alcantara <pc@manguebit.com> (DFS, global name space)
|
||||
R: Paulo Alcantara <pc@manguebit.org> (DFS, global name space)
|
||||
R: Ronnie Sahlberg <ronniesahlberg@gmail.com> (directory leases, sparse files)
|
||||
R: Shyam Prasad N <sprasad@microsoft.com> (multichannel)
|
||||
R: Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
|
||||
|
@ -9280,7 +9280,7 @@ F: include/linux/iomap.h
|
|||
|
||||
FILESYSTEMS [NETFS LIBRARY]
|
||||
M: David Howells <dhowells@redhat.com>
|
||||
M: Paulo Alcantara <pc@manguebit.com>
|
||||
M: Paulo Alcantara <pc@manguebit.org>
|
||||
L: netfs@lists.linux.dev
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
S: Supported
|
||||
|
|
|
@ -362,6 +362,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
|||
c = 0;
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
struct smbdirect_socket_parameters *sp;
|
||||
#endif
|
||||
|
||||
/* channel info will be printed as a part of sessions below */
|
||||
if (SERVER_IS_CHAN(server))
|
||||
continue;
|
||||
|
@ -383,25 +387,26 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
|||
seq_printf(m, "\nSMBDirect transport not available");
|
||||
goto skip_rdma;
|
||||
}
|
||||
sp = &server->smbd_conn->socket.parameters;
|
||||
|
||||
seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
|
||||
"transport status: %x",
|
||||
server->smbd_conn->protocol,
|
||||
server->smbd_conn->transport_status);
|
||||
server->smbd_conn->socket.status);
|
||||
seq_printf(m, "\nConn receive_credit_max: %x "
|
||||
"send_credit_target: %x max_send_size: %x",
|
||||
server->smbd_conn->receive_credit_max,
|
||||
server->smbd_conn->send_credit_target,
|
||||
server->smbd_conn->max_send_size);
|
||||
sp->recv_credit_max,
|
||||
sp->send_credit_target,
|
||||
sp->max_send_size);
|
||||
seq_printf(m, "\nConn max_fragmented_recv_size: %x "
|
||||
"max_fragmented_send_size: %x max_receive_size:%x",
|
||||
server->smbd_conn->max_fragmented_recv_size,
|
||||
server->smbd_conn->max_fragmented_send_size,
|
||||
server->smbd_conn->max_receive_size);
|
||||
sp->max_fragmented_recv_size,
|
||||
sp->max_fragmented_send_size,
|
||||
sp->max_recv_size);
|
||||
seq_printf(m, "\nConn keep_alive_interval: %x "
|
||||
"max_readwrite_size: %x rdma_readwrite_threshold: %x",
|
||||
server->smbd_conn->keep_alive_interval,
|
||||
server->smbd_conn->max_readwrite_size,
|
||||
sp->keepalive_interval_msec * 1000,
|
||||
sp->max_read_write_size,
|
||||
server->smbd_conn->rdma_readwrite_threshold);
|
||||
seq_printf(m, "\nDebug count_get_receive_buffer: %x "
|
||||
"count_put_receive_buffer: %x count_send_empty: %x",
|
||||
|
|
|
@ -145,6 +145,6 @@ extern const struct export_operations cifs_export_ops;
|
|||
#endif /* CONFIG_CIFS_NFSD_EXPORT */
|
||||
|
||||
/* when changing internal version - update following two lines at same time */
|
||||
#define SMB3_PRODUCT_BUILD 54
|
||||
#define CIFS_VERSION "2.54"
|
||||
#define SMB3_PRODUCT_BUILD 55
|
||||
#define CIFS_VERSION "2.55"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
|
|
@ -1085,6 +1085,7 @@ struct cifs_chan {
|
|||
};
|
||||
|
||||
#define CIFS_SES_FLAG_SCALE_CHANNELS (0x1)
|
||||
#define CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES (0x2)
|
||||
|
||||
/*
|
||||
* Session structure. One of these for each uid session with a particular host
|
||||
|
|
|
@ -116,13 +116,9 @@ static void smb2_query_server_interfaces(struct work_struct *work)
|
|||
rc = server->ops->query_server_interfaces(xid, tcon, false);
|
||||
free_xid(xid);
|
||||
|
||||
if (rc) {
|
||||
if (rc == -EOPNOTSUPP)
|
||||
return;
|
||||
|
||||
if (rc)
|
||||
cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
|
|
|
@ -504,6 +504,9 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
|
|||
wsize = min_t(unsigned int, wsize, server->max_write);
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
if (server->rdma) {
|
||||
struct smbdirect_socket_parameters *sp =
|
||||
&server->smbd_conn->socket.parameters;
|
||||
|
||||
if (server->sign)
|
||||
/*
|
||||
* Account for SMB2 data transfer packet header and
|
||||
|
@ -511,12 +514,12 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
|
|||
*/
|
||||
wsize = min_t(unsigned int,
|
||||
wsize,
|
||||
server->smbd_conn->max_fragmented_send_size -
|
||||
sp->max_fragmented_send_size -
|
||||
SMB2_READWRITE_PDU_HEADER_SIZE -
|
||||
sizeof(struct smb2_transform_hdr));
|
||||
else
|
||||
wsize = min_t(unsigned int,
|
||||
wsize, server->smbd_conn->max_readwrite_size);
|
||||
wsize, sp->max_read_write_size);
|
||||
}
|
||||
#endif
|
||||
if (!(server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
|
||||
|
@ -552,6 +555,9 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
|
|||
rsize = min_t(unsigned int, rsize, server->max_read);
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
if (server->rdma) {
|
||||
struct smbdirect_socket_parameters *sp =
|
||||
&server->smbd_conn->socket.parameters;
|
||||
|
||||
if (server->sign)
|
||||
/*
|
||||
* Account for SMB2 data transfer packet header and
|
||||
|
@ -559,12 +565,12 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)
|
|||
*/
|
||||
rsize = min_t(unsigned int,
|
||||
rsize,
|
||||
server->smbd_conn->max_fragmented_recv_size -
|
||||
sp->max_fragmented_recv_size -
|
||||
SMB2_READWRITE_PDU_HEADER_SIZE -
|
||||
sizeof(struct smb2_transform_hdr));
|
||||
else
|
||||
rsize = min_t(unsigned int,
|
||||
rsize, server->smbd_conn->max_readwrite_size);
|
||||
rsize, sp->max_read_write_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "smb2glob.h"
|
||||
#include "cifspdu.h"
|
||||
#include "cifs_spnego.h"
|
||||
#include "../common/smbdirect/smbdirect.h"
|
||||
#include "smbdirect.h"
|
||||
#include "trace.h"
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
|
@ -411,14 +412,23 @@ skip_sess_setup:
|
|||
if (!rc &&
|
||||
(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
|
||||
server->ops->query_server_interfaces) {
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
|
||||
/*
|
||||
* query server network interfaces, in case they change
|
||||
* query server network interfaces, in case they change.
|
||||
* Also mark the session as pending this update while the query
|
||||
* is in progress. This will be used to avoid calling
|
||||
* smb2_reconnect recursively.
|
||||
*/
|
||||
ses->flags |= CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
|
||||
xid = get_xid();
|
||||
rc = server->ops->query_server_interfaces(xid, tcon, false);
|
||||
free_xid(xid);
|
||||
ses->flags &= ~CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES;
|
||||
|
||||
/* regardless of rc value, setup polling */
|
||||
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
|
||||
if (rc == -EOPNOTSUPP && ses->chan_count > 1) {
|
||||
/*
|
||||
|
@ -438,11 +448,8 @@ skip_sess_setup:
|
|||
if (ses->chan_max > ses->chan_count &&
|
||||
ses->iface_count &&
|
||||
!SERVER_IS_CHAN(server)) {
|
||||
if (ses->chan_count == 1) {
|
||||
if (ses->chan_count == 1)
|
||||
cifs_server_dbg(VFS, "supports multichannel now\n");
|
||||
queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
|
||||
(SMB_INTERFACE_POLL_INTERVAL * HZ));
|
||||
}
|
||||
|
||||
cifs_try_adding_channels(ses);
|
||||
}
|
||||
|
@ -560,11 +567,18 @@ static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
|
|||
struct TCP_Server_Info *server,
|
||||
void **request_buf, unsigned int *total_len)
|
||||
{
|
||||
/* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
|
||||
if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
|
||||
/*
|
||||
* Skip reconnect in one of the following cases:
|
||||
* 1. For FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs
|
||||
* 2. For FSCTL_QUERY_NETWORK_INTERFACE_INFO IOCTL when called from
|
||||
* smb2_reconnect (indicated by CIFS_SES_FLAG_SCALE_CHANNELS ses flag)
|
||||
*/
|
||||
if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO ||
|
||||
(opcode == FSCTL_QUERY_NETWORK_INTERFACE_INFO &&
|
||||
(tcon->ses->flags & CIFS_SES_FLAGS_PENDING_QUERY_INTERFACES)))
|
||||
return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
|
||||
request_buf, total_len);
|
||||
}
|
||||
|
||||
return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
|
||||
request_buf, total_len);
|
||||
}
|
||||
|
@ -4449,10 +4463,10 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
|
|||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
/*
|
||||
* If we want to do a RDMA write, fill in and append
|
||||
* smbd_buffer_descriptor_v1 to the end of read request
|
||||
* smbdirect_buffer_descriptor_v1 to the end of read request
|
||||
*/
|
||||
if (rdata && smb3_use_rdma_offload(io_parms)) {
|
||||
struct smbd_buffer_descriptor_v1 *v1;
|
||||
struct smbdirect_buffer_descriptor_v1 *v1;
|
||||
bool need_invalidate = server->dialect == SMB30_PROT_ID;
|
||||
|
||||
rdata->mr = smbd_register_mr(server->smbd_conn, &rdata->subreq.io_iter,
|
||||
|
@ -4466,8 +4480,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
|
|||
req->ReadChannelInfoOffset =
|
||||
cpu_to_le16(offsetof(struct smb2_read_req, Buffer));
|
||||
req->ReadChannelInfoLength =
|
||||
cpu_to_le16(sizeof(struct smbd_buffer_descriptor_v1));
|
||||
v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0];
|
||||
cpu_to_le16(sizeof(struct smbdirect_buffer_descriptor_v1));
|
||||
v1 = (struct smbdirect_buffer_descriptor_v1 *) &req->Buffer[0];
|
||||
v1->offset = cpu_to_le64(rdata->mr->mr->iova);
|
||||
v1->token = cpu_to_le32(rdata->mr->mr->rkey);
|
||||
v1->length = cpu_to_le32(rdata->mr->mr->length);
|
||||
|
@ -4975,10 +4989,10 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
|||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
/*
|
||||
* If we want to do a server RDMA read, fill in and append
|
||||
* smbd_buffer_descriptor_v1 to the end of write request
|
||||
* smbdirect_buffer_descriptor_v1 to the end of write request
|
||||
*/
|
||||
if (smb3_use_rdma_offload(io_parms)) {
|
||||
struct smbd_buffer_descriptor_v1 *v1;
|
||||
struct smbdirect_buffer_descriptor_v1 *v1;
|
||||
bool need_invalidate = server->dialect == SMB30_PROT_ID;
|
||||
|
||||
wdata->mr = smbd_register_mr(server->smbd_conn, &wdata->subreq.io_iter,
|
||||
|
@ -4997,8 +5011,8 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
|
|||
req->WriteChannelInfoOffset =
|
||||
cpu_to_le16(offsetof(struct smb2_write_req, Buffer));
|
||||
req->WriteChannelInfoLength =
|
||||
cpu_to_le16(sizeof(struct smbd_buffer_descriptor_v1));
|
||||
v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0];
|
||||
cpu_to_le16(sizeof(struct smbdirect_buffer_descriptor_v1));
|
||||
v1 = (struct smbdirect_buffer_descriptor_v1 *) &req->Buffer[0];
|
||||
v1->offset = cpu_to_le64(wdata->mr->mr->iova);
|
||||
v1->token = cpu_to_le32(wdata->mr->mr->rkey);
|
||||
v1->length = cpu_to_le32(wdata->mr->mr->length);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,6 +15,9 @@
|
|||
#include <rdma/rdma_cm.h>
|
||||
#include <linux/mempool.h>
|
||||
|
||||
#include "../common/smbdirect/smbdirect.h"
|
||||
#include "../common/smbdirect/smbdirect_socket.h"
|
||||
|
||||
extern int rdma_readwrite_threshold;
|
||||
extern int smbd_max_frmr_depth;
|
||||
extern int smbd_keep_alive_interval;
|
||||
|
@ -50,14 +53,8 @@ enum smbd_connection_status {
|
|||
* 5. mempools for allocating packets
|
||||
*/
|
||||
struct smbd_connection {
|
||||
enum smbd_connection_status transport_status;
|
||||
struct smbdirect_socket socket;
|
||||
|
||||
/* RDMA related */
|
||||
struct rdma_cm_id *id;
|
||||
struct ib_qp_init_attr qp_attr;
|
||||
struct ib_pd *pd;
|
||||
struct ib_cq *send_cq, *recv_cq;
|
||||
struct ib_device_attr dev_attr;
|
||||
int ri_rc;
|
||||
struct completion ri_done;
|
||||
wait_queue_head_t conn_wait;
|
||||
|
@ -72,15 +69,7 @@ struct smbd_connection {
|
|||
spinlock_t lock_new_credits_offered;
|
||||
int new_credits_offered;
|
||||
|
||||
/* Connection parameters defined in [MS-SMBD] 3.1.1.1 */
|
||||
int receive_credit_max;
|
||||
int send_credit_target;
|
||||
int max_send_size;
|
||||
int max_fragmented_recv_size;
|
||||
int max_fragmented_send_size;
|
||||
int max_receive_size;
|
||||
int keep_alive_interval;
|
||||
int max_readwrite_size;
|
||||
/* dynamic connection parameters defined in [MS-SMBD] 3.1.1.1 */
|
||||
enum keep_alive_status keep_alive_requested;
|
||||
int protocol;
|
||||
atomic_t send_credits;
|
||||
|
@ -177,54 +166,6 @@ enum smbd_message_type {
|
|||
SMBD_TRANSFER_DATA,
|
||||
};
|
||||
|
||||
#define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
|
||||
|
||||
/* SMBD negotiation request packet [MS-SMBD] 2.2.1 */
|
||||
struct smbd_negotiate_req {
|
||||
__le16 min_version;
|
||||
__le16 max_version;
|
||||
__le16 reserved;
|
||||
__le16 credits_requested;
|
||||
__le32 preferred_send_size;
|
||||
__le32 max_receive_size;
|
||||
__le32 max_fragmented_size;
|
||||
} __packed;
|
||||
|
||||
/* SMBD negotiation response packet [MS-SMBD] 2.2.2 */
|
||||
struct smbd_negotiate_resp {
|
||||
__le16 min_version;
|
||||
__le16 max_version;
|
||||
__le16 negotiated_version;
|
||||
__le16 reserved;
|
||||
__le16 credits_requested;
|
||||
__le16 credits_granted;
|
||||
__le32 status;
|
||||
__le32 max_readwrite_size;
|
||||
__le32 preferred_send_size;
|
||||
__le32 max_receive_size;
|
||||
__le32 max_fragmented_size;
|
||||
} __packed;
|
||||
|
||||
/* SMBD data transfer packet with payload [MS-SMBD] 2.2.3 */
|
||||
struct smbd_data_transfer {
|
||||
__le16 credits_requested;
|
||||
__le16 credits_granted;
|
||||
__le16 flags;
|
||||
__le16 reserved;
|
||||
__le32 remaining_data_length;
|
||||
__le32 data_offset;
|
||||
__le32 data_length;
|
||||
__le32 padding;
|
||||
__u8 buffer[];
|
||||
} __packed;
|
||||
|
||||
/* The packet fields for a registered RDMA buffer */
|
||||
struct smbd_buffer_descriptor_v1 {
|
||||
__le64 offset;
|
||||
__le32 token;
|
||||
__le32 length;
|
||||
} __packed;
|
||||
|
||||
/* Maximum number of SGEs used by smbdirect.c in any send work request */
|
||||
#define SMBDIRECT_MAX_SEND_SGE 6
|
||||
|
||||
|
|
|
@ -1018,14 +1018,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
|
|||
uint index = 0;
|
||||
unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
|
||||
struct TCP_Server_Info *server = NULL;
|
||||
int i;
|
||||
int i, start, cur;
|
||||
|
||||
if (!ses)
|
||||
return NULL;
|
||||
|
||||
spin_lock(&ses->chan_lock);
|
||||
start = atomic_inc_return(&ses->chan_seq);
|
||||
for (i = 0; i < ses->chan_count; i++) {
|
||||
server = ses->chans[i].server;
|
||||
cur = (start + i) % ses->chan_count;
|
||||
server = ses->chans[cur].server;
|
||||
if (!server || server->terminate)
|
||||
continue;
|
||||
|
||||
|
@ -1042,17 +1044,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
|
|||
*/
|
||||
if (server->in_flight < min_in_flight) {
|
||||
min_in_flight = server->in_flight;
|
||||
index = i;
|
||||
index = cur;
|
||||
}
|
||||
if (server->in_flight > max_in_flight)
|
||||
max_in_flight = server->in_flight;
|
||||
}
|
||||
|
||||
/* if all channels are equally loaded, fall back to round-robin */
|
||||
if (min_in_flight == max_in_flight) {
|
||||
index = (uint)atomic_inc_return(&ses->chan_seq);
|
||||
index %= ses->chan_count;
|
||||
}
|
||||
if (min_in_flight == max_in_flight)
|
||||
index = (uint)start % ses->chan_count;
|
||||
|
||||
server = ses->chans[index].server;
|
||||
spin_unlock(&ses->chan_lock);
|
||||
|
|
37
fs/smb/common/smbdirect/smbdirect.h
Normal file
37
fs/smb/common/smbdirect/smbdirect.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2017, Microsoft Corporation.
|
||||
* Copyright (C) 2018, LG Electronics.
|
||||
*/
|
||||
|
||||
#ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_H__
|
||||
#define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_H__
|
||||
|
||||
/* SMB-DIRECT buffer descriptor V1 structure [MS-SMBD] 2.2.3.1 */
|
||||
struct smbdirect_buffer_descriptor_v1 {
|
||||
__le64 offset;
|
||||
__le32 token;
|
||||
__le32 length;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Connection parameters mostly from [MS-SMBD] 3.1.1.1
|
||||
*
|
||||
* These are setup and negotiated at the beginning of a
|
||||
* connection and remain constant unless explicitly changed.
|
||||
*
|
||||
* Some values are important for the upper layer.
|
||||
*/
|
||||
struct smbdirect_socket_parameters {
|
||||
__u16 recv_credit_max;
|
||||
__u16 send_credit_target;
|
||||
__u32 max_send_size;
|
||||
__u32 max_fragmented_send_size;
|
||||
__u32 max_recv_size;
|
||||
__u32 max_fragmented_recv_size;
|
||||
__u32 max_read_write_size;
|
||||
__u32 keepalive_interval_msec;
|
||||
__u32 keepalive_timeout_msec;
|
||||
} __packed;
|
||||
|
||||
#endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_H__ */
|
55
fs/smb/common/smbdirect/smbdirect_pdu.h
Normal file
55
fs/smb/common/smbdirect/smbdirect_pdu.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2017 Stefan Metzmacher
|
||||
*/
|
||||
|
||||
#ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_PDU_H__
|
||||
#define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_PDU_H__
|
||||
|
||||
#define SMBDIRECT_V1 0x0100
|
||||
|
||||
/* SMBD negotiation request packet [MS-SMBD] 2.2.1 */
|
||||
struct smbdirect_negotiate_req {
|
||||
__le16 min_version;
|
||||
__le16 max_version;
|
||||
__le16 reserved;
|
||||
__le16 credits_requested;
|
||||
__le32 preferred_send_size;
|
||||
__le32 max_receive_size;
|
||||
__le32 max_fragmented_size;
|
||||
} __packed;
|
||||
|
||||
/* SMBD negotiation response packet [MS-SMBD] 2.2.2 */
|
||||
struct smbdirect_negotiate_resp {
|
||||
__le16 min_version;
|
||||
__le16 max_version;
|
||||
__le16 negotiated_version;
|
||||
__le16 reserved;
|
||||
__le16 credits_requested;
|
||||
__le16 credits_granted;
|
||||
__le32 status;
|
||||
__le32 max_readwrite_size;
|
||||
__le32 preferred_send_size;
|
||||
__le32 max_receive_size;
|
||||
__le32 max_fragmented_size;
|
||||
} __packed;
|
||||
|
||||
#define SMBDIRECT_DATA_MIN_HDR_SIZE 0x14
|
||||
#define SMBDIRECT_DATA_OFFSET 0x18
|
||||
|
||||
#define SMBDIRECT_FLAG_RESPONSE_REQUESTED 0x0001
|
||||
|
||||
/* SMBD data transfer packet with payload [MS-SMBD] 2.2.3 */
|
||||
struct smbdirect_data_transfer {
|
||||
__le16 credits_requested;
|
||||
__le16 credits_granted;
|
||||
__le16 flags;
|
||||
__le16 reserved;
|
||||
__le32 remaining_data_length;
|
||||
__le32 data_offset;
|
||||
__le32 data_length;
|
||||
__le32 padding;
|
||||
__u8 buffer[];
|
||||
} __packed;
|
||||
|
||||
#endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_PDU_H__ */
|
43
fs/smb/common/smbdirect/smbdirect_socket.h
Normal file
43
fs/smb/common/smbdirect/smbdirect_socket.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2025 Stefan Metzmacher
|
||||
*/
|
||||
|
||||
#ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
|
||||
#define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
|
||||
|
||||
enum smbdirect_socket_status {
|
||||
SMBDIRECT_SOCKET_CREATED,
|
||||
SMBDIRECT_SOCKET_CONNECTING,
|
||||
SMBDIRECT_SOCKET_CONNECTED,
|
||||
SMBDIRECT_SOCKET_NEGOTIATE_FAILED,
|
||||
SMBDIRECT_SOCKET_DISCONNECTING,
|
||||
SMBDIRECT_SOCKET_DISCONNECTED,
|
||||
SMBDIRECT_SOCKET_DESTROYED
|
||||
};
|
||||
|
||||
struct smbdirect_socket {
|
||||
enum smbdirect_socket_status status;
|
||||
|
||||
/* RDMA related */
|
||||
struct {
|
||||
struct rdma_cm_id *cm_id;
|
||||
} rdma;
|
||||
|
||||
/* IB verbs related */
|
||||
struct {
|
||||
struct ib_pd *pd;
|
||||
struct ib_cq *send_cq;
|
||||
struct ib_cq *recv_cq;
|
||||
|
||||
/*
|
||||
* shortcuts for rdma.cm_id->{qp,device};
|
||||
*/
|
||||
struct ib_qp *qp;
|
||||
struct ib_device *dev;
|
||||
} ib;
|
||||
|
||||
struct smbdirect_socket_parameters parameters;
|
||||
};
|
||||
|
||||
#endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */
|
Loading…
Add table
Reference in a new issue