Commit 1bab27af authored by David Howells's avatar David Howells

rxrpc: Set up a connection bundle from a call, not rxrpc_conn_parameters

Use the information now stored in struct rxrpc_call to configure the
connection bundle and thence the connection, rather than using the
rxrpc_conn_parameters struct.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent 2953d3b8
...@@ -178,7 +178,6 @@ ...@@ -178,7 +178,6 @@
#define rxrpc_peer_traces \ #define rxrpc_peer_traces \
EM(rxrpc_peer_free, "FREE ") \ EM(rxrpc_peer_free, "FREE ") \
EM(rxrpc_peer_get_accept, "GET accept ") \ EM(rxrpc_peer_get_accept, "GET accept ") \
EM(rxrpc_peer_get_activate_call, "GET act-call") \
EM(rxrpc_peer_get_bundle, "GET bundle ") \ EM(rxrpc_peer_get_bundle, "GET bundle ") \
EM(rxrpc_peer_get_client_conn, "GET cln-conn") \ EM(rxrpc_peer_get_client_conn, "GET cln-conn") \
EM(rxrpc_peer_get_input, "GET input ") \ EM(rxrpc_peer_get_input, "GET input ") \
...@@ -191,7 +190,6 @@ ...@@ -191,7 +190,6 @@
EM(rxrpc_peer_put_bundle, "PUT bundle ") \ EM(rxrpc_peer_put_bundle, "PUT bundle ") \
EM(rxrpc_peer_put_call, "PUT call ") \ EM(rxrpc_peer_put_call, "PUT call ") \
EM(rxrpc_peer_put_conn, "PUT conn ") \ EM(rxrpc_peer_put_conn, "PUT conn ") \
EM(rxrpc_peer_put_discard_tmp, "PUT disc-tmp") \
EM(rxrpc_peer_put_input, "PUT input ") \ EM(rxrpc_peer_put_input, "PUT input ") \
EM(rxrpc_peer_put_input_error, "PUT inpt-err") \ EM(rxrpc_peer_put_input_error, "PUT inpt-err") \
E_(rxrpc_peer_put_keepalive, "PUT keepaliv") E_(rxrpc_peer_put_keepalive, "PUT keepaliv")
...@@ -201,6 +199,7 @@ ...@@ -201,6 +199,7 @@
EM(rxrpc_bundle_get_client_call, "GET clt-call") \ EM(rxrpc_bundle_get_client_call, "GET clt-call") \
EM(rxrpc_bundle_get_client_conn, "GET clt-conn") \ EM(rxrpc_bundle_get_client_conn, "GET clt-conn") \
EM(rxrpc_bundle_get_service_conn, "GET svc-conn") \ EM(rxrpc_bundle_get_service_conn, "GET svc-conn") \
EM(rxrpc_bundle_put_call, "PUT call ") \
EM(rxrpc_bundle_put_conn, "PUT conn ") \ EM(rxrpc_bundle_put_conn, "PUT conn ") \
EM(rxrpc_bundle_put_discard, "PUT discard ") \ EM(rxrpc_bundle_put_discard, "PUT discard ") \
E_(rxrpc_bundle_new, "NEW ") E_(rxrpc_bundle_new, "NEW ")
......
...@@ -328,7 +328,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock, ...@@ -328,7 +328,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
mutex_unlock(&call->user_mutex); mutex_unlock(&call->user_mutex);
} }
rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp);
_leave(" = %p", call); _leave(" = %p", call);
return call; return call;
} }
......
...@@ -360,7 +360,6 @@ struct rxrpc_conn_proto { ...@@ -360,7 +360,6 @@ struct rxrpc_conn_proto {
struct rxrpc_conn_parameters { struct rxrpc_conn_parameters {
struct rxrpc_local *local; /* Representation of local endpoint */ struct rxrpc_local *local; /* Representation of local endpoint */
struct rxrpc_peer *peer; /* Remote endpoint */
struct key *key; /* Security details */ struct key *key; /* Security details */
bool exclusive; /* T if conn is exclusive */ bool exclusive; /* T if conn is exclusive */
bool upgrade; /* T if service ID can be upgraded */ bool upgrade; /* T if service ID can be upgraded */
...@@ -428,6 +427,7 @@ struct rxrpc_bundle { ...@@ -428,6 +427,7 @@ struct rxrpc_bundle {
struct rxrpc_local *local; /* Representation of local endpoint */ struct rxrpc_local *local; /* Representation of local endpoint */
struct rxrpc_peer *peer; /* Remote endpoint */ struct rxrpc_peer *peer; /* Remote endpoint */
struct key *key; /* Security details */ struct key *key; /* Security details */
const struct rxrpc_security *security; /* applied security module */
refcount_t ref; refcount_t ref;
atomic_t active; /* Number of active users */ atomic_t active; /* Number of active users */
unsigned int debug_id; unsigned int debug_id;
...@@ -593,6 +593,7 @@ enum rxrpc_congest_mode { ...@@ -593,6 +593,7 @@ enum rxrpc_congest_mode {
struct rxrpc_call { struct rxrpc_call {
struct rcu_head rcu; struct rcu_head rcu;
struct rxrpc_connection *conn; /* connection carrying call */ struct rxrpc_connection *conn; /* connection carrying call */
struct rxrpc_bundle *bundle; /* Connection bundle to use */
struct rxrpc_peer *peer; /* Peer record for remote address */ struct rxrpc_peer *peer; /* Peer record for remote address */
struct rxrpc_local *local; /* Representation of local endpoint */ struct rxrpc_local *local; /* Representation of local endpoint */
struct rxrpc_sock __rcu *socket; /* socket responsible */ struct rxrpc_sock __rcu *socket; /* socket responsible */
...@@ -894,11 +895,10 @@ extern unsigned long rxrpc_conn_idle_client_fast_expiry; ...@@ -894,11 +895,10 @@ extern unsigned long rxrpc_conn_idle_client_fast_expiry;
void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local); void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local);
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace); struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace); void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *, int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp);
struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *,
gfp_t);
void rxrpc_expose_client_call(struct rxrpc_call *); void rxrpc_expose_client_call(struct rxrpc_call *);
void rxrpc_disconnect_client_call(struct rxrpc_bundle *, struct rxrpc_call *); void rxrpc_disconnect_client_call(struct rxrpc_bundle *, struct rxrpc_call *);
void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle);
void rxrpc_put_client_conn(struct rxrpc_connection *, enum rxrpc_conn_trace); void rxrpc_put_client_conn(struct rxrpc_connection *, enum rxrpc_conn_trace);
void rxrpc_discard_expired_client_conns(struct work_struct *); void rxrpc_discard_expired_client_conns(struct work_struct *);
void rxrpc_destroy_all_client_connections(struct rxrpc_net *); void rxrpc_destroy_all_client_connections(struct rxrpc_net *);
......
...@@ -365,7 +365,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx, ...@@ -365,7 +365,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
/* Set up or get a connection record and set the protocol parameters, /* Set up or get a connection record and set the protocol parameters,
* including channel number and call ID. * including channel number and call ID.
*/ */
ret = rxrpc_connect_call(rx, call, cp, srx, gfp); ret = rxrpc_connect_call(call, gfp);
if (ret < 0) if (ret < 0)
goto error_attached_to_socket; goto error_attached_to_socket;
...@@ -663,6 +663,8 @@ static void rxrpc_destroy_call(struct work_struct *work) ...@@ -663,6 +663,8 @@ static void rxrpc_destroy_call(struct work_struct *work)
rxrpc_put_txbuf(call->tx_pending, rxrpc_txbuf_put_cleaned); rxrpc_put_txbuf(call->tx_pending, rxrpc_txbuf_put_cleaned);
rxrpc_put_connection(call->conn, rxrpc_conn_put_call); rxrpc_put_connection(call->conn, rxrpc_conn_put_call);
rxrpc_deactivate_bundle(call->bundle);
rxrpc_put_bundle(call->bundle, rxrpc_bundle_put_call);
rxrpc_put_peer(call->peer, rxrpc_peer_put_call); rxrpc_put_peer(call->peer, rxrpc_peer_put_call);
rxrpc_put_local(call->local, rxrpc_local_put_call); rxrpc_put_local(call->local, rxrpc_local_put_call);
call_rcu(&call->rcu, rxrpc_rcu_free_call); call_rcu(&call->rcu, rxrpc_rcu_free_call);
......
...@@ -34,7 +34,10 @@ __read_mostly unsigned int rxrpc_reap_client_connections = 900; ...@@ -34,7 +34,10 @@ __read_mostly unsigned int rxrpc_reap_client_connections = 900;
__read_mostly unsigned long rxrpc_conn_idle_client_expiry = 2 * 60 * HZ; __read_mostly unsigned long rxrpc_conn_idle_client_expiry = 2 * 60 * HZ;
__read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ; __read_mostly unsigned long rxrpc_conn_idle_client_fast_expiry = 2 * HZ;
static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle); static void rxrpc_activate_bundle(struct rxrpc_bundle *bundle)
{
atomic_inc(&bundle->active);
}
/* /*
* Get a connection ID and epoch for a client connection from the global pool. * Get a connection ID and epoch for a client connection from the global pool.
...@@ -109,20 +112,21 @@ void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local) ...@@ -109,20 +112,21 @@ void rxrpc_destroy_client_conn_ids(struct rxrpc_local *local)
/* /*
* Allocate a connection bundle. * Allocate a connection bundle.
*/ */
static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp, static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call,
gfp_t gfp) gfp_t gfp)
{ {
struct rxrpc_bundle *bundle; struct rxrpc_bundle *bundle;
bundle = kzalloc(sizeof(*bundle), gfp); bundle = kzalloc(sizeof(*bundle), gfp);
if (bundle) { if (bundle) {
bundle->local = cp->local; bundle->local = call->local;
bundle->peer = rxrpc_get_peer(cp->peer, rxrpc_peer_get_bundle); bundle->peer = rxrpc_get_peer(call->peer, rxrpc_peer_get_bundle);
bundle->key = cp->key; bundle->key = key_get(call->key);
bundle->exclusive = cp->exclusive; bundle->security = call->security;
bundle->upgrade = cp->upgrade; bundle->exclusive = test_bit(RXRPC_CALL_EXCLUSIVE, &call->flags);
bundle->service_id = cp->service_id; bundle->upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags);
bundle->security_level = cp->security_level; bundle->service_id = call->dest_srx.srx_service;
bundle->security_level = call->security_level;
refcount_set(&bundle->ref, 1); refcount_set(&bundle->ref, 1);
atomic_set(&bundle->active, 1); atomic_set(&bundle->active, 1);
spin_lock_init(&bundle->channel_lock); spin_lock_init(&bundle->channel_lock);
...@@ -146,19 +150,23 @@ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle) ...@@ -146,19 +150,23 @@ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
{ {
trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free); trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free);
rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle); rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
key_put(bundle->key);
kfree(bundle); kfree(bundle);
} }
void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why) void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why)
{ {
unsigned int id = bundle->debug_id; unsigned int id;
bool dead; bool dead;
int r; int r;
dead = __refcount_dec_and_test(&bundle->ref, &r); if (bundle) {
trace_rxrpc_bundle(id, r - 1, why); id = bundle->debug_id;
if (dead) dead = __refcount_dec_and_test(&bundle->ref, &r);
rxrpc_free_bundle(bundle); trace_rxrpc_bundle(id, r - 1, why);
if (dead)
rxrpc_free_bundle(bundle);
}
} }
/* /*
...@@ -272,20 +280,23 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn) ...@@ -272,20 +280,23 @@ static bool rxrpc_may_reuse_conn(struct rxrpc_connection *conn)
* Look up the conn bundle that matches the connection parameters, adding it if * Look up the conn bundle that matches the connection parameters, adding it if
* it doesn't yet exist. * it doesn't yet exist.
*/ */
static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *cp, static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_call *call, gfp_t gfp)
gfp_t gfp)
{ {
static atomic_t rxrpc_bundle_id; static atomic_t rxrpc_bundle_id;
struct rxrpc_bundle *bundle, *candidate; struct rxrpc_bundle *bundle, *candidate;
struct rxrpc_local *local = cp->local; struct rxrpc_local *local = call->local;
struct rb_node *p, **pp, *parent; struct rb_node *p, **pp, *parent;
long diff; long diff;
bool upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags);
_enter("{%px,%x,%u,%u}", _enter("{%px,%x,%u,%u}",
cp->peer, key_serial(cp->key), cp->security_level, cp->upgrade); call->peer, key_serial(call->key), call->security_level,
upgrade);
if (cp->exclusive) if (test_bit(RXRPC_CALL_EXCLUSIVE, &call->flags)) {
return rxrpc_alloc_bundle(cp, gfp); call->bundle = rxrpc_alloc_bundle(call, gfp);
return call->bundle;
}
/* First, see if the bundle is already there. */ /* First, see if the bundle is already there. */
_debug("search 1"); _debug("search 1");
...@@ -294,11 +305,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c ...@@ -294,11 +305,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
while (p) { while (p) {
bundle = rb_entry(p, struct rxrpc_bundle, local_node); bundle = rb_entry(p, struct rxrpc_bundle, local_node);
#define cmp(X) ((long)bundle->X - (long)cp->X) #define cmp(X, Y) ((long)(X) - (long)(Y))
diff = (cmp(peer) ?: diff = (cmp(bundle->peer, call->peer) ?:
cmp(key) ?: cmp(bundle->key, call->key) ?:
cmp(security_level) ?: cmp(bundle->security_level, call->security_level) ?:
cmp(upgrade)); cmp(bundle->upgrade, upgrade));
#undef cmp #undef cmp
if (diff < 0) if (diff < 0)
p = p->rb_left; p = p->rb_left;
...@@ -311,9 +322,9 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c ...@@ -311,9 +322,9 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
_debug("not found"); _debug("not found");
/* It wasn't. We need to add one. */ /* It wasn't. We need to add one. */
candidate = rxrpc_alloc_bundle(cp, gfp); candidate = rxrpc_alloc_bundle(call, gfp);
if (!candidate) if (!candidate)
return NULL; return ERR_PTR(-ENOMEM);
_debug("search 2"); _debug("search 2");
spin_lock(&local->client_bundles_lock); spin_lock(&local->client_bundles_lock);
...@@ -323,11 +334,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c ...@@ -323,11 +334,11 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
parent = *pp; parent = *pp;
bundle = rb_entry(parent, struct rxrpc_bundle, local_node); bundle = rb_entry(parent, struct rxrpc_bundle, local_node);
#define cmp(X) ((long)bundle->X - (long)cp->X) #define cmp(X, Y) ((long)(X) - (long)(Y))
diff = (cmp(peer) ?: diff = (cmp(bundle->peer, call->peer) ?:
cmp(key) ?: cmp(bundle->key, call->key) ?:
cmp(security_level) ?: cmp(bundle->security_level, call->security_level) ?:
cmp(upgrade)); cmp(bundle->upgrade, upgrade));
#undef cmp #undef cmp
if (diff < 0) if (diff < 0)
pp = &(*pp)->rb_left; pp = &(*pp)->rb_left;
...@@ -341,19 +352,19 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c ...@@ -341,19 +352,19 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id); candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id);
rb_link_node(&candidate->local_node, parent, pp); rb_link_node(&candidate->local_node, parent, pp);
rb_insert_color(&candidate->local_node, &local->client_bundles); rb_insert_color(&candidate->local_node, &local->client_bundles);
rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call); call->bundle = rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
spin_unlock(&local->client_bundles_lock); spin_unlock(&local->client_bundles_lock);
_leave(" = %u [new]", candidate->debug_id); _leave(" = B=%u [new]", call->bundle->debug_id);
return candidate; return call->bundle;
found_bundle_free: found_bundle_free:
rxrpc_free_bundle(candidate); rxrpc_free_bundle(candidate);
found_bundle: found_bundle:
rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call); call->bundle = rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call);
atomic_inc(&bundle->active); rxrpc_activate_bundle(bundle);
spin_unlock(&local->client_bundles_lock); spin_unlock(&local->client_bundles_lock);
_leave(" = %u [found]", bundle->debug_id); _leave(" = B=%u [found]", call->bundle->debug_id);
return bundle; return call->bundle;
} }
/* /*
...@@ -362,31 +373,25 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c ...@@ -362,31 +373,25 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
* If we return with a connection, the call will be on its waiting list. It's * If we return with a connection, the call will be on its waiting list. It's
* left to the caller to assign a channel and wake up the call. * left to the caller to assign a channel and wake up the call.
*/ */
static struct rxrpc_bundle *rxrpc_prep_call(struct rxrpc_sock *rx, static struct rxrpc_bundle *rxrpc_prep_call(struct rxrpc_call *call, gfp_t gfp)
struct rxrpc_call *call,
struct rxrpc_conn_parameters *cp,
struct sockaddr_rxrpc *srx,
gfp_t gfp)
{ {
struct rxrpc_bundle *bundle; struct rxrpc_bundle *bundle;
_enter("{%d,%lx},", call->debug_id, call->user_call_ID); _enter("{%d,%lx},", call->debug_id, call->user_call_ID);
cp->peer = rxrpc_lookup_peer(cp->local, srx, gfp); call->peer = rxrpc_lookup_peer(call->local, &call->dest_srx, gfp);
if (!cp->peer) if (!call->peer)
goto error; goto error;
call->tx_last_sent = ktime_get_real(); call->tx_last_sent = ktime_get_real();
call->cong_ssthresh = cp->peer->cong_ssthresh; call->cong_ssthresh = call->peer->cong_ssthresh;
if (call->cong_cwnd >= call->cong_ssthresh) if (call->cong_cwnd >= call->cong_ssthresh)
call->cong_mode = RXRPC_CALL_CONGEST_AVOIDANCE; call->cong_mode = RXRPC_CALL_CONGEST_AVOIDANCE;
else else
call->cong_mode = RXRPC_CALL_SLOW_START; call->cong_mode = RXRPC_CALL_SLOW_START;
if (cp->upgrade)
__set_bit(RXRPC_CALL_UPGRADE, &call->flags);
/* Find the client connection bundle. */ /* Find the client connection bundle. */
bundle = rxrpc_look_up_bundle(cp, gfp); bundle = rxrpc_look_up_bundle(call, gfp);
if (!bundle) if (!bundle)
goto error; goto error;
...@@ -449,7 +454,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp) ...@@ -449,7 +454,7 @@ static void rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, gfp_t gfp)
if (old) if (old)
trace_rxrpc_client(old, -1, rxrpc_client_replace); trace_rxrpc_client(old, -1, rxrpc_client_replace);
candidate->bundle_shift = shift; candidate->bundle_shift = shift;
atomic_inc(&bundle->active); rxrpc_activate_bundle(bundle);
bundle->conns[i] = candidate; bundle->conns[i] = candidate;
for (j = 0; j < RXRPC_MAXCALLS; j++) for (j = 0; j < RXRPC_MAXCALLS; j++)
set_bit(shift + j, &bundle->avail_chans); set_bit(shift + j, &bundle->avail_chans);
...@@ -541,7 +546,6 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn, ...@@ -541,7 +546,6 @@ static void rxrpc_activate_one_channel(struct rxrpc_connection *conn,
rxrpc_see_call(call, rxrpc_call_see_activate_client); rxrpc_see_call(call, rxrpc_call_see_activate_client);
list_del_init(&call->chan_wait_link); list_del_init(&call->chan_wait_link);
call->peer = rxrpc_get_peer(conn->peer, rxrpc_peer_get_activate_call);
call->conn = rxrpc_get_connection(conn, rxrpc_conn_get_activate_call); call->conn = rxrpc_get_connection(conn, rxrpc_conn_get_activate_call);
call->cid = conn->proto.cid | channel; call->cid = conn->proto.cid | channel;
call->call_id = call_id; call->call_id = call_id;
...@@ -705,14 +709,11 @@ static int rxrpc_wait_for_channel(struct rxrpc_bundle *bundle, ...@@ -705,14 +709,11 @@ static int rxrpc_wait_for_channel(struct rxrpc_bundle *bundle,
* find a connection for a call * find a connection for a call
* - called in process context with IRQs enabled * - called in process context with IRQs enabled
*/ */
int rxrpc_connect_call(struct rxrpc_sock *rx, int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp)
struct rxrpc_call *call,
struct rxrpc_conn_parameters *cp,
struct sockaddr_rxrpc *srx,
gfp_t gfp)
{ {
struct rxrpc_bundle *bundle; struct rxrpc_bundle *bundle;
struct rxrpc_net *rxnet = cp->local->rxnet; struct rxrpc_local *local = call->local;
struct rxrpc_net *rxnet = local->rxnet;
int ret = 0; int ret = 0;
_enter("{%d,%lx},", call->debug_id, call->user_call_ID); _enter("{%d,%lx},", call->debug_id, call->user_call_ID);
...@@ -721,7 +722,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx, ...@@ -721,7 +722,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
rxrpc_get_call(call, rxrpc_call_get_io_thread); rxrpc_get_call(call, rxrpc_call_get_io_thread);
bundle = rxrpc_prep_call(rx, call, cp, srx, gfp); bundle = rxrpc_prep_call(call, gfp);
if (IS_ERR(bundle)) { if (IS_ERR(bundle)) {
rxrpc_put_call(call, rxrpc_call_get_io_thread); rxrpc_put_call(call, rxrpc_call_get_io_thread);
ret = PTR_ERR(bundle); ret = PTR_ERR(bundle);
...@@ -738,9 +739,6 @@ int rxrpc_connect_call(struct rxrpc_sock *rx, ...@@ -738,9 +739,6 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
/* Paired with the write barrier in rxrpc_activate_one_channel(). */ /* Paired with the write barrier in rxrpc_activate_one_channel(). */
smp_rmb(); smp_rmb();
out_put_bundle:
rxrpc_deactivate_bundle(bundle);
rxrpc_put_bundle(bundle, rxrpc_bundle_get_client_call);
out: out:
_leave(" = %d", ret); _leave(" = %d", ret);
return ret; return ret;
...@@ -758,7 +756,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx, ...@@ -758,7 +756,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,
trace_rxrpc_client(call->conn, ret, rxrpc_client_chan_wait_failed); trace_rxrpc_client(call->conn, ret, rxrpc_client_chan_wait_failed);
rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret); rxrpc_set_call_completion(call, RXRPC_CALL_LOCAL_ERROR, 0, ret);
rxrpc_disconnect_client_call(bundle, call); rxrpc_disconnect_client_call(bundle, call);
goto out_put_bundle; goto out;
} }
/* /*
...@@ -945,11 +943,15 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn) ...@@ -945,11 +943,15 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
/* /*
* Drop the active count on a bundle. * Drop the active count on a bundle.
*/ */
static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle) void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)
{ {
struct rxrpc_local *local = bundle->local; struct rxrpc_local *local;
bool need_put = false; bool need_put = false;
if (!bundle)
return;
local = bundle->local;
if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) { if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) {
if (!bundle->exclusive) { if (!bundle->exclusive) {
_debug("erase bundle"); _debug("erase bundle");
......
...@@ -208,7 +208,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call) ...@@ -208,7 +208,7 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
} }
if (rxrpc_is_client_call(call)) { if (rxrpc_is_client_call(call)) {
rxrpc_disconnect_client_call(conn->bundle, call); rxrpc_disconnect_client_call(call->bundle, call);
} else { } else {
spin_lock(&conn->bundle->channel_lock); spin_lock(&conn->bundle->channel_lock);
__rxrpc_disconnect_call(conn, call); __rxrpc_disconnect_call(conn, call);
......
...@@ -564,7 +564,6 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg, ...@@ -564,7 +564,6 @@ rxrpc_new_client_call_for_sendmsg(struct rxrpc_sock *rx, struct msghdr *msg,
atomic_inc_return(&rxrpc_debug_id)); atomic_inc_return(&rxrpc_debug_id));
/* The socket is now unlocked */ /* The socket is now unlocked */
rxrpc_put_peer(cp.peer, rxrpc_peer_put_discard_tmp);
_leave(" = %p\n", call); _leave(" = %p\n", call);
return call; return call;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment