SUNRPC: remove timeout arg from svc_recv()
authorNeilBrown <neilb@suse.de>
Tue, 18 Jul 2023 06:38:08 +0000 (16:38 +1000)
committerChuck Lever <chuck.lever@oracle.com>
Tue, 29 Aug 2023 21:45:22 +0000 (17:45 -0400)
Most svc threads have no interest in a timeout.
nfsd sets it to 1 hour, but this is a wart of no significance.

lockd uses the timeout so that it can call nlmsvc_retry_blocked().
It also sometimes calls svc_wake_up() to ensure this is called.

So change lockd to be consistent and always use svc_wake_up() to trigger
nlmsvc_retry_blocked() - using a timer instead of a timeout to
svc_recv().

And change svc_recv() to not take a timeout arg.

This makes the sp_threads_timedout counter always zero.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svc.c
fs/lockd/svclock.c
fs/nfs/callback.c
fs/nfsd/nfssvc.c
include/linux/lockd/lockd.h
include/linux/sunrpc/svc.h
include/linux/sunrpc/svcsock.h
net/sunrpc/svc.c
net/sunrpc/svc_xprt.c

index cf4ff7d..ef3f77a 100644 (file)
@@ -56,6 +56,12 @@ static unsigned int          nlmsvc_users;
 static struct svc_serv         *nlmsvc_serv;
 unsigned long                  nlmsvc_timeout;
 
+static void nlmsvc_request_retry(struct timer_list *tl)
+{
+       svc_wake_up(nlmsvc_serv);
+}
+DEFINE_TIMER(nlmsvc_retry, nlmsvc_request_retry);
+
 unsigned int lockd_net_id;
 
 /*
@@ -130,14 +136,11 @@ lockd(void *vrqstp)
         * NFS mount or NFS daemon has gone away.
         */
        while (!kthread_should_stop()) {
-               long timeout = MAX_SCHEDULE_TIMEOUT;
-
                /* update sv_maxconn if it has changed */
                rqstp->rq_server->sv_maxconn = nlm_max_connections;
 
-               timeout = nlmsvc_retry_blocked();
-
-               svc_recv(rqstp, timeout);
+               nlmsvc_retry_blocked();
+               svc_recv(rqstp);
        }
        if (nlmsvc_ops)
                nlmsvc_invalidate_all();
@@ -371,6 +374,7 @@ static void lockd_put(void)
 #endif
 
        svc_set_num_threads(nlmsvc_serv, NULL, 0);
+       timer_delete_sync(&nlmsvc_retry);
        nlmsvc_serv = NULL;
        dprintk("lockd_down: service destroyed\n");
 }
index 28abec5..43aeba9 100644 (file)
@@ -1019,7 +1019,7 @@ retry_deferred_block(struct nlm_block *block)
  * picks up locks that can be granted, or grant notifications that must
  * be retransmitted.
  */
-unsigned long
+void
 nlmsvc_retry_blocked(void)
 {
        unsigned long   timeout = MAX_SCHEDULE_TIMEOUT;
@@ -1049,5 +1049,6 @@ nlmsvc_retry_blocked(void)
        }
        spin_unlock(&nlm_blocked_lock);
 
-       return timeout;
+       if (timeout < MAX_SCHEDULE_TIMEOUT)
+               mod_timer(&nlmsvc_retry, jiffies + timeout);
 }
index 54155b4..39a0ba7 100644 (file)
@@ -79,7 +79,7 @@ nfs4_callback_svc(void *vrqstp)
        set_freezable();
 
        while (!kthread_freezable_should_stop(NULL))
-               svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT);
+               svc_recv(rqstp);
 
        svc_exit_thread(rqstp);
        return 0;
index 4c0ab10..1582af3 100644 (file)
@@ -961,7 +961,7 @@ nfsd(void *vrqstp)
                /* Update sv_maxconn if it has changed */
                rqstp->rq_server->sv_maxconn = nn->max_connections;
 
-               svc_recv(rqstp, 60*60*HZ);
+               svc_recv(rqstp);
                validate_process_creds();
        }
 
index f42594a..0f016d6 100644 (file)
@@ -204,6 +204,8 @@ extern unsigned long                nlmsvc_timeout;
 extern bool                    nsm_use_hostnames;
 extern u32                     nsm_local_state;
 
+extern struct timer_list       nlmsvc_retry;
+
 /*
  * Lockd client functions
  */
@@ -280,7 +282,7 @@ __be32                nlmsvc_testlock(struct svc_rqst *, struct nlm_file *,
                        struct nlm_host *, struct nlm_lock *,
                        struct nlm_lock *, struct nlm_cookie *);
 __be32           nlmsvc_cancel_blocked(struct net *net, struct nlm_file *, struct nlm_lock *);
