Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81244386 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields
Browse files

sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it



...also make the manipulation of sp_all_threads list use RCU-friendly
functions.

Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
Tested-by: default avatarChris Worley <chris.worley@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 0b5707e4
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -223,6 +223,7 @@ static inline void svc_putu32(struct kvec *iov, __be32 val)
struct svc_rqst {
struct svc_rqst {
	struct list_head	rq_list;	/* idle list */
	struct list_head	rq_list;	/* idle list */
	struct list_head	rq_all;		/* all threads list */
	struct list_head	rq_all;		/* all threads list */
	struct rcu_head		rq_rcu_head;	/* for RCU deferred kfree */
	struct svc_xprt *	rq_xprt;	/* transport ptr */
	struct svc_xprt *	rq_xprt;	/* transport ptr */


	struct sockaddr_storage	rq_addr;	/* peer address */
	struct sockaddr_storage	rq_addr;	/* peer address */
@@ -262,6 +263,7 @@ struct svc_rqst {
#define	RQ_SPLICE_OK	(4)			/* turned off in gss privacy
#define	RQ_SPLICE_OK	(4)			/* turned off in gss privacy
						 * to prevent encrypting page
						 * to prevent encrypting page
						 * cache pages */
						 * cache pages */
#define	RQ_VICTIM	(5)			/* about to be shut down */
	unsigned long		rq_flags;	/* flags field */
	unsigned long		rq_flags;	/* flags field */


	void *			rq_argp;	/* decoded arguments */
	void *			rq_argp;	/* decoded arguments */
+2 −1
Original line number Original line Diff line number Diff line
@@ -418,7 +418,8 @@ TRACE_EVENT(xs_tcp_data_recv,
		{ (1UL << RQ_LOCAL),		"RQ_LOCAL"},		\
		{ (1UL << RQ_LOCAL),		"RQ_LOCAL"},		\
		{ (1UL << RQ_USEDEFERRAL),	"RQ_USEDEFERRAL"},	\
		{ (1UL << RQ_USEDEFERRAL),	"RQ_USEDEFERRAL"},	\
		{ (1UL << RQ_DROPME),		"RQ_DROPME"},		\
		{ (1UL << RQ_DROPME),		"RQ_DROPME"},		\
		{ (1UL << RQ_SPLICE_OK),	"RQ_SPLICE_OK"})
		{ (1UL << RQ_SPLICE_OK),	"RQ_SPLICE_OK"},	\
		{ (1UL << RQ_VICTIM),		"RQ_VICTIM"})


TRACE_EVENT(svc_recv,
TRACE_EVENT(svc_recv,
	TP_PROTO(struct svc_rqst *rqst, int status),
	TP_PROTO(struct svc_rqst *rqst, int status),
+6 −4
Original line number Original line Diff line number Diff line
@@ -616,7 +616,7 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
	serv->sv_nrthreads++;
	serv->sv_nrthreads++;
	spin_lock_bh(&pool->sp_lock);
	spin_lock_bh(&pool->sp_lock);
	pool->sp_nrthreads++;
	pool->sp_nrthreads++;
	list_add(&rqstp->rq_all, &pool->sp_all_threads);
	list_add_rcu(&rqstp->rq_all, &pool->sp_all_threads);
	spin_unlock_bh(&pool->sp_lock);
	spin_unlock_bh(&pool->sp_lock);
	rqstp->rq_server = serv;
	rqstp->rq_server = serv;
	rqstp->rq_pool = pool;
	rqstp->rq_pool = pool;
@@ -684,7 +684,8 @@ choose_victim(struct svc_serv *serv, struct svc_pool *pool, unsigned int *state)
		 * so we don't try to kill it again.
		 * so we don't try to kill it again.
		 */
		 */
		rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all);
		rqstp = list_entry(pool->sp_all_threads.next, struct svc_rqst, rq_all);
		list_del_init(&rqstp->rq_all);
		set_bit(RQ_VICTIM, &rqstp->rq_flags);
		list_del_rcu(&rqstp->rq_all);
		task = rqstp->rq_task;
		task = rqstp->rq_task;
	}
	}
	spin_unlock_bh(&pool->sp_lock);
	spin_unlock_bh(&pool->sp_lock);
@@ -782,10 +783,11 @@ svc_exit_thread(struct svc_rqst *rqstp)


	spin_lock_bh(&pool->sp_lock);
	spin_lock_bh(&pool->sp_lock);
	pool->sp_nrthreads--;
	pool->sp_nrthreads--;
	list_del(&rqstp->rq_all);
	if (!test_and_set_bit(RQ_VICTIM, &rqstp->rq_flags))
		list_del_rcu(&rqstp->rq_all);
	spin_unlock_bh(&pool->sp_lock);
	spin_unlock_bh(&pool->sp_lock);


	kfree(rqstp);
	kfree_rcu(rqstp, rq_rcu_head);


	/* Release the server */
	/* Release the server */
	if (serv)
	if (serv)