kern/65448: _mtx_unlock_sleep() race condition if ADAPTIVE_MUTEXES
is defined
Stephan Uphoff
ups at tree.com
Sun Apr 11 18:10:18 PDT 2004
>Number: 65448
>Category: kern
>Synopsis: _mtx_unlock_sleep() race condition if ADAPTIVE_MUTEXES is defined
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Apr 11 18:10:17 PDT 2004
>Closed-Date:
>Last-Modified:
>Originator: Stephan Uphoff
>Release: current
>Organization:
>Environment:
N/A
>Description:
The following waiting loop is used in _mtx_unlock_sleep()
if both ADAPTIVE_MUTEXES and SMP is defined.
while (mtx_owner(m) == owner && TD_IS_RUNNING(owner)) {
#ifdef __i386__
ia32_pause();
#endif
}
Problem:
The current thread has no lock or reference count
on the "owner" thread.
This means that the thread pointed to by owner
can terminate and become invalid.
If the "owner" thread terminates between the tests
"mtx_owner(m) == owner" and "TD_IS_RUNNING(owner)"
the second test might access an invalid memory address.
Additional Nitpick:
Because TD_IS_RUNNING(owner) is defined as
#define TD_IS_RUNNING(td) ((td)->td_state == TDS_RUNNING)
and
The td_state field is not volatile.
and
ia32_pause() is not marked to modify memory.
the compiler can regard the test "TD_IS_RUNNING(owner)" as being
loop invariant and rewrite the code fragment above as:
if((mtx_owner(m) == owner && TD_IS_RUNNING(owner))
do {
#ifdef __i386__
ia32_pause();
#endif
while (mtx_owner(m) == owner);
This would cause problems.
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list