The previous patch gave each transport its own connection count in
t_conn_count, incremented and decremented at exactly the points where
the global rds_conn_count is. That leaves rds_conn_count with a
single remaining consumer: the seed of the per-path workqueue names
in __rds_conn_create().
Switch the name seed to t_conn_count, as UEK does, and remove
rds_conn_count. The numbering becomes per-transport instead of
global, so connections of different transports can now receive the
same seed; workqueue names carry no uniqueness requirement, and the
seed was already reused as the count rose and fell. Removing the
counter also removes the rds_conn_lock round-trip that
rds_conn_destroy_fini() took solely to decrement it. (The free path
still sleeps in destroy_workqueue(), so the last reference has to be
dropped from process context as before; only that one lock goes.)
Based on the Oracle UEK commit "net/rds: Each RDS transport
should keep its own connection count".
Assisted-by: Claude-Code:claude-fable-5
Signed-off-by: Allison Henderson <achender@kernel.org>
---
net/rds/connection.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/net/rds/connection.c b/net/rds/connection.c
index adeaf35d0ed0..22fd9d768724 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -47,7 +47,6 @@
/* converting this to RCU is a chore for another day.. */
static DEFINE_SPINLOCK(rds_conn_lock);
-static unsigned long rds_conn_count;
/* woken whenever a transport's t_conn_count drops to zero */
static DECLARE_WAIT_QUEUE_HEAD(rds_conn_freed_waitq);
static struct hlist_head rds_conn_hash[RDS_CONNECTION_HASH_ENTRIES];
@@ -332,12 +331,13 @@ static struct rds_connection *__rds_conn_create(struct net *net,
init_waitqueue_head(&conn->c_hs_waitq);
for (i = 0; i < npaths; i++) {
+ int seq = atomic_read(&trans->t_conn_count);
+
__rds_conn_path_init(conn, &conn->c_path[i],
is_outgoing);
conn->c_path[i].cp_index = i;
conn->c_path[i].cp_wq =
- alloc_ordered_workqueue("krds_cp_wq#%lu/%d", 0,
- rds_conn_count, i);
+ alloc_ordered_workqueue("krds_cp_wq#%d/%d", 0, seq, i);
if (!conn->c_path[i].cp_wq)
conn->c_path[i].cp_wq = rds_wq;
}@@ -408,7 +408,6 @@ static struct rds_connection *__rds_conn_create(struct net *net,
rds_conn_get(conn); /* caller */
rcu_assign_pointer(parent->c_passive, conn);
rds_cong_add_conn(conn);
- rds_conn_count++;
atomic_inc(&conn->c_trans->t_conn_count);
}
} else {@@ -431,7 +430,6 @@ static struct rds_connection *__rds_conn_create(struct net *net,
rds_conn_get(conn);
hlist_add_head_rcu(&conn->c_hash_node, head);
rds_cong_add_conn(conn);
- rds_conn_count++;
atomic_inc(&conn->c_trans->t_conn_count);
}
}
@@ -668,7 +666,6 @@ static void rds_conn_destroy_fini(struct kref *kref)
c_refcount);
int npaths = (conn->c_trans->t_mp_capable ? RDS_MPATH_WORKERS : 1);
struct rds_transport *trans = conn->c_trans;
- unsigned long flags;
int i;
for (i = 0; i < npaths; i++)
@@ -677,10 +674,6 @@ static void rds_conn_destroy_fini(struct kref *kref)
kfree(conn->c_path);
kmem_cache_free(rds_conn_slab, conn);
- spin_lock_irqsave(&rds_conn_lock, flags);
- rds_conn_count--;
- spin_unlock_irqrestore(&rds_conn_lock, flags);
-
/* only after everything the transport module owns has been
* freed above may its unload proceed
*/
--
2.25.1