-unsigned long    nlmsvc_retry_blocked(void);
+void             nlmsvc_retry_blocked(void);
 void             nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
                                        nlm_host_match_fn_t match);
 void             nlmsvc_grant_reply(struct nlm_cookie *, __be32);
index 2230148..b206fdd 100644 (file)
@@ -41,7 +41,6 @@ struct svc_pool {
        /* statistics on pool operation */
        struct percpu_counter   sp_sockets_queued;
        struct percpu_counter   sp_threads_woken;
-       struct percpu_counter   sp_threads_timedout;
 
 #define        SP_TASK_PENDING         (0)             /* still work to do even if no
                                                 * xprt is queued. */
index c0ddd33..d4a173c 100644 (file)
@@ -57,7 +57,7 @@ static inline u32 svc_sock_final_rec(struct svc_sock *svsk)
  * Function prototypes.
  */
 void           svc_close_net(struct svc_serv *, struct net *);
-void           svc_recv(struct svc_rqst *, long);
+void           svc_recv(struct svc_rqst *rqstp);
 void           svc_send(struct svc_rqst *rqstp);
 void           svc_drop(struct svc_rqst *);
 void           svc_sock_update_bufs(struct svc_serv *serv);
index c69896c..030f8c7 100644 (file)
@@ -515,7 +515,6 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
 
                percpu_counter_init(&pool->sp_sockets_queued, 0, GFP_KERNEL);
                percpu_counter_init(&pool->sp_threads_woken, 0, GFP_KERNEL);
-               percpu_counter_init(&pool->sp_threads_timedout, 0, GFP_KERNEL);
        }
 
        return serv;
@@ -590,7 +589,6 @@ svc_destroy(struct kref *ref)
 
                percpu_counter_destroy(&pool->sp_sockets_queued);
                percpu_counter_destroy(&pool->sp_threads_woken);
-               percpu_counter_destroy(&pool->sp_threads_timedout);
        }
        kfree(serv->sv_pools);
        kfree(serv);
index d7d6914..9bdcdd8 100644 (file)
@@ -750,10 +750,9 @@ rqst_should_sleep(struct svc_rqst *rqstp)
        return true;
 }
 
-static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
+static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp)
 {
        struct svc_pool         *pool = rqstp->rq_pool;
-       long                    time_left = 0;
 
        /* rq_xprt should be clear on entry */
        WARN_ON_ONCE(rqstp->rq_xprt);
@@ -769,7 +768,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
        smp_mb__after_atomic();
 
        if (likely(rqst_should_sleep(rqstp)))
-               time_left = schedule_timeout(timeout);
+               schedule();
        else
                __set_current_state(TASK_RUNNING);
 
@@ -781,9 +780,6 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
        if (rqstp->rq_xprt)
                goto out_found;
 
-       if (!time_left)
-               percpu_counter_inc(&pool->sp_threads_timedout);
-
        if (kthread_should_stop())
                return NULL;
        return NULL;
@@ -863,12 +859,15 @@ out:
        return len;
 }
 
-/*
- * Receive the next request on any transport.  This code is carefully
- * organised not to touch any cachelines in the shared svc_serv
- * structure, only cachelines in the local svc_pool.
+/**
+ * svc_recv - Receive and process the next request on any transport
+ * @rqstp: an idle RPC service thread
+ *
+ * This code is carefully organised not to touch any cachelines in
+ * the shared svc_serv structure, only cachelines in the local
+ * svc_pool.
  */
-void svc_recv(struct svc_rqst *rqstp, long timeout)
+void svc_recv(struct svc_rqst *rqstp)
 {
        struct svc_xprt         *xprt = NULL;
        struct svc_serv         *serv = rqstp->rq_server;
@@ -882,7 +881,7 @@ void svc_recv(struct svc_rqst *rqstp, long timeout)
        if (kthread_should_stop())
                goto out;
 
-       xprt = svc_get_next_xprt(rqstp, timeout);
+       xprt = svc_get_next_xprt(rqstp);
        if (!xprt)
                goto out;
 
@@ -1447,12 +1446,11 @@ static int svc_pool_stats_show(struct seq_file *m, void *p)
                return 0;
        }
 
-       seq_printf(m, "%u %llu %llu %llu %llu\n",
-               pool->sp_id,
-               percpu_counter_sum_positive(&pool->sp_sockets_queued),
-               percpu_counter_sum_positive(&pool->sp_sockets_queued),
-               percpu_counter_sum_positive(&pool->sp_threads_woken),
-               percpu_counter_sum_positive(&pool->sp_threads_timedout));
+       seq_printf(m, "%u %llu %llu %llu 0\n",
+                  pool->sp_id,
+                  percpu_counter_sum_positive(&pool->sp_sockets_queued),
+                  percpu_counter_sum_positive(&pool->sp_sockets_queued),
+                  percpu_counter_sum_positive(&pool->sp_threads_woken));
 
        return 0;
 }