Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sunrpc: split svc_set_num_threads() into two functions

svc_set_num_threads() will set the number of running threads for a given
pool. If the pool argument is set to NULL however, it will distribute
the threads among all of the pools evenly.

These divergent codepaths complicate the move to dynamic threading.
Simplify the API by splitting these two cases into different helpers:

Add a new svc_set_pool_threads() function that sets the number of
threads in a single, given pool. Modify svc_set_num_threads() to
distribute the threads evenly between all of the pools and then call
svc_set_pool_threads() for each.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Jeff Layton and committed by
Chuck Lever
e344f872 5288993c

+72 -35
+2 -2
fs/lockd/svc.c
··· 340 340 return -ENOMEM; 341 341 } 342 342 343 - error = svc_set_num_threads(serv, NULL, 1); 343 + error = svc_set_num_threads(serv, 1); 344 344 if (error < 0) { 345 345 svc_destroy(&serv); 346 346 return error; ··· 368 368 unregister_inet6addr_notifier(&lockd_inet6addr_notifier); 369 369 #endif 370 370 371 - svc_set_num_threads(nlmsvc_serv, NULL, 0); 371 + svc_set_num_threads(nlmsvc_serv, 0); 372 372 timer_delete_sync(&nlmsvc_retry); 373 373 svc_destroy(&nlmsvc_serv); 374 374 dprintk("lockd_down: service destroyed\n");
+4 -4
fs/nfs/callback.c
··· 119 119 if (serv->sv_nrthreads == nrservs) 120 120 return 0; 121 121 122 - ret = svc_set_num_threads(serv, NULL, nrservs); 122 + ret = svc_set_num_threads(serv, nrservs); 123 123 if (ret) { 124 - svc_set_num_threads(serv, NULL, 0); 124 + svc_set_num_threads(serv, 0); 125 125 return ret; 126 126 } 127 127 dprintk("nfs_callback_up: service started\n"); ··· 242 242 cb_info->users++; 243 243 err_net: 244 244 if (!cb_info->users) { 245 - svc_set_num_threads(cb_info->serv, NULL, 0); 245 + svc_set_num_threads(cb_info->serv, 0); 246 246 svc_destroy(&cb_info->serv); 247 247 } 248 248 err_create: ··· 268 268 nfs_callback_down_net(minorversion, serv, net); 269 269 cb_info->users--; 270 270 if (cb_info->users == 0) { 271 - svc_set_num_threads(serv, NULL, 0); 271 + svc_set_num_threads(serv, 0); 272 272 dprintk("nfs_callback_down: service destroyed\n"); 273 273 xprt_svc_destroy_nullify_bc(xprt, &cb_info->serv); 274 274 }
+9 -12
fs/nfsd/nfssvc.c
··· 580 580 } 581 581 582 582 /* Kill outstanding nfsd threads */ 583 - svc_set_num_threads(serv, NULL, 0); 583 + svc_set_num_threads(serv, 0); 584 584 nfsd_destroy_serv(net); 585 585 mutex_unlock(&nfsd_mutex); 586 586 } ··· 688 688 if (nn->nfsd_serv == NULL || n <= 0) 689 689 return 0; 690 690 691 - /* 692 - * Special case: When n == 1, pass in NULL for the pool, so that the 693 - * change is distributed equally among them. 694 - */ 691 + /* Special case: When n == 1, distribute threads equally among pools. */ 695 692 if (n == 1) 696 - return svc_set_num_threads(nn->nfsd_serv, NULL, nthreads[0]); 693 + return svc_set_num_threads(nn->nfsd_serv, nthreads[0]); 697 694 698 695 if (n > nn->nfsd_serv->sv_nrpools) 699 696 n = nn->nfsd_serv->sv_nrpools; ··· 716 719 717 720 /* apply the new numbers */ 718 721 for (i = 0; i < n; i++) { 719 - err = svc_set_num_threads(nn->nfsd_serv, 720 - &nn->nfsd_serv->sv_pools[i], 721 - nthreads[i]); 722 + err = svc_set_pool_threads(nn->nfsd_serv, 723 + &nn->nfsd_serv->sv_pools[i], 724 + nthreads[i]); 722 725 if (err) 723 726 goto out; 724 727 } 725 728 726 729 /* Anything undefined in array is considered to be 0 */ 727 730 for (i = n; i < nn->nfsd_serv->sv_nrpools; ++i) { 728 - err = svc_set_num_threads(nn->nfsd_serv, 729 - &nn->nfsd_serv->sv_pools[i], 730 - 0); 731 + err = svc_set_pool_threads(nn->nfsd_serv, 732 + &nn->nfsd_serv->sv_pools[i], 733 + 0); 731 734 if (err) 732 735 goto out; 733 736 }
+3 -1
include/linux/sunrpc/svc.h
··· 446 446 struct svc_stat *stats, 447 447 unsigned int bufsize, 448 448 int (*threadfn)(void *data)); 449 - int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); 449 + int svc_set_pool_threads(struct svc_serv *serv, struct svc_pool *pool, 450 + unsigned int nrservs); 451 + int svc_set_num_threads(struct svc_serv *serv, unsigned int nrservs); 450 452 int svc_pool_stats_open(struct svc_info *si, struct file *file); 451 453 void svc_process(struct svc_rqst *rqstp); 452 454 void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp);
+54 -16
net/sunrpc/svc.c
··· 856 856 } 857 857 858 858 /** 859 - * svc_set_num_threads - adjust number of threads per RPC service 859 + * svc_set_pool_threads - adjust number of threads per pool 860 860 * @serv: RPC service to adjust 861 - * @pool: Specific pool from which to choose threads, or NULL 862 - * @nrservs: New number of threads for @serv (0 or less means kill all threads) 861 + * @pool: Specific pool from which to choose threads 862 + * @nrservs: New number of threads for @serv (0 means kill all threads) 863 863 * 864 - * Create or destroy threads to make the number of threads for @serv the 865 - * given number. If @pool is non-NULL, change only threads in that pool; 866 - * otherwise, round-robin between all pools for @serv. @serv's 867 - * sv_nrthreads is adjusted for each thread created or destroyed. 864 + * Create or destroy threads in @pool to bring it to @nrservs. 868 865 * 869 866 * Caller must ensure mutual exclusion between this and server startup or 870 867 * shutdown. ··· 870 873 * starting a thread. 871 874 */ 872 875 int 873 - svc_set_num_threads(struct svc_serv *serv, struct svc_pool *pool, int nrservs) 876 + svc_set_pool_threads(struct svc_serv *serv, struct svc_pool *pool, 877 + unsigned int nrservs) 874 878 { 875 - if (!pool) 876 - nrservs -= serv->sv_nrthreads; 877 - else 878 - nrservs -= pool->sp_nrthreads; 879 + int delta = nrservs; 879 880 880 - if (nrservs > 0) 881 - return svc_start_kthreads(serv, pool, nrservs); 882 - if (nrservs < 0) 883 - return svc_stop_kthreads(serv, pool, nrservs); 881 + if (!pool) 882 + return -EINVAL; 883 + 884 + delta -= pool->sp_nrthreads; 885 + 886 + if (delta > 0) 887 + return svc_start_kthreads(serv, pool, delta); 888 + if (delta < 0) 889 + return svc_stop_kthreads(serv, pool, delta); 884 890 return 0; 891 + } 892 + EXPORT_SYMBOL_GPL(svc_set_pool_threads); 893 + 894 + /** 895 + * svc_set_num_threads - adjust number of threads in serv 896 + * @serv: RPC service to adjust 897 + * @nrservs: New number of threads for @serv (0 means kill all threads) 898 + * 899 + * Create or destroy threads in @serv to bring it to @nrservs. If there 900 + * are multiple pools then the new threads or victims will be distributed 901 + * evenly among them. 902 + * 903 + * Caller must ensure mutual exclusion between this and server startup or 904 + * shutdown. 905 + * 906 + * Returns zero on success or a negative errno if an error occurred while 907 + * starting a thread. On failure, some pools may have already been 908 + * adjusted; the caller is responsible for recovery. 909 + */ 910 + int 911 + svc_set_num_threads(struct svc_serv *serv, unsigned int nrservs) 912 + { 913 + unsigned int base = nrservs / serv->sv_nrpools; 914 + unsigned int remain = nrservs % serv->sv_nrpools; 915 + int i, err = 0; 916 + 917 + for (i = 0; i < serv->sv_nrpools; ++i) { 918 + int threads = base; 919 + 920 + if (remain) { 921 + ++threads; 922 + --remain; 923 + } 924 + err = svc_set_pool_threads(serv, &serv->sv_pools[i], threads); 925 + if (err) 926 + break; 927 + } 928 + return err; 885 929 } 886 930 EXPORT_SYMBOL_GPL(svc_set_num_threads); 887 931