rxrpc: Provide more refcount helper functions

Provide refcount helper functions for connections so that the code doesn't
touch local or connection usage counts directly.

Also make it such that local and peer put functions can take a NULL
pointer.

Signed-off-by: David Howells <dhowells@redhat.com>
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index b29bb50..57dcbfc 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -674,11 +674,8 @@
 	flush_workqueue(rxrpc_workqueue);
 	rxrpc_purge_queue(&sk->sk_receive_queue);
 
-	if (rx->local) {
-		rxrpc_put_local(rx->local);
-		rx->local = NULL;
-	}
-
+	rxrpc_put_local(rx->local);
+	rx->local = NULL;
 	key_put(rx->key);
 	rx->key = NULL;
 	key_put(rx->securities);
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index cfbd028..c0ed5e7 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -597,6 +597,17 @@
 	return conn->proto.in_clientflag;
 }
 
+static inline void rxrpc_get_connection(struct rxrpc_connection *conn)
+{
+	atomic_inc(&conn->usage);
+}
+
+static inline
+struct rxrpc_connection *rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
+{
+	return atomic_inc_not_zero(&conn->usage) ? conn : NULL;
+}
+
 /*
  * input.c
  */
@@ -645,7 +656,7 @@
 
 static inline void rxrpc_put_local(struct rxrpc_local *local)
 {
-	if (atomic_dec_and_test(&local->usage))
+	if (local && atomic_dec_and_test(&local->usage))
 		__rxrpc_put_local(local);
 }
 
@@ -702,7 +713,7 @@
 extern void __rxrpc_put_peer(struct rxrpc_peer *peer);
 static inline void rxrpc_put_peer(struct rxrpc_peer *peer)
 {
-	if (atomic_dec_and_test(&peer->usage))
+	if (peer && atomic_dec_and_test(&peer->usage))
 		__rxrpc_put_peer(peer);
 }
 
diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c
index 5a70dc4..833ad06 100644
--- a/net/rxrpc/call_accept.c
+++ b/net/rxrpc/call_accept.c
@@ -141,7 +141,7 @@
 			_debug("await conn sec");
 			list_add_tail(&call->accept_link, &rx->secureq);
 			call->conn->state = RXRPC_CONN_SERVER_CHALLENGING;
-			atomic_inc(&call->conn->usage);
+			rxrpc_get_connection(call->conn);
 			set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events);
 			rxrpc_queue_conn(call->conn);
 		} else {
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c
index d83f2cb..45849a6 100644
--- a/net/rxrpc/call_object.c
+++ b/net/rxrpc/call_object.c
@@ -515,7 +515,7 @@
 	rb_insert_color(&call->conn_node, &conn->calls);
 	conn->channels[call->channel] = call;
 	sock_hold(&rx->sk);
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	write_unlock_bh(&conn->lock);
 
 	spin_lock(&conn->params.peer->lock);
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index a022439..bf69715 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -263,7 +263,7 @@
 
 	_enter("{%d}", conn->debug_id);
 
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 
 	if (test_and_clear_bit(RXRPC_CONN_CHALLENGE, &conn->events)) {
 		rxrpc_secure_connection(conn);
diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c
index 312b750..1754f2e 100644
--- a/net/rxrpc/conn_object.c
+++ b/net/rxrpc/conn_object.c
@@ -333,7 +333,7 @@
 	 * channel.
 	 */
 	chan = 0;
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	conn->avail_calls = RXRPC_MAXCALLS - 1;
 	conn->channels[chan] = call;
 	conn->call_counter = 1;
@@ -392,7 +392,7 @@
 			       conn->channels[1] == NULL ||
 			       conn->channels[2] == NULL ||
 			       conn->channels[3] == NULL);
-			atomic_inc(&conn->usage);
+			rxrpc_get_connection(conn);
 			break;
 		}
 
@@ -412,7 +412,7 @@
 			       conn->channels[1] == NULL &&
 			       conn->channels[2] == NULL &&
 			       conn->channels[3] == NULL);
-			atomic_inc(&conn->usage);
+			rxrpc_get_connection(conn);
 			list_move(&conn->bundle_link, &bundle->avail_conns);
 			break;
 		}
@@ -629,7 +629,7 @@
 		read_unlock_bh(&trans->conn_lock);
 		goto security_mismatch;
 	}
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	read_unlock_bh(&trans->conn_lock);
 	goto success;
 
@@ -639,7 +639,7 @@
 		write_unlock_bh(&trans->conn_lock);
 		goto security_mismatch;
 	}
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	write_unlock_bh(&trans->conn_lock);
 	kfree(candidate);
 	goto success;
@@ -698,7 +698,7 @@
 	return NULL;
 
 found:
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	read_unlock_bh(&trans->conn_lock);
 	_leave(" = %p", conn);
 	return conn;
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index cf540ef..799aec1 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -580,7 +580,7 @@
 {
 	_enter("%p,%p", conn, skb);
 
-	atomic_inc(&conn->usage);
+	rxrpc_get_connection(conn);
 	skb_queue_tail(&conn->rx_queue, skb);
 	rxrpc_queue_conn(conn);
 }
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 009b321..5703b0d 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -209,7 +209,7 @@
 		 * bind the transport socket may still fail if we're attempting
 		 * to use a local address that the dying object is still using.
 		 */
-		if (!atomic_inc_not_zero(&local->usage)) {
+		if (!rxrpc_get_local_maybe(local)) {
 			cursor = cursor->next;
 			list_del_init(&local->link);
 			break;