From: Gustavo Bittencourt <gbitten@gmail.com>
To: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: linux-rt-users <linux-rt-users@vger.kernel.org>
Subject: Re: [PATCH] rtmutex: enable deadlock detection in ww_mutex_lock functions
Date: Mon, 26 Jan 2015 13:06:35 -0200 [thread overview]
Message-ID: <54C657FB.2060106@gmail.com> (raw)
In-Reply-To: <CAP=VYLq2JS0072Y0P=A+oWrt2MHjy42uG0LgQvfyHXfzf7PXeg@mail.gmail.com>
I'm not sure if those patches are connected, so I am posting my findings
for anyone.
ABOUT NOUVEAU AND WW_MUTEX:
The nouveau driver intensely uses the ww_mutex. According the
ww-mutex-design.txt documentation, the ww_mutex makes the following
steps when try to lock a resource:
1) It calls the ww_mutex_lock (or ww_mutex_lock_interruptible) function
for normal lock acquisition.
2) If it returns -EDEADLK, the wounded task must drop all already
acquired locks and call the ww_mutex_lock_slow (or
ww_mutex_lock_slow_interruptible) function.
In the nouveau driver, those steps happen in the validate_init function
(drivers/gpu/drm/nouveau_gem.c) when it calls the functions
ttm_bo_reserve (step 1) and ttm_bo_reserve_slowpath (step 2):
validate_init(...)
{
...
ret = ttm_bo_reserve(&nvbo->bo, true, false, true, &op->ticket);
if (ret) {
validate_fini_no_ticket(op, NULL);
if (unlikely(ret == -EDEADLK)) {
ret = ttm_bo_reserve_slowpath(&nvbo->bo, true,
&op->ticket);
...
}
THE PROBLEM:
When I run the PREEMPT_RT in my computer, it freezes as soon I start
some big graphical application (e.g. Firefox or Chrome). The following
execution path happens until reaching an infinite loop:
a) nouveau_gem_ioctl_pushbuf()
b) nouveau_gem_pushbuf_validate()
c) validate_init()
d) ttm_bo_reserve()
e) ttm_bo_reserve_nolru()
f) ww_mutex_lock_interruptible()
g) __ww_mutex_lock_interruptible()
h) rt_mutex_slowlock()
i) rt_mutex_handle_deadlock() -> infinite loop
The infinite loop that I mentioned above is the while(1){...} inside the
rt_mutex_handle_deadlock function:
static void rt_mutex_handle_deadlock(int res, int detect_deadlock,
struct rt_mutex_waiter *w)
{
/*
* If the result is not -EDEADLOCK or the caller requested
* deadlock detection, nothing to do here.
*/
if (res != -EDEADLOCK || detect_deadlock)
return;
/*
* Yell lowdly and stop the task right here.
*/
rt_mutex_print_deadlock(w);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
schedule();
}
}
CONCLUSION:
My conclusion was the detect_deadlock should be enabled to the
rt_mutex_handle_deadlock function returns -EDEADLK and hence the
ww_mutex_lock_interruptible returns -EDEADLK too. BTW, since I have
applied my patch, I've not had anymore freezing issue.
PS: I am a kernelnewbie so it is possible that I am writing some BS here.
On 01/25/2015 06:55 PM, Paul Gortmaker wrote:
> On Tue, Jan 20, 2015 at 3:02 PM, Gustavo Bittencourt <gbitten@gmail.com> wrote:
>> The functions ww_mutex_lock_interruptible and ww_mutex_lock should return -EDEADLK when faced with
>> a deadlock. To do so, the paramenter detect_deadlock in rt_mutex_slowlock must be TRUE.
>> This patch corrects potential deadlocks when running PREEMPT_RT with nouveau driver.
>>
>> Kernel version: 3.14.25-rt22
>
> You might want to have a look at this:
>
> http://www.spinics.net/lists/linux-rt-users/msg12259.html
>
> as it also impacts what the deadlock detection flag does.
>
> Paul.
> --
>
>>
>> Signed-off-by: Gustavo Bittencourt <gbitten@gmail.com>
>> ---
>> kernel/locking/rtmutex.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
>> index 6c40660..3f6ef91 100644
>> --- a/kernel/locking/rtmutex.c
>> +++ b/kernel/locking/rtmutex.c
>> @@ -1965,7 +1965,7 @@ __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ww_c
>> might_sleep();
>>
>> mutex_acquire(&lock->base.dep_map, 0, 0, _RET_IP_);
>> - ret = rt_mutex_slowlock(&lock->base.lock, TASK_INTERRUPTIBLE, NULL, 0, ww_ctx);
>> + ret = rt_mutex_slowlock(&lock->base.lock, TASK_INTERRUPTIBLE, NULL, 1, ww_ctx);
>> if (ret)
>> mutex_release(&lock->base.dep_map, 1, _RET_IP_);
>> else if (!ret && ww_ctx->acquired > 1)
>> @@ -1984,7 +1984,7 @@ __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx)
>>
>> mutex_acquire_nest(&lock->base.dep_map, 0, 0, &ww_ctx->dep_map,
>> _RET_IP_);
>> - ret = rt_mutex_slowlock(&lock->base.lock, TASK_UNINTERRUPTIBLE, NULL, 0, ww_ctx);
>> + ret = rt_mutex_slowlock(&lock->base.lock, TASK_UNINTERRUPTIBLE, NULL, 1, ww_ctx);
>> if (ret)
>> mutex_release(&lock->base.dep_map, 1, _RET_IP_);
>> else if (!ret && ww_ctx->acquired > 1)
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-01-26 15:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-20 20:02 [PATCH] rtmutex: enable deadlock detection in ww_mutex_lock functions Gustavo Bittencourt
2015-01-25 20:55 ` Paul Gortmaker
2015-01-26 15:06 ` Gustavo Bittencourt [this message]
2015-02-17 17:46 ` Sebastian Andrzej Siewior
2015-02-18 0:18 ` Gustavo Bittencourt
2015-02-18 9:43 ` Sebastian Andrzej Siewior
2015-02-23 16:31 ` Gustavo Bittencourt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54C657FB.2060106@gmail.com \
--to=gbitten@gmail.com \
--cc=linux-rt-users@vger.kernel.org \
--cc=paul.gortmaker@windriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).