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

nfsd/sunrpc: factor svc_rqst allocation and freeing from sv_nrthreads refcounting

In later patches, we'll want to be able to allocate and free svc_rqst
structures without monkeying with the serv->sv_nrthreads refcount.

Factor those pieces out of their respective functions.

Signed-off-by: Shirley Ma <shirley.ma@oracle.com>
Acked-by: Jeff Layton <jlayton@primarydata.com>
Tested-by: Shirley Ma <shirley.ma@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>

authored by

Jeff Layton and committed by
J. Bruce Fields
1b6dc1df d70bc0c6

+45 -24
+3
include/linux/sunrpc/svc.h
··· 458 458 int svc_bind(struct svc_serv *serv, struct net *net); 459 459 struct svc_serv *svc_create(struct svc_program *, unsigned int, 460 460 struct svc_serv_ops *); 461 + struct svc_rqst *svc_rqst_alloc(struct svc_serv *serv, 462 + struct svc_pool *pool, int node); 461 463 struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, 462 464 struct svc_pool *pool, int node); 465 + void svc_rqst_free(struct svc_rqst *); 463 466 void svc_exit_thread(struct svc_rqst *); 464 467 unsigned int svc_pool_map_get(void); 465 468 void svc_pool_map_put(void);
+42 -24
net/sunrpc/svc.c
··· 583 583 } 584 584 585 585 struct svc_rqst * 586 - svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node) 586 + svc_rqst_alloc(struct svc_serv *serv, struct svc_pool *pool, int node) 587 587 { 588 588 struct svc_rqst *rqstp; 589 589 590 590 rqstp = kzalloc_node(sizeof(*rqstp), GFP_KERNEL, node); 591 591 if (!rqstp) 592 - goto out_enomem; 592 + return rqstp; 593 593 594 - serv->sv_nrthreads++; 595 594 __set_bit(RQ_BUSY, &rqstp->rq_flags); 596 595 spin_lock_init(&rqstp->rq_lock); 597 596 rqstp->rq_server = serv; 598 597 rqstp->rq_pool = pool; 598 + 599 + rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node); 600 + if (!rqstp->rq_argp) 601 + goto out_enomem; 602 + 603 + rqstp->rq_resp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node); 604 + if (!rqstp->rq_resp) 605 + goto out_enomem; 606 + 607 + if (!svc_init_buffer(rqstp, serv->sv_max_mesg, node)) 608 + goto out_enomem; 609 + 610 + return rqstp; 611 + out_enomem: 612 + svc_rqst_free(rqstp); 613 + return NULL; 614 + } 615 + EXPORT_SYMBOL_GPL(svc_rqst_alloc); 616 + 617 + struct svc_rqst * 618 + svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node) 619 + { 620 + struct svc_rqst *rqstp; 621 + 622 + rqstp = svc_rqst_alloc(serv, pool, node); 623 + if (!rqstp) 624 + return ERR_PTR(-ENOMEM); 625 + 626 + serv->sv_nrthreads++; 599 627 spin_lock_bh(&pool->sp_lock); 600 628 pool->sp_nrthreads++; 601 629 list_add_rcu(&rqstp->rq_all, &pool->sp_all_threads); 602 630 spin_unlock_bh(&pool->sp_lock); 603 - 604 - rqstp->rq_argp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node); 605 - if (!rqstp->rq_argp) 606 - goto out_thread; 607 - 608 - rqstp->rq_resp = kmalloc_node(serv->sv_xdrsize, GFP_KERNEL, node); 609 - if (!rqstp->rq_resp) 610 - goto out_thread; 611 - 612 - if (!svc_init_buffer(rqstp, serv->sv_max_mesg, node)) 613 - goto out_thread; 614 - 615 631 return rqstp; 616 - out_thread: 617 - svc_exit_thread(rqstp); 618 - out_enomem: 619 - return ERR_PTR(-ENOMEM); 620 632 } 621 633 EXPORT_SYMBOL_GPL(svc_prepare_thread); 622 634 ··· 763 751 * mutex" for the service. 764 752 */ 765 753 void 766 - svc_exit_thread(struct svc_rqst *rqstp) 754 + svc_rqst_free(struct svc_rqst *rqstp) 767 755 { 768 - struct svc_serv *serv = rqstp->rq_server; 769 - struct svc_pool *pool = rqstp->rq_pool; 770 - 771 756 svc_release_buffer(rqstp); 772 757 kfree(rqstp->rq_resp); 773 758 kfree(rqstp->rq_argp); 774 759 kfree(rqstp->rq_auth_data); 760 + kfree_rcu(rqstp, rq_rcu_head); 761 + } 762 + EXPORT_SYMBOL_GPL(svc_rqst_free); 763 + 764 + void 765 + svc_exit_thread(struct svc_rqst *rqstp) 766 + { 767 + struct svc_serv *serv = rqstp->rq_server; 768 + struct svc_pool *pool = rqstp->rq_pool; 775 769 776 770 spin_lock_bh(&pool->sp_lock); 777 771 pool->sp_nrthreads--; ··· 785 767 list_del_rcu(&rqstp->rq_all); 786 768 spin_unlock_bh(&pool->sp_lock); 787 769 788 - kfree_rcu(rqstp, rq_rcu_head); 770 + svc_rqst_free(rqstp); 789 771 790 772 /* Release the server */ 791 773 if (serv)