conn_object.c 11.7 KB
Newer Older
1
/* RxRPC virtual connection handler, common bits.
2
 *
3
 * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
4 5 6 7 8 9 10 11
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

12 13
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

14
#include <linux/module.h>
15
#include <linux/slab.h>
16 17 18 19
#include <linux/net.h>
#include <linux/skbuff.h>
#include "ar-internal.h"

20 21 22
/*
 * Time till a connection expires after last use (in seconds).
 */
23
unsigned int rxrpc_connection_expiry = 10 * 60;
24

25 26
static void rxrpc_destroy_connection(struct rcu_head *);

27 28 29 30 31 32 33 34
static void rxrpc_connection_timer(struct timer_list *timer)
{
	struct rxrpc_connection *conn =
		container_of(timer, struct rxrpc_connection, timer);

	rxrpc_queue_conn(conn);
}

35 36 37
/*
 * allocate a new connection
 */
38
struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
39 40 41 42 43 44 45
{
	struct rxrpc_connection *conn;

	_enter("");

	conn = kzalloc(sizeof(struct rxrpc_connection), gfp);
	if (conn) {
46
		INIT_LIST_HEAD(&conn->cache_link);
47
		spin_lock_init(&conn->channel_lock);
48
		INIT_LIST_HEAD(&conn->waiting_calls);
49
		timer_setup(&conn->timer, &rxrpc_connection_timer, 0);
50
		INIT_WORK(&conn->processor, &rxrpc_process_connection);
51
		INIT_LIST_HEAD(&conn->proc_link);
52
		INIT_LIST_HEAD(&conn->link);
53
		skb_queue_head_init(&conn->rx_queue);
54
		conn->security = &rxrpc_no_security;
55 56 57
		spin_lock_init(&conn->state_lock);
		conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
		conn->size_align = 4;
58
		conn->idle_timestamp = jiffies;
59 60
	}

61
	_leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
62 63 64 65
	return conn;
}

/*
66 67 68 69 70 71
 * Look up a connection in the cache by protocol parameters.
 *
 * If successful, a pointer to the connection is returned, but no ref is taken.
 * NULL is returned if there is no match.
 *
 * The caller must be holding the RCU read lock.
72
 */
73 74
struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
						   struct sk_buff *skb)
75 76
{
	struct rxrpc_connection *conn;
77
	struct rxrpc_conn_proto k;
78
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
79 80
	struct sockaddr_rxrpc srx;
	struct rxrpc_peer *peer;
81

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

D
David Howells 已提交
84
	if (rxrpc_extract_addr_from_skb(local, &srx, skb) < 0)
85
		goto not_found;
86

87 88 89
	k.epoch	= sp->hdr.epoch;
	k.cid	= sp->hdr.cid & RXRPC_CIDMASK;

90 91 92 93 94 95 96 97 98 99
	/* We may have to handle mixing IPv4 and IPv6 */
	if (srx.transport.family != local->srx.transport.family) {
		pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
				    srx.transport.family,
				    local->srx.transport.family);
		goto not_found;
	}

	k.epoch	= sp->hdr.epoch;
	k.cid	= sp->hdr.cid & RXRPC_CIDMASK;
100

