Lines Matching refs:bundle
37 static void rxrpc_activate_bundle(struct rxrpc_bundle *bundle) in rxrpc_activate_bundle() argument
39 atomic_inc(&bundle->active); in rxrpc_activate_bundle()
77 struct rxrpc_bundle *bundle; in rxrpc_alloc_bundle() local
79 bundle = kzalloc(sizeof(*bundle), gfp); in rxrpc_alloc_bundle()
80 if (bundle) { in rxrpc_alloc_bundle()
81 bundle->local = call->local; in rxrpc_alloc_bundle()
82 bundle->peer = rxrpc_get_peer(call->peer, rxrpc_peer_get_bundle); in rxrpc_alloc_bundle()
83 bundle->key = key_get(call->key); in rxrpc_alloc_bundle()
84 bundle->security = call->security; in rxrpc_alloc_bundle()
85 bundle->exclusive = test_bit(RXRPC_CALL_EXCLUSIVE, &call->flags); in rxrpc_alloc_bundle()
86 bundle->upgrade = test_bit(RXRPC_CALL_UPGRADE, &call->flags); in rxrpc_alloc_bundle()
87 bundle->service_id = call->dest_srx.srx_service; in rxrpc_alloc_bundle()
88 bundle->security_level = call->security_level; in rxrpc_alloc_bundle()
89 bundle->debug_id = atomic_inc_return(&rxrpc_bundle_id); in rxrpc_alloc_bundle()
90 refcount_set(&bundle->ref, 1); in rxrpc_alloc_bundle()
91 atomic_set(&bundle->active, 1); in rxrpc_alloc_bundle()
92 INIT_LIST_HEAD(&bundle->waiting_calls); in rxrpc_alloc_bundle()
93 trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_new); in rxrpc_alloc_bundle()
95 write_lock(&bundle->local->rxnet->conn_lock); in rxrpc_alloc_bundle()
96 list_add_tail(&bundle->proc_link, &bundle->local->rxnet->bundle_proc_list); in rxrpc_alloc_bundle()
97 write_unlock(&bundle->local->rxnet->conn_lock); in rxrpc_alloc_bundle()
99 return bundle; in rxrpc_alloc_bundle()
102 struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle, in rxrpc_get_bundle() argument
107 __refcount_inc(&bundle->ref, &r); in rxrpc_get_bundle()
108 trace_rxrpc_bundle(bundle->debug_id, r + 1, why); in rxrpc_get_bundle()
109 return bundle; in rxrpc_get_bundle()
112 static void rxrpc_free_bundle(struct rxrpc_bundle *bundle) in rxrpc_free_bundle() argument
114 trace_rxrpc_bundle(bundle->debug_id, refcount_read(&bundle->ref), in rxrpc_free_bundle()
116 write_lock(&bundle->local->rxnet->conn_lock); in rxrpc_free_bundle()
117 list_del(&bundle->proc_link); in rxrpc_free_bundle()
118 write_unlock(&bundle->local->rxnet->conn_lock); in rxrpc_free_bundle()
119 rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle); in rxrpc_free_bundle()
120 key_put(bundle->key); in rxrpc_free_bundle()
121 kfree(bundle); in rxrpc_free_bundle()
124 void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why) in rxrpc_put_bundle() argument
130 if (bundle) { in rxrpc_put_bundle()
131 id = bundle->debug_id; in rxrpc_put_bundle()
132 dead = __refcount_dec_and_test(&bundle->ref, &r); in rxrpc_put_bundle()
135 rxrpc_free_bundle(bundle); in rxrpc_put_bundle()
152 rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle) in rxrpc_alloc_client_connection() argument
155 struct rxrpc_local *local = bundle->local; in rxrpc_alloc_client_connection()
176 conn->bundle = rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_conn); in rxrpc_alloc_client_connection()
177 conn->local = rxrpc_get_local(bundle->local, rxrpc_local_get_client_conn); in rxrpc_alloc_client_connection()
178 conn->peer = rxrpc_get_peer(bundle->peer, rxrpc_peer_get_client_conn); in rxrpc_alloc_client_connection()
179 conn->key = key_get(bundle->key); in rxrpc_alloc_client_connection()
180 conn->security = bundle->security; in rxrpc_alloc_client_connection()
181 conn->exclusive = bundle->exclusive; in rxrpc_alloc_client_connection()
182 conn->upgrade = bundle->upgrade; in rxrpc_alloc_client_connection()
183 conn->orig_service_id = bundle->service_id; in rxrpc_alloc_client_connection()
184 conn->security_level = bundle->security_level; in rxrpc_alloc_client_connection()
252 struct rxrpc_bundle *bundle, *candidate; in rxrpc_look_up_bundle() local
263 call->bundle = rxrpc_alloc_bundle(call, gfp); in rxrpc_look_up_bundle()
264 return call->bundle ? 0 : -ENOMEM; in rxrpc_look_up_bundle()
272 bundle = rb_entry(p, struct rxrpc_bundle, local_node); in rxrpc_look_up_bundle()
275 diff = (cmp(bundle->peer, call->peer) ?: in rxrpc_look_up_bundle()
276 cmp(bundle->key, call->key) ?: in rxrpc_look_up_bundle()
277 cmp(bundle->security_level, call->security_level) ?: in rxrpc_look_up_bundle()
278 cmp(bundle->upgrade, upgrade)); in rxrpc_look_up_bundle()
301 bundle = rb_entry(parent, struct rxrpc_bundle, local_node); in rxrpc_look_up_bundle()
304 diff = (cmp(bundle->peer, call->peer) ?: in rxrpc_look_up_bundle()
305 cmp(bundle->key, call->key) ?: in rxrpc_look_up_bundle()
306 cmp(bundle->security_level, call->security_level) ?: in rxrpc_look_up_bundle()
307 cmp(bundle->upgrade, upgrade)); in rxrpc_look_up_bundle()
320 call->bundle = rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call); in rxrpc_look_up_bundle()
322 _leave(" = B=%u [new]", call->bundle->debug_id); in rxrpc_look_up_bundle()
328 call->bundle = rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call); in rxrpc_look_up_bundle()
329 rxrpc_activate_bundle(bundle); in rxrpc_look_up_bundle()
331 _leave(" = B=%u [found]", call->bundle->debug_id); in rxrpc_look_up_bundle()
338 static bool rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle, in rxrpc_add_conn_to_bundle() argument
345 old = bundle->conns[slot]; in rxrpc_add_conn_to_bundle()
347 bundle->conns[slot] = NULL; in rxrpc_add_conn_to_bundle()
348 bundle->conn_ids[slot] = 0; in rxrpc_add_conn_to_bundle()
353 conn = rxrpc_alloc_client_connection(bundle); in rxrpc_add_conn_to_bundle()
355 bundle->alloc_error = PTR_ERR(conn); in rxrpc_add_conn_to_bundle()
359 rxrpc_activate_bundle(bundle); in rxrpc_add_conn_to_bundle()
361 bundle->conns[slot] = conn; in rxrpc_add_conn_to_bundle()
362 bundle->conn_ids[slot] = conn->debug_id; in rxrpc_add_conn_to_bundle()
364 set_bit(shift + i, &bundle->avail_chans); in rxrpc_add_conn_to_bundle()
372 static bool rxrpc_bundle_has_space(struct rxrpc_bundle *bundle) in rxrpc_bundle_has_space() argument
378 bundle->alloc_error = 0; in rxrpc_bundle_has_space()
382 for (i = 0; i < ARRAY_SIZE(bundle->conns); i++) { in rxrpc_bundle_has_space()
383 if (rxrpc_may_reuse_conn(bundle->conns[i])) in rxrpc_bundle_has_space()
389 if (!usable && bundle->upgrade) in rxrpc_bundle_has_space()
390 bundle->try_upgrade = true; in rxrpc_bundle_has_space()
395 if (!bundle->avail_chans && in rxrpc_bundle_has_space()
396 !bundle->try_upgrade && in rxrpc_bundle_has_space()
397 usable < ARRAY_SIZE(bundle->conns)) in rxrpc_bundle_has_space()
404 return slot >= 0 ? rxrpc_add_conn_to_bundle(bundle, slot) : false; in rxrpc_bundle_has_space()
416 struct rxrpc_bundle *bundle = conn->bundle; in rxrpc_activate_one_channel() local
417 struct rxrpc_call *call = list_entry(bundle->waiting_calls.next, in rxrpc_activate_one_channel()
431 clear_bit(conn->bundle_shift + channel, &bundle->avail_chans); in rxrpc_activate_one_channel()
470 static void rxrpc_activate_channels(struct rxrpc_bundle *bundle) in rxrpc_activate_channels() argument
478 if (bundle->try_upgrade) in rxrpc_activate_channels()
483 while (!list_empty(&bundle->waiting_calls)) { in rxrpc_activate_channels()
484 avail = bundle->avail_chans & mask; in rxrpc_activate_channels()
488 clear_bit(channel, &bundle->avail_chans); in rxrpc_activate_channels()
491 conn = bundle->conns[slot]; in rxrpc_activate_channels()
495 if (bundle->try_upgrade) in rxrpc_activate_channels()
519 struct rxrpc_bundle *bundle = call->bundle; in rxrpc_connect_client_calls() local
521 list_move_tail(&call->wait_link, &bundle->waiting_calls); in rxrpc_connect_client_calls()
524 if (rxrpc_bundle_has_space(bundle)) in rxrpc_connect_client_calls()
525 rxrpc_activate_channels(bundle); in rxrpc_connect_client_calls()
573 void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call *call) in rxrpc_disconnect_client_call() argument
577 struct rxrpc_local *local = bundle->local; in rxrpc_disconnect_client_call()
624 bundle->try_upgrade = false; in rxrpc_disconnect_client_call()
626 rxrpc_activate_channels(bundle); in rxrpc_disconnect_client_call()
631 if (may_reuse && !list_empty(&bundle->waiting_calls)) { in rxrpc_disconnect_client_call()
653 set_bit(conn->bundle_shift + channel, &conn->bundle->avail_chans); in rxrpc_disconnect_client_call()
676 struct rxrpc_bundle *bundle = conn->bundle; in rxrpc_unbundle_conn() local
686 if (bundle->conns[bindex] == conn) { in rxrpc_unbundle_conn()
688 bundle->conns[bindex] = NULL; in rxrpc_unbundle_conn()
689 bundle->conn_ids[bindex] = 0; in rxrpc_unbundle_conn()
691 clear_bit(conn->bundle_shift + i, &bundle->avail_chans); in rxrpc_unbundle_conn()
692 rxrpc_put_client_connection_id(bundle->local, conn); in rxrpc_unbundle_conn()
693 rxrpc_deactivate_bundle(bundle); in rxrpc_unbundle_conn()
701 void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle) in rxrpc_deactivate_bundle() argument
706 if (!bundle) in rxrpc_deactivate_bundle()
709 local = bundle->local; in rxrpc_deactivate_bundle()
710 if (atomic_dec_and_lock(&bundle->active, &local->client_bundles_lock)) { in rxrpc_deactivate_bundle()
711 if (!bundle->exclusive) { in rxrpc_deactivate_bundle()
713 rb_erase(&bundle->local_node, &local->client_bundles); in rxrpc_deactivate_bundle()
719 rxrpc_put_bundle(bundle, rxrpc_bundle_put_discard); in rxrpc_deactivate_bundle()