From: Andriy Skulysh Date: Wed, 6 Jul 2016 08:34:27 +0000 (+0300) Subject: LU-8354 ldlm: soft lockup in ldlm_plain_compat_queue X-Git-Tag: 2.8.56~35 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=5546521fa5d619865902c867d2170dbf1a51c778;ds=sidebyside LU-8354 ldlm: soft lockup in ldlm_plain_compat_queue commit c09b59bb958f3e089b95dd9492cc1bef17cb3782 LU-3963 ldlm: convert to linux list api breaks loop iteration optimisation. tmp variable is modified later to skip already processed locks from the same mode group. Change-Id: I4dd493d6bd5bb2ac54801cb289dc89efabdfa920 Seagate-bug-id: MRP-3611 Signed-off-by: Andriy Skulysh Reviewed-on: http://review.whamcloud.com/21093 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- diff --git a/lustre/ldlm/ldlm_plain.c b/lustre/ldlm/ldlm_plain.c index 6a99608..bbc355f 100644 --- a/lustre/ldlm/ldlm_plain.c +++ b/lustre/ldlm/ldlm_plain.c @@ -73,14 +73,14 @@ ldlm_plain_compat_queue(struct list_head *queue, struct ldlm_lock *req, struct list_head *work_list) { enum ldlm_mode req_mode = req->l_req_mode; - struct ldlm_lock *lock; - struct list_head *tmp; + struct ldlm_lock *lock, *next_lock; int compat = 1; ENTRY; lockmode_verify(req_mode); - list_for_each_entry(lock, queue, l_res_link) { + list_for_each_entry_safe(lock, next_lock, queue, l_res_link) { + /* We stop walking the queue if we hit ourselves so we don't * take conflicting locks enqueued after us into account, * or we'd wait forever. */ @@ -88,8 +88,10 @@ ldlm_plain_compat_queue(struct list_head *queue, struct ldlm_lock *req, RETURN(compat); /* Advance loop cursor to last lock of mode group. */ - tmp = &list_entry(lock->l_sl_mode.prev, struct ldlm_lock, - l_sl_mode)->l_res_link; + next_lock = list_entry(list_entry(lock->l_sl_mode.prev, + struct ldlm_lock, + l_sl_mode)->l_res_link.next, + struct ldlm_lock, l_res_link); if (lockmode_compat(lock->l_req_mode, req_mode)) continue;