101
	if (sp->hdr.flags & RXRPC_CLIENT_INITIATED) {
102 103 104 105 106 107 108
		/* We need to look up service connections by the full protocol
		 * parameter set.  We look up the peer first as an intermediate
		 * step and then the connection from the peer's tree.
		 */
		peer = rxrpc_lookup_peer_rcu(local, &srx);
		if (!peer)
			goto not_found;
109 110 111 112 113
		conn = rxrpc_find_service_conn_rcu(peer, skb);
		if (!conn || atomic_read(&conn->usage) == 0)
			goto not_found;
		_leave(" = %p", conn);
		return conn;
114
	} else {
115 116 117
		/* Look up client connections by connection ID alone as their
		 * IDs are unique for this machine.
		 */
118
		conn = idr_find(&rxrpc_client_conn_ids,
119 120 121 122 123 124 125
				sp->hdr.cid >> RXRPC_CIDSHIFT);
		if (!conn || atomic_read(&conn->usage) == 0) {
			_debug("no conn");
			goto not_found;
		}

		if (conn->proto.epoch != k.epoch ||
126 127 128 129 130 131 132 133 134 135 136 137
		    conn->params.local != local)
			goto not_found;

		peer = conn->params.peer;
		switch (srx.transport.family) {
		case AF_INET:
			if (peer->srx.transport.sin.sin_port !=
			    srx.transport.sin.sin_port ||
			    peer->srx.transport.sin.sin_addr.s_addr !=
			    srx.transport.sin.sin_addr.s_addr)
				goto not_found;
			break;
138
#ifdef CONFIG_AF_RXRPC_IPV6
D
David Howells 已提交
139 140 141 142 143 144 145 146
		case AF_INET6:
			if (peer->srx.transport.sin6.sin6_port !=
			    srx.transport.sin6.sin6_port ||
			    memcmp(&peer->srx.transport.sin6.sin6_addr,
				   &srx.transport.sin6.sin6_addr,
				   sizeof(struct in6_addr)) != 0)
				goto not_found;
			break;
147
#endif
148 149 150 151 152 153
		default:
			BUG();
		}

		_leave(" = %p", conn);
		return conn;
154 155
	}

156
not_found:
157 158 159 160
	_leave(" = NULL");
	return NULL;
}

161 162
/*
 * Disconnect a call and clear any channel it occupies when that call
163 164
 * terminates.  The caller must hold the channel_lock and must release the
 * call's ref on the connection.
165
 */
166 167
void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
			     struct rxrpc_call *call)
168
{
169 170
	struct rxrpc_channel *chan =
		&conn->channels[call->cid & RXRPC_CHANNELMASK];
171

172
	_enter("%d,%x", conn->debug_id, call->cid);
173

174 175 176 177
	if (rcu_access_pointer(chan->call) == call) {
		/* Save the result of the call so that we can repeat it if necessary
		 * through the channel, whilst disposing of the actual call record.
		 */
D
David Howells 已提交
178
		trace_rxrpc_disconnect_call(call);
179 180
		if (call->abort_code) {
			chan->last_abort = call->abort_code;
181 182
			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
		} else {
183
			chan->last_seq = call->rx_hard_ack;
184 185 186
			chan->last_type = RXRPC_PACKET_TYPE_ACK;
		}
		/* Sync with rxrpc_conn_retransmit(). */
187 188 189
		smp_wmb();
		chan->last_call = chan->call_id;
		chan->call_id = chan->call_counter;
190

191
		rcu_assign_pointer(chan->call, NULL);
192
	}
193

194 195 196 197 198 199 200 201 202 203 204
	_leave("");
}

/*
 * Disconnect a call and clear any channel it occupies when that call
 * terminates.
 */
void rxrpc_disconnect_call(struct rxrpc_call *call)
{
	struct rxrpc_connection *conn = call->conn;

205 206
	call->peer->cong_cwnd = call->cong_cwnd;

207 208 209 210
	spin_lock_bh(&conn->params.peer->lock);
	hlist_del_init(&call->error_link);
	spin_unlock_bh(&conn->params.peer->lock);

211 212 213
	if (rxrpc_is_client_call(call))
		return rxrpc_disconnect_client_call(call);

214
	spin_lock(&conn->channel_lock);
215
	__rxrpc_disconnect_call(conn, call);
216 217 218
	spin_unlock(&conn->channel_lock);

	call->conn = NULL;
219
	conn->idle_timestamp = jiffies;
220
	rxrpc_put_connection(conn);
221 222
}

223 224 225 226 227
/*
 * Kill off a connection.
 */
