From e99df1e20945f0b7e2d8f0af47108567992b745e Mon Sep 17 00:00:00 2001 From: fengquyoumo <1455117463@qq.com> Date: Tue, 3 Dec 2024 22:11:36 +0800 Subject: [PATCH 1/4] fix dead loop when transfer large data (size>20474) by rdma Signed-off-by: fengquyoumo <1455117463@qq.com> --- src/rdma.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rdma.c b/src/rdma.c index de7ea396a1..83c3c238b5 100644 --- a/src/rdma.c +++ b/src/rdma.c @@ -678,6 +678,7 @@ static connection *connCreateAcceptedRdma(int fd, void *priv) { static void connRdmaEventHandler(struct aeEventLoop *el, int fd, void *clientData, int mask) { rdma_connection *rdma_conn = (rdma_connection *)clientData; connection *conn = &rdma_conn->c; + client *c = connGetPrivateData(conn); struct rdma_cm_id *cm_id = rdma_conn->cm_id; RdmaContext *ctx = cm_id->context; int ret = 0; @@ -694,6 +695,9 @@ static void connRdmaEventHandler(struct aeEventLoop *el, int fd, void *clientDat /* uplayer should read all */ while (ctx->rx.pos < ctx->rx.offset) { + if (c->io_read_state == CLIENT_COMPLETED_IO || c->io_write_state == CLIENT_COMPLETED_IO) { + break; + } if (conn->read_handler && (callHandler(conn, conn->read_handler) == C_ERR)) { return; } From 9b8acb2c8982e35f6aa0aeeec96cb413be494453 Mon Sep 17 00:00:00 2001 From: fengquyoumo <1455117463@qq.com> Date: Thu, 5 Dec 2024 14:08:04 +0800 Subject: [PATCH 2/4] Fix the dead loop when rdma transfers large data by implementing postpone_update_state and update_stat Signed-off-by: fengquyoumo <1455117463@qq.com> --- src/rdma.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/rdma.c b/src/rdma.c index 83c3c238b5..2fe53a0da0 100644 --- a/src/rdma.c +++ b/src/rdma.c @@ -77,8 +77,11 @@ typedef enum ValkeyRdmaOpcode { #define VALKEY_RDMA_INVALID_OPCODE 0xffff #define VALKEY_RDMA_KEEPALIVE_MS 3000 +#define RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE (1 << 0) + typedef struct rdma_connection { connection c; + int flags; struct rdma_cm_id *cm_id; int last_errno; listNode *pending_list_node; @@ -678,7 +681,6 @@ static connection *connCreateAcceptedRdma(int fd, void *priv) { static void connRdmaEventHandler(struct aeEventLoop *el, int fd, void *clientData, int mask) { rdma_connection *rdma_conn = (rdma_connection *)clientData; connection *conn = &rdma_conn->c; - client *c = connGetPrivateData(conn); struct rdma_cm_id *cm_id = rdma_conn->cm_id; RdmaContext *ctx = cm_id->context; int ret = 0; @@ -694,10 +696,7 @@ static void connRdmaEventHandler(struct aeEventLoop *el, int fd, void *clientDat } /* uplayer should read all */ - while (ctx->rx.pos < ctx->rx.offset) { - if (c->io_read_state == CLIENT_COMPLETED_IO || c->io_write_state == CLIENT_COMPLETED_IO) { - break; - } + while (!(rdma_conn->flags & RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE) && ctx->rx.pos < ctx->rx.offset) { if (conn->read_handler && (callHandler(conn, conn->read_handler) == C_ERR)) { return; } @@ -709,7 +708,7 @@ static void connRdmaEventHandler(struct aeEventLoop *el, int fd, void *clientDat } /* RDMA comp channel has no POLLOUT event, try to send remaining buffer */ - if ((ctx->tx.offset < ctx->tx.length) && conn->write_handler) { + if (!(rdma_conn->flags & RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE) && ctx->tx.offset < ctx->tx.length && conn->write_handler) { callHandler(conn, conn->write_handler); } } @@ -888,6 +887,9 @@ static void connRdmaAcceptHandler(aeEventLoop *el, int fd, void *privdata, int m } static int connRdmaSetRwHandler(connection *conn) { + rdma_connection *rdma_conn = (rdma_connection *)conn; + if (rdma_conn->flags & RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE) return C_OK; + /* IB channel only has POLLIN event */ if (conn->read_handler || conn->write_handler) { if (aeCreateFileEvent(server.el, conn->fd, AE_READABLE, conn->type->ae_handler, conn) == AE_ERR) { @@ -1725,12 +1727,12 @@ static int rdmaProcessPendingData(void) { listNode *ln; rdma_connection *rdma_conn; connection *conn; - int processed; + int processed = 0; - processed = listLength(pending_list); listRewind(pending_list, &li); while ((ln = listNext(&li))) { rdma_conn = listNodeValue(ln); + if (rdma_conn->flags & RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE) continue; conn = &rdma_conn->c; /* a connection can be disconnected by remote peer, CM event mark state as CONN_STATE_CLOSED, kick connection @@ -1745,15 +1747,32 @@ static int rdmaProcessPendingData(void) { callHandler(conn, conn->write_handler); } + ++processed; continue; } connRdmaEventHandler(NULL, -1, rdma_conn, 0); + ++processed; } return processed; } +static void postPoneUpdateRdmaState(struct connection *conn, int postpone) { + rdma_connection *rdma_conn = (rdma_connection *)conn; + if (postpone) { + rdma_conn->flags |= RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE; + } else { + rdma_conn->flags &= ~RDMA_CONN_FLAG_POSTPONE_UPDATE_STATE; + } +} + +static void updateRdmaState(struct connection *conn) { + rdma_connection *rdma_conn = (rdma_connection *)conn; + connRdmaSetRwHandler(conn); + connRdmaEventHandler(NULL, -1, rdma_conn, 0); +} + static ConnectionType CT_RDMA = { /* connection type */ .get_type = connRdmaGetType, @@ -1796,6 +1815,8 @@ static ConnectionType CT_RDMA = { /* pending data */ .has_pending_data = rdmaHasPendingData, .process_pending_data = rdmaProcessPendingData, + .postpone_update_state = postPoneUpdateRdmaState, + .update_state = updateRdmaState }; ConnectionType *connectionTypeRdma(void) { From 0710aa1af90f228fa8fc30be9920bd52b9c47110 Mon Sep 17 00:00:00 2001 From: fengquyoumo <1455117463@qq.com> Date: Thu, 5 Dec 2024 17:37:55 +0800 Subject: [PATCH 3/4] Adjust the location of flags in struct rdma_connection because of memory alignment Signed-off-by: fengquyoumo <1455117463@qq.com> --- src/rdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdma.c b/src/rdma.c index 2fe53a0da0..ffa3b3dacd 100644 --- a/src/rdma.c +++ b/src/rdma.c @@ -81,8 +81,8 @@ typedef enum ValkeyRdmaOpcode { typedef struct rdma_connection { connection c; - int flags; struct rdma_cm_id *cm_id; + int flags; int last_errno; listNode *pending_list_node; } rdma_connection; From 8517cde2a17cc65f5d326f86b1caf55d9d504c34 Mon Sep 17 00:00:00 2001 From: fengquyoumo <1455117463@qq.com> Date: Thu, 5 Dec 2024 19:08:27 +0800 Subject: [PATCH 4/4] adjust format Signed-off-by: fengquyoumo <1455117463@qq.com> --- src/rdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rdma.c b/src/rdma.c index ffa3b3dacd..7fe65ad2d2 100644 --- a/src/rdma.c +++ b/src/rdma.c @@ -1816,7 +1816,7 @@ static ConnectionType CT_RDMA = { .has_pending_data = rdmaHasPendingData, .process_pending_data = rdmaProcessPendingData, .postpone_update_state = postPoneUpdateRdmaState, - .update_state = updateRdmaState + .update_state = updateRdmaState, }; ConnectionType *connectionTypeRdma(void) {