Bug 476659 - softlockups due to infinite loops in posix_locks_deadlock
Summary: softlockups due to infinite loops in posix_locks_deadlock
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: kernel
Version: 5.1
Hardware: All
OS: Linux
Target Milestone: rc
: ---
Assignee: Josef Bacik
QA Contact: Red Hat Kernel QE team
Depends On:
Blocks: 483701 485920 496842 504279 546230
TreeView+ depends on / blocked
Reported: 2008-12-16 14:27 UTC by Bryn M. Reeves
Modified: 2018-10-27 11:41 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 504279 (view as bug list)
Last Closed: 2009-09-02 08:07:05 UTC
Target Upstream Version:

Attachments (Terms of Use)

System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2009:1243 0 normal SHIPPED_LIVE Important: Red Hat Enterprise Linux 5.4 kernel security and bug fix update 2009-09-01 08:53:34 UTC

Description Bryn M. Reeves 2008-12-16 14:27:31 UTC
Description of problem:

From http://lkml.org/lkml/2007/10/17/314:

"We have observed hangs in posix_locks_deadlock() when multiple threads
use fcntl(2) F_SETLKW to synchronize file accesses.  The problem appears
to be due to an error in the implementation of posix_locks_deadlock() in
which "goto next_task" is used to break out of the list_for_each_entry()
file_lock search after which the posix_same_owner(caller_fl, block_fl)
test may evaluate to false and the list_for_each_entry() loop restarts
all over again.  This in turn leads to a hang where posix_locks_deadlock()
never returns.  The workaround is to change the posix_same_owner()
test within the list_for_each_entry() loop to directly compare caller_fl
against current fl entry."

A reproducer was posted here:


Version-Release number of selected component (if applicable):

How reproducible:
Fairly straightforward - see reproducer at: http://lkml.org/lkml/2007/10/17/472

Steps to Reproduce:
1. Compile fcntltest.c
2. Run fcntltest

Actual results:
Softlockup warnings appear after some time:

Expected results:
No softlockup.

Additional info:
Fixed by 97855b49b6bac0bd25f16b017883634d13591d00, there are a few other related commits since that time, but this is the one that fixes the above lockup.

commit 97855b49b6bac0bd25f16b017883634d13591d00
Author: J. Bruce Fields <bfields@citi.umich.edu>
Date:   Tue Oct 30 11:20:02 2007 -0400

    locks: fix possible infinite loop in posix deadlock detection
    It's currently possible to send posix_locks_deadlock() into an infinite
    loop (under the BKL).
    For now, fix this just by bailing out after a few iterations.  We may
    want to fix this in a way that better clarifies the semantics of
    deadlock detection.  But that will take more time, and this minimal fix
    is probably adequate for any realistic scenario, and is simple enough to
    be appropriate for applying to stable kernels now.
    Thanks to George Davis for reporting the problem.
    Cc: "George G. Davis" <gdavis@mvista.com>
    Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
    Acked-by: Alan Cox <alan@redhat.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/locks.c b/fs/locks.c
index 0127a28..8b8388e 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -696,17 +696,28 @@ EXPORT_SYMBOL(posix_test_lock);
  * Note: the above assumption may not be true when handling lock requests
  * from a broken NFS client. But broken NFS clients have a lot more to
  * worry about than proper deadlock detection anyway... --okir
+ *
+ * However, the failure of this assumption (also possible in the case of
+ * multiple tasks sharing the same open file table) also means there's no
+ * guarantee that the loop below will terminate.  As a hack, we give up
+ * after a few iterations.
 static int posix_locks_deadlock(struct file_lock *caller_fl,
                                struct file_lock *block_fl)
        struct file_lock *fl;
+       int i = 0;
        if (posix_same_owner(caller_fl, block_fl))
                return 1;
        list_for_each_entry(fl, &blocked_list, fl_link) {
                if (posix_same_owner(fl, block_fl)) {
+                       if (i++ > MAX_DEADLK_ITERATIONS)
+                               return 0;
                        fl = fl->fl_next;
                        block_fl = fl;
                        goto next_task;

Comment 2 Issue Tracker 2008-12-23 20:42:47 UTC
I'm working on a one-off hotfix kernel build to provide the customer until
we can get the Z-stream release done.

Barring any great difficulties due to the # of patches against the RHEL5
kernel, it should be ready in a bit.  Will keep ticket updated with


This event sent from IssueTracker by vincew 
 issue 240372

Comment 3 Issue Tracker 2008-12-23 22:10:09 UTC
The hotfix kernel build is underway.  Here's the Brew task URL:


I will check in on this periodically to monitor its progress.


This event sent from IssueTracker by vincew 
 issue 240372

Comment 5 RHEL Program Management 2009-02-16 15:12:55 UTC
Updating PM score.

Comment 14 Don Zickus 2009-05-06 17:15:24 UTC
in kernel-2.6.18-144.el5
You can download this test kernel from http://people.redhat.com/dzickus/el5

Please do NOT transition this bugzilla state to VERIFIED until our QE team
has sent specific instructions indicating when to do so.  However feel free
to provide a comment indicating that this fix has been verified.

Comment 19 errata-xmlrpc 2009-09-02 08:07:05 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.


Note You need to log in before you can comment on or make changes to this bug.