void rxrpc_kill_connection(struct rxrpc_connection *conn)
{
228 229
	struct rxrpc_net *rxnet = conn->params.local->rxnet;

230 231 232 233 234 235
	ASSERT(!rcu_access_pointer(conn->channels[0].call) &&
	       !rcu_access_pointer(conn->channels[1].call) &&
	       !rcu_access_pointer(conn->channels[2].call) &&
	       !rcu_access_pointer(conn->channels[3].call));
	ASSERT(list_empty(&conn->cache_link));

236
	write_lock(&rxnet->conn_lock);
237
	list_del_init(&conn->proc_link);
238
	write_unlock(&rxnet->conn_lock);
239 240 241 242 243 244 245 246 247 248 249 250 251 252

	/* Drain the Rx queue.  Note that even though we've unpublished, an
	 * incoming packet could still be being added to our Rx queue, so we
	 * will need to drain it again in the RCU cleanup handler.
	 */
	rxrpc_purge_queue(&conn->rx_queue);

	/* Leave final destruction to RCU.  The connection processor work item
	 * must carry a ref on the connection to prevent us getting here whilst
	 * it is queued or running.
	 */
	call_rcu(&conn->rcu, rxrpc_destroy_connection);
}

253
/*
254 255
 * Queue a connection's work processor, getting a ref to pass to the work
 * queue.
256
 */
257
bool rxrpc_queue_conn(struct rxrpc_connection *conn)
258
{
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
	const void *here = __builtin_return_address(0);
	int n = __atomic_add_unless(&conn->usage, 1, 0);
	if (n == 0)
		return false;
	if (rxrpc_queue_work(&conn->processor))
		trace_rxrpc_conn(conn, rxrpc_conn_queued, n + 1, here);
	else
		rxrpc_put_connection(conn);
	return true;
}

/*
 * Note the re-emergence of a connection.
 */
void rxrpc_see_connection(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);
	if (conn) {
		int n = atomic_read(&conn->usage);

		trace_rxrpc_conn(conn, rxrpc_conn_seen, n, here);
	}
}

/*
 * Get a ref on a connection.
 */
void rxrpc_get_connection(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);
	int n = atomic_inc_return(&conn->usage);

	trace_rxrpc_conn(conn, rxrpc_conn_got, n, here);
}

/*
 * Try to get a ref on a connection.
 */
struct rxrpc_connection *
rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
{
	const void *here = __builtin_return_address(0);

	if (conn) {
		int n = __atomic_add_unless(&conn->usage, 1, 0);
		if (n > 0)
			trace_rxrpc_conn(conn, rxrpc_conn_got, n + 1, here);
		else
			conn = NULL;
	}
	return conn;
}

/*
 * Release a service connection
 */
void rxrpc_put_service_conn(struct rxrpc_connection *conn)
{
317
	struct rxrpc_net *rxnet;
318 319 320 321 322 323
	const void *here = __builtin_return_address(0);
	int n;

	n = atomic_dec_return(&conn->usage);
	trace_rxrpc_conn(conn, rxrpc_conn_put_service, n, here);
	ASSERTCMP(n, >=, 0);
324 325 326 327
	if (n == 0) {
		rxnet = conn->params.local->rxnet;
		rxrpc_queue_delayed_work(&rxnet->service_conn_reaper, 0);
	}
328 329 330 331 332
}

/*
 * destroy a virtual connection
 */
333
static void rxrpc_destroy_connection(struct rcu_head *rcu)
334
{
335 336 337 338
	struct rxrpc_connection *conn =
		container_of(rcu, struct rxrpc_connection, rcu);

	_enter("{%d,u=%d}", conn->debug_id, atomic_read(&conn->usage));
339 340 341 342 343

	ASSERTCMP(atomic_read(&conn->usage), ==, 0);

	_net("DESTROY CONN %d", conn->debug_id);

344
	del_timer_sync(&conn->timer);
345 346
	rxrpc_purge_queue(&conn->rx_queue);

347
	conn->security->clear(conn);
348
	key_put(conn->params.key);
349
	key_put(conn->server_key);
350 351
	rxrpc_put_peer(conn->params.peer);
	rxrpc_put_local(conn->params.local);
352

353 354 355 356 357
	kfree(conn);
	_leave("");
}

