summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/smbdirect.c11
-rw-r--r--fs/cifs/smbdirect.h1
2 files changed, 11 insertions, 1 deletions
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c
index 79d8dcbd0034..c7ef2d7ce0ef 100644
--- a/fs/cifs/smbdirect.c
+++ b/fs/cifs/smbdirect.c
@@ -287,6 +287,7 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
if (atomic_dec_and_test(&request->info->send_pending))
wake_up(&request->info->wait_send_pending);
+ wake_up(&request->info->wait_post_send);
mempool_free(request, request->info->request_mempool);
}
@@ -939,7 +940,14 @@ static int smbd_post_send(struct smbd_connection *info,
send_wr.opcode = IB_WR_SEND;
send_wr.send_flags = IB_SEND_SIGNALED;
- atomic_inc(&info->send_pending);
+wait_sq:
+ wait_event(info->wait_post_send,
+ atomic_read(&info->send_pending) < info->send_credit_target);
+ if (unlikely(atomic_inc_return(&info->send_pending) >
+ info->send_credit_target)) {
+ atomic_dec(&info->send_pending);
+ goto wait_sq;
+ }
rc = ib_post_send(info->id->qp, &send_wr, NULL);
if (rc) {
@@ -1733,6 +1741,7 @@ static struct smbd_connection *_smbd_get_connection(
init_waitqueue_head(&info->wait_send_pending);
atomic_set(&info->send_pending, 0);
+ init_waitqueue_head(&info->wait_post_send);
INIT_WORK(&info->disconnect_work, smbd_disconnect_rdma_work);
INIT_WORK(&info->post_send_credits_work, smbd_post_send_credits);
diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h
index f70c7119a456..07c8f5638c39 100644
--- a/fs/cifs/smbdirect.h
+++ b/fs/cifs/smbdirect.h
@@ -114,6 +114,7 @@ struct smbd_connection {
/* Activity accoutning */
atomic_t send_pending;
wait_queue_head_t wait_send_pending;
+ wait_queue_head_t wait_post_send;
/* Receive queue */
struct list_head receive_queue;