large set of small restructuring smbdirect related patches moving ksmbd and client code to common code for smbdirect

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmjZ5tQACgkQiiy9cAdy
 T1GB2wv8D5slPmD1Ytx9r4jU8ZjYwXQ6SXf97MOnUvk2zFqdBxxCsPTv0H24lhMI
 jl7/3pKjTXMM9uWyTXIJ4hpNNj6sB4GSLFiRxHyUOtwIr9RgOPUYYv80P16MFq3O
 3AIDhGgwEqhrCtGmRef4ahQ9lcmSLqKa+kbmDY3tmOtZJ8gPuNXGh7TiZ7G9adK2
 sSicxowTu0sTrzF3lPn3nyDU2YXDj8aDHAzbe8Op7bvl7DtHlN6wzIT4hakBIHJg
 X6RbWFz1Lw6BCz1C8lme8qxglCbNsfxb1ahkEqAk4VtX9n2OhyKepeA6FfKWsU+/
 tgH9IYaTTwosrWmbDsjwhVpv/0xuAHdDHjp3n08U86PfD3C6Fjvh5kpmLi6JMkzI
 xXyVkDVvXJ40/7gZIcFXZcrLYn8uQiYI/Of2JJv2PYAI5lRrWCLAV/9OFwUq+GZx
 szzQbpBI3UfKMPUDTFAFGLRQHIXg9b9cYHNb7di5zR1Pt+SCd8bS3aoMyTW0sKo2
 bnhFfQde
 =Y1f0
 -----END PGP SIGNATURE-----

Merge tag 'v6.18-rc-part1-smb3-common' of git://git.samba.org/ksmbd

Pull smb restructuring updates from Steve French:
 "Large set of small restructuring smbdirect related patches for cifs.ko
  and ksmbd.ko.

  This is the next step in order to use common structures for smbdirect
  handling across both modules. And also includes improved handling of
  broken connections, as well as fixed negotiation as rdma resources.

  Moving to common functions is planned for 6.19, as well as also
  providing smbdirect via sockets to userspace (e.g. for samba to also
  be able to use smbdirect for userspace server and userspace client
  tools).

  This was heavily reviewed and tested at the recent SMB3.1.1 test event
  at SDC"

* tag 'v6.18-rc-part1-smb3-common' of git://git.samba.org/ksmbd: (159 commits)
  smb: server: let smb_direct_flush_send_list() invalidate a remote key first
  smb: server: make use of ib_alloc_cq_any() instead of ib_alloc_cq()
  smb: server: make consitent use of spin_lock_irq{save,restore}() in transport_rdma.c
  smb: server: let {free_transport,smb_direct_disconnect_rdma_{work,connection}}() wake up all wait queues
  smb: server: let smb_direct_disconnect_rdma_connection() disable all work but disconnect_work
  smb: server: fill in smbdirect_socket.first_error on error
  smb: server: let smb_direct_disconnect_rdma_connection() set SMBDIRECT_SOCKET_ERROR...
  smb: server: pass struct smbdirect_socket to smb_direct_send_negotiate_response()
  smb: server: pass struct smbdirect_socket to {enqueue,get_first}_reassembly()
  smb: server: pass struct smbdirect_socket to smb_direct_post_send_data()
  smb: server: pass struct smbdirect_socket to post_sendmsg()
  smb: server: pass struct smbdirect_socket to smb_direct_create_header()
  smb: server: pass struct smbdirect_socket to manage_keep_alive_before_sending()
  smb: server: pass struct smbdirect_socket to manage_credits_prior_sending()
  smb: server: pass struct smbdirect_socket to calc_rw_credits()
  smb: server: pass struct smbdirect_socket to wait_for_rw_credits()
  smb: server: pass struct smbdirect_socket to wait_for_send_credits()
  smb: server: pass struct smbdirect_socket to wait_for_credits()
  smb: server: pass struct smbdirect_socket to smb_direct_flush_send_list()
  smb: server: pass struct smbdirect_socket to smb_direct_post_send()
  ...