/*
358
 * reap dead service connections
359
 */
360
void rxrpc_service_connection_reaper(struct work_struct *work)
361 362
{
	struct rxrpc_connection *conn, *_p;
363 364 365
	struct rxrpc_net *rxnet =
		container_of(to_delayed_work(work),
			     struct rxrpc_net, service_conn_reaper);
366
	unsigned long reap_older_than, earliest, idle_timestamp, now;
367 368 369 370 371

	LIST_HEAD(graveyard);

	_enter("");

372 373
	now = jiffies;
	reap_older_than = now - rxrpc_connection_expiry * HZ;
374 375
	earliest = ULONG_MAX;

376 377
	write_lock(&rxnet->conn_lock);
	list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
378 379
		ASSERTCMP(atomic_read(&conn->usage), >, 0);
		if (likely(atomic_read(&conn->usage) > 1))
380
			continue;
381 382
		if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
			continue;
383

384 385 386 387 388 389 390 391
		idle_timestamp = READ_ONCE(conn->idle_timestamp);
		_debug("reap CONN %d { u=%d,t=%ld }",
		       conn->debug_id, atomic_read(&conn->usage),
		       (long)reap_older_than - (long)idle_timestamp);

		if (time_after(idle_timestamp, reap_older_than)) {
			if (time_before(idle_timestamp, earliest))
				earliest = idle_timestamp;
392
			continue;
393
		}
394 395 396 397 398 399 400 401

		/* The usage count sits at 1 whilst the object is unused on the
		 * list; we reduce that to 0 to make the object unavailable.
		 */
		if (atomic_cmpxchg(&conn->usage, 1, 0) != 1)
			continue;

		if (rxrpc_conn_is_client(conn))
402
			BUG();
403 404 405 406
		else
			rxrpc_unpublish_service_conn(conn);

		list_move_tail(&conn->link, &graveyard);
407
	}
408
	write_unlock(&rxnet->conn_lock);
409 410 411

	if (earliest != ULONG_MAX) {
		_debug("reschedule reaper %ld", (long) earliest - now);
412
		ASSERT(time_after(earliest, now));
413
		rxrpc_queue_delayed_work(&rxnet->client_conn_reaper,
414
					 earliest - now);
415 416 417 418 419 420 421 422
	}

	while (!list_empty(&graveyard)) {
		conn = list_entry(graveyard.next, struct rxrpc_connection,
				  link);
		list_del_init(&conn->link);

		ASSERTCMP(atomic_read(&conn->usage), ==, 0);
423
		rxrpc_kill_connection(conn);
424 425 426 427 428 429
	}

	_leave("");
}

/*
430 431
 * preemptively destroy all the service connection records rather than
 * waiting for them to time out
432
 */
433
void rxrpc_destroy_all_connections(struct rxrpc_net *rxnet)
434
{
435 436 437
	struct rxrpc_connection *conn, *_p;
	bool leak = false;

438 439
	_enter("");

440
	rxrpc_destroy_all_client_connections(rxnet);
441

442
	rxrpc_connection_expiry = 0;
443 444
	cancel_delayed_work(&rxnet->client_conn_reaper);
	rxrpc_queue_delayed_work(&rxnet->client_conn_reaper, 0);
445 446
	flush_workqueue(rxrpc_workqueue);

447 448
	write_lock(&rxnet->conn_lock);
	list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
449 450 451 452
		pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
		       conn, atomic_read(&conn->usage));
		leak = true;
	}
453
	write_unlock(&rxnet->conn_lock);
454 455
	BUG_ON(leak);

456
	ASSERT(list_empty(&rxnet->conn_proc_list));
457 458 459

	_leave("");
}