Skip to content

Commit f06cb29

Browse files
committed
rxrpc: Make the set of connection IDs per local endpoint
Make the set of connection IDs per local endpoint so that endpoints don't cause each other's connections to get dismissed. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: [email protected]
1 parent 57af281 commit f06cb29

File tree

5 files changed

+35
-38
lines changed

5 files changed

+35
-38
lines changed

net/rxrpc/af_rxrpc.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -957,16 +957,9 @@ static const struct net_proto_family rxrpc_family_ops = {
957957
static int __init af_rxrpc_init(void)
958958
{
959959
int ret = -1;
960-
unsigned int tmp;
961960

962961
BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > sizeof_field(struct sk_buff, cb));
963962

964-
get_random_bytes(&tmp, sizeof(tmp));
965-
tmp &= 0x3fffffff;
966-
if (tmp == 0)
967-
tmp = 1;
968-
idr_set_cursor(&rxrpc_client_conn_ids, tmp);
969-
970963
ret = -ENOMEM;
971964
rxrpc_call_jar = kmem_cache_create(
972965
"rxrpc_call_jar", sizeof(struct rxrpc_call), 0,
@@ -1062,7 +1055,6 @@ static void __exit af_rxrpc_exit(void)
10621055
* are released.
10631056
*/
10641057
rcu_barrier();
1065-
rxrpc_destroy_client_conn_ids();
10661058

10671059
destroy_workqueue(rxrpc_workqueue);
10681060
rxrpc_exit_security();

net/rxrpc/ar-internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ struct rxrpc_local {
300300
int debug_id; /* debug ID for printks */
301301
bool dead;
302302
bool service_closed; /* Service socket closed */
303+
struct idr conn_ids; /* List of connection IDs */
304+
spinlock_t conn_lock; /* Lock for client connection pool */
303305
struct sockaddr_rxrpc srx; /* local address */
304306
};
305307

@@ -887,9 +889,8 @@ static inline bool rxrpc_is_client_call(const struct rxrpc_call *call)
887889
extern unsigned int rxrpc_reap_client_connections;
888890
extern unsigned long rxrpc_conn_idle_client_expiry;
889891
extern unsigned long rxrpc_conn_idle_client_fast_expiry;
890-
extern struct idr rxrpc_client_conn_ids;
891892

892-
void rxrpc_destroy_client_conn_ids(void);
893+
void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local);
893894
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
894895
void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
895896
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,

net/rxrpc/conn_client.c

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ __read_mostly unsigned int rxrpc_reap_client_connections = 900;
3434
__read_mostly unsigned long rxrpc_conn_idle_client_expiry = 2 * 60 * HZ;
3535
__read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
3636

37-
/*
38-
* We use machine-unique IDs for our client connections.
39-
*/
40-
DEFINE_IDR(rxrpc_client_conn_ids);
41-
static DEFINE_SPINLOCK(rxrpc_conn_id_lock);
42-
4337
static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
4438

4539
/*
@@ -51,65 +45,65 @@ static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
5145
static int rxrpc_get_client_connection_id(struct rxrpc_connection *conn,
5246
gfp_t gfp)
5347
{
54-
struct rxrpc_net *rxnet = conn->rxnet;
48+
struct rxrpc_local *local = conn->local;
5549
int id;
5650

5751
_enter("");
5852

5953
idr_preload(gfp);
60-
spin_lock(&rxrpc_conn_id_lock);
54+
spin_lock(&local->conn_lock);
6155

62-
id = idr_alloc_cyclic(&rxrpc_client_conn_ids, conn,
56+
id = idr_alloc_cyclic(&local->conn_ids, conn,
6357
1, 0x40000000, GFP_NOWAIT);
6458
if (id < 0)
6559
goto error;
6660

67-
spin_unlock(&rxrpc_conn_id_lock);
61+
spin_unlock(&local->conn_lock);
6862
idr_preload_end();
6963

70-
conn->proto.epoch = rxnet->epoch;
64+
conn->proto.epoch = local->rxnet->epoch;
7165
conn->proto.cid = id << RXRPC_CIDSHIFT;
7266
set_bit(RXRPC_CONN_HAS_IDR, &conn->flags);
7367
_leave(" [CID %x]", conn->proto.cid);
7468
return 0;
7569

7670
error:
77-
spin_unlock(&rxrpc_conn_id_lock);
71+
spin_unlock(&local->conn_lock);
7872
idr_preload_end();
7973
_leave(" = %d", id);
8074
return id;
8175
}
8276

8377
/*
84-
* Release a connection ID for a client connection from the global pool.
78+
* Release a connection ID for a client connection.
8579
*/
86-
static void rxrpc_put_client_connection_id(struct rxrpc_connection *conn)
80+
static void rxrpc_put_client_connection_id(struct rxrpc_local *local,
81+
struct rxrpc_connection *conn)
8782
{
8883
if (test_bit(RXRPC_CONN_HAS_IDR, &conn->flags)) {
89-
spin_lock(&rxrpc_conn_id_lock);
90-
idr_remove(&rxrpc_client_conn_ids,
91-
conn->proto.cid >> RXRPC_CIDSHIFT);
92-
spin_unlock(&rxrpc_conn_id_lock);
84+
spin_lock(&local->conn_lock);
85+
idr_remove(&local->conn_ids, conn->proto.cid >> RXRPC_CIDSHIFT);
86+
spin_unlock(&local->conn_lock);
9387
}
9488
}
9589

9690
/*
9791
* Destroy the client connection ID tree.
9892
*/
99-
void rxrpc_destroy_client_conn_ids(void)
93+
void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
10094
{
10195
struct rxrpc_connection *conn;
10296
int id;
10397

104-
if (!idr_is_empty(&rxrpc_client_conn_ids)) {
105-
idr_for_each_entry(&rxrpc_client_conn_ids, conn, id) {
98+
if (!idr_is_empty(&local->conn_ids)) {
99+
idr_for_each_entry(&local->conn_ids, conn, id) {
106100
pr_err("AF_RXRPC: Leaked client conn %p {%d}\n",
107101
conn, refcount_read(&conn->ref));
108102
}
109103
BUG();
110104
}
111105

112-
idr_destroy(&rxrpc_client_conn_ids);
106+
idr_destroy(&local->conn_ids);
113107
}
114108

115109
/*
@@ -225,7 +219,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
225219
return conn;
226220

227221
error_1:
228-
rxrpc_put_client_connection_id(conn);
222+
rxrpc_put_client_connection_id(bundle->local, conn);
229223
error_0:
230224
kfree(conn);
231225
_leave(" = %d", ret);
@@ -257,7 +251,7 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
257251
* times the maximum number of client conns away from the current
258252
* allocation point to try and keep the IDs concentrated.
259253
*/
260-
id_cursor = idr_get_cursor(&rxrpc_client_conn_ids);
254+
id_cursor = idr_get_cursor(&conn->local->conn_ids);
261255
id = conn->proto.cid >> RXRPC_CIDSHIFT;
262256
distance = id - id_cursor;
263257
if (distance < 0)
@@ -982,7 +976,7 @@ void rxrpc_kill_client_conn(struct rxrpc_connection *conn)
982976
trace_rxrpc_client(conn, -1, rxrpc_client_cleanup);
983977
atomic_dec(&rxnet->nr_client_conns);
984978

985-
rxrpc_put_client_connection_id(conn);
979+
rxrpc_put_client_connection_id(local, conn);
986980
}
987981

988982
/*

net/rxrpc/conn_object.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ struct rxrpc_connection *rxrpc_find_client_connection_rcu(struct rxrpc_local *lo
100100

101101
_enter(",%x", sp->hdr.cid & RXRPC_CIDMASK);
102102

103-
/* Look up client connections by connection ID alone as their IDs are
104-
* unique for this machine.
103+
/* Look up client connections by connection ID alone as their
104+
* IDs are unique for this machine.
105105
*/
106-
conn = idr_find(&rxrpc_client_conn_ids, sp->hdr.cid >> RXRPC_CIDSHIFT);
106+
conn = idr_find(&local->conn_ids, sp->hdr.cid >> RXRPC_CIDSHIFT);
107107
if (!conn || refcount_read(&conn->ref) == 0) {
108108
_debug("no conn");
109109
goto not_found;

net/rxrpc/local_object.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct net *net,
8989
const struct sockaddr_rxrpc *srx)
9090
{
9191
struct rxrpc_local *local;
92+
u32 tmp;
9293

9394
local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL);
9495
if (local) {
@@ -109,6 +110,14 @@ static struct rxrpc_local *rxrpc_alloc_local(struct net *net,
109110
local->debug_id = atomic_inc_return(&rxrpc_debug_id);
110111
memcpy(&local->srx, srx, sizeof(*srx));
111112
local->srx.srx_service = 0;
113+
idr_init(&local->conn_ids);
114+
get_random_bytes(&tmp, sizeof(tmp));
115+
tmp &= 0x3fffffff;
116+
if (tmp == 0)
117+
tmp = 1;
118+
idr_set_cursor(&local->conn_ids, tmp);
119+
spin_lock_init(&local->conn_lock);
120+
112121
trace_rxrpc_local(local->debug_id, rxrpc_local_new, 1, 1);
113122
}
114123

@@ -409,6 +418,7 @@ void rxrpc_destroy_local(struct rxrpc_local *local)
409418
* local endpoint.
410419
*/
411420
rxrpc_purge_queue(&local->rx_queue);
421+
rxrpc_destroy_client_conn_ids(local);
412422
}
413423

414424
/*

0 commit comments

Comments
 (0)