Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux.git] / net / rxrpc / call_object.c
index 0b2db38dd32d4c2418827236faf5219bc70cc97f..f6734d8cb01a711317854a17c981b2506625846b 100644 (file)
@@ -99,9 +99,11 @@ found_extant_call:
 /*
  * allocate a new call
  */
-struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp)
+struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
+                                   unsigned int debug_id)
 {
        struct rxrpc_call *call;
+       struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk));
 
        call = kmem_cache_zalloc(rxrpc_call_jar, gfp);
        if (!call)
@@ -138,7 +140,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp)
        spin_lock_init(&call->notify_lock);
        rwlock_init(&call->state_lock);
        atomic_set(&call->usage, 1);
-       call->debug_id = atomic_inc_return(&rxrpc_debug_id);
+       call->debug_id = debug_id;
        call->tx_total_len = -1;
        call->next_rx_timo = 20 * HZ;
        call->next_req_timo = 1 * HZ;
@@ -152,6 +154,9 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp)
 
        call->cong_cwnd = 2;
        call->cong_ssthresh = RXRPC_RXTX_BUFF_SIZE - 1;
+
+       call->rxnet = rxnet;
+       atomic_inc(&rxnet->nr_calls);
        return call;
 
 nomem_2:
@@ -166,14 +171,15 @@ nomem:
  */
 static struct rxrpc_call *rxrpc_alloc_client_call(struct rxrpc_sock *rx,
                                                  struct sockaddr_rxrpc *srx,
-                                                 gfp_t gfp)
+                                                 gfp_t gfp,
+                                                 unsigned int debug_id)
 {
        struct rxrpc_call *call;
        ktime_t now;
 
        _enter("");
 
-       call = rxrpc_alloc_call(rx, gfp);
+       call = rxrpc_alloc_call(rx, gfp, debug_id);
        if (!call)
                return ERR_PTR(-ENOMEM);
        call->state = RXRPC_CALL_CLIENT_AWAIT_CONN;
@@ -214,18 +220,20 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
                                         struct rxrpc_conn_parameters *cp,
                                         struct sockaddr_rxrpc *srx,
                                         struct rxrpc_call_params *p,
-                                        gfp_t gfp)
+                                        gfp_t gfp,
+                                        unsigned int debug_id)
        __releases(&rx->sk.sk_lock.slock)
+       __acquires(&call->user_mutex)
 {
        struct rxrpc_call *call, *xcall;
-       struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk));
+       struct rxrpc_net *rxnet;
        struct rb_node *parent, **pp;
        const void *here = __builtin_return_address(0);
        int ret;
 
        _enter("%p,%lx", rx, p->user_call_ID);
 
-       call = rxrpc_alloc_client_call(rx, srx, gfp);
+       call = rxrpc_alloc_client_call(rx, srx, gfp, debug_id);
        if (IS_ERR(call)) {
                release_sock(&rx->sk);
                _leave(" = %ld", PTR_ERR(call));
@@ -268,6 +276,7 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
 
        write_unlock(&rx->call_lock);
 
+       rxnet = call->rxnet;
        write_lock(&rxnet->call_lock);
        list_add_tail(&call->link, &rxnet->calls);
        write_unlock(&rxnet->call_lock);
@@ -613,7 +622,7 @@ void rxrpc_release_calls_on_socket(struct rxrpc_sock *rx)
  */
 void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
 {
-       struct rxrpc_net *rxnet;
+       struct rxrpc_net *rxnet = call->rxnet;
        const void *here = __builtin_return_address(0);
        int n;
 
@@ -627,7 +636,6 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
                ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
 
                if (!list_empty(&call->link)) {
-                       rxnet = rxrpc_net(sock_net(&call->socket->sk));
                        write_lock(&rxnet->call_lock);
                        list_del_init(&call->link);
                        write_unlock(&rxnet->call_lock);
@@ -643,11 +651,14 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
 static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
 {
        struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
+       struct rxrpc_net *rxnet = call->rxnet;
 
        rxrpc_put_peer(call->peer);
        kfree(call->rxtx_buffer);
        kfree(call->rxtx_annotations);
        kmem_cache_free(rxrpc_call_jar, call);
+       if (atomic_dec_and_test(&rxnet->nr_calls))
+               wake_up_var(&rxnet->nr_calls);
 }
 
 /*
@@ -712,4 +723,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
        }
 
        write_unlock(&rxnet->call_lock);
+
+       atomic_dec(&rxnet->nr_calls);
+       wait_var_event(&rxnet->nr_calls, !atomic_read(&rxnet->nr_calls));
 }
This page took 0.030782 seconds and 4 git commands to generate.