This commit is contained in:
Linus Torvalds 2025-09-29 14:57:08 -07:00
commit a9401710a5
16 changed files with 2071 additions and 1396 deletions

View File

@ -24,6 +24,7 @@
#endif
#ifdef CONFIG_CIFS_SMB_DIRECT
#include "smbdirect.h"
#include "../common/smbdirect/smbdirect_pdu.h"
#endif
#include "cifs_swn.h"
#include "cached_dir.h"
@ -456,57 +457,55 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
sc = &server->smbd_conn->socket;
sp = &sc->parameters;
seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
"transport status: %x",
server->smbd_conn->protocol,
server->smbd_conn->socket.status);
seq_printf(m, "\nConn receive_credit_max: %x "
"send_credit_target: %x max_send_size: %x",
seq_printf(m, "\nSMBDirect protocol version: 0x%x "
"transport status: %s (%u)",
SMBDIRECT_V1,
smbdirect_socket_status_string(sc->status),
sc->status);
seq_printf(m, "\nConn receive_credit_max: %u "
"send_credit_target: %u max_send_size: %u",
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",
seq_printf(m, "\nConn max_fragmented_recv_size: %u "
"max_fragmented_send_size: %u max_receive_size:%u",
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",
seq_printf(m, "\nConn keep_alive_interval: %u "
"max_readwrite_size: %u rdma_readwrite_threshold: %u",
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",
server->smbd_conn->count_get_receive_buffer,
server->smbd_conn->count_put_receive_buffer,
server->smbd_conn->count_send_empty);
seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
"count_enqueue_reassembly_queue: %x "
"count_dequeue_reassembly_queue: %x "
"reassembly_data_length: %x "
"reassembly_queue_length: %x",
server->smbd_conn->count_reassembly_queue,
server->smbd_conn->count_enqueue_reassembly_queue,
server->smbd_conn->count_dequeue_reassembly_queue,
server->rdma_readwrite_threshold);
seq_printf(m, "\nDebug count_get_receive_buffer: %llu "
"count_put_receive_buffer: %llu count_send_empty: %llu",
sc->statistics.get_receive_buffer,
sc->statistics.put_receive_buffer,
sc->statistics.send_empty);
seq_printf(m, "\nRead Queue "
"count_enqueue_reassembly_queue: %llu "
"count_dequeue_reassembly_queue: %llu "
"reassembly_data_length: %u "
"reassembly_queue_length: %u",
sc->statistics.enqueue_reassembly_queue,
sc->statistics.dequeue_reassembly_queue,
sc->recv_io.reassembly.data_length,
sc->recv_io.reassembly.queue_length);
seq_printf(m, "\nCurrent Credits send_credits: %x "
"receive_credits: %x receive_credit_target: %x",
atomic_read(&server->smbd_conn->send_credits),
atomic_read(&server->smbd_conn->receive_credits),
server->smbd_conn->receive_credit_target);
seq_printf(m, "\nPending send_pending: %x ",
atomic_read(&server->smbd_conn->send_pending));
seq_printf(m, "\nReceive buffers count_receive_queue: %x ",
server->smbd_conn->count_receive_queue);
seq_printf(m, "\nMR responder_resources: %x "
"max_frmr_depth: %x mr_type: %x",
server->smbd_conn->responder_resources,
server->smbd_conn->max_frmr_depth,
server->smbd_conn->mr_type);
seq_printf(m, "\nMR mr_ready_count: %x mr_used_count: %x",
atomic_read(&server->smbd_conn->mr_ready_count),
atomic_read(&server->smbd_conn->mr_used_count));
seq_printf(m, "\nCurrent Credits send_credits: %u "
"receive_credits: %u receive_credit_target: %u",
atomic_read(&sc->send_io.credits.count),
atomic_read(&sc->recv_io.credits.count),
sc->recv_io.credits.target);
seq_printf(m, "\nPending send_pending: %u ",
atomic_read(&sc->send_io.pending.count));
seq_printf(m, "\nMR responder_resources: %u "
"max_frmr_depth: %u mr_type: 0x%x",
sp->responder_resources,
sp->max_frmr_depth,
sc->mr_io.type);
seq_printf(m, "\nMR mr_ready_count: %u mr_used_count: %u",
atomic_read(&sc->mr_io.ready.count),
atomic_read(&sc->mr_io.used.count));
skip_rdma:
#endif
seq_printf(m, "\nNumber of credits: %d,%d,%d Dialect 0x%x",

View File

@ -814,6 +814,13 @@ struct TCP_Server_Info {
unsigned int max_read;
unsigned int max_write;
unsigned int min_offload;
/*
* If payload is less than or equal to the threshold,
* use RDMA send/recv to send upper layer I/O.
* If payload is more than the threshold,
* use RDMA read/write through memory registration for I/O.
*/
unsigned int rdma_readwrite_threshold;
unsigned int retrans;
struct {
bool requested; /* "compress" mount option set*/
@ -1540,7 +1547,7 @@ struct cifs_io_subrequest {
struct kvec iov[2];
struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
struct smbdirect_mr_io *mr;
#endif
struct cifs_credits credits;
};

View File

@ -97,8 +97,12 @@ static void cifs_prepare_write(struct netfs_io_subrequest *subreq)
cifs_trace_rw_credits_write_prepare);
#ifdef CONFIG_CIFS_SMB_DIRECT
if (server->smbd_conn)
stream->sreq_max_segs = server->smbd_conn->max_frmr_depth;
if (server->smbd_conn) {
const struct smbdirect_socket_parameters *sp =
smbd_get_parameters(server->smbd_conn);
stream->sreq_max_segs = sp->max_frmr_depth;
}
#endif
}
@ -187,8 +191,12 @@ static int cifs_prepare_read(struct netfs_io_subrequest *subreq)
cifs_trace_rw_credits_read_submit);
#ifdef CONFIG_CIFS_SMB_DIRECT
if (server->smbd_conn)
rreq->io_streams[0].sreq_max_segs = server->smbd_conn->max_frmr_depth;
if (server->smbd_conn) {
const struct smbdirect_socket_parameters *sp =
smbd_get_parameters(server->smbd_conn);
rreq->io_streams[0].sreq_max_segs = sp->max_frmr_depth;
}
#endif
return 0;
}

View File

@ -504,8 +504,8 @@ 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;
const struct smbdirect_socket_parameters *sp =
smbd_get_parameters(server->smbd_conn);
if (server->sign)
/*
@ -555,8 +555,8 @@ 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;
const struct smbdirect_socket_parameters *sp =
smbd_get_parameters(server->smbd_conn);
if (server->sign)
/*

View File

@ -4411,7 +4411,7 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
return false;
/* offload also has its overhead, so only do it if desired */
if (io_parms->length < server->smbd_conn->rdma_readwrite_threshold)
if (io_parms->length < server->rdma_readwrite_threshold)
return false;
return true;

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,6 @@ extern int smbd_max_send_size;
extern int smbd_send_credit_target;
extern int smbd_receive_credit_max;
enum keep_alive_status {
KEEP_ALIVE_NONE,
KEEP_ALIVE_PENDING,
KEEP_ALIVE_SENT,
};
/*
* The context for the SMBDirect transport
* Everything related to the transport is here. It has several logical parts
@ -44,79 +38,14 @@ enum keep_alive_status {
*/
struct smbd_connection {
struct smbdirect_socket socket;
int ri_rc;
struct completion ri_done;
wait_queue_head_t status_wait;
struct completion negotiate_completion;
bool negotiate_done;
struct work_struct disconnect_work;
struct work_struct post_send_credits_work;
spinlock_t lock_new_credits_offered;
int new_credits_offered;
/* dynamic connection parameters defined in [MS-SMBD] 3.1.1.1 */
enum keep_alive_status keep_alive_requested;
int protocol;
atomic_t send_credits;
atomic_t receive_credits;
int receive_credit_target;
/* Memory registrations */
/* Maximum number of RDMA read/write outstanding on this connection */
int responder_resources;
/* Maximum number of pages in a single RDMA write/read on this connection */
int max_frmr_depth;
/*
* If payload is less than or equal to the threshold,
* use RDMA send/recv to send upper layer I/O.
* If payload is more than the threshold,
* use RDMA read/write through memory registration for I/O.
*/
int rdma_readwrite_threshold;
enum ib_mr_type mr_type;
struct list_head mr_list;
spinlock_t mr_list_lock;
/* The number of available MRs ready for memory registration */
atomic_t mr_ready_count;
atomic_t mr_used_count;
wait_queue_head_t wait_mr;
struct work_struct mr_recovery_work;
/* Used by transport to wait until all MRs are returned */
wait_queue_head_t wait_for_mr_cleanup;
/* Activity accounting */
atomic_t send_pending;
wait_queue_head_t wait_send_pending;
wait_queue_head_t wait_post_send;
/* Receive queue */
int count_receive_queue;
wait_queue_head_t wait_receive_queues;
bool send_immediate;
wait_queue_head_t wait_send_queue;
struct workqueue_struct *workqueue;
struct delayed_work idle_timer_work;
/* for debug purposes */
unsigned int count_get_receive_buffer;
unsigned int count_put_receive_buffer;
unsigned int count_reassembly_queue;
unsigned int count_enqueue_reassembly_queue;
unsigned int count_dequeue_reassembly_queue;
unsigned int count_send_empty;
};
/* Create a SMBDirect session */
struct smbd_connection *smbd_get_connection(
struct TCP_Server_Info *server, struct sockaddr *dstaddr);
const struct smbdirect_socket_parameters *smbd_get_parameters(struct smbd_connection *conn);
/* Reconnect SMBDirect session */
int smbd_reconnect(struct TCP_Server_Info *server);
/* Destroy SMBDirect session */
@ -127,34 +56,11 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
int smbd_send(struct TCP_Server_Info *server,
int num_rqst, struct smb_rqst *rqst);
enum mr_state {
MR_READY,
MR_REGISTERED,
MR_INVALIDATED,
MR_ERROR
};
struct smbd_mr {
struct smbd_connection *conn;
struct list_head list;
enum mr_state state;
struct ib_mr *mr;
struct sg_table sgt;
enum dma_data_direction dir;
union {
struct ib_reg_wr wr;
struct ib_send_wr inv_wr;
};
struct ib_cqe cqe;
bool need_invalidate;
struct completion invalidate_done;
};
/* Interfaces to register and deregister MR for RDMA read/write */
struct smbd_mr *smbd_register_mr(
struct smbdirect_mr_io *smbd_register_mr(
struct smbd_connection *info, struct iov_iter *iter,
bool writing, bool need_invalidate);
int smbd_deregister_mr(struct smbd_mr *mr);
int smbd_deregister_mr(struct smbdirect_mr_io *mr);
#else
#define cifs_rdma_enabled(server) 0

View File

@ -23,6 +23,12 @@ struct smbdirect_buffer_descriptor_v1 {
* Some values are important for the upper layer.
*/
struct smbdirect_socket_parameters {
__u32 resolve_addr_timeout_msec;
__u32 resolve_route_timeout_msec;
__u32 rdma_connect_timeout_msec;
__u32 negotiate_timeout_msec;
__u8 initiator_depth;
__u8 responder_resources;
__u16 recv_credit_max;
__u16 send_credit_target;
__u32 max_send_size;
@ -30,6 +36,7 @@ struct smbdirect_socket_parameters {
__u32 max_recv_size;
__u32 max_fragmented_recv_size;
__u32 max_read_write_size;
__u32 max_frmr_depth;
__u32 keepalive_interval_msec;
__u32 keepalive_timeout_msec;
} __packed;

View File

@ -6,22 +6,102 @@
#ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
#define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
#include <rdma/rw.h>
enum smbdirect_socket_status {
SMBDIRECT_SOCKET_CREATED,
SMBDIRECT_SOCKET_CONNECTING,
SMBDIRECT_SOCKET_CONNECTED,
SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED,
SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING,
SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED,
SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED,
SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING,
SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED,
SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED,
SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING,
SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED,
SMBDIRECT_SOCKET_NEGOTIATE_NEEDED,
SMBDIRECT_SOCKET_NEGOTIATE_RUNNING,
SMBDIRECT_SOCKET_NEGOTIATE_FAILED,
SMBDIRECT_SOCKET_CONNECTED,
SMBDIRECT_SOCKET_ERROR,
SMBDIRECT_SOCKET_DISCONNECTING,
SMBDIRECT_SOCKET_DISCONNECTED,
SMBDIRECT_SOCKET_DESTROYED
};
static __always_inline
const char *smbdirect_socket_status_string(enum smbdirect_socket_status status)
{
switch (status) {
case SMBDIRECT_SOCKET_CREATED:
return "CREATED";
case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED:
return "RESOLVE_ADDR_NEEDED";
case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING:
return "RESOLVE_ADDR_RUNNING";
case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
return "RESOLVE_ADDR_FAILED";
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED:
return "RESOLVE_ROUTE_NEEDED";
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING:
return "RESOLVE_ROUTE_RUNNING";
case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
return "RESOLVE_ROUTE_FAILED";
case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED:
return "RDMA_CONNECT_NEEDED";
case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING:
return "RDMA_CONNECT_RUNNING";
case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED:
return "RDMA_CONNECT_FAILED";
case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
return "NEGOTIATE_NEEDED";
case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
return "NEGOTIATE_RUNNING";
case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
return "NEGOTIATE_FAILED";
case SMBDIRECT_SOCKET_CONNECTED:
return "CONNECTED";
case SMBDIRECT_SOCKET_ERROR:
return "ERROR";
case SMBDIRECT_SOCKET_DISCONNECTING:
return "DISCONNECTING";
case SMBDIRECT_SOCKET_DISCONNECTED:
return "DISCONNECTED";
case SMBDIRECT_SOCKET_DESTROYED:
return "DESTROYED";
}
return "<unknown>";
}
enum smbdirect_keepalive_status {
SMBDIRECT_KEEPALIVE_NONE,
SMBDIRECT_KEEPALIVE_PENDING,
SMBDIRECT_KEEPALIVE_SENT
};
struct smbdirect_socket {
enum smbdirect_socket_status status;
wait_queue_head_t status_wait;
int first_error;
/*
* This points to the workqueue to
* be used for this socket.
* It can be per socket (on the client)
* or point to a global workqueue (on the server)
*/
struct workqueue_struct *workqueue;
struct work_struct disconnect_work;
/* RDMA related */
struct {
struct rdma_cm_id *cm_id;
/*
* This is for iWarp MPA v1
*/
bool legacy_iwarp;
} rdma;
/* IB verbs related */
@ -39,6 +119,15 @@ struct smbdirect_socket {
struct smbdirect_socket_parameters parameters;
/*
* The state for keepalive and timeout handling
*/
struct {
enum smbdirect_keepalive_status keepalive;
struct work_struct immediate_work;
struct delayed_work timer_work;
} idle;
/*
* The state for posted send buffers
*/
@ -51,6 +140,29 @@ struct smbdirect_socket {
struct kmem_cache *cache;
mempool_t *pool;
} mem;
/*
* The credit state for the send side
*/
struct {
atomic_t count;
wait_queue_head_t wait_queue;
} credits;
/*
* The state about posted/pending sends
*/
struct {
atomic_t count;
/*
* woken when count is decremented
*/
wait_queue_head_t dec_wait_queue;
/*
* woken when count reached zero
*/
wait_queue_head_t zero_wait_queue;
} pending;
} send_io;
/*
@ -84,6 +196,23 @@ struct smbdirect_socket {
spinlock_t lock;
} free;
/*
* The state for posted recv_io messages
* and the refill work struct.
*/
struct {
atomic_t count;
struct work_struct refill_work;
} posted;
/*
* The credit state for the recv side
*/
struct {
u16 target;
atomic_t count;
} credits;
/*
* The list of arrived non-empty smbdirect_recv_io
* structures
@ -110,8 +239,137 @@ struct smbdirect_socket {
bool full_packet_received;
} reassembly;
} recv_io;
/*
* The state for Memory registrations on the client
*/
struct {
enum ib_mr_type type;
/*
* The list of free smbdirect_mr_io
* structures
*/
struct {
struct list_head list;
spinlock_t lock;
} all;
/*
* The number of available MRs ready for memory registration
*/
struct {
atomic_t count;
wait_queue_head_t wait_queue;
} ready;
/*
* The number of used MRs
*/
struct {
atomic_t count;
} used;
struct work_struct recovery_work;
/* Used by transport to wait until all MRs are returned */
struct {
wait_queue_head_t wait_queue;
} cleanup;
} mr_io;
/*
* The state for RDMA read/write requests on the server
*/
struct {
/*
* The credit state for the send side
*/
struct {
/*
* The maximum number of rw credits
*/
size_t max;
/*
* The number of pages per credit
*/
size_t num_pages;
atomic_t count;
wait_queue_head_t wait_queue;
} credits;
} rw_io;
/*
* For debug purposes
*/
struct {
u64 get_receive_buffer;
u64 put_receive_buffer;
u64 enqueue_reassembly_queue;
u64 dequeue_reassembly_queue;
u64 send_empty;
} statistics;
};
static void __smbdirect_socket_disabled_work(struct work_struct *work)
{
/*
* Should never be called as disable_[delayed_]work_sync() was used.
*/
WARN_ON_ONCE(1);
}
static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
{
/*
* This also sets status = SMBDIRECT_SOCKET_CREATED
*/
BUILD_BUG_ON(SMBDIRECT_SOCKET_CREATED != 0);
memset(sc, 0, sizeof(*sc));
init_waitqueue_head(&sc->status_wait);
INIT_WORK(&sc->disconnect_work, __smbdirect_socket_disabled_work);
disable_work_sync(&sc->disconnect_work);
INIT_WORK(&sc->idle.immediate_work, __smbdirect_socket_disabled_work);
disable_work_sync(&sc->idle.immediate_work);
INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work);
disable_delayed_work_sync(&sc->idle.timer_work);
atomic_set(&sc->send_io.credits.count, 0);
init_waitqueue_head(&sc->send_io.credits.wait_queue);
atomic_set(&sc->send_io.pending.count, 0);
init_waitqueue_head(&sc->send_io.pending.dec_wait_queue);
init_waitqueue_head(&sc->send_io.pending.zero_wait_queue);
INIT_LIST_HEAD(&sc->recv_io.free.list);
spin_lock_init(&sc->recv_io.free.lock);
atomic_set(&sc->recv_io.posted.count, 0);
INIT_WORK(&sc->recv_io.posted.refill_work, __smbdirect_socket_disabled_work);
disable_work_sync(&sc->recv_io.posted.refill_work);
atomic_set(&sc->recv_io.credits.count, 0);
INIT_LIST_HEAD(&sc->recv_io.reassembly.list);
spin_lock_init(&sc->recv_io.reassembly.lock);
init_waitqueue_head(&sc->recv_io.reassembly.wait_queue);
atomic_set(&sc->rw_io.credits.count, 0);
init_waitqueue_head(&sc->rw_io.credits.wait_queue);
spin_lock_init(&sc->mr_io.all.lock);
INIT_LIST_HEAD(&sc->mr_io.all.list);
atomic_set(&sc->mr_io.ready.count, 0);
init_waitqueue_head(&sc->mr_io.ready.wait_queue);
atomic_set(&sc->mr_io.used.count, 0);
INIT_WORK(&sc->mr_io.recovery_work, __smbdirect_socket_disabled_work);
disable_work_sync(&sc->mr_io.recovery_work);
init_waitqueue_head(&sc->mr_io.cleanup.wait_queue);
}
struct smbdirect_send_io {
struct smbdirect_socket *socket;
struct ib_cqe cqe;
@ -136,6 +394,23 @@ struct smbdirect_send_io {
u8 packet[];
};
struct smbdirect_send_batch {
/*
* List of smbdirect_send_io messages
*/
struct list_head msg_list;
/*
* Number of list entries
*/
size_t wr_cnt;
/*
* Possible remote key invalidation state
*/
bool need_invalidate_rkey;
u32 remote_key;
};
struct smbdirect_recv_io {
struct smbdirect_socket *socket;
struct ib_cqe cqe;
@ -158,4 +433,44 @@ struct smbdirect_recv_io {
u8 packet[];
};
enum smbdirect_mr_state {
SMBDIRECT_MR_READY,
SMBDIRECT_MR_REGISTERED,
SMBDIRECT_MR_INVALIDATED,
SMBDIRECT_MR_ERROR
};
struct smbdirect_mr_io {
struct smbdirect_socket *socket;
struct ib_cqe cqe;
struct list_head list;
enum smbdirect_mr_state state;
struct ib_mr *mr;
struct sg_table sgt;
enum dma_data_direction dir;
union {
struct ib_reg_wr wr;
struct ib_send_wr inv_wr;
};
bool need_invalidate;
struct completion invalidate_done;
};
struct smbdirect_rw_io {
struct smbdirect_socket *socket;
struct ib_cqe cqe;
struct list_head list;
int error;
struct completion *completion;
struct rdma_rw_ctx rdma_ctx;
struct sg_table sgt;
struct scatterlist sg_list[];
};
#endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */

View File

@ -243,7 +243,7 @@ int ksmbd_conn_write(struct ksmbd_work *work)
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
void *buf, unsigned int buflen,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len)
{
int ret = -EINVAL;
@ -257,7 +257,7 @@ int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
void *buf, unsigned int buflen,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len)
{
int ret = -EINVAL;

View File

@ -19,6 +19,8 @@
#include "smb_common.h"
#include "ksmbd_work.h"
struct smbdirect_buffer_descriptor_v1;
#define KSMBD_SOCKET_BACKLOG 16
enum {
@ -133,11 +135,11 @@ struct ksmbd_transport_ops {
unsigned int remote_key);
int (*rdma_read)(struct ksmbd_transport *t,
void *buf, unsigned int len,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len);
int (*rdma_write)(struct ksmbd_transport *t,
void *buf, unsigned int len,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len);
void (*free_transport)(struct ksmbd_transport *kt);
};
@ -163,11 +165,11 @@ bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
int ksmbd_conn_write(struct ksmbd_work *work);
int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
void *buf, unsigned int buflen,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len);
int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
void *buf, unsigned int buflen,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
unsigned int desc_len);
void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);

View File

@ -365,6 +365,7 @@ static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
return;
}
pr_info("running\n");
WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
}

