Merge tag 'timers-core-2020-03-30' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / afs / rxrpc.c
index 58d3965..1ecc67d 100644 (file)
@@ -18,7 +18,6 @@ struct workqueue_struct *afs_async_calls;
 
 static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
-static void afs_delete_async_call(struct work_struct *);
 static void afs_process_async_call(struct work_struct *);
 static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long);
 static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long);
@@ -169,7 +168,7 @@ void afs_put_call(struct afs_call *call)
        int n = atomic_dec_return(&call->usage);
        int o = atomic_read(&net->nr_outstanding_calls);
 
-       trace_afs_call(call, afs_call_trace_put, n + 1, o,
+       trace_afs_call(call, afs_call_trace_put, n, o,
                       __builtin_return_address(0));
 
        ASSERTCMP(n, >=, 0);
@@ -402,8 +401,10 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
        /* If the call is going to be asynchronous, we need an extra ref for
         * the call to hold itself so the caller need not hang on to its ref.
         */
-       if (call->async)
+       if (call->async) {
                afs_get_call(call, afs_call_trace_get);
+               call->drop_ref = true;
+       }
 
        /* create a call */
        rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key,
@@ -413,7 +414,8 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
                                          afs_wake_up_async_call :
                                          afs_wake_up_call_waiter),
                                         call->upgrade,
-                                        call->intr,
+                                        (call->intr ? RXRPC_PREINTERRUPTIBLE :
+                                         RXRPC_UNINTERRUPTIBLE),
                                         call->debug_id);
        if (IS_ERR(rxcall)) {
                ret = PTR_ERR(rxcall);
@@ -584,8 +586,6 @@ static void afs_deliver_to_call(struct afs_call *call)
 done:
        if (call->type->done)
                call->type->done(call);
-       if (state == AFS_CALL_COMPLETE && call->incoming)
-               afs_put_call(call);
 out:
        _leave("");
        return;
@@ -604,11 +604,7 @@ call_complete:
 long afs_wait_for_call_to_complete(struct afs_call *call,
                                   struct afs_addr_cursor *ac)
 {
-       signed long rtt2, timeout;
        long ret;
-       bool stalled = false;
-       u64 rtt;
-       u32 life, last_life;
        bool rxrpc_complete = false;
 
        DECLARE_WAITQUEUE(myself, current);
@@ -619,14 +615,6 @@ long afs_wait_for_call_to_complete(struct afs_call *call,
        if (ret < 0)
                goto out;
 
-       rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall);
-       rtt2 = nsecs_to_jiffies64(rtt) * 2;
-       if (rtt2 < 2)
-               rtt2 = 2;
-
-       timeout = rtt2;
-       rxrpc_kernel_check_life(call->net->socket, call->rxcall, &last_life);
-
        add_wait_queue(&call->waitq, &myself);
        for (;;) {
                set_current_state(TASK_UNINTERRUPTIBLE);
@@ -637,37 +625,19 @@ long afs_wait_for_call_to_complete(struct afs_call *call,
                        call->need_attention = false;
                        __set_current_state(TASK_RUNNING);
                        afs_deliver_to_call(call);
-                       timeout = rtt2;
                        continue;
                }
 
                if (afs_check_call_state(call, AFS_CALL_COMPLETE))
                        break;
 
-               if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall, &life)) {
+               if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) {
                        /* rxrpc terminated the call. */
                        rxrpc_complete = true;
                        break;
                }
 
-               if (call->intr && timeout == 0 &&
-                   life == last_life && signal_pending(current)) {
-                       if (stalled)
-                               break;
-                       __set_current_state(TASK_RUNNING);
-                       rxrpc_kernel_probe_life(call->net->socket, call->rxcall);
-                       timeout = rtt2;
-                       stalled = true;
-                       continue;
-               }
-
-               if (life != last_life) {
-                       timeout = rtt2;
-                       last_life = life;
-                       stalled = false;
-               }
-
-               timeout = schedule_timeout(timeout);
+               schedule();
        }
 
        remove_wait_queue(&call->waitq, &myself);
@@ -735,7 +705,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
 
        u = atomic_fetch_add_unless(&call->usage, 1, 0);
        if (u != 0) {
-               trace_afs_call(call, afs_call_trace_wake, u,
+               trace_afs_call(call, afs_call_trace_wake, u + 1,
                               atomic_read(&call->net->nr_outstanding_calls),
                               __builtin_return_address(0));
 
@@ -744,21 +714,6 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
        }
 }
 
-/*
- * Delete an asynchronous call.  The work item carries a ref to the call struct
- * that we need to release.
- */
-static void afs_delete_async_call(struct work_struct *work)
-{
-       struct afs_call *call = container_of(work, struct afs_call, async_work);
-
-       _enter("");
-
-       afs_put_call(call);
-
-       _leave("");
-}
-
 /*
  * Perform I/O processing on an asynchronous call.  The work item carries a ref
  * to the call struct that we either need to release or to pass on.
@@ -774,16 +729,6 @@ static void afs_process_async_call(struct work_struct *work)
                afs_deliver_to_call(call);
        }
 
-       if (call->state == AFS_CALL_COMPLETE) {
-               /* We have two refs to release - one from the alloc and one
-                * queued with the work item - and we can't just deallocate the
-                * call because the work item may be queued again.
-                */
-               call->async_work.func = afs_delete_async_call;
-               if (!queue_work(afs_async_calls, &call->async_work))
-                       afs_put_call(call);
-       }
-
        afs_put_call(call);
        _leave("");
 }
@@ -810,6 +755,7 @@ void afs_charge_preallocation(struct work_struct *work)
                        if (!call)
                                break;
 
+                       call->drop_ref = true;
                        call->async = true;
                        call->state = AFS_CALL_SV_AWAIT_OP_ID;
                        init_waitqueue_head(&call->waitq);