|
@@ -616,7 +616,7 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node)
|
|
|
serv->sv_nrthreads++;
|
|
|
spin_lock_bh(&pool->sp_lock);
|
|
|
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);
|
|
|
rqstp->rq_server = serv;
|
|
|
rqstp->rq_pool = pool;
|
|
@@ -684,7 +684,8 @@ found_pool:
|
|
|
* so we don't try to kill it again.
|
|
|
*/
|
|
|
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;
|
|
|
}
|
|
|
spin_unlock_bh(&pool->sp_lock);
|
|
@@ -782,10 +783,11 @@ svc_exit_thread(struct svc_rqst *rqstp)
|
|
|
|
|
|
spin_lock_bh(&pool->sp_lock);
|
|
|
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);
|
|
|
|
|
|
- kfree(rqstp);
|
|
|
+ kfree_rcu(rqstp, rq_rcu_head);
|
|
|
|
|
|
/* Release the server */
|
|
|
if (serv)
|