[rds-devel] [PATCH AUTOSEL 6.19-5.10] net/rds: Clear reconnect pending bit

Sasha Levin sashal at kernel.org
Sat Feb 14 21:22:42 UTC 2026


From: Håkon Bugge <haakon.bugge at oracle.com>

[ Upstream commit b89fc7c2523b2b0750d91840f4e52521270d70ed ]

When canceling the reconnect worker, care must be taken to reset the
reconnect-pending bit. If the reconnect worker has not yet been
scheduled before it is canceled, the reconnect-pending bit will stay
on forever.

Signed-off-by: Håkon Bugge <haakon.bugge at oracle.com>
Signed-off-by: Allison Henderson <allison.henderson at oracle.com>
Link: https://patch.msgid.link/20260203055723.1085751-6-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---

LLM Generated explanations, may be completely bogus:

### 3. BUG MECHANISM — CLEAR AND CRITICAL

Now the full picture is clear:

**The flow:**
1. `rds_queue_reconnect()` at line 138 sets `RDS_RECONNECT_PENDING` and
   queues the delayed work.
2. `rds_connect_worker()` (the worker function) at line 173 clears
   `RDS_RECONNECT_PENDING` when it runs.
3. `rds_conn_path_connect_if_down()` at line 911 uses
   `test_and_set_bit(RDS_RECONNECT_PENDING, ...)` — if the bit is
   already set, it returns without queuing work, trusting that a
   reconnect is already pending.

**The bug:**
In `rds_conn_shutdown()`, `cancel_delayed_work_sync()` cancels the
queued worker. If the worker hadn't started yet, it never runs
`clear_bit(RDS_RECONNECT_PENDING, ...)`. The bit stays set. Then when
`rds_conn_path_connect_if_down()` is later called (e.g., when trying to
send data), `test_and_set_bit` finds the bit already set and skips
queuing — **forever**. The connection can never reconnect.

This is a **permanent connection failure** bug — once triggered, the RDS
connection path is effectively dead until the system is rebooted or the
module is reloaded.

### 4. CLASSIFICATION

- **Bug type:** State corruption / logic bug leading to permanent loss
  of network connectivity
- **Severity:** HIGH — RDS is used in production Oracle RAC clusters and
  RDMA-based environments
- **Trigger:** Race between shutdown and reconnect scheduling —
  realistic in production with network flaps

### 5. SCOPE AND RISK

- **Change size:** 1 functional line (plus 1 blank line) — extremely
  small and surgical
- **Files changed:** 1 file (`net/rds/connection.c`)
- **Risk of regression:** Very low — `clear_bit` is idempotent. If the
  worker already ran and cleared the bit, clearing it again is harmless.
  If the worker didn't run, this is the correct fix.
- **The fix is placed correctly:** After `cancel_delayed_work_sync()`
  guarantees the worker won't run, and before `rds_queue_reconnect()`
  which will set the bit again if needed.

### 6. STABLE KERNEL CRITERIA

- **Obviously correct:** Yes — the logic is straightforward and well-
  explained
- **Fixes a real bug:** Yes — permanent loss of RDS connectivity
- **Important issue:** Yes — affects network reliability for RDS users
  (Oracle, RDMA environments)
- **Small and contained:** Yes — 1 line in 1 file
- **No new features:** Correct — purely a bug fix
- **No new APIs:** Correct

### 7. DEPENDENCY CHECK

This fix is self-contained. It only adds a `clear_bit()` call after an
existing `cancel_delayed_work_sync()` call. The `RDS_RECONNECT_PENDING`
flag and the surrounding code have been in the kernel for a long time.
This should apply cleanly to any stable tree that has the RDS subsystem.

### Conclusion

This is a textbook stable backport candidate: a tiny, obviously correct,
one-line fix for a serious bug (permanent connection failure) in
networking code used in production environments. The fix has zero risk
of regression due to the idempotent nature of `clear_bit`, and the bug
mechanism is clearly explained and verified through code analysis.

**YES**

 net/rds/connection.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/rds/connection.c b/net/rds/connection.c
index ad8027e6f54ef..dbfea6fa11260 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -429,6 +429,8 @@ void rds_conn_shutdown(struct rds_conn_path *cp)
 	 * to the conn hash, so we never trigger a reconnect on this
 	 * conn - the reconnect is always triggered by the active peer. */
 	cancel_delayed_work_sync(&cp->cp_conn_w);
+
+	clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
 	rcu_read_lock();
 	if (!hlist_unhashed(&conn->c_hash_node)) {
 		rcu_read_unlock();
-- 
2.51.0




More information about the rds-devel mailing list