summaryrefslogtreecommitdiffstats
path: root/net/rxrpc/conn_event.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-06-27 10:32:03 +0100
committerDavid Howells <dhowells@redhat.com>2016-07-06 10:43:51 +0100
commit2c4579e4b1d5a6219522c6e970500b2fd43fe1f8 (patch)
treec1b3c53567772f18c104213a0296b0860f5157c2 /net/rxrpc/conn_event.c
parenteb9b9d22754d1926771a22638e81384d517c6ce5 (diff)
downloadlinux-2c4579e4b1d5a6219522c6e970500b2fd43fe1f8.tar.gz
linux-2c4579e4b1d5a6219522c6e970500b2fd43fe1f8.tar.bz2
linux-2c4579e4b1d5a6219522c6e970500b2fd43fe1f8.zip
rxrpc: Move usage count getting into rxrpc_queue_conn()
Rather than calling rxrpc_get_connection() manually before calling rxrpc_queue_conn(), do it inside the queue wrapper. This allows us to do some important fixes: (1) If the usage count is 0, do nothing. This prevents connections from being reanimated once they're dead. (2) If rxrpc_queue_work() fails because the work item is already queued, retract the usage count increment which would otherwise be lost. (3) Don't take a ref on the connection in the work function. By passing the ref through the work item, this is unnecessary. Doing it in the work function is too late anyway. Previously, connection-directed packets held a ref on the connection, but that's not really the best idea. And another useful changes: (*) Don't need to take a refcount on the connection in the data_ready handler unless we invoke the connection's work item. We're using RCU there so that's otherwise redundant. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net/rxrpc/conn_event.c')
-rw-r--r--net/rxrpc/conn_event.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c
index b9c39b83eddb..9ceddd3fd5db 100644
--- a/net/rxrpc/conn_event.c
+++ b/net/rxrpc/conn_event.c
@@ -266,12 +266,8 @@ void rxrpc_process_connection(struct work_struct *work)
_enter("{%d}", conn->debug_id);
- rxrpc_get_connection(conn);
-
- if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events)) {
+ if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events))
rxrpc_secure_connection(conn);
- rxrpc_put_connection(conn);
- }
/* go through the conn-level event packets, releasing the ref on this
* connection that each one has when we've finished with it */
@@ -286,7 +282,6 @@ void rxrpc_process_connection(struct work_struct *work)
goto requeue_and_leave;
case -ECONNABORTED:
default:
- rxrpc_put_connection(conn);
rxrpc_free_skb(skb);
break;
}
@@ -304,7 +299,6 @@ requeue_and_leave:
protocol_error:
if (rxrpc_abort_connection(conn, -ret, abort_code) < 0)
goto requeue_and_leave;
- rxrpc_put_connection(conn);
rxrpc_free_skb(skb);
_leave(" [EPROTO]");
goto out;