LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport
@ 2018-05-07 22:20 Long Li
2018-05-07 22:20 ` [PATCH 2/7] cifs: smbd: Don't destroy transport on RDMA disconnect Long Li
` (7 more replies)
0 siblings, 8 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
On transport recoonect, upper layer CIFS code destroys the current
transport and then recoonect. This code path is not used by SMBD, in that
SMBD destroys its transport on RDMA disconnect notification independent of
CIFS upper layer behavior.
This approach adds some costs to SMBD layer to handle transport shutdown
and restart, and to deal with several racing conditions on reconnecting
transport.
Re-work this code path by introducing a new smbd_destroy. This function is
called form upper layer to ask SMBD to destroy the transport. SMBD will no
longer need to destroy the transport by itself while worrying about data
transfer is in progress. The upper layer guarantees the transport is
locked.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/connect.c | 9 ++---
fs/cifs/smbdirect.c | 114 +++++++++++++++++++++++++++++++++++++++++++---------
fs/cifs/smbdirect.h | 3 +-
3 files changed, 100 insertions(+), 26 deletions(-)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 83b0234..5db3e9d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -377,7 +377,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
server->ssocket->state, server->ssocket->flags);
sock_release(server->ssocket);
server->ssocket = NULL;
- }
+ } else if (cifs_rdma_enabled(server))
+ smbd_destroy(server);
server->sequence_number = 0;
server->session_estab = false;
kfree(server->session_key.response);
@@ -710,10 +711,8 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
wake_up_all(&server->request_q);
/* give those requests time to exit */
msleep(125);
- if (cifs_rdma_enabled(server) && server->smbd_conn) {
- smbd_destroy(server->smbd_conn);
- server->smbd_conn = NULL;
- }
+ if (cifs_rdma_enabled(server))
+ smbd_destroy(server);
if (server->ssocket) {
sock_release(server->ssocket);
server->ssocket = NULL;
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index c62f7c9..1aa2d35 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -318,6 +318,9 @@ static int smbd_conn_upcall(
info->transport_status = SMBD_DISCONNECTED;
smbd_process_disconnected(info);
+ wake_up(&info->disconn_wait);
+ wake_up_interruptible(&info->wait_reassembly_queue);
+ wake_up_interruptible_all(&info->wait_send_queue);
break;
default:
@@ -1476,17 +1479,97 @@ static void idle_connection_timer(struct work_struct *work)
info->keep_alive_interval*HZ);
}
-/* Destroy this SMBD connection, called from upper layer */
-void smbd_destroy(struct smbd_connection *info)
+/*
+ * Destroy the transport and related RDMA and memory resources
+ * Need to go through all the pending counters and make sure on one is using
+ * the transport while it is destroyed
+ */
+void smbd_destroy(struct TCP_Server_Info *server)
{
+ struct smbd_connection *info = server->smbd_conn;
+ struct smbd_response *response;
+ unsigned long flags;
+
+ if (!info) {
+ log_rdma_event(INFO, "rdma session already destroyed\n");
+ return;
+ }
+
log_rdma_event(INFO, "destroying rdma session\n");
+ if (info->transport_status != SMBD_DISCONNECTED) {
+ rdma_disconnect(server->smbd_conn->id);
+ log_rdma_event(INFO, "wait for transport being disconnected\n");
+ wait_event(
+ info->disconn_wait,
+ info->transport_status == SMBD_DISCONNECTED);
+ }
- /* Kick off the disconnection process */
- smbd_disconnect_rdma_connection(info);
+ log_rdma_event(INFO, "destroying qp\n");
+ ib_drain_qp(info->id->qp);
+ rdma_destroy_qp(info->id);
+
+ log_rdma_event(INFO, "cancelling idle timer\n");
+ cancel_delayed_work_sync(&info->idle_timer_work);
+ log_rdma_event(INFO, "cancelling send immediate work\n");
+ cancel_delayed_work_sync(&info->send_immediate_work);
- log_rdma_event(INFO, "wait for transport being destroyed\n");
- wait_event(info->wait_destroy,
- info->transport_status == SMBD_DESTROYED);
+ log_rdma_event(INFO, "wait for all send posted to IB to finish\n");
+ wait_event(info->wait_send_pending,
+ atomic_read(&info->send_pending) == 0);
+ wait_event(info->wait_send_payload_pending,
+ atomic_read(&info->send_payload_pending) == 0);
+
+ /* It's not posssible for upper layer to get to reassembly */
+ log_rdma_event(INFO, "drain the reassembly queue\n");
+ do {
+ spin_lock_irqsave(&info->reassembly_queue_lock, flags);
+ response = _get_first_reassembly(info);
+ if (response) {
+ list_del(&response->list);
+ spin_unlock_irqrestore(
+ &info->reassembly_queue_lock, flags);
+ put_receive_buffer(info, response);
+ } else
+ spin_unlock_irqrestore(
+ &info->reassembly_queue_lock, flags);
+ } while (response);
+ info->reassembly_data_length = 0;
+
+ log_rdma_event(INFO, "free receive buffers\n");
+ wait_event(info->wait_receive_queues,
+ info->count_receive_queue + info->count_empty_packet_queue
+ == info->receive_credit_max);
+ destroy_receive_buffers(info);
+
+ /*
+ * For performance reasons, memory registration and deregistration
+ * are not locked by srv_mutex. It is possible some processes are
+ * blocked on transport srv_mutex while holding memory registration.
+ * Release the transport srv_mutex to allow them to hit the failure
+ * path when sending data, and then release memory registartions.
+ */
+ log_rdma_event(INFO, "freeing mr list\n");
+ wake_up_interruptible_all(&info->wait_mr);
+ while (atomic_read(&info->mr_used_count)) {
+ mutex_unlock(&server->srv_mutex);
+ msleep(1000);
+ mutex_lock(&server->srv_mutex);
+ }
+ destroy_mr_list(info);
+
+ ib_free_cq(info->send_cq);
+ ib_free_cq(info->recv_cq);
+ ib_dealloc_pd(info->pd);
+ rdma_destroy_id(info->id);
+
+ /* free mempools */
+ mempool_destroy(info->request_mempool);
+ kmem_cache_destroy(info->request_cache);
+
+ mempool_destroy(info->response_mempool);
+ kmem_cache_destroy(info->response_cache);
+
+ info->transport_status = SMBD_DESTROYED;
destroy_workqueue(info->workqueue);
kfree(info);
@@ -1511,17 +1594,9 @@ int smbd_reconnect(struct TCP_Server_Info *server)
*/
if (server->smbd_conn->transport_status == SMBD_CONNECTED) {
log_rdma_event(INFO, "disconnecting transport\n");
- smbd_disconnect_rdma_connection(server->smbd_conn);
+ smbd_destroy(server);
}
- /* wait until the transport is destroyed */
- if (!wait_event_timeout(server->smbd_conn->wait_destroy,
- server->smbd_conn->transport_status == SMBD_DESTROYED, 5*HZ))
- return -EAGAIN;
-
- destroy_workqueue(server->smbd_conn->workqueue);
- kfree(server->smbd_conn);
-
create_conn:
log_rdma_event(INFO, "creating rdma session\n");
server->smbd_conn = smbd_get_connection(
@@ -1730,12 +1805,13 @@ static struct smbd_connection *_smbd_get_connection(
conn_param.retry_count = SMBD_CM_RETRY;
conn_param.rnr_retry_count = SMBD_CM_RNR_RETRY;
conn_param.flow_control = 0;
- init_waitqueue_head(&info->wait_destroy);
log_rdma_event(INFO, "connecting to IP %pI4 port %d\n",
&addr_in->sin_addr, port);
init_waitqueue_head(&info->conn_wait);
+ init_waitqueue_head(&info->disconn_wait);
+ init_waitqueue_head(&info->wait_reassembly_queue);
rc = rdma_connect(info->id, &conn_param);
if (rc) {
log_rdma_event(ERR, "rdma_connect() failed with %i\n", rc);
@@ -1759,8 +1835,6 @@ static struct smbd_connection *_smbd_get_connection(
}
init_waitqueue_head(&info->wait_send_queue);
- init_waitqueue_head(&info->wait_reassembly_queue);
-
INIT_DELAYED_WORK(&info->idle_timer_work, idle_connection_timer);
INIT_DELAYED_WORK(&info->send_immediate_work, send_immediate_work);
queue_delayed_work(info->workqueue, &info->idle_timer_work,
@@ -1801,7 +1875,7 @@ static struct smbd_connection *_smbd_get_connection(
allocate_mr_failed:
/* At this point, need to a full transport shutdown */
- smbd_destroy(info);
+ smbd_destroy(server);
return NULL;
negotiation_failed:
diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h
index f9038da..7849989 100644
--- a/fs/cifs/smbdirect.h
+++ b/fs/cifs/smbdirect.h
@@ -71,6 +71,7 @@ struct smbd_connection {
struct completion ri_done;
wait_queue_head_t conn_wait;
wait_queue_head_t wait_destroy;
+ wait_queue_head_t disconn_wait;
struct completion negotiate_completion;
bool negotiate_done;
@@ -288,7 +289,7 @@ struct smbd_connection *smbd_get_connection(
/* Reconnect SMBDirect session */
int smbd_reconnect(struct TCP_Server_Info *server);
/* Destroy SMBDirect session */
-void smbd_destroy(struct smbd_connection *info);
+void smbd_destroy(struct TCP_Server_Info *server);
/* Interface for carrying upper layer I/O through send/recv */
int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/7] cifs: smbd: Don't destroy transport on RDMA disconnect
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-07 22:20 ` [PATCH 3/7] cifs: smbd: Return EINTR when interrupted Long Li
` (6 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
Now upper layer is handling the transport shutdown and reconnect, remove
the code that handling transport shutdown on RDMA disconnect.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/cifs_debug.c | 8 ++--
fs/cifs/smbdirect.c | 122 ++++-----------------------------------------------
fs/cifs/smbdirect.h | 9 ----
3 files changed, 11 insertions(+), 128 deletions(-)
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index e6025e9..0337ee8 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -214,12 +214,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
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 send_payload_pending:"
- " %x smbd_send_pending: %x smbd_recv_pending: %x",
+ seq_printf(m, "\nPending send_pending: %x "
+ "send_payload_pending: %x",
atomic_read(&server->smbd_conn->send_pending),
- atomic_read(&server->smbd_conn->send_payload_pending),
- server->smbd_conn->smbd_send_pending,
- server->smbd_conn->smbd_recv_pending);
+ atomic_read(&server->smbd_conn->send_payload_pending));
seq_printf(m, "\nReceive buffers count_receive_queue: %x "
"count_empty_packet_queue: %x",
server->smbd_conn->count_receive_queue,
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 1aa2d35..79b025e 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -162,95 +162,6 @@ do { \
#define log_rdma_mr(level, fmt, args...) \
log_rdma(level, LOG_RDMA_MR, fmt, ##args)
-/*
- * Destroy the transport and related RDMA and memory resources
- * Need to go through all the pending counters and make sure on one is using
- * the transport while it is destroyed
- */
-static void smbd_destroy_rdma_work(struct work_struct *work)
-{
- struct smbd_response *response;
- struct smbd_connection *info =
- container_of(work, struct smbd_connection, destroy_work);
- unsigned long flags;
-
- log_rdma_event(INFO, "destroying qp\n");
- ib_drain_qp(info->id->qp);
- rdma_destroy_qp(info->id);
-
- /* Unblock all I/O waiting on the send queue */
- wake_up_interruptible_all(&info->wait_send_queue);
-
- log_rdma_event(INFO, "cancelling idle timer\n");
- cancel_delayed_work_sync(&info->idle_timer_work);
- log_rdma_event(INFO, "cancelling send immediate work\n");
- cancel_delayed_work_sync(&info->send_immediate_work);
-
- log_rdma_event(INFO, "wait for all send to finish\n");
- wait_event(info->wait_smbd_send_pending,
- info->smbd_send_pending == 0);
-
- log_rdma_event(INFO, "wait for all recv to finish\n");
- wake_up_interruptible(&info->wait_reassembly_queue);
- wait_event(info->wait_smbd_recv_pending,
- info->smbd_recv_pending == 0);
-
- log_rdma_event(INFO, "wait for all send posted to IB to finish\n");
- wait_event(info->wait_send_pending,
- atomic_read(&info->send_pending) == 0);
- wait_event(info->wait_send_payload_pending,
- atomic_read(&info->send_payload_pending) == 0);
-
- log_rdma_event(INFO, "freeing mr list\n");
- wake_up_interruptible_all(&info->wait_mr);
- wait_event(info->wait_for_mr_cleanup,
- atomic_read(&info->mr_used_count) == 0);
- destroy_mr_list(info);
-
- /* It's not posssible for upper layer to get to reassembly */
- log_rdma_event(INFO, "drain the reassembly queue\n");
- do {
- spin_lock_irqsave(&info->reassembly_queue_lock, flags);
- response = _get_first_reassembly(info);
- if (response) {
- list_del(&response->list);
- spin_unlock_irqrestore(
- &info->reassembly_queue_lock, flags);
- put_receive_buffer(info, response);
- } else
- spin_unlock_irqrestore(&info->reassembly_queue_lock, flags);
- } while (response);
-
- info->reassembly_data_length = 0;
-
- log_rdma_event(INFO, "free receive buffers\n");
- wait_event(info->wait_receive_queues,
- info->count_receive_queue + info->count_empty_packet_queue
- == info->receive_credit_max);
- destroy_receive_buffers(info);
-
- ib_free_cq(info->send_cq);
- ib_free_cq(info->recv_cq);
- ib_dealloc_pd(info->pd);
- rdma_destroy_id(info->id);
-
- /* free mempools */
- mempool_destroy(info->request_mempool);
- kmem_cache_destroy(info->request_cache);
-
- mempool_destroy(info->response_mempool);
- kmem_cache_destroy(info->response_cache);
-
- info->transport_status = SMBD_DESTROYED;
- wake_up_all(&info->wait_destroy);
-}
-
-static int smbd_process_disconnected(struct smbd_connection *info)
-{
- schedule_work(&info->destroy_work);
- return 0;
-}
-
static void smbd_disconnect_rdma_work(struct work_struct *work)
{
struct smbd_connection *info =
@@ -317,8 +228,7 @@ static int smbd_conn_upcall(
}
info->transport_status = SMBD_DISCONNECTED;
- smbd_process_disconnected(info);
- wake_up(&info->disconn_wait);
+ wake_up_interruptible(&info->disconn_wait);
wake_up_interruptible(&info->wait_reassembly_queue);
wake_up_interruptible_all(&info->wait_send_queue);
break;
@@ -1499,7 +1409,7 @@ void smbd_destroy(struct TCP_Server_Info *server)
if (info->transport_status != SMBD_DISCONNECTED) {
rdma_disconnect(server->smbd_conn->id);
log_rdma_event(INFO, "wait for transport being disconnected\n");
- wait_event(
+ wait_event_interruptible(
info->disconn_wait,
info->transport_status == SMBD_DISCONNECTED);
}
@@ -1840,12 +1750,6 @@ static struct smbd_connection *_smbd_get_connection(
queue_delayed_work(info->workqueue, &info->idle_timer_work,
info->keep_alive_interval*HZ);
- init_waitqueue_head(&info->wait_smbd_send_pending);
- info->smbd_send_pending = 0;
-
- init_waitqueue_head(&info->wait_smbd_recv_pending);
- info->smbd_recv_pending = 0;
-
init_waitqueue_head(&info->wait_send_pending);
atomic_set(&info->send_pending, 0);
@@ -1853,7 +1757,6 @@ static struct smbd_connection *_smbd_get_connection(
atomic_set(&info->send_payload_pending, 0);
INIT_WORK(&info->disconnect_work, smbd_disconnect_rdma_work);
- INIT_WORK(&info->destroy_work, smbd_destroy_rdma_work);
INIT_WORK(&info->recv_done_work, smbd_recv_done_work);
INIT_WORK(&info->post_send_credits_work, smbd_post_send_credits);
info->new_credits_offered = 0;
@@ -1947,11 +1850,6 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf,
int rc;
again:
- if (info->transport_status != SMBD_CONNECTED) {
- log_read(ERR, "disconnected\n");
- return -ENODEV;
- }
-
/*
* No need to hold the reassembly queue lock all the time as we are
* the only one reading from the front of the queue. The transport
@@ -2067,6 +1965,11 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf,
if (rc)
return -ENODEV;
+ if (info->transport_status != SMBD_CONNECTED) {
+ log_read(ERR, "disconnected\n");
+ return 0;
+ }
+
goto again;
}
@@ -2114,8 +2017,6 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
unsigned int to_read;
int rc;
- info->smbd_recv_pending++;
-
switch (msg->msg_iter.type) {
case READ | ITER_KVEC:
buf = msg->msg_iter.kvec->iov_base;
@@ -2133,12 +2034,9 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
/* It's a bug in upper layer to get there */
cifs_dbg(VFS, "CIFS: invalid msg type %d\n",
msg->msg_iter.type);
- rc = -EIO;
+ rc = -EINVAL;
}
- info->smbd_recv_pending--;
- wake_up(&info->wait_smbd_recv_pending);
-
/* SMBDirect will read it all or nothing */
if (rc > 0)
msg->msg_iter.count = 0;
@@ -2163,7 +2061,6 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
struct kvec *iov;
int rc;
- info->smbd_send_pending++;
if (info->transport_status != SMBD_CONNECTED) {
rc = -ENODEV;
goto done;
@@ -2319,9 +2216,6 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
wait_event(info->wait_send_payload_pending,
atomic_read(&info->send_payload_pending) == 0);
- info->smbd_send_pending--;
- wake_up(&info->wait_smbd_send_pending);
-
return rc;
}
diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h
index 7849989..4563c0c 100644
--- a/fs/cifs/smbdirect.h
+++ b/fs/cifs/smbdirect.h
@@ -70,13 +70,11 @@ struct smbd_connection {
int ri_rc;
struct completion ri_done;
wait_queue_head_t conn_wait;
- wait_queue_head_t wait_destroy;
wait_queue_head_t disconn_wait;
struct completion negotiate_completion;
bool negotiate_done;
- struct work_struct destroy_work;
struct work_struct disconnect_work;
struct work_struct recv_done_work;
struct work_struct post_send_credits_work;
@@ -124,13 +122,6 @@ struct smbd_connection {
wait_queue_head_t wait_for_mr_cleanup;
/* Activity accoutning */
- /* Pending reqeusts issued from upper layer */
- int smbd_send_pending;
- wait_queue_head_t wait_smbd_send_pending;
-
- int smbd_recv_pending;
- wait_queue_head_t wait_smbd_recv_pending;
-
atomic_t send_pending;
wait_queue_head_t wait_send_pending;
atomic_t send_payload_pending;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/7] cifs: smbd: Return EINTR when interrupted
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
2018-05-07 22:20 ` [PATCH 2/7] cifs: smbd: Don't destroy transport on RDMA disconnect Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-07 22:20 ` [PATCH 4/7] cifs: smbd: Indicate to retry on transport sending failure Long Li
` (5 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
When packets are waiting for outbound I/O and interrupted, return the
proper error code to user process.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/smbdirect.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 79b025e..b8dd493 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -1963,7 +1963,7 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf,
info->transport_status != SMBD_CONNECTED);
/* Don't return any data if interrupted */
if (rc)
- return -ENODEV;
+ return rc;
if (info->transport_status != SMBD_CONNECTED) {
log_read(ERR, "disconnected\n");
@@ -1991,7 +1991,7 @@ static int smbd_recv_page(struct smbd_connection *info,
info->reassembly_data_length >= to_read ||
info->transport_status != SMBD_CONNECTED);
if (ret)
- return 0;
+ return ret;
/* now we can read from reassembly queue and not sleep */
to_address = kmap_atomic(page);
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/7] cifs: smbd: Indicate to retry on transport sending failure
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
2018-05-07 22:20 ` [PATCH 2/7] cifs: smbd: Don't destroy transport on RDMA disconnect Long Li
2018-05-07 22:20 ` [PATCH 3/7] cifs: smbd: Return EINTR when interrupted Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-07 22:20 ` [PATCH 5/7] cifs: smbd: Protect memory registration using RCU Long Li
` (4 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
Failure to send a packet doesn't mean it's a permanent failure, it can't be
returned to user process. This I/O should be retried or failed based on
server packet response and transport health. This logic is handled by the
upper layer.
Give this decision to upper layer.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/smbdirect.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index b8dd493..74620f5 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -851,7 +851,7 @@ static int smbd_create_header(struct smbd_connection *info,
if (info->transport_status != SMBD_CONNECTED) {
log_outgoing(ERR, "disconnected not sending\n");
- return -ENOENT;
+ return -EAGAIN;
}
atomic_dec(&info->send_credits);
@@ -977,6 +977,7 @@ static int smbd_post_send(struct smbd_connection *info,
wake_up(&info->wait_send_pending);
}
smbd_disconnect_rdma_connection(info);
+ rc = -EAGAIN;
} else
/* Reset timer for idle connection after packet is sent */
mod_delayed_work(info->workqueue, &info->idle_timer_work,
@@ -2062,7 +2063,7 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst)
int rc;
if (info->transport_status != SMBD_CONNECTED) {
- rc = -ENODEV;
+ rc = -EAGAIN;
goto done;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/7] cifs: smbd: Protect memory registration using RCU
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
` (2 preceding siblings ...)
2018-05-07 22:20 ` [PATCH 4/7] cifs: smbd: Indicate to retry on transport sending failure Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-08 6:35 ` kbuild test robot
2018-05-07 22:20 ` [PATCH 6/7] cifs: smbd: Retry on memory registration failure Long Li
` (3 subsequent siblings)
7 siblings, 1 reply; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
Unlike packet I/O sending path, the memory registration is not locked. They
need to be protected when doing transport reconnect or shutdown.
It's not necessary to lock for memory deregistration, since at the time the
transport is already destroyed so it's impossible to pick up the wrong
transport.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/smb2pdu.c | 6 ++++++
fs/cifs/smbdirect.c | 3 +++
2 files changed, 9 insertions(+)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 8cd164e..09ca098 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2609,10 +2609,13 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
bool need_invalidate =
io_parms->tcon->ses->server->dialect == SMB30_PROT_ID;
+ rcu_read_lock();
+ rcu_dereference(server->smbd_conn);
rdata->mr = smbd_register_mr(
server->smbd_conn, rdata->pages,
rdata->nr_pages, rdata->tailsz,
true, need_invalidate);
+ rcu_read_unlock();
if (!rdata->mr)
return -ENOBUFS;
@@ -2986,10 +2989,13 @@ smb2_async_writev(struct cifs_writedata *wdata,
struct smbd_buffer_descriptor_v1 *v1;
bool need_invalidate = server->dialect == SMB30_PROT_ID;
+ rcu_read_lock();
+ rcu_dereference(server->smbd_conn);
wdata->mr = smbd_register_mr(
server->smbd_conn, wdata->pages,
wdata->nr_pages, wdata->tailsz,
false, need_invalidate);
+ rcu_read_unlock();
if (!wdata->mr) {
rc = -ENOBUFS;
goto async_writev_out;
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 74620f5..8c46898 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -1482,6 +1482,9 @@ void smbd_destroy(struct TCP_Server_Info *server)
info->transport_status = SMBD_DESTROYED;
+ rcu_assign_pointer(server->smbd_conn, NULL);
+ synchronize_rcu();
+
destroy_workqueue(info->workqueue);
kfree(info);
}
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/7] cifs: smbd: Retry on memory registration failure
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
` (3 preceding siblings ...)
2018-05-07 22:20 ` [PATCH 5/7] cifs: smbd: Protect memory registration using RCU Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-07 22:20 ` [PATCH 7/7] cifs: Call MID callback before destroying transport Long Li
` (2 subsequent siblings)
7 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
Memory registration failure doesn't mean this I/O has failed, it means the
transport is hitting I/O error or needs reconnect. This error is not from
the server.
Indicate this error to upper layer, and let upper layer decide how to
reconnect and proceed with this I/O.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/smb2pdu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 09ca098..c72d1fa 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2617,7 +2617,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
true, need_invalidate);
rcu_read_unlock();
if (!rdata->mr)
- return -ENOBUFS;
+ return -EAGAIN;
req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
if (need_invalidate)
@@ -2997,7 +2997,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
false, need_invalidate);
rcu_read_unlock();
if (!wdata->mr) {
- rc = -ENOBUFS;
+ rc = -EAGAIN;
goto async_writev_out;
}
req->Length = 0;
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 7/7] cifs: Call MID callback before destroying transport
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
` (4 preceding siblings ...)
2018-05-07 22:20 ` [PATCH 6/7] cifs: smbd: Retry on memory registration failure Long Li
@ 2018-05-07 22:20 ` Long Li
2018-05-08 3:45 ` [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport kbuild test robot
2018-05-08 5:24 ` kbuild test robot
7 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-07 22:20 UTC (permalink / raw)
To: Steve French, linux-cifs, samba-technical, linux-kernel, linux-rdma
Cc: Long Li
From: Long Li <longli@microsoft.com>
When transport is being destroyed, it's possible that some processes may
hold memory registrations that need to be deregistred.
Call them first so nobody is using transport resources, and it can be
destroyed.
Signed-off-by: Long Li <longli@microsoft.com>
---
fs/cifs/connect.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5db3e9d..7e7d40e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -369,22 +369,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
/* do not want to be sending data on a socket we are freeing */
cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
mutex_lock(&server->srv_mutex);
- if (server->ssocket) {
- cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
- server->ssocket->state, server->ssocket->flags);
- kernel_sock_shutdown(server->ssocket, SHUT_WR);
- cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
- server->ssocket->state, server->ssocket->flags);
- sock_release(server->ssocket);
- server->ssocket = NULL;
- } else if (cifs_rdma_enabled(server))
- smbd_destroy(server);
- server->sequence_number = 0;
- server->session_estab = false;
- kfree(server->session_key.response);
- server->session_key.response = NULL;
- server->session_key.len = 0;
- server->lstrp = jiffies;
/* mark submitted MIDs for retry and issue callback */
INIT_LIST_HEAD(&retry_list);
@@ -397,7 +381,6 @@ cifs_reconnect(struct TCP_Server_Info *server)
list_move(&mid_entry->qhead, &retry_list);
}
spin_unlock(&GlobalMid_Lock);
- mutex_unlock(&server->srv_mutex);
cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
list_for_each_safe(tmp, tmp2, &retry_list) {
@@ -406,6 +389,25 @@ cifs_reconnect(struct TCP_Server_Info *server)
mid_entry->callback(mid_entry);
}
+ if (server->ssocket) {
+ cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
+ server->ssocket->state, server->ssocket->flags);
+ kernel_sock_shutdown(server->ssocket, SHUT_WR);
+ cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
+ server->ssocket->state, server->ssocket->flags);
+ sock_release(server->ssocket);
+ server->ssocket = NULL;
+ } else if (cifs_rdma_enabled(server))
+ smbd_destroy(server);
+ server->sequence_number = 0;
+ server->session_estab = false;
+ kfree(server->session_key.response);
+ server->session_key.response = NULL;
+ server->session_key.len = 0;
+ server->lstrp = jiffies;
+
+ mutex_unlock(&server->srv_mutex);
+
do {
try_to_freeze();
--
2.7.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
` (5 preceding siblings ...)
2018-05-07 22:20 ` [PATCH 7/7] cifs: Call MID callback before destroying transport Long Li
@ 2018-05-08 3:45 ` kbuild test robot
2018-05-08 5:24 ` kbuild test robot
7 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2018-05-08 3:45 UTC (permalink / raw)
To: Long Li
Cc: kbuild-all, Steve French, linux-cifs, samba-technical,
linux-kernel, linux-rdma, Long Li
[-- Attachment #1: Type: text/plain, Size: 6758 bytes --]
Hi Long,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on cifs/for-next]
[also build test WARNING on v4.17-rc4 next-20180507]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Long-Li/cifs-smbd-Make-upper-layer-decide-when-to-destroy-the-transport/20180508-110150
base: git://git.samba.org/sfrench/cifs-2.6.git for-next
config: i386-randconfig-a1-05080831 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All warnings (new ones prefixed by >>):
fs//cifs/connect.c: In function 'cifs_reconnect':
>> fs//cifs/connect.c:381:16: warning: passing argument 1 of 'smbd_destroy' from incompatible pointer type
smbd_destroy(server);
^
In file included from fs//cifs/connect.c:58:0:
fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but argument is of type 'struct TCP_Server_Info *'
static inline void smbd_destroy(struct smbd_connection *info) {}
^
fs//cifs/connect.c: In function 'clean_demultiplex_info':
fs//cifs/connect.c:715:16: warning: passing argument 1 of 'smbd_destroy' from incompatible pointer type
smbd_destroy(server);
^
In file included from fs//cifs/connect.c:58:0:
fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but argument is of type 'struct TCP_Server_Info *'
static inline void smbd_destroy(struct smbd_connection *info) {}
^
vim +/smbd_destroy +381 fs//cifs/connect.c
312
313 static int ip_connect(struct TCP_Server_Info *server);
314 static int generic_ip_connect(struct TCP_Server_Info *server);
315 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
316 static void cifs_prune_tlinks(struct work_struct *work);
317 static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
318 const char *devname);
319
320 /*
321 * cifs tcp session reconnection
322 *
323 * mark tcp session as reconnecting so temporarily locked
324 * mark all smb sessions as reconnecting for tcp session
325 * reconnect tcp session
326 * wake up waiters on reconnection? - (not needed currently)
327 */
328 int
329 cifs_reconnect(struct TCP_Server_Info *server)
330 {
331 int rc = 0;
332 struct list_head *tmp, *tmp2;
333 struct cifs_ses *ses;
334 struct cifs_tcon *tcon;
335 struct mid_q_entry *mid_entry;
336 struct list_head retry_list;
337
338 spin_lock(&GlobalMid_Lock);
339 if (server->tcpStatus == CifsExiting) {
340 /* the demux thread will exit normally
341 next time through the loop */
342 spin_unlock(&GlobalMid_Lock);
343 return rc;
344 } else
345 server->tcpStatus = CifsNeedReconnect;
346 spin_unlock(&GlobalMid_Lock);
347 server->maxBuf = 0;
348 server->max_read = 0;
349
350 cifs_dbg(FYI, "Reconnecting tcp session\n");
351
352 /* before reconnecting the tcp session, mark the smb session (uid)
353 and the tid bad so they are not used until reconnected */
354 cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
355 __func__);
356 spin_lock(&cifs_tcp_ses_lock);
357 list_for_each(tmp, &server->smb_ses_list) {
358 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
359 ses->need_reconnect = true;
360 list_for_each(tmp2, &ses->tcon_list) {
361 tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
362 tcon->need_reconnect = true;
363 }
364 if (ses->tcon_ipc)
365 ses->tcon_ipc->need_reconnect = true;
366 }
367 spin_unlock(&cifs_tcp_ses_lock);
368
369 /* do not want to be sending data on a socket we are freeing */
370 cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
371 mutex_lock(&server->srv_mutex);
372 if (server->ssocket) {
373 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
374 server->ssocket->state, server->ssocket->flags);
375 kernel_sock_shutdown(server->ssocket, SHUT_WR);
376 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
377 server->ssocket->state, server->ssocket->flags);
378 sock_release(server->ssocket);
379 server->ssocket = NULL;
380 } else if (cifs_rdma_enabled(server))
> 381 smbd_destroy(server);
382 server->sequence_number = 0;
383 server->session_estab = false;
384 kfree(server->session_key.response);
385 server->session_key.response = NULL;
386 server->session_key.len = 0;
387 server->lstrp = jiffies;
388
389 /* mark submitted MIDs for retry and issue callback */
390 INIT_LIST_HEAD(&retry_list);
391 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
392 spin_lock(&GlobalMid_Lock);
393 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
394 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
395 if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
396 mid_entry->mid_state = MID_RETRY_NEEDED;
397 list_move(&mid_entry->qhead, &retry_list);
398 }
399 spin_unlock(&GlobalMid_Lock);
400 mutex_unlock(&server->srv_mutex);
401
402 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
403 list_for_each_safe(tmp, tmp2, &retry_list) {
404 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
405 list_del_init(&mid_entry->qhead);
406 mid_entry->callback(mid_entry);
407 }
408
409 do {
410 try_to_freeze();
411
412 /* we should try only the port we connected to before */
413 mutex_lock(&server->srv_mutex);
414 if (cifs_rdma_enabled(server))
415 rc = smbd_reconnect(server);
416 else
417 rc = generic_ip_connect(server);
418 if (rc) {
419 cifs_dbg(FYI, "reconnect error %d\n", rc);
420 mutex_unlock(&server->srv_mutex);
421 msleep(3000);
422 } else {
423 atomic_inc(&tcpSesReconnectCount);
424 spin_lock(&GlobalMid_Lock);
425 if (server->tcpStatus != CifsExiting)
426 server->tcpStatus = CifsNeedNegotiate;
427 spin_unlock(&GlobalMid_Lock);
428 mutex_unlock(&server->srv_mutex);
429 }
430 } while (server->tcpStatus == CifsNeedReconnect);
431
432 if (server->tcpStatus == CifsNeedNegotiate)
433 mod_delayed_work(cifsiod_wq, &server->echo, 0);
434
435 return rc;
436 }
437
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 33165 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
` (6 preceding siblings ...)
2018-05-08 3:45 ` [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport kbuild test robot
@ 2018-05-08 5:24 ` kbuild test robot
2018-05-08 19:29 ` Long Li
7 siblings, 1 reply; 12+ messages in thread
From: kbuild test robot @ 2018-05-08 5:24 UTC (permalink / raw)
To: Long Li
Cc: kbuild-all, Steve French, linux-cifs, samba-technical,
linux-kernel, linux-rdma, Long Li
[-- Attachment #1: Type: text/plain, Size: 12484 bytes --]
Hi Long,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on cifs/for-next]
[also build test ERROR on v4.17-rc4 next-20180507]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Long-Li/cifs-smbd-Make-upper-layer-decide-when-to-destroy-the-transport/20180508-110150
base: git://git.samba.org/sfrench/cifs-2.6.git for-next
config: i386-randconfig-x013-201818 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
fs//cifs/connect.c: In function 'cifs_reconnect':
>> fs//cifs/connect.c:381:16: error: passing argument 1 of 'smbd_destroy' from incompatible pointer type [-Werror=incompatible-pointer-types]
smbd_destroy(server);
^~~~~~
In file included from fs//cifs/connect.c:58:0:
fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but argument is of type 'struct TCP_Server_Info *'
static inline void smbd_destroy(struct smbd_connection *info) {}
^~~~~~~~~~~~
fs//cifs/connect.c: In function 'clean_demultiplex_info':
fs//cifs/connect.c:715:16: error: passing argument 1 of 'smbd_destroy' from incompatible pointer type [-Werror=incompatible-pointer-types]
smbd_destroy(server);
^~~~~~
In file included from fs//cifs/connect.c:58:0:
fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but argument is of type 'struct TCP_Server_Info *'
static inline void smbd_destroy(struct smbd_connection *info) {}
^~~~~~~~~~~~
Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_read
Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_write
Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit
Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:clear_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls
Cyclomatic Complexity 1 include/uapi/linux/byteorder/little_endian.h:__le16_to_cpup
Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32
Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
Cyclomatic Complexity 2 include/linux/list.h:__list_add
Cyclomatic Complexity 1 include/linux/list.h:list_add
Cyclomatic Complexity 1 include/linux/list.h:__list_del
Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
Cyclomatic Complexity 1 include/linux/list.h:list_del_init
Cyclomatic Complexity 1 include/linux/list.h:list_move
Cyclomatic Complexity 1 include/linux/list.h:list_empty
Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
Cyclomatic Complexity 1 include/linux/string.h:strnlen
Cyclomatic Complexity 4 include/linux/string.h:strlen
Cyclomatic Complexity 6 include/linux/string.h:strlcpy
Cyclomatic Complexity 3 include/linux/string.h:memset
Cyclomatic Complexity 4 include/linux/string.h:memcpy
Cyclomatic Complexity 2 include/linux/string.h:strcpy
Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
Cyclomatic Complexity 1 include/linux/err.h:ERR_PTR
Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_read
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_inc
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_dec_and_test
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_add_return
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_sub_return
Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_read
Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_inc
Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_inc_return
Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_dec_return
Cyclomatic Complexity 1 include/asm-generic/atomic-instrumented.h:atomic_dec_and_test
Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_sub
Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock
Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock
Cyclomatic Complexity 1 include/linux/uidgid.h:__kuid_val
Cyclomatic Complexity 1 include/linux/uidgid.h:__kgid_val
Cyclomatic Complexity 1 include/linux/uidgid.h:uid_eq
Cyclomatic Complexity 1 include/linux/uidgid.h:gid_eq
Cyclomatic Complexity 1 include/linux/uidgid.h:uid_gt
Cyclomatic Complexity 1 include/linux/uidgid.h:uid_lt
Cyclomatic Complexity 1 include/linux/uidgid.h:uid_valid
Cyclomatic Complexity 1 include/linux/uidgid.h:gid_valid
Cyclomatic Complexity 1 include/linux/uidgid.h:make_kuid
Cyclomatic Complexity 1 include/linux/uidgid.h:make_kgid
Cyclomatic Complexity 1 include/linux/uidgid.h:from_kuid
Cyclomatic Complexity 1 include/linux/rbtree.h:rb_link_node
Cyclomatic Complexity 1 include/linux/debug_locks.h:debug_check_no_locks_held
Cyclomatic Complexity 1 include/linux/workqueue.h:__init_work
Cyclomatic Complexity 1 include/linux/uio.h:iov_iter_count
Cyclomatic Complexity 1 include/linux/socket.h:msg_data_left
Cyclomatic Complexity 1 include/linux/sched.h:task_pid_nr
Cyclomatic Complexity 1 include/linux/sched.h:task_thread_info
Cyclomatic Complexity 1 include/linux/cred.h:current_user_ns
Cyclomatic Complexity 1 include/linux/kasan.h:kasan_kmalloc
Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index
Cyclomatic Complexity 1 include/linux/slab.h:kmem_cache_alloc_trace
Cyclomatic Complexity 1 include/linux/slab.h:kmalloc_order_trace
Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large
Cyclomatic Complexity 5 include/linux/slab.h:kmalloc
Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
Cyclomatic Complexity 2 include/linux/ctype.h:__toupper
Cyclomatic Complexity 1 include/linux/utsname.h:utsname
Cyclomatic Complexity 1 include/net/net_namespace.h:get_net
Cyclomatic Complexity 1 include/net/net_namespace.h:put_net
Cyclomatic Complexity 1 include/net/net_namespace.h:net_eq
Cyclomatic Complexity 1 include/linux/module.h:__module_get
Cyclomatic Complexity 1 include/linux/module.h:module_put
Cyclomatic Complexity 1 include/keys/user-type.h:user_key_payload_locked
Cyclomatic Complexity 1 include/net/ipv6.h:ipv6_addr_equal
Cyclomatic Complexity 1 include/linux/unaligned/access_ok.h:get_unaligned_le16
Cyclomatic Complexity 1 fs//cifs/cifspdu.h:BCC
Cyclomatic Complexity 1 fs//cifs/cifspdu.h:get_bcc
Cyclomatic Complexity 1 fs//cifs/cifsglob.h:set_credits
Cyclomatic Complexity 1 fs//cifs/cifsglob.h:get_next_mid
vim +/smbd_destroy +381 fs//cifs/connect.c
312
313 static int ip_connect(struct TCP_Server_Info *server);
314 static int generic_ip_connect(struct TCP_Server_Info *server);
315 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
316 static void cifs_prune_tlinks(struct work_struct *work);
317 static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
318 const char *devname);
319
320 /*
321 * cifs tcp session reconnection
322 *
323 * mark tcp session as reconnecting so temporarily locked
324 * mark all smb sessions as reconnecting for tcp session
325 * reconnect tcp session
326 * wake up waiters on reconnection? - (not needed currently)
327 */
328 int
329 cifs_reconnect(struct TCP_Server_Info *server)
330 {
331 int rc = 0;
332 struct list_head *tmp, *tmp2;
333 struct cifs_ses *ses;
334 struct cifs_tcon *tcon;
335 struct mid_q_entry *mid_entry;
336 struct list_head retry_list;
337
338 spin_lock(&GlobalMid_Lock);
339 if (server->tcpStatus == CifsExiting) {
340 /* the demux thread will exit normally
341 next time through the loop */
342 spin_unlock(&GlobalMid_Lock);
343 return rc;
344 } else
345 server->tcpStatus = CifsNeedReconnect;
346 spin_unlock(&GlobalMid_Lock);
347 server->maxBuf = 0;
348 server->max_read = 0;
349
350 cifs_dbg(FYI, "Reconnecting tcp session\n");
351
352 /* before reconnecting the tcp session, mark the smb session (uid)
353 and the tid bad so they are not used until reconnected */
354 cifs_dbg(FYI, "%s: marking sessions and tcons for reconnect\n",
355 __func__);
356 spin_lock(&cifs_tcp_ses_lock);
357 list_for_each(tmp, &server->smb_ses_list) {
358 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
359 ses->need_reconnect = true;
360 list_for_each(tmp2, &ses->tcon_list) {
361 tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
362 tcon->need_reconnect = true;
363 }
364 if (ses->tcon_ipc)
365 ses->tcon_ipc->need_reconnect = true;
366 }
367 spin_unlock(&cifs_tcp_ses_lock);
368
369 /* do not want to be sending data on a socket we are freeing */
370 cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
371 mutex_lock(&server->srv_mutex);
372 if (server->ssocket) {
373 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
374 server->ssocket->state, server->ssocket->flags);
375 kernel_sock_shutdown(server->ssocket, SHUT_WR);
376 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
377 server->ssocket->state, server->ssocket->flags);
378 sock_release(server->ssocket);
379 server->ssocket = NULL;
380 } else if (cifs_rdma_enabled(server))
> 381 smbd_destroy(server);
382 server->sequence_number = 0;
383 server->session_estab = false;
384 kfree(server->session_key.response);
385 server->session_key.response = NULL;
386 server->session_key.len = 0;
387 server->lstrp = jiffies;
388
389 /* mark submitted MIDs for retry and issue callback */
390 INIT_LIST_HEAD(&retry_list);
391 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
392 spin_lock(&GlobalMid_Lock);
393 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
394 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
395 if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
396 mid_entry->mid_state = MID_RETRY_NEEDED;
397 list_move(&mid_entry->qhead, &retry_list);
398 }
399 spin_unlock(&GlobalMid_Lock);
400 mutex_unlock(&server->srv_mutex);
401
402 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
403 list_for_each_safe(tmp, tmp2, &retry_list) {
404 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
405 list_del_init(&mid_entry->qhead);
406 mid_entry->callback(mid_entry);
407 }
408
409 do {
410 try_to_freeze();
411
412 /* we should try only the port we connected to before */
413 mutex_lock(&server->srv_mutex);
414 if (cifs_rdma_enabled(server))
415 rc = smbd_reconnect(server);
416 else
417 rc = generic_ip_connect(server);
418 if (rc) {
419 cifs_dbg(FYI, "reconnect error %d\n", rc);
420 mutex_unlock(&server->srv_mutex);
421 msleep(3000);
422 } else {
423 atomic_inc(&tcpSesReconnectCount);
424 spin_lock(&GlobalMid_Lock);
425 if (server->tcpStatus != CifsExiting)
426 server->tcpStatus = CifsNeedNegotiate;
427 spin_unlock(&GlobalMid_Lock);
428 mutex_unlock(&server->srv_mutex);
429 }
430 } while (server->tcpStatus == CifsNeedReconnect);
431
432 if (server->tcpStatus == CifsNeedNegotiate)
433 mod_delayed_work(cifsiod_wq, &server->echo, 0);
434
435 return rc;
436 }
437
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27621 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 5/7] cifs: smbd: Protect memory registration using RCU
2018-05-07 22:20 ` [PATCH 5/7] cifs: smbd: Protect memory registration using RCU Long Li
@ 2018-05-08 6:35 ` kbuild test robot
2018-05-08 22:16 ` Long Li
0 siblings, 1 reply; 12+ messages in thread
From: kbuild test robot @ 2018-05-08 6:35 UTC (permalink / raw)
To: Long Li
Cc: kbuild-all, Steve French, linux-cifs, samba-technical,
linux-kernel, linux-rdma, Long Li
Hi Long,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on cifs/for-next]
[also build test WARNING on v4.17-rc4 next-20180507]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Long-Li/cifs-smbd-Make-upper-layer-decide-when-to-destroy-the-transport/20180508-110150
base: git://git.samba.org/sfrench/cifs-2.6.git for-next
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
fs/cifs/smb2pdu.c:110:47: sparse: expression using sizeof(void)
fs/cifs/smb2pdu.c:681:26: sparse: expression using sizeof(void)
>> fs/cifs/smb2pdu.c:2613:17: sparse: incompatible types in comparison expression (different address spaces)
fs/cifs/smb2pdu.c:2993:17: sparse: incompatible types in comparison expression (different address spaces)
fs/cifs/smb2pdu.c:3251:23: sparse: expression using sizeof(void)
fs/cifs/smb2pdu.c:3251:23: sparse: expression using sizeof(void)
fs/cifs/smb2pdu.c:3252:23: sparse: expression using sizeof(void)
fs/cifs/smb2pdu.c:3713:17: sparse: expression using sizeof(void)
fs/cifs/smb2pdu.c:3713:17: sparse: expression using sizeof(void)
vim +2613 fs/cifs/smb2pdu.c
2565
2566 /*
2567 * To form a chain of read requests, any read requests after the first should
2568 * have the end_of_chain boolean set to true.
2569 */
2570 static int
2571 smb2_new_read_req(void **buf, unsigned int *total_len,
2572 struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
2573 unsigned int remaining_bytes, int request_type)
2574 {
2575 int rc = -EACCES;
2576 struct smb2_read_plain_req *req = NULL;
2577 struct smb2_sync_hdr *shdr;
2578 struct TCP_Server_Info *server;
2579
2580 rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, (void **) &req,
2581 total_len);
2582 if (rc)
2583 return rc;
2584
2585 server = io_parms->tcon->ses->server;
2586 if (server == NULL)
2587 return -ECONNABORTED;
2588
2589 shdr = &req->sync_hdr;
2590 shdr->ProcessId = cpu_to_le32(io_parms->pid);
2591
2592 req->PersistentFileId = io_parms->persistent_fid;
2593 req->VolatileFileId = io_parms->volatile_fid;
2594 req->ReadChannelInfoOffset = 0; /* reserved */
2595 req->ReadChannelInfoLength = 0; /* reserved */
2596 req->Channel = 0; /* reserved */
2597 req->MinimumCount = 0;
2598 req->Length = cpu_to_le32(io_parms->length);
2599 req->Offset = cpu_to_le64(io_parms->offset);
2600 #ifdef CONFIG_CIFS_SMB_DIRECT
2601 /*
2602 * If we want to do a RDMA write, fill in and append
2603 * smbd_buffer_descriptor_v1 to the end of read request
2604 */
2605 if (server->rdma && rdata && !server->sign &&
2606 rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
2607
2608 struct smbd_buffer_descriptor_v1 *v1;
2609 bool need_invalidate =
2610 io_parms->tcon->ses->server->dialect == SMB30_PROT_ID;
2611
2612 rcu_read_lock();
> 2613 rcu_dereference(server->smbd_conn);
2614 rdata->mr = smbd_register_mr(
2615 server->smbd_conn, rdata->pages,
2616 rdata->nr_pages, rdata->tailsz,
2617 true, need_invalidate);
2618 rcu_read_unlock();
2619 if (!rdata->mr)
2620 return -ENOBUFS;
2621
2622 req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
2623 if (need_invalidate)
2624 req->Channel = SMB2_CHANNEL_RDMA_V1;
2625 req->ReadChannelInfoOffset =
2626 cpu_to_le16(offsetof(struct smb2_read_plain_req, Buffer));
2627 req->ReadChannelInfoLength =
2628 cpu_to_le16(sizeof(struct smbd_buffer_descriptor_v1));
2629 v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0];
2630 v1->offset = cpu_to_le64(rdata->mr->mr->iova);
2631 v1->token = cpu_to_le32(rdata->mr->mr->rkey);
2632 v1->length = cpu_to_le32(rdata->mr->mr->length);
2633
2634 *total_len += sizeof(*v1) - 1;
2635 }
2636 #endif
2637 if (request_type & CHAINED_REQUEST) {
2638 if (!(request_type & END_OF_CHAIN)) {
2639 /* next 8-byte aligned request */
2640 *total_len = DIV_ROUND_UP(*total_len, 8) * 8;
2641 shdr->NextCommand = cpu_to_le32(*total_len);
2642 } else /* END_OF_CHAIN */
2643 shdr->NextCommand = 0;
2644 if (request_type & RELATED_REQUEST) {
2645 shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
2646 /*
2647 * Related requests use info from previous read request
2648 * in chain.
2649 */
2650 shdr->SessionId = 0xFFFFFFFF;
2651 shdr->TreeId = 0xFFFFFFFF;
2652 req->PersistentFileId = 0xFFFFFFFF;
2653 req->VolatileFileId = 0xFFFFFFFF;
2654 }
2655 }
2656 if (remaining_bytes > io_parms->length)
2657 req->RemainingBytes = cpu_to_le32(remaining_bytes);
2658 else
2659 req->RemainingBytes = 0;
2660
2661 *buf = req;
2662 return rc;
2663 }
2664
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport
2018-05-08 5:24 ` kbuild test robot
@ 2018-05-08 19:29 ` Long Li
0 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-08 19:29 UTC (permalink / raw)
To: kbuild test robot, Long Li
Cc: kbuild-all, Steve French, linux-cifs, samba-technical,
linux-kernel, linux-rdma
> Subject: Re: [PATCH 1/7] cifs: smbd: Make upper layer decide when to
> destroy the transport
>
> Hi Long,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on cifs/for-next] [also build test ERROR on v4.17-rc4
> next-20180507] [if your patch is applied to the wrong git tree, please drop us
> a note to help improve the system]
>
> url:
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub
> .com%2F0day-ci%2Flinux%2Fcommits%2FLong-Li%2Fcifs-smbd-Make-upper-
> layer-decide-when-to-destroy-the-transport%2F20180508-
> 110150&data=02%7C01%7Clongli%40microsoft.com%7C8eeef6813ee14ded2
> dcc08d5b4a4113a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636
> 613539125415461&sdata=6EzmQWCVBK9EESOC3UQwrObR9AL9W5u660M4k
> bDvoJw%3D&reserved=0
> base: git://git.samba.org/sfrench/cifs-2.6.git for-next
> config: i386-randconfig-x013-201818 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
> fs//cifs/connect.c: In function 'cifs_reconnect':
> >> fs//cifs/connect.c:381:16: error: passing argument 1 of
> >> 'smbd_destroy' from incompatible pointer type
> >> [-Werror=incompatible-pointer-types]
> smbd_destroy(server);
> ^~~~~~
Thanks! I will send v2.
> In file included from fs//cifs/connect.c:58:0:
> fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but
> argument is of type 'struct TCP_Server_Info *'
> static inline void smbd_destroy(struct smbd_connection *info) {}
> ^~~~~~~~~~~~
> fs//cifs/connect.c: In function 'clean_demultiplex_info':
> fs//cifs/connect.c:715:16: error: passing argument 1 of 'smbd_destroy' from
> incompatible pointer type [-Werror=incompatible-pointer-types]
> smbd_destroy(server);
> ^~~~~~
> In file included from fs//cifs/connect.c:58:0:
> fs//cifs/smbdirect.h:334:20: note: expected 'struct smbd_connection *' but
> argument is of type 'struct TCP_Server_Info *'
> static inline void smbd_destroy(struct smbd_connection *info) {}
> ^~~~~~~~~~~~
> Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
> Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
> Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_read
> Cyclomatic Complexity 1 include/linux/kasan-checks.h:kasan_check_write
> Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:set_bit
> Cyclomatic Complexity 2 arch/x86/include/asm/bitops.h:clear_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_set_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls
> Cyclomatic Complexity 1
> include/uapi/linux/byteorder/little_endian.h:__le16_to_cpup
> Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u32
> Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
> Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
> Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
> Cyclomatic Complexity 2 include/linux/list.h:__list_add
> Cyclomatic Complexity 1 include/linux/list.h:list_add
> Cyclomatic Complexity 1 include/linux/list.h:__list_del
> Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
> Cyclomatic Complexity 1 include/linux/list.h:list_del_init
> Cyclomatic Complexity 1 include/linux/list.h:list_move
> Cyclomatic Complexity 1 include/linux/list.h:list_empty
> Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
> Cyclomatic Complexity 1 include/linux/string.h:strnlen
> Cyclomatic Complexity 4 include/linux/string.h:strlen
> Cyclomatic Complexity 6 include/linux/string.h:strlcpy
> Cyclomatic Complexity 3 include/linux/string.h:memset
> Cyclomatic Complexity 4 include/linux/string.h:memcpy
> Cyclomatic Complexity 2 include/linux/string.h:strcpy
> Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
> Cyclomatic Complexity 1 include/linux/err.h:ERR_PTR
> Cyclomatic Complexity 1 include/linux/err.h:PTR_ERR
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_read
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:arch_atomic_inc
> Cyclomatic Complexity 1
> arch/x86/include/asm/atomic.h:arch_atomic_dec_and_test
> Cyclomatic Complexity 1
> arch/x86/include/asm/atomic.h:arch_atomic_add_return
> Cyclomatic Complexity 1
> arch/x86/include/asm/atomic.h:arch_atomic_sub_return
> Cyclomatic Complexity 1 include/asm-generic/atomic-
> instrumented.h:atomic_read
> Cyclomatic Complexity 1 include/asm-generic/atomic-
> instrumented.h:atomic_inc
> Cyclomatic Complexity 1 include/asm-generic/atomic-
> instrumented.h:atomic_inc_return
> Cyclomatic Complexity 1 include/asm-generic/atomic-
> instrumented.h:atomic_dec_return
> Cyclomatic Complexity 1 include/asm-generic/atomic-
> instrumented.h:atomic_dec_and_test
> Cyclomatic Complexity 5
> arch/x86/include/asm/preempt.h:__preempt_count_sub
> Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
> Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock
> Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock
> Cyclomatic Complexity 1 include/linux/uidgid.h:__kuid_val
> Cyclomatic Complexity 1 include/linux/uidgid.h:__kgid_val
> Cyclomatic Complexity 1 include/linux/uidgid.h:uid_eq
> Cyclomatic Complexity 1 include/linux/uidgid.h:gid_eq
> Cyclomatic Complexity 1 include/linux/uidgid.h:uid_gt
> Cyclomatic Complexity 1 include/linux/uidgid.h:uid_lt
> Cyclomatic Complexity 1 include/linux/uidgid.h:uid_valid
> Cyclomatic Complexity 1 include/linux/uidgid.h:gid_valid
> Cyclomatic Complexity 1 include/linux/uidgid.h:make_kuid
> Cyclomatic Complexity 1 include/linux/uidgid.h:make_kgid
> Cyclomatic Complexity 1 include/linux/uidgid.h:from_kuid
> Cyclomatic Complexity 1 include/linux/rbtree.h:rb_link_node
> Cyclomatic Complexity 1
> include/linux/debug_locks.h:debug_check_no_locks_held
> Cyclomatic Complexity 1 include/linux/workqueue.h:__init_work
> Cyclomatic Complexity 1 include/linux/uio.h:iov_iter_count
> Cyclomatic Complexity 1 include/linux/socket.h:msg_data_left
> Cyclomatic Complexity 1 include/linux/sched.h:task_pid_nr
> Cyclomatic Complexity 1 include/linux/sched.h:task_thread_info
> Cyclomatic Complexity 1 include/linux/cred.h:current_user_ns
> Cyclomatic Complexity 1 include/linux/kasan.h:kasan_kmalloc
> Cyclomatic Complexity 28 include/linux/slab.h:kmalloc_index
> Cyclomatic Complexity 1 include/linux/slab.h:kmem_cache_alloc_trace
> Cyclomatic Complexity 1 include/linux/slab.h:kmalloc_order_trace
> Cyclomatic Complexity 67 include/linux/slab.h:kmalloc_large
> Cyclomatic Complexity 5 include/linux/slab.h:kmalloc
> Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
> Cyclomatic Complexity 2 include/linux/ctype.h:__toupper
> Cyclomatic Complexity 1 include/linux/utsname.h:utsname
> Cyclomatic Complexity 1 include/net/net_namespace.h:get_net
> Cyclomatic Complexity 1 include/net/net_namespace.h:put_net
> Cyclomatic Complexity 1 include/net/net_namespace.h:net_eq
> Cyclomatic Complexity 1 include/linux/module.h:__module_get
> Cyclomatic Complexity 1 include/linux/module.h:module_put
> Cyclomatic Complexity 1 include/keys/user-
> type.h:user_key_payload_locked
> Cyclomatic Complexity 1 include/net/ipv6.h:ipv6_addr_equal
> Cyclomatic Complexity 1
> include/linux/unaligned/access_ok.h:get_unaligned_le16
> Cyclomatic Complexity 1 fs//cifs/cifspdu.h:BCC
> Cyclomatic Complexity 1 fs//cifs/cifspdu.h:get_bcc
> Cyclomatic Complexity 1 fs//cifs/cifsglob.h:set_credits
> Cyclomatic Complexity 1 fs//cifs/cifsglob.h:get_next_mid
>
> vim +/smbd_destroy +381 fs//cifs/connect.c
>
> 312
> 313 static int ip_connect(struct TCP_Server_Info *server);
> 314 static int generic_ip_connect(struct TCP_Server_Info *server);
> 315 static void tlink_rb_insert(struct rb_root *root, struct tcon_link
> *new_tlink);
> 316 static void cifs_prune_tlinks(struct work_struct *work);
> 317 static int cifs_setup_volume_info(struct smb_vol *volume_info, char
> *mount_data,
> 318 const char *devname);
> 319
> 320 /*
> 321 * cifs tcp session reconnection
> 322 *
> 323 * mark tcp session as reconnecting so temporarily locked
> 324 * mark all smb sessions as reconnecting for tcp session
> 325 * reconnect tcp session
> 326 * wake up waiters on reconnection? - (not needed currently)
> 327 */
> 328 int
> 329 cifs_reconnect(struct TCP_Server_Info *server)
> 330 {
> 331 int rc = 0;
> 332 struct list_head *tmp, *tmp2;
> 333 struct cifs_ses *ses;
> 334 struct cifs_tcon *tcon;
> 335 struct mid_q_entry *mid_entry;
> 336 struct list_head retry_list;
> 337
> 338 spin_lock(&GlobalMid_Lock);
> 339 if (server->tcpStatus == CifsExiting) {
> 340 /* the demux thread will exit normally
> 341 next time through the loop */
> 342 spin_unlock(&GlobalMid_Lock);
> 343 return rc;
> 344 } else
> 345 server->tcpStatus = CifsNeedReconnect;
> 346 spin_unlock(&GlobalMid_Lock);
> 347 server->maxBuf = 0;
> 348 server->max_read = 0;
> 349
> 350 cifs_dbg(FYI, "Reconnecting tcp session\n");
> 351
> 352 /* before reconnecting the tcp session, mark the smb
> session (uid)
> 353 and the tid bad so they are not used until
> reconnected */
> 354 cifs_dbg(FYI, "%s: marking sessions and tcons for
> reconnect\n",
> 355 __func__);
> 356 spin_lock(&cifs_tcp_ses_lock);
> 357 list_for_each(tmp, &server->smb_ses_list) {
> 358 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
> 359 ses->need_reconnect = true;
> 360 list_for_each(tmp2, &ses->tcon_list) {
> 361 tcon = list_entry(tmp2, struct cifs_tcon,
> tcon_list);
> 362 tcon->need_reconnect = true;
> 363 }
> 364 if (ses->tcon_ipc)
> 365 ses->tcon_ipc->need_reconnect = true;
> 366 }
> 367 spin_unlock(&cifs_tcp_ses_lock);
> 368
> 369 /* do not want to be sending data on a socket we are freeing
> */
> 370 cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
> 371 mutex_lock(&server->srv_mutex);
> 372 if (server->ssocket) {
> 373 cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
> 374 server->ssocket->state, server->ssocket-
> >flags);
> 375 kernel_sock_shutdown(server->ssocket, SHUT_WR);
> 376 cifs_dbg(FYI, "Post shutdown state: 0x%x Flags:
> 0x%lx\n",
> 377 server->ssocket->state, server->ssocket-
> >flags);
> 378 sock_release(server->ssocket);
> 379 server->ssocket = NULL;
> 380 } else if (cifs_rdma_enabled(server))
> > 381 smbd_destroy(server);
> 382 server->sequence_number = 0;
> 383 server->session_estab = false;
> 384 kfree(server->session_key.response);
> 385 server->session_key.response = NULL;
> 386 server->session_key.len = 0;
> 387 server->lstrp = jiffies;
> 388
> 389 /* mark submitted MIDs for retry and issue callback */
> 390 INIT_LIST_HEAD(&retry_list);
> 391 cifs_dbg(FYI, "%s: moving mids to private list\n", __func__);
> 392 spin_lock(&GlobalMid_Lock);
> 393 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
> 394 mid_entry = list_entry(tmp, struct mid_q_entry,
> qhead);
> 395 if (mid_entry->mid_state ==
> MID_REQUEST_SUBMITTED)
> 396 mid_entry->mid_state =
> MID_RETRY_NEEDED;
> 397 list_move(&mid_entry->qhead, &retry_list);
> 398 }
> 399 spin_unlock(&GlobalMid_Lock);
> 400 mutex_unlock(&server->srv_mutex);
> 401
> 402 cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
> 403 list_for_each_safe(tmp, tmp2, &retry_list) {
> 404 mid_entry = list_entry(tmp, struct mid_q_entry,
> qhead);
> 405 list_del_init(&mid_entry->qhead);
> 406 mid_entry->callback(mid_entry);
> 407 }
> 408
> 409 do {
> 410 try_to_freeze();
> 411
> 412 /* we should try only the port we connected to
> before */
> 413 mutex_lock(&server->srv_mutex);
> 414 if (cifs_rdma_enabled(server))
> 415 rc = smbd_reconnect(server);
> 416 else
> 417 rc = generic_ip_connect(server);
> 418 if (rc) {
> 419 cifs_dbg(FYI, "reconnect error %d\n", rc);
> 420 mutex_unlock(&server->srv_mutex);
> 421 msleep(3000);
> 422 } else {
> 423 atomic_inc(&tcpSesReconnectCount);
> 424 spin_lock(&GlobalMid_Lock);
> 425 if (server->tcpStatus != CifsExiting)
> 426 server->tcpStatus =
> CifsNeedNegotiate;
> 427 spin_unlock(&GlobalMid_Lock);
> 428 mutex_unlock(&server->srv_mutex);
> 429 }
> 430 } while (server->tcpStatus == CifsNeedReconnect);
> 431
> 432 if (server->tcpStatus == CifsNeedNegotiate)
> 433 mod_delayed_work(cifsiod_wq, &server->echo, 0);
> 434
> 435 return rc;
> 436 }
> 437
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01
> .org%2Fpipermail%2Fkbuild-
> all&data=02%7C01%7Clongli%40microsoft.com%7C8eeef6813ee14ded2dcc08
> d5b4a4113a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C63661353
> 9125415461&sdata=OrOmZ1yCHuTbOlK8c6oBG9FpUbjBcQR5nGGa%2BntzwL
> E%3D&reserved=0 Intel Corporation
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 5/7] cifs: smbd: Protect memory registration using RCU
2018-05-08 6:35 ` kbuild test robot
@ 2018-05-08 22:16 ` Long Li
0 siblings, 0 replies; 12+ messages in thread
From: Long Li @ 2018-05-08 22:16 UTC (permalink / raw)
To: kbuild test robot, Long Li
Cc: kbuild-all, Steve French, linux-cifs, samba-technical,
linux-kernel, linux-rdma
Hi Steve
Please drop this patch. I will find another solution.
The other patches in the series can be reviewed and applied.
Long
> -----Original Message-----
> From: kbuild test robot <lkp@intel.com>
> Sent: Monday, May 7, 2018 11:36 PM
> To: Long Li <longli@linuxonhyperv.com>
> Cc: kbuild-all@01.org; Steve French <sfrench@samba.org>; linux-
> cifs@vger.kernel.org; samba-technical@lists.samba.org; linux-
> kernel@vger.kernel.org; linux-rdma@vger.kernel.org; Long Li
> <longli@microsoft.com>
> Subject: Re: [PATCH 5/7] cifs: smbd: Protect memory registration using RCU
>
> Hi Long,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on cifs/for-next] [also build test WARNING on
> v4.17-rc4 next-20180507] [if your patch is applied to the wrong git tree,
> please drop us a note to help improve the system]
>
> url:
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub
> .com%2F0day-ci%2Flinux%2Fcommits%2FLong-Li%2Fcifs-smbd-Make-upper-
> layer-decide-when-to-destroy-the-transport%2F20180508-
> 110150&data=02%7C01%7Clongli%40microsoft.com%7C56045b01aeae4e53b1
> 9408d5b4ae0502%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6366
> 13581873868980&sdata=a1Ds3qI7sRrLCE77Eoasifonm1rUQYi7rdUEnLnGOB4%
> 3D&reserved=0
> base: git://git.samba.org/sfrench/cifs-2.6.git for-next
> reproduce:
> # apt-get install sparse
> make ARCH=x86_64 allmodconfig
> make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
> fs/cifs/smb2pdu.c:110:47: sparse: expression using sizeof(void)
> fs/cifs/smb2pdu.c:681:26: sparse: expression using sizeof(void)
> >> fs/cifs/smb2pdu.c:2613:17: sparse: incompatible types in comparison
> >> expression (different address spaces)
> fs/cifs/smb2pdu.c:2993:17: sparse: incompatible types in comparison
> expression (different address spaces)
> fs/cifs/smb2pdu.c:3251:23: sparse: expression using sizeof(void)
> fs/cifs/smb2pdu.c:3251:23: sparse: expression using sizeof(void)
> fs/cifs/smb2pdu.c:3252:23: sparse: expression using sizeof(void)
> fs/cifs/smb2pdu.c:3713:17: sparse: expression using sizeof(void)
> fs/cifs/smb2pdu.c:3713:17: sparse: expression using sizeof(void)
>
> vim +2613 fs/cifs/smb2pdu.c
>
> 2565
> 2566 /*
> 2567 * To form a chain of read requests, any read requests after the first
> should
> 2568 * have the end_of_chain boolean set to true.
> 2569 */
> 2570 static int
> 2571 smb2_new_read_req(void **buf, unsigned int *total_len,
> 2572 struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
> 2573 unsigned int remaining_bytes, int request_type)
> 2574 {
> 2575 int rc = -EACCES;
> 2576 struct smb2_read_plain_req *req = NULL;
> 2577 struct smb2_sync_hdr *shdr;
> 2578 struct TCP_Server_Info *server;
> 2579
> 2580 rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, (void
> **) &req,
> 2581 total_len);
> 2582 if (rc)
> 2583 return rc;
> 2584
> 2585 server = io_parms->tcon->ses->server;
> 2586 if (server == NULL)
> 2587 return -ECONNABORTED;
> 2588
> 2589 shdr = &req->sync_hdr;
> 2590 shdr->ProcessId = cpu_to_le32(io_parms->pid);
> 2591
> 2592 req->PersistentFileId = io_parms->persistent_fid;
> 2593 req->VolatileFileId = io_parms->volatile_fid;
> 2594 req->ReadChannelInfoOffset = 0; /* reserved */
> 2595 req->ReadChannelInfoLength = 0; /* reserved */
> 2596 req->Channel = 0; /* reserved */
> 2597 req->MinimumCount = 0;
> 2598 req->Length = cpu_to_le32(io_parms->length);
> 2599 req->Offset = cpu_to_le64(io_parms->offset);
> 2600 #ifdef CONFIG_CIFS_SMB_DIRECT
> 2601 /*
> 2602 * If we want to do a RDMA write, fill in and append
> 2603 * smbd_buffer_descriptor_v1 to the end of read request
> 2604 */
> 2605 if (server->rdma && rdata && !server->sign &&
> 2606 rdata->bytes >= server->smbd_conn-
> >rdma_readwrite_threshold) {
> 2607
> 2608 struct smbd_buffer_descriptor_v1 *v1;
> 2609 bool need_invalidate =
> 2610 io_parms->tcon->ses->server->dialect ==
> SMB30_PROT_ID;
> 2611
> 2612 rcu_read_lock();
> > 2613 rcu_dereference(server->smbd_conn);
> 2614 rdata->mr = smbd_register_mr(
> 2615 server->smbd_conn, rdata->pages,
> 2616 rdata->nr_pages, rdata->tailsz,
> 2617 true, need_invalidate);
> 2618 rcu_read_unlock();
> 2619 if (!rdata->mr)
> 2620 return -ENOBUFS;
> 2621
> 2622 req->Channel =
> SMB2_CHANNEL_RDMA_V1_INVALIDATE;
> 2623 if (need_invalidate)
> 2624 req->Channel = SMB2_CHANNEL_RDMA_V1;
> 2625 req->ReadChannelInfoOffset =
> 2626 cpu_to_le16(offsetof(struct
> smb2_read_plain_req, Buffer));
> 2627 req->ReadChannelInfoLength =
> 2628 cpu_to_le16(sizeof(struct
> smbd_buffer_descriptor_v1));
> 2629 v1 = (struct smbd_buffer_descriptor_v1 *) &req-
> >Buffer[0];
> 2630 v1->offset = cpu_to_le64(rdata->mr->mr->iova);
> 2631 v1->token = cpu_to_le32(rdata->mr->mr->rkey);
> 2632 v1->length = cpu_to_le32(rdata->mr->mr->length);
> 2633
> 2634 *total_len += sizeof(*v1) - 1;
> 2635 }
> 2636 #endif
> 2637 if (request_type & CHAINED_REQUEST) {
> 2638 if (!(request_type & END_OF_CHAIN)) {
> 2639 /* next 8-byte aligned request */
> 2640 *total_len = DIV_ROUND_UP(*total_len, 8) *
> 8;
> 2641 shdr->NextCommand =
> cpu_to_le32(*total_len);
> 2642 } else /* END_OF_CHAIN */
> 2643 shdr->NextCommand = 0;
> 2644 if (request_type & RELATED_REQUEST) {
> 2645 shdr->Flags |=
> SMB2_FLAGS_RELATED_OPERATIONS;
> 2646 /*
> 2647 * Related requests use info from previous
> read request
> 2648 * in chain.
> 2649 */
> 2650 shdr->SessionId = 0xFFFFFFFF;
> 2651 shdr->TreeId = 0xFFFFFFFF;
> 2652 req->PersistentFileId = 0xFFFFFFFF;
> 2653 req->VolatileFileId = 0xFFFFFFFF;
> 2654 }
> 2655 }
> 2656 if (remaining_bytes > io_parms->length)
> 2657 req->RemainingBytes =
> cpu_to_le32(remaining_bytes);
> 2658 else
> 2659 req->RemainingBytes = 0;
> 2660
> 2661 *buf = req;
> 2662 return rc;
> 2663 }
> 2664
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01
> .org%2Fpipermail%2Fkbuild-
> all&data=02%7C01%7Clongli%40microsoft.com%7C56045b01aeae4e53b19408
> d5b4ae0502%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C63661358
> 1873868980&sdata=y3BYFeKEayhIfrs6hodamCPCyz8n3YQdN1yX3yXKs80%3D
> &reserved=0 Intel Corporation
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2018-05-08 22:16 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-07 22:20 [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport Long Li
2018-05-07 22:20 ` [PATCH 2/7] cifs: smbd: Don't destroy transport on RDMA disconnect Long Li
2018-05-07 22:20 ` [PATCH 3/7] cifs: smbd: Return EINTR when interrupted Long Li
2018-05-07 22:20 ` [PATCH 4/7] cifs: smbd: Indicate to retry on transport sending failure Long Li
2018-05-07 22:20 ` [PATCH 5/7] cifs: smbd: Protect memory registration using RCU Long Li
2018-05-08 6:35 ` kbuild test robot
2018-05-08 22:16 ` Long Li
2018-05-07 22:20 ` [PATCH 6/7] cifs: smbd: Retry on memory registration failure Long Li
2018-05-07 22:20 ` [PATCH 7/7] cifs: Call MID callback before destroying transport Long Li
2018-05-08 3:45 ` [PATCH 1/7] cifs: smbd: Make upper layer decide when to destroy the transport kbuild test robot
2018-05-08 5:24 ` kbuild test robot
2018-05-08 19:29 ` Long Li
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).