diff options
-rw-r--r-- | fs/cifs/smbdirect.c | 11 | ||||
-rw-r--r-- | fs/cifs/smbdirect.h | 1 |
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; |