sunrpc: add a rcu_head to svc_rqst and use kfree_rcu to free it
[cascardo/linux.git] / net / sunrpc / svc.c
index a06a891..b90d1bc 100644 (file)
@@ -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)