aboutsummaryrefslogtreecommitdiff
path: root/net/rxrpc/ar-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/rxrpc/ar-connection.c')
-rw-r--r--net/rxrpc/ar-connection.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/net/rxrpc/ar-connection.c b/net/rxrpc/ar-connection.c
index 3869a586675..6631f4f1e39 100644
--- a/net/rxrpc/ar-connection.c
+++ b/net/rxrpc/ar-connection.c
@@ -10,6 +10,7 @@
*/
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
@@ -17,11 +18,15 @@
#include <net/af_rxrpc.h>
#include "ar-internal.h"
+/*
+ * Time till a connection expires after last use (in seconds).
+ */
+unsigned rxrpc_connection_expiry = 10 * 60;
+
static void rxrpc_connection_reaper(struct work_struct *work);
LIST_HEAD(rxrpc_connections);
DEFINE_RWLOCK(rxrpc_connection_lock);
-static unsigned long rxrpc_connection_timeout = 10 * 60;
static DECLARE_DELAYED_WORK(rxrpc_connection_reap, rxrpc_connection_reaper);
/*
@@ -343,9 +348,9 @@ static int rxrpc_connect_exclusive(struct rxrpc_sock *rx,
/* not yet present - create a candidate for a new connection
* and then redo the check */
conn = rxrpc_alloc_connection(gfp);
- if (IS_ERR(conn)) {
- _leave(" = %ld", PTR_ERR(conn));
- return PTR_ERR(conn);
+ if (!conn) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
}
conn->trans = trans;
@@ -380,6 +385,8 @@ static int rxrpc_connect_exclusive(struct rxrpc_sock *rx,
rxrpc_assign_connection_id(conn);
rx->conn = conn;
+ } else {
+ spin_lock(&trans->client_lock);
}
/* we've got a connection with a free channel and we can now attach the
@@ -444,6 +451,11 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
conn = list_entry(bundle->avail_conns.next,
struct rxrpc_connection,
bundle_link);
+ if (conn->state >= RXRPC_CONN_REMOTELY_ABORTED) {
+ list_del_init(&conn->bundle_link);
+ bundle->num_conns--;
+ continue;
+ }
if (--conn->avail_calls == 0)
list_move(&conn->bundle_link,
&bundle->busy_conns);
@@ -461,6 +473,11 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
conn = list_entry(bundle->unused_conns.next,
struct rxrpc_connection,
bundle_link);
+ if (conn->state >= RXRPC_CONN_REMOTELY_ABORTED) {
+ list_del_init(&conn->bundle_link);
+ bundle->num_conns--;
+ continue;
+ }
ASSERTCMP(conn->avail_calls, ==, RXRPC_MAXCALLS);
conn->avail_calls = RXRPC_MAXCALLS - 1;
ASSERT(conn->channels[0] == NULL &&
@@ -508,9 +525,9 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
/* not yet present - create a candidate for a new connection and then
* redo the check */
candidate = rxrpc_alloc_connection(gfp);
- if (IS_ERR(candidate)) {
- _leave(" = %ld", PTR_ERR(candidate));
- return PTR_ERR(candidate);
+ if (!candidate) {
+ _leave(" = -ENOMEM");
+ return -ENOMEM;
}
candidate->trans = trans;
@@ -826,7 +843,7 @@ static void rxrpc_destroy_connection(struct rxrpc_connection *conn)
/*
* reap dead connections
*/
-void rxrpc_connection_reaper(struct work_struct *work)
+static void rxrpc_connection_reaper(struct work_struct *work)
{
struct rxrpc_connection *conn, *_p;
unsigned long now, earliest, reap_time;
@@ -849,7 +866,7 @@ void rxrpc_connection_reaper(struct work_struct *work)
spin_lock(&conn->trans->client_lock);
write_lock(&conn->trans->conn_lock);
- reap_time = conn->put_time + rxrpc_connection_timeout;
+ reap_time = conn->put_time + rxrpc_connection_expiry;
if (atomic_read(&conn->usage) > 0) {
;
@@ -903,7 +920,7 @@ void __exit rxrpc_destroy_all_connections(void)
{
_enter("");
- rxrpc_connection_timeout = 0;
+ rxrpc_connection_expiry = 0;
cancel_delayed_work(&rxrpc_connection_reap);
rxrpc_queue_delayed_work(&rxrpc_connection_reap, 0);