From 6b0f2340286f9109380d5a0f57d981c15bd9c596 Mon Sep 17 00:00:00 2001 From: "Alexander.Zarochentev" Date: Wed, 3 Feb 2010 12:00:47 +0300 Subject: [PATCH 1/1] b=21879 fix hr->hr_index overload i=eric.barton i=zhen.liang --- lustre/ptlrpc/service.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 73aff1b..b72848a 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -230,6 +230,22 @@ static void rs_batch_init(struct rs_batch *b) } /** + * Choose an hr thread to dispatch requests to. + */ +static unsigned int get_hr_thread_index(struct ptlrpc_hr_service *hr) +{ + unsigned int idx; + + /* Concurrent modification of hr_index w/o any spinlock + protection is harmless as long as the result fits + [0..(hr_n_threads-1)] range and each thread gets near equal + load. */ + idx = hr->hr_index; + hr->hr_index = (idx >= hr->hr_n_threads - 1) ? 0 : idx + 1; + return idx; +} + +/** * Dispatch all replies accumulated in the batch to one from * dedicated reply handling threads. * @@ -241,9 +257,7 @@ static void rs_batch_dispatch(struct rs_batch *b) struct ptlrpc_hr_service *hr = ptlrpc_hr; int idx; - idx = hr->hr_index++; - if (hr->hr_index >= hr->hr_n_threads) - hr->hr_index = 0; + idx = get_hr_thread_index(hr); cfs_spin_lock(&hr->hr_threads[idx].hrt_lock); cfs_list_splice_init(&b->rsb_replies, @@ -319,9 +333,7 @@ void ptlrpc_dispatch_difficult_reply(struct ptlrpc_reply_state *rs) LASSERT(cfs_list_empty(&rs->rs_list)); - idx = hr->hr_index++; - if (hr->hr_index >= hr->hr_n_threads) - hr->hr_index = 0; + idx = get_hr_thread_index(hr); cfs_spin_lock(&hr->hr_threads[idx].hrt_lock); cfs_list_add_tail(&rs->rs_list, &hr->hr_threads[idx].hrt_queue); cfs_spin_unlock(&hr->hr_threads[idx].hrt_lock); -- 1.8.3.1