All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Adamushko <dmitry.adamushko@domain.hid>
To: Jan Kiszka <jan.kiszka@domain.hid>
Cc: xenomai@xenomai.org
Subject: Re: [Xenomai-core] [BUG] racy xnshadow_harden under CONFIG_PREEMPT
Date: Sun, 22 Jan 2006 10:10:23 +0200	[thread overview]
Message-ID: <b647ffbd0601220010x3cc023an@domain.hid> (raw)
In-Reply-To: <43D21144.8040005@domain.hid>

[-- Attachment #1: Type: text/plain, Size: 4194 bytes --]

> Hi,
>
> well, if I'm not totally wrong, we have a design problem in the
> RT-thread hardening path. I dug into the crash Jeroen reported > and I'm
> quite sure that this is the reason.
>
> So that's the bad news. The good one is that we can at least
> work around
> it by switching off CONFIG_PREEMPT for Linux (this implicitly means that
> it's a 2.6-only issue).
>
>
> But let's start with two assumptions my further analysis is
> based on:
>
> [Xenomai]
>  o Shadow threads have only one stack, i.e. one context. If the
>   real-time part is active (this includes it is blocked on some
> xnsynch object or delayed), the original Linux task must
> NEVER EVER be
>   executed, even if it will immediately fall asleep again. That's
>   because the stack is in use by the real-time part at that time. > And
this condition is checked in do_schedule_event() [1].
>
> [Linux]
>  o A Linux task which has called
> set_current_state(<blocking_bit>) will
>  remain in the run-queue as long as it calls schedule() on its
> own.

Yes, you are right.

Let's keep in mind the following piece of code.

[*]

[code]    from sched.c::schedule()
...
    switch_count = &prev->nivcsw;
    if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {    <--- MUST
BE TRUE FOR A TASK TO BE REMOVED
        switch_count = &prev->nvcsw;
        if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
                unlikely(signal_pending(prev))))
            prev->state = TASK_RUNNING;
        else {
            if (prev->state == TASK_UNINTERRUPTIBLE)
                rq->nr_uninterruptible++;
            deactivate_task(prev, rq);            <--- removing from the
active queue
        }
    }
...
[/code]

On executing schedule(), a "current" (prev = current) task is not removed
from the active queue in one of the following cases:

[1] prev->state == 0, i.e. == TASK_RUNNING (since #define TASK_RUNNING  0);

[2] add_preempt_count(PREEMPT_ACTIVE) has been called before calling
schedule() from the task's context
    i.e. from the context of the "current" task (prev = current in
schedule());

[3] there is a pending signal for the "current" task.

Keeping that in mind too, let's take a look at what happens in your
"crash"-scenario.

> ...
>
> 3) Interruption by some Linux IRQ. This may cause other
> threads to become runnable as well, but the gatekeeper has
> the highest prio and will therefore be the next. The problem is
> that the rescheduling on Linux IRQ exit will PREEMPT our task > in
xnshadow_harden(), it will NOT remove it from the Linux
> run-queue.

Right. But what actually happens is the following sequence of calls:

ret_from_intr ---> resume_kernel ---> need_resched --->
sched.c::preempt_schedule_irq() ---> schedule()        (**)

As a result, schedule() is called indeed but it does not execute the [*]
code -
the "current" task is not removed from the active queue.
The reason is [2] (from the list above) and that's done in
preempt_schedule_irq().

> And now we are in real troubles: The
> gatekeeper will kick off our RT part which will take over the
> thread's stack. As soon as the RT domain falls asleep and
> Linux takes over again, it will continue our non-RT part as well! >
Actually, this seems to be the reason for the panic in
> do_schedule_event(). Without CONFIG_XENO_OPT_DEBUG
> and this check, we will run both parts AT THE SAME
> TIME now, thus violating my first assumption. The system gets > fatally
corrupted.
>
> Well, I would be happy if someone can prove me wrong here.

I'm afraid you are right.


> The problem is that I don't see a solution because Linux does
> not provide an atomic wake-up + schedule-out under
> CONFIG_PREEMPT. I'm
> currently considering a hack to remove the migrating Linux
> thread manually from the run-queue, but this could easily break > the
Linux scheduler.

I have a "stupid" idea on top of my head but I'd prefer to test it on my own
first so not to look as a complete idiot if it's totally wrong. Err... it's
difficult to look more an idiot than I'm already? :o)


> Jan

--
Best regards,
Dmitry Adamushko

[-- Attachment #2: Type: text/html, Size: 5528 bytes --]

  parent reply	other threads:[~2006-01-22  8:10 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-21 10:47 [Xenomai-core] [BUG] racy xnshadow_harden under CONFIG_PREEMPT Jan Kiszka
2006-01-21 10:51 ` [Xenomai-core] " Jeroen Van den Keybus
2006-01-21 16:47 ` [Xenomai-core] " Hannes Mayer
2006-01-21 17:01   ` Jan Kiszka
2006-01-22  8:10 ` Dmitry Adamushko [this message]
2006-01-22 16:19   ` Jeroen Van den Keybus
2006-01-23 18:22     ` Gilles Chanteperdrix
2006-01-23 19:16       ` Jan Kiszka
2006-01-30 14:51         ` Philippe Gerum
2006-01-30 15:33           ` Philippe Gerum
2006-01-30 16:01             ` Jan Kiszka
2006-01-30 23:10               ` Philippe Gerum
2006-01-31 19:01                 ` Jan Kiszka
2006-01-30 15:35           ` Philippe Gerum
2006-01-31 21:09             ` Jeroen Van den Keybus
2006-01-31 21:45               ` Philippe Gerum
2006-02-01  9:57                 ` Jeroen Van den Keybus
2006-02-01 10:03                   ` Jan Kiszka
2006-02-01 12:23                     ` Jeroen Van den Keybus
2006-02-01 12:34                       ` Jan Kiszka
2006-01-24 13:14       ` Dmitry Adamushko
2006-01-24 13:26         ` Jan Kiszka
2006-01-30 11:37           ` Dmitry Adamushko
2006-01-30 11:48             ` Jan Kiszka
2006-01-30 13:02               ` Dmitry Adamushko
2006-01-29 23:48 ` Philippe Gerum
2006-01-30 10:14   ` Philippe Gerum

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=b647ffbd0601220010x3cc023an@domain.hid \
    --to=dmitry.adamushko@domain.hid \
    --cc=jan.kiszka@domain.hid \
    --cc=xenomai@xenomai.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.