View File

@ -23,6 +23,7 @@
#include "asn1.h"
#include "connection.h"
#include "transport_ipc.h"
#include "../common/smbdirect/smbdirect.h"
#include "transport_rdma.h"
#include "vfs.h"
#include "vfs_cache.h"
@ -6665,7 +6666,7 @@ static noinline int smb2_read_pipe(struct ksmbd_work *work)
}
static int smb2_set_remote_key_for_rdma(struct ksmbd_work *work,
struct smb2_buffer_desc_v1 *desc,
struct smbdirect_buffer_descriptor_v1 *desc,
__le32 Channel,
__le16 ChannelInfoLength)
{
@ -6701,7 +6702,7 @@ static ssize_t smb2_read_rdma_channel(struct ksmbd_work *work,
int err;
err = ksmbd_conn_rdma_write(work->conn, data_buf, length,
(struct smb2_buffer_desc_v1 *)
(struct smbdirect_buffer_descriptor_v1 *)
((char *)req + le16_to_cpu(req->ReadChannelInfoOffset)),
le16_to_cpu(req->ReadChannelInfoLength));
if (err)
@ -6761,7 +6762,11 @@ int smb2_read(struct ksmbd_work *work)
if (req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE ||
req->Channel == SMB2_CHANNEL_RDMA_V1) {
is_rdma_channel = true;
max_read_size = get_smbd_max_read_write_size();
max_read_size = get_smbd_max_read_write_size(work->conn->transport);
if (max_read_size == 0) {
err = -EINVAL;
goto out;
}
}
if (is_rdma_channel == true) {
@ -6772,7 +6777,7 @@ int smb2_read(struct ksmbd_work *work)
goto out;
}
err = smb2_set_remote_key_for_rdma(work,
(struct smb2_buffer_desc_v1 *)
(struct smbdirect_buffer_descriptor_v1 *)
((char *)req + ch_offset),
req->Channel,
req->ReadChannelInfoLength);
@ -6967,7 +6972,7 @@ static ssize_t smb2_write_rdma_channel(struct ksmbd_work *work,
return -ENOMEM;
ret = ksmbd_conn_rdma_read(work->conn, data_buf, length,
(struct smb2_buffer_desc_v1 *)
(struct smbdirect_buffer_descriptor_v1 *)
((char *)req + le16_to_cpu(req->WriteChannelInfoOffset)),
le16_to_cpu(req->WriteChannelInfoLength));
if (ret < 0) {
@ -7019,7 +7024,11 @@ int smb2_write(struct ksmbd_work *work)
if (req->Channel == SMB2_CHANNEL_RDMA_V1 ||
req->Channel == SMB2_CHANNEL_RDMA_V1_INVALIDATE) {
is_rdma_channel = true;
max_write_size = get_smbd_max_read_write_size();
max_write_size = get_smbd_max_read_write_size(work->conn->transport);
if (max_write_size == 0) {
err = -EINVAL;
goto out;
}
length = le32_to_cpu(req->RemainingBytes);
}
@ -7032,7 +7041,7 @@ int smb2_write(struct ksmbd_work *work)
goto out;
}
err = smb2_set_remote_key_for_rdma(work,
(struct smb2_buffer_desc_v1 *)
(struct smbdirect_buffer_descriptor_v1 *)
((char *)req + ch_offset),
req->Channel,
req->WriteChannelInfoLength);

View File

@ -136,12 +136,6 @@ struct create_posix_rsp {
u8 SidBuffer[44];
} __packed;
struct smb2_buffer_desc_v1 {
__le64 offset;
__le32 token;
__le32 length;
} __packed;
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001
struct smb_sockaddr_in {

File diff suppressed because it is too large Load Diff

View File

@ -11,61 +11,20 @@
#define SMBD_MIN_IOSIZE (512 * 1024)
#define SMBD_MAX_IOSIZE (16 * 1024 * 1024)
/* SMB DIRECT negotiation request packet [MS-SMBD] 2.2.1 */
struct smb_direct_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;
/* SMB DIRECT negotiation response packet [MS-SMBD] 2.2.2 */
struct smb_direct_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 SMB_DIRECT_RESPONSE_REQUESTED 0x0001
/* SMB DIRECT data transfer packet with payload [MS-SMBD] 2.2.3 */
struct smb_direct_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;
#ifdef CONFIG_SMB_SERVER_SMBDIRECT
int ksmbd_rdma_init(void);
void ksmbd_rdma_stop_listening(void);
void ksmbd_rdma_destroy(void);
bool ksmbd_rdma_capable_netdev(struct net_device *netdev);
void init_smbd_max_io_size(unsigned int sz);
unsigned int get_smbd_max_read_write_size(void);
unsigned int get_smbd_max_read_write_size(struct ksmbd_transport *kt);
#else
static inline int ksmbd_rdma_init(void) { return 0; }
static inline void ksmbd_rdma_stop_listening(void) { }
static inline void ksmbd_rdma_destroy(void) { }
static inline bool ksmbd_rdma_capable_netdev(struct net_device *netdev) { return false; }
static inline void init_smbd_max_io_size(unsigned int sz) { }
static inline unsigned int get_smbd_max_read_write_size(void) { return 0; }
static inline unsigned int get_smbd_max_read_write_size(struct ksmbd_transport *kt) { return 0; }
#endif
#endif /* __KSMBD_TRANSPORT_RDMA_H__ */