* [Xenomai-core] Policy switching and XNOTHER maintenance
@ 2011-09-11 10:50 Jan Kiszka
2011-09-11 11:49 ` Jan Kiszka
2011-09-11 14:24 ` Gilles Chanteperdrix
0 siblings, 2 replies; 14+ messages in thread
From: Jan Kiszka @ 2011-09-11 10:50 UTC (permalink / raw)
To: xenomai-core
[-- Attachment #1: Type: text/plain, Size: 771 bytes --]
Hi all,
just looked into the hrescnt issue again, specifically the corner case
of a shadow thread switching from real-time policy to SCHED_OTHER.
Looks like we don't support this at all ATM:
do_setsched_event ignores events that enabled SCHED_OTHER, and the
XNOTHER flag is only set on xnshadow_map, not updated anywhere else.
Fixing this is not straightforward as that flag resides in a state
variable that is owned by the thread (ie. updated non-atomically) while
do_setsched_event can also be called over different contexts.
Or am I missing something?
In the light of this, I would vote for reverting f9bfab3457 ("only
update rescnt for XNOTHER threads") as it only adds conditional branches
to the hot paths without solving the issue.
Jan
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-11 10:50 [Xenomai-core] Policy switching and XNOTHER maintenance Jan Kiszka @ 2011-09-11 11:49 ` Jan Kiszka 2011-09-11 14:24 ` Gilles Chanteperdrix 1 sibling, 0 replies; 14+ messages in thread From: Jan Kiszka @ 2011-09-11 11:49 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 1195 bytes --] On 2011-09-11 12:50, Jan Kiszka wrote: > Hi all, > > just looked into the hrescnt issue again, specifically the corner case > of a shadow thread switching from real-time policy to SCHED_OTHER. > > Looks like we don't support this at all ATM: > > do_setsched_event ignores events that enabled SCHED_OTHER, and the > XNOTHER flag is only set on xnshadow_map, not updated anywhere else. > Fixing this is not straightforward as that flag resides in a state > variable that is owned by the thread (ie. updated non-atomically) while > do_setsched_event can also be called over different contexts. OK, it just takes nklock to update the thread state. > > Or am I missing something? From __xnpod_set_thread_schedparam: "A non-real-time shadow may upgrade to real-time FIFO scheduling, but the latter may never downgrade to SCHED_NORMAL Xenomai-wise. In the valid case, we clear XNOTHER to reflect the change." What prevents us from setting XNOTHER if the priority drops to 0, i.e. the Linux task re-enters SCHED_NORMAL (while Xenomai will still schedule it via its RT class of course)? We cannot deny such a transition on the Linux side anyway, can we? Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-11 10:50 [Xenomai-core] Policy switching and XNOTHER maintenance Jan Kiszka 2011-09-11 11:49 ` Jan Kiszka @ 2011-09-11 14:24 ` Gilles Chanteperdrix 2011-09-11 14:29 ` Jan Kiszka 1 sibling, 1 reply; 14+ messages in thread From: Gilles Chanteperdrix @ 2011-09-11 14:24 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On 09/11/2011 12:50 PM, Jan Kiszka wrote: > Hi all, > > just looked into the hrescnt issue again, specifically the corner case > of a shadow thread switching from real-time policy to SCHED_OTHER. Doing this while holding a mutex looks invalid. If we do not do it, the current code is valid. -- Gilles. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-11 14:24 ` Gilles Chanteperdrix @ 2011-09-11 14:29 ` Jan Kiszka 2011-09-16 20:13 ` Gilles Chanteperdrix 0 siblings, 1 reply; 14+ messages in thread From: Jan Kiszka @ 2011-09-11 14:29 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 770 bytes --] On 2011-09-11 16:24, Gilles Chanteperdrix wrote: > On 09/11/2011 12:50 PM, Jan Kiszka wrote: >> Hi all, >> >> just looked into the hrescnt issue again, specifically the corner case >> of a shadow thread switching from real-time policy to SCHED_OTHER. > > Doing this while holding a mutex looks invalid. Looking at POSIX e.g., is there anything in the spec that makes this invalid? If the kernel preserves or established proper priority boosting, I do not see what could break in principle. It is nothing I would design into some app, but we should somehow handle it (doc update or code adjustments). > If we do not do it, the current code is valid. Except for its dependency on XNOTHER which is not updated on RT->NORMAL transitions. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-11 14:29 ` Jan Kiszka @ 2011-09-16 20:13 ` Gilles Chanteperdrix 2011-09-16 20:39 ` Gilles Chanteperdrix 0 siblings, 1 reply; 14+ messages in thread From: Gilles Chanteperdrix @ 2011-09-16 20:13 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On 09/11/2011 04:29 PM, Jan Kiszka wrote: > On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>> Hi all, >>> >>> just looked into the hrescnt issue again, specifically the corner case >>> of a shadow thread switching from real-time policy to SCHED_OTHER. >> >> Doing this while holding a mutex looks invalid. > > Looking at POSIX e.g., is there anything in the spec that makes this > invalid? If the kernel preserves or established proper priority > boosting, I do not see what could break in principle. > > It is nothing I would design into some app, but we should somehow handle > it (doc update or code adjustments). > >> If we do not do it, the current code is valid. > > Except for its dependency on XNOTHER which is not updated on RT->NORMAL > transitions. The fact that this update did not take place made the code work. No negative rescnt could happen with that code. Anyway, here is a patch to allow switching back from RT to NORMAL, but send a SIGDEBUG to a thread attempting to release a mutex while its counter is already 0. We end up avoiding a big chunk of code that would have been useful for a really strange corner case. diff --git a/examples/native/sigdebug.c b/examples/native/sigdebug.c index e20714b..7b840f9 100644 --- a/examples/native/sigdebug.c +++ b/examples/native/sigdebug.c @@ -34,6 +34,8 @@ static const char *reason_str[] = { [SIGDEBUG_MIGRATE_PRIOINV] = "affected by priority inversion", [SIGDEBUG_NOMLOCK] = "missing mlockall", [SIGDEBUG_WATCHDOG] = "runaway thread", + [SIGDEBUG_SCHED_CHANGE_W_MX] = + "switched to SCHED_OTHER policy with mutex held", }; void warn_upon_switch(int sig, siginfo_t *si, void *context) diff --git a/include/asm-generic/syscall.h b/include/asm-generic/syscall.h index a9cdc87..5b6c764 100644 --- a/include/asm-generic/syscall.h +++ b/include/asm-generic/syscall.h @@ -61,6 +61,7 @@ typedef struct xnsysinfo { #define SIGDEBUG_MIGRATE_PRIOINV 4 #define SIGDEBUG_NOMLOCK 5 #define SIGDEBUG_WATCHDOG 6 +#define SIGDEBUG_SCHED_CHANGE_W_MX 7 #ifdef __KERNEL__ diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h index 6399a17..3cc7185 100644 --- a/include/nucleus/sched-idle.h +++ b/include/nucleus/sched-idle.h @@ -39,6 +39,7 @@ extern struct xnsched_class xnsched_class_idle; static inline void __xnsched_idle_setparam(struct xnthread *thread, const union xnsched_policy_param *p) { + xnthread_set_state(thread, XNOTHER); thread->cprio = p->idle.prio; } diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h index 71f655c..d17b058 100644 --- a/include/nucleus/sched-rt.h +++ b/include/nucleus/sched-rt.h @@ -86,6 +86,10 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, const union xnsched_policy_param *p) { thread->cprio = p->rt.prio; + if (thread->cprio) + xnthread_clear_state(thread, XNOTHER); + else + xnthread_set_state(thread, XNOTHER); } static inline void __xnsched_rt_getparam(struct xnthread *thread, diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index 9a02e80..d19999f 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, xnsched_putback(thread); #ifdef CONFIG_XENO_OPT_PERVASIVE - /* - * A non-real-time shadow may upgrade to real-time FIFO - * scheduling, but the latter may never downgrade to - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear - * XNOTHER to reflect the change. Note that we keep handling - * non real-time shadow specifics in higher code layers, not - * to pollute the core scheduler with peculiarities. - */ - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) - xnthread_clear_state(thread, XNOTHER); if (propagate) { if (xnthread_test_state(thread, XNRELAX)) xnshadow_renice(thread); diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c index fd37c21..587be4a 100644 --- a/ksrc/nucleus/sched-sporadic.c +++ b/ksrc/nucleus/sched-sporadic.c @@ -258,6 +258,7 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, } } + xnthread_clear_state(thread, XNOTHER); thread->cprio = p->pss.current_prio; } diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c index 43a548e..2423e81 100644 --- a/ksrc/nucleus/sched-tp.c +++ b/ksrc/nucleus/sched-tp.c @@ -100,6 +100,7 @@ static void xnsched_tp_setparam(struct xnthread *thread, { struct xnsched *sched = thread->sched; + xnthread_clear_state(thread, XNOTHER); thread->tps = &sched->tp.partitions[p->tp.ptid]; thread->cprio = p->tp.prio; } diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c index b956e46..e3442a4 100644 --- a/ksrc/nucleus/synch.c +++ b/ksrc/nucleus/synch.c @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); - if (xnthread_test_state(lastowner, XNOTHER)) - xnthread_dec_rescnt(lastowner); - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); + if (xnthread_test_state(lastowner, XNOTHER)) { + if (xnthread_get_rescnt(lastowner)) + xnshadow_send_sig(lastowner, SIGDEBUG, + SIGDEBUG_SCHED_CHANGE_W_MX, 1); + else + xnthread_dec_rescnt(lastowner); + } lastownerh = xnthread_handle(lastowner); if (use_fastlock && -- Gilles. ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-16 20:13 ` Gilles Chanteperdrix @ 2011-09-16 20:39 ` Gilles Chanteperdrix 2011-09-18 14:02 ` Philippe Gerum 0 siblings, 1 reply; 14+ messages in thread From: Gilles Chanteperdrix @ 2011-09-16 20:39 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: > On 09/11/2011 04:29 PM, Jan Kiszka wrote: >> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>> Hi all, >>>> >>>> just looked into the hrescnt issue again, specifically the corner case >>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>> >>> Doing this while holding a mutex looks invalid. >> >> Looking at POSIX e.g., is there anything in the spec that makes this >> invalid? If the kernel preserves or established proper priority >> boosting, I do not see what could break in principle. >> >> It is nothing I would design into some app, but we should somehow handle >> it (doc update or code adjustments). >> >>> If we do not do it, the current code is valid. >> >> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >> transitions. > > The fact that this update did not take place made the code work. No > negative rescnt could happen with that code. > > Anyway, here is a patch to allow switching back from RT to NORMAL, but > send a SIGDEBUG to a thread attempting to release a mutex while its > counter is already 0. We end up avoiding a big chunk of code that would > have been useful for a really strange corner case. > Here comes version 2: diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h index 6399a17..417170f 100644 --- a/include/nucleus/sched-idle.h +++ b/include/nucleus/sched-idle.h @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; static inline void __xnsched_idle_setparam(struct xnthread *thread, const union xnsched_policy_param *p) { + if (xnthread_test_state(thread, XNSHADOW)) + xnthread_clear_state(thread, XNOTHER); thread->cprio = p->idle.prio; } diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h index 71f655c..cc1cefa 100644 --- a/include/nucleus/sched-rt.h +++ b/include/nucleus/sched-rt.h @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, const union xnsched_policy_param *p) { thread->cprio = p->rt.prio; + if (xnthread_test_state(thread, XNSHADOW)) { + if (thread->cprio) + xnthread_clear_state(thread, XNOTHER); + else + xnthread_set_state(thread, XNOTHER); + } } static inline void __xnsched_rt_getparam(struct xnthread *thread, diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index 9a02e80..d19999f 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, xnsched_putback(thread); #ifdef CONFIG_XENO_OPT_PERVASIVE - /* - * A non-real-time shadow may upgrade to real-time FIFO - * scheduling, but the latter may never downgrade to - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear - * XNOTHER to reflect the change. Note that we keep handling - * non real-time shadow specifics in higher code layers, not - * to pollute the core scheduler with peculiarities. - */ - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) - xnthread_clear_state(thread, XNOTHER); if (propagate) { if (xnthread_test_state(thread, XNRELAX)) xnshadow_renice(thread); diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c index fd37c21..ffc9bab 100644 --- a/ksrc/nucleus/sched-sporadic.c +++ b/ksrc/nucleus/sched-sporadic.c @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, } } + if (xnthread_test_state(thread, XNSHADOW)) + xnthread_clear_state(thread, XNOTHER); thread->cprio = p->pss.current_prio; } diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c index 43a548e..a2af1d3 100644 --- a/ksrc/nucleus/sched-tp.c +++ b/ksrc/nucleus/sched-tp.c @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, { struct xnsched *sched = thread->sched; + if (xnthread_test_state(thread, XNSHADOW)) + xnthread_clear_state(thread, XNOTHER); thread->tps = &sched->tp.partitions[p->tp.ptid]; thread->cprio = p->tp.prio; } diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c index b956e46..47bc0c5 100644 --- a/ksrc/nucleus/synch.c +++ b/ksrc/nucleus/synch.c @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); - if (xnthread_test_state(lastowner, XNOTHER)) - xnthread_dec_rescnt(lastowner); - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); + if (xnthread_test_state(lastowner, XNOTHER)) { + if (xnthread_get_rescnt(lastowner) == 0) + xnshadow_send_sig(lastowner, SIGDEBUG, + SIGDEBUG_MIGRATE_PRIOINV, 1); + else + xnthread_dec_rescnt(lastowner); + } lastownerh = xnthread_handle(lastowner); if (use_fastlock && -- Gilles. ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-16 20:39 ` Gilles Chanteperdrix @ 2011-09-18 14:02 ` Philippe Gerum 2011-09-18 14:34 ` Jan Kiszka 0 siblings, 1 reply; 14+ messages in thread From: Philippe Gerum @ 2011-09-18 14:02 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: Jan Kiszka, xenomai-core On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: > On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: > > On 09/11/2011 04:29 PM, Jan Kiszka wrote: > >> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: > >>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: > >>>> Hi all, > >>>> > >>>> just looked into the hrescnt issue again, specifically the corner case > >>>> of a shadow thread switching from real-time policy to SCHED_OTHER. > >>> > >>> Doing this while holding a mutex looks invalid. > >> > >> Looking at POSIX e.g., is there anything in the spec that makes this > >> invalid? If the kernel preserves or established proper priority > >> boosting, I do not see what could break in principle. > >> > >> It is nothing I would design into some app, but we should somehow handle > >> it (doc update or code adjustments). > >> > >>> If we do not do it, the current code is valid. > >> > >> Except for its dependency on XNOTHER which is not updated on RT->NORMAL > >> transitions. > > > > The fact that this update did not take place made the code work. No > > negative rescnt could happen with that code. > > > > Anyway, here is a patch to allow switching back from RT to NORMAL, but > > send a SIGDEBUG to a thread attempting to release a mutex while its > > counter is already 0. We end up avoiding a big chunk of code that would > > have been useful for a really strange corner case. > > > > Here comes version 2: > diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h > index 6399a17..417170f 100644 > --- a/include/nucleus/sched-idle.h > +++ b/include/nucleus/sched-idle.h > @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; > static inline void __xnsched_idle_setparam(struct xnthread *thread, > const union xnsched_policy_param *p) > { > + if (xnthread_test_state(thread, XNSHADOW)) > + xnthread_clear_state(thread, XNOTHER); > thread->cprio = p->idle.prio; > } > > diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h > index 71f655c..cc1cefa 100644 > --- a/include/nucleus/sched-rt.h > +++ b/include/nucleus/sched-rt.h > @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, > const union xnsched_policy_param *p) > { > thread->cprio = p->rt.prio; > + if (xnthread_test_state(thread, XNSHADOW)) { > + if (thread->cprio) > + xnthread_clear_state(thread, XNOTHER); > + else > + xnthread_set_state(thread, XNOTHER); > + } > } > > static inline void __xnsched_rt_getparam(struct xnthread *thread, > diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c > index 9a02e80..d19999f 100644 > --- a/ksrc/nucleus/pod.c > +++ b/ksrc/nucleus/pod.c > @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, > xnsched_putback(thread); > > #ifdef CONFIG_XENO_OPT_PERVASIVE > - /* > - * A non-real-time shadow may upgrade to real-time FIFO > - * scheduling, but the latter may never downgrade to > - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear > - * XNOTHER to reflect the change. Note that we keep handling > - * non real-time shadow specifics in higher code layers, not > - * to pollute the core scheduler with peculiarities. > - */ > - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) > - xnthread_clear_state(thread, XNOTHER); > if (propagate) { > if (xnthread_test_state(thread, XNRELAX)) > xnshadow_renice(thread); > diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c > index fd37c21..ffc9bab 100644 > --- a/ksrc/nucleus/sched-sporadic.c > +++ b/ksrc/nucleus/sched-sporadic.c > @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, > } > } > > + if (xnthread_test_state(thread, XNSHADOW)) > + xnthread_clear_state(thread, XNOTHER); > thread->cprio = p->pss.current_prio; > } > > diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c > index 43a548e..a2af1d3 100644 > --- a/ksrc/nucleus/sched-tp.c > +++ b/ksrc/nucleus/sched-tp.c > @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, > { > struct xnsched *sched = thread->sched; > > + if (xnthread_test_state(thread, XNSHADOW)) > + xnthread_clear_state(thread, XNOTHER); > thread->tps = &sched->tp.partitions[p->tp.ptid]; > thread->cprio = p->tp.prio; > } > diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c > index b956e46..47bc0c5 100644 > --- a/ksrc/nucleus/synch.c > +++ b/ksrc/nucleus/synch.c > @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) > > XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); > > - if (xnthread_test_state(lastowner, XNOTHER)) > - xnthread_dec_rescnt(lastowner); > - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); > + if (xnthread_test_state(lastowner, XNOTHER)) { > + if (xnthread_get_rescnt(lastowner) == 0) > + xnshadow_send_sig(lastowner, SIGDEBUG, > + SIGDEBUG_MIGRATE_PRIOINV, 1); > + else > + xnthread_dec_rescnt(lastowner); > + } > lastownerh = xnthread_handle(lastowner); > > if (use_fastlock && > > > Agreed, the logic of this patch sounds right. Switching from -rt to -nrt while holding a -rt mutex is pathological behavior. We don't have to support apps implementing voluntary priority inversion. -- Philippe. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 14:02 ` Philippe Gerum @ 2011-09-18 14:34 ` Jan Kiszka 2011-09-18 15:10 ` Philippe Gerum 0 siblings, 1 reply; 14+ messages in thread From: Jan Kiszka @ 2011-09-18 14:34 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 6283 bytes --] On 2011-09-18 16:02, Philippe Gerum wrote: > On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: >> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: >>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: >>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>>>> Hi all, >>>>>> >>>>>> just looked into the hrescnt issue again, specifically the corner case >>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>>>> >>>>> Doing this while holding a mutex looks invalid. >>>> >>>> Looking at POSIX e.g., is there anything in the spec that makes this >>>> invalid? If the kernel preserves or established proper priority >>>> boosting, I do not see what could break in principle. >>>> >>>> It is nothing I would design into some app, but we should somehow handle >>>> it (doc update or code adjustments). >>>> >>>>> If we do not do it, the current code is valid. >>>> >>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >>>> transitions. >>> >>> The fact that this update did not take place made the code work. No >>> negative rescnt could happen with that code. >>> >>> Anyway, here is a patch to allow switching back from RT to NORMAL, but >>> send a SIGDEBUG to a thread attempting to release a mutex while its >>> counter is already 0. We end up avoiding a big chunk of code that would >>> have been useful for a really strange corner case. >>> >> >> Here comes version 2: >> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h >> index 6399a17..417170f 100644 >> --- a/include/nucleus/sched-idle.h >> +++ b/include/nucleus/sched-idle.h >> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; >> static inline void __xnsched_idle_setparam(struct xnthread *thread, >> const union xnsched_policy_param *p) >> { >> + if (xnthread_test_state(thread, XNSHADOW)) >> + xnthread_clear_state(thread, XNOTHER); >> thread->cprio = p->idle.prio; >> } >> >> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h >> index 71f655c..cc1cefa 100644 >> --- a/include/nucleus/sched-rt.h >> +++ b/include/nucleus/sched-rt.h >> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, >> const union xnsched_policy_param *p) >> { >> thread->cprio = p->rt.prio; >> + if (xnthread_test_state(thread, XNSHADOW)) { >> + if (thread->cprio) >> + xnthread_clear_state(thread, XNOTHER); >> + else >> + xnthread_set_state(thread, XNOTHER); >> + } >> } >> >> static inline void __xnsched_rt_getparam(struct xnthread *thread, >> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c >> index 9a02e80..d19999f 100644 >> --- a/ksrc/nucleus/pod.c >> +++ b/ksrc/nucleus/pod.c >> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, >> xnsched_putback(thread); >> >> #ifdef CONFIG_XENO_OPT_PERVASIVE >> - /* >> - * A non-real-time shadow may upgrade to real-time FIFO >> - * scheduling, but the latter may never downgrade to >> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear >> - * XNOTHER to reflect the change. Note that we keep handling >> - * non real-time shadow specifics in higher code layers, not >> - * to pollute the core scheduler with peculiarities. >> - */ >> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) >> - xnthread_clear_state(thread, XNOTHER); >> if (propagate) { >> if (xnthread_test_state(thread, XNRELAX)) >> xnshadow_renice(thread); >> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c >> index fd37c21..ffc9bab 100644 >> --- a/ksrc/nucleus/sched-sporadic.c >> +++ b/ksrc/nucleus/sched-sporadic.c >> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, >> } >> } >> >> + if (xnthread_test_state(thread, XNSHADOW)) >> + xnthread_clear_state(thread, XNOTHER); >> thread->cprio = p->pss.current_prio; >> } >> >> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c >> index 43a548e..a2af1d3 100644 >> --- a/ksrc/nucleus/sched-tp.c >> +++ b/ksrc/nucleus/sched-tp.c >> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, >> { >> struct xnsched *sched = thread->sched; >> >> + if (xnthread_test_state(thread, XNSHADOW)) >> + xnthread_clear_state(thread, XNOTHER); >> thread->tps = &sched->tp.partitions[p->tp.ptid]; >> thread->cprio = p->tp.prio; >> } >> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c >> index b956e46..47bc0c5 100644 >> --- a/ksrc/nucleus/synch.c >> +++ b/ksrc/nucleus/synch.c >> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) >> >> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); >> >> - if (xnthread_test_state(lastowner, XNOTHER)) >> - xnthread_dec_rescnt(lastowner); >> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); >> + if (xnthread_test_state(lastowner, XNOTHER)) { >> + if (xnthread_get_rescnt(lastowner) == 0) >> + xnshadow_send_sig(lastowner, SIGDEBUG, >> + SIGDEBUG_MIGRATE_PRIOINV, 1); >> + else >> + xnthread_dec_rescnt(lastowner); >> + } >> lastownerh = xnthread_handle(lastowner); >> >> if (use_fastlock && >> >> >> > > Agreed, the logic of this patch sounds right. Switching from -rt to -nrt > while holding a -rt mutex is pathological behavior. We don't have to > support apps implementing voluntary priority inversion. > No concerns either. Now we just need diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c index 21cc191..27bc829 100644 --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) union xnsched_policy_param param; struct xnsched *sched; - if (!thread || p->policy != SCHED_FIFO) + if (!thread) return; + if (p->policy == SCHED_FIFO) + priority = 0; + /* * Linux's priority scale is a subset of the core pod's * priority scale, so there is no need to bound the priority to track the policy change when done via Linux. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 14:34 ` Jan Kiszka @ 2011-09-18 15:10 ` Philippe Gerum 2011-09-18 15:11 ` Jan Kiszka 0 siblings, 1 reply; 14+ messages in thread From: Philippe Gerum @ 2011-09-18 15:10 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On Sun, 2011-09-18 at 16:34 +0200, Jan Kiszka wrote: > On 2011-09-18 16:02, Philippe Gerum wrote: > > On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: > >> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: > >>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: > >>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: > >>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: > >>>>>> Hi all, > >>>>>> > >>>>>> just looked into the hrescnt issue again, specifically the corner case > >>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. > >>>>> > >>>>> Doing this while holding a mutex looks invalid. > >>>> > >>>> Looking at POSIX e.g., is there anything in the spec that makes this > >>>> invalid? If the kernel preserves or established proper priority > >>>> boosting, I do not see what could break in principle. > >>>> > >>>> It is nothing I would design into some app, but we should somehow handle > >>>> it (doc update or code adjustments). > >>>> > >>>>> If we do not do it, the current code is valid. > >>>> > >>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL > >>>> transitions. > >>> > >>> The fact that this update did not take place made the code work. No > >>> negative rescnt could happen with that code. > >>> > >>> Anyway, here is a patch to allow switching back from RT to NORMAL, but > >>> send a SIGDEBUG to a thread attempting to release a mutex while its > >>> counter is already 0. We end up avoiding a big chunk of code that would > >>> have been useful for a really strange corner case. > >>> > >> > >> Here comes version 2: > >> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h > >> index 6399a17..417170f 100644 > >> --- a/include/nucleus/sched-idle.h > >> +++ b/include/nucleus/sched-idle.h > >> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; > >> static inline void __xnsched_idle_setparam(struct xnthread *thread, > >> const union xnsched_policy_param *p) > >> { > >> + if (xnthread_test_state(thread, XNSHADOW)) > >> + xnthread_clear_state(thread, XNOTHER); > >> thread->cprio = p->idle.prio; > >> } > >> > >> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h > >> index 71f655c..cc1cefa 100644 > >> --- a/include/nucleus/sched-rt.h > >> +++ b/include/nucleus/sched-rt.h > >> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, > >> const union xnsched_policy_param *p) > >> { > >> thread->cprio = p->rt.prio; > >> + if (xnthread_test_state(thread, XNSHADOW)) { > >> + if (thread->cprio) > >> + xnthread_clear_state(thread, XNOTHER); > >> + else > >> + xnthread_set_state(thread, XNOTHER); > >> + } > >> } > >> > >> static inline void __xnsched_rt_getparam(struct xnthread *thread, > >> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c > >> index 9a02e80..d19999f 100644 > >> --- a/ksrc/nucleus/pod.c > >> +++ b/ksrc/nucleus/pod.c > >> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, > >> xnsched_putback(thread); > >> > >> #ifdef CONFIG_XENO_OPT_PERVASIVE > >> - /* > >> - * A non-real-time shadow may upgrade to real-time FIFO > >> - * scheduling, but the latter may never downgrade to > >> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear > >> - * XNOTHER to reflect the change. Note that we keep handling > >> - * non real-time shadow specifics in higher code layers, not > >> - * to pollute the core scheduler with peculiarities. > >> - */ > >> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) > >> - xnthread_clear_state(thread, XNOTHER); > >> if (propagate) { > >> if (xnthread_test_state(thread, XNRELAX)) > >> xnshadow_renice(thread); > >> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c > >> index fd37c21..ffc9bab 100644 > >> --- a/ksrc/nucleus/sched-sporadic.c > >> +++ b/ksrc/nucleus/sched-sporadic.c > >> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, > >> } > >> } > >> > >> + if (xnthread_test_state(thread, XNSHADOW)) > >> + xnthread_clear_state(thread, XNOTHER); > >> thread->cprio = p->pss.current_prio; > >> } > >> > >> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c > >> index 43a548e..a2af1d3 100644 > >> --- a/ksrc/nucleus/sched-tp.c > >> +++ b/ksrc/nucleus/sched-tp.c > >> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, > >> { > >> struct xnsched *sched = thread->sched; > >> > >> + if (xnthread_test_state(thread, XNSHADOW)) > >> + xnthread_clear_state(thread, XNOTHER); > >> thread->tps = &sched->tp.partitions[p->tp.ptid]; > >> thread->cprio = p->tp.prio; > >> } > >> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c > >> index b956e46..47bc0c5 100644 > >> --- a/ksrc/nucleus/synch.c > >> +++ b/ksrc/nucleus/synch.c > >> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) > >> > >> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); > >> > >> - if (xnthread_test_state(lastowner, XNOTHER)) > >> - xnthread_dec_rescnt(lastowner); > >> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); > >> + if (xnthread_test_state(lastowner, XNOTHER)) { > >> + if (xnthread_get_rescnt(lastowner) == 0) > >> + xnshadow_send_sig(lastowner, SIGDEBUG, > >> + SIGDEBUG_MIGRATE_PRIOINV, 1); > >> + else > >> + xnthread_dec_rescnt(lastowner); > >> + } > >> lastownerh = xnthread_handle(lastowner); > >> > >> if (use_fastlock && > >> > >> > >> > > > > Agreed, the logic of this patch sounds right. Switching from -rt to -nrt > > while holding a -rt mutex is pathological behavior. We don't have to > > support apps implementing voluntary priority inversion. > > > > No concerns either. > > Now we just need > > diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c > index 21cc191..27bc829 100644 > --- a/ksrc/nucleus/shadow.c > +++ b/ksrc/nucleus/shadow.c > @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) > union xnsched_policy_param param; > struct xnsched *sched; > > - if (!thread || p->policy != SCHED_FIFO) > + if (!thread) > return; > > + if (p->policy == SCHED_FIFO) ^^ inverted? > + priority = 0; > + > /* > * Linux's priority scale is a subset of the core pod's > * priority scale, so there is no need to bound the priority > > > to track the policy change when done via Linux. > > Jan > -- Philippe. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 15:10 ` Philippe Gerum @ 2011-09-18 15:11 ` Jan Kiszka 2011-09-18 15:13 ` Jan Kiszka 0 siblings, 1 reply; 14+ messages in thread From: Jan Kiszka @ 2011-09-18 15:11 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 6550 bytes --] On 2011-09-18 17:10, Philippe Gerum wrote: > On Sun, 2011-09-18 at 16:34 +0200, Jan Kiszka wrote: >> On 2011-09-18 16:02, Philippe Gerum wrote: >>> On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: >>>> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: >>>>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: >>>>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>>>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>>>>>> Hi all, >>>>>>>> >>>>>>>> just looked into the hrescnt issue again, specifically the corner case >>>>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>>>>>> >>>>>>> Doing this while holding a mutex looks invalid. >>>>>> >>>>>> Looking at POSIX e.g., is there anything in the spec that makes this >>>>>> invalid? If the kernel preserves or established proper priority >>>>>> boosting, I do not see what could break in principle. >>>>>> >>>>>> It is nothing I would design into some app, but we should somehow handle >>>>>> it (doc update or code adjustments). >>>>>> >>>>>>> If we do not do it, the current code is valid. >>>>>> >>>>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >>>>>> transitions. >>>>> >>>>> The fact that this update did not take place made the code work. No >>>>> negative rescnt could happen with that code. >>>>> >>>>> Anyway, here is a patch to allow switching back from RT to NORMAL, but >>>>> send a SIGDEBUG to a thread attempting to release a mutex while its >>>>> counter is already 0. We end up avoiding a big chunk of code that would >>>>> have been useful for a really strange corner case. >>>>> >>>> >>>> Here comes version 2: >>>> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h >>>> index 6399a17..417170f 100644 >>>> --- a/include/nucleus/sched-idle.h >>>> +++ b/include/nucleus/sched-idle.h >>>> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; >>>> static inline void __xnsched_idle_setparam(struct xnthread *thread, >>>> const union xnsched_policy_param *p) >>>> { >>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>> + xnthread_clear_state(thread, XNOTHER); >>>> thread->cprio = p->idle.prio; >>>> } >>>> >>>> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h >>>> index 71f655c..cc1cefa 100644 >>>> --- a/include/nucleus/sched-rt.h >>>> +++ b/include/nucleus/sched-rt.h >>>> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, >>>> const union xnsched_policy_param *p) >>>> { >>>> thread->cprio = p->rt.prio; >>>> + if (xnthread_test_state(thread, XNSHADOW)) { >>>> + if (thread->cprio) >>>> + xnthread_clear_state(thread, XNOTHER); >>>> + else >>>> + xnthread_set_state(thread, XNOTHER); >>>> + } >>>> } >>>> >>>> static inline void __xnsched_rt_getparam(struct xnthread *thread, >>>> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c >>>> index 9a02e80..d19999f 100644 >>>> --- a/ksrc/nucleus/pod.c >>>> +++ b/ksrc/nucleus/pod.c >>>> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, >>>> xnsched_putback(thread); >>>> >>>> #ifdef CONFIG_XENO_OPT_PERVASIVE >>>> - /* >>>> - * A non-real-time shadow may upgrade to real-time FIFO >>>> - * scheduling, but the latter may never downgrade to >>>> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear >>>> - * XNOTHER to reflect the change. Note that we keep handling >>>> - * non real-time shadow specifics in higher code layers, not >>>> - * to pollute the core scheduler with peculiarities. >>>> - */ >>>> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) >>>> - xnthread_clear_state(thread, XNOTHER); >>>> if (propagate) { >>>> if (xnthread_test_state(thread, XNRELAX)) >>>> xnshadow_renice(thread); >>>> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c >>>> index fd37c21..ffc9bab 100644 >>>> --- a/ksrc/nucleus/sched-sporadic.c >>>> +++ b/ksrc/nucleus/sched-sporadic.c >>>> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, >>>> } >>>> } >>>> >>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>> + xnthread_clear_state(thread, XNOTHER); >>>> thread->cprio = p->pss.current_prio; >>>> } >>>> >>>> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c >>>> index 43a548e..a2af1d3 100644 >>>> --- a/ksrc/nucleus/sched-tp.c >>>> +++ b/ksrc/nucleus/sched-tp.c >>>> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, >>>> { >>>> struct xnsched *sched = thread->sched; >>>> >>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>> + xnthread_clear_state(thread, XNOTHER); >>>> thread->tps = &sched->tp.partitions[p->tp.ptid]; >>>> thread->cprio = p->tp.prio; >>>> } >>>> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c >>>> index b956e46..47bc0c5 100644 >>>> --- a/ksrc/nucleus/synch.c >>>> +++ b/ksrc/nucleus/synch.c >>>> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) >>>> >>>> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); >>>> >>>> - if (xnthread_test_state(lastowner, XNOTHER)) >>>> - xnthread_dec_rescnt(lastowner); >>>> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); >>>> + if (xnthread_test_state(lastowner, XNOTHER)) { >>>> + if (xnthread_get_rescnt(lastowner) == 0) >>>> + xnshadow_send_sig(lastowner, SIGDEBUG, >>>> + SIGDEBUG_MIGRATE_PRIOINV, 1); >>>> + else >>>> + xnthread_dec_rescnt(lastowner); >>>> + } >>>> lastownerh = xnthread_handle(lastowner); >>>> >>>> if (use_fastlock && >>>> >>>> >>>> >>> >>> Agreed, the logic of this patch sounds right. Switching from -rt to -nrt >>> while holding a -rt mutex is pathological behavior. We don't have to >>> support apps implementing voluntary priority inversion. >>> >> >> No concerns either. >> >> Now we just need >> >> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c >> index 21cc191..27bc829 100644 >> --- a/ksrc/nucleus/shadow.c >> +++ b/ksrc/nucleus/shadow.c >> @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) >> union xnsched_policy_param param; >> struct xnsched *sched; >> >> - if (!thread || p->policy != SCHED_FIFO) >> + if (!thread) >> return; >> >> + if (p->policy == SCHED_FIFO) > ^^ > inverted? Of course. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 15:11 ` Jan Kiszka @ 2011-09-18 15:13 ` Jan Kiszka 2011-09-18 15:18 ` Gilles Chanteperdrix 0 siblings, 1 reply; 14+ messages in thread From: Jan Kiszka @ 2011-09-18 15:13 UTC (permalink / raw) To: Philippe Gerum; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 6853 bytes --] On 2011-09-18 17:11, Jan Kiszka wrote: > On 2011-09-18 17:10, Philippe Gerum wrote: >> On Sun, 2011-09-18 at 16:34 +0200, Jan Kiszka wrote: >>> On 2011-09-18 16:02, Philippe Gerum wrote: >>>> On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: >>>>> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: >>>>>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: >>>>>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>>>>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>>>>>>> Hi all, >>>>>>>>> >>>>>>>>> just looked into the hrescnt issue again, specifically the corner case >>>>>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>>>>>>> >>>>>>>> Doing this while holding a mutex looks invalid. >>>>>>> >>>>>>> Looking at POSIX e.g., is there anything in the spec that makes this >>>>>>> invalid? If the kernel preserves or established proper priority >>>>>>> boosting, I do not see what could break in principle. >>>>>>> >>>>>>> It is nothing I would design into some app, but we should somehow handle >>>>>>> it (doc update or code adjustments). >>>>>>> >>>>>>>> If we do not do it, the current code is valid. >>>>>>> >>>>>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >>>>>>> transitions. >>>>>> >>>>>> The fact that this update did not take place made the code work. No >>>>>> negative rescnt could happen with that code. >>>>>> >>>>>> Anyway, here is a patch to allow switching back from RT to NORMAL, but >>>>>> send a SIGDEBUG to a thread attempting to release a mutex while its >>>>>> counter is already 0. We end up avoiding a big chunk of code that would >>>>>> have been useful for a really strange corner case. >>>>>> >>>>> >>>>> Here comes version 2: >>>>> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h >>>>> index 6399a17..417170f 100644 >>>>> --- a/include/nucleus/sched-idle.h >>>>> +++ b/include/nucleus/sched-idle.h >>>>> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; >>>>> static inline void __xnsched_idle_setparam(struct xnthread *thread, >>>>> const union xnsched_policy_param *p) >>>>> { >>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>> + xnthread_clear_state(thread, XNOTHER); >>>>> thread->cprio = p->idle.prio; >>>>> } >>>>> >>>>> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h >>>>> index 71f655c..cc1cefa 100644 >>>>> --- a/include/nucleus/sched-rt.h >>>>> +++ b/include/nucleus/sched-rt.h >>>>> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, >>>>> const union xnsched_policy_param *p) >>>>> { >>>>> thread->cprio = p->rt.prio; >>>>> + if (xnthread_test_state(thread, XNSHADOW)) { >>>>> + if (thread->cprio) >>>>> + xnthread_clear_state(thread, XNOTHER); >>>>> + else >>>>> + xnthread_set_state(thread, XNOTHER); >>>>> + } >>>>> } >>>>> >>>>> static inline void __xnsched_rt_getparam(struct xnthread *thread, >>>>> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c >>>>> index 9a02e80..d19999f 100644 >>>>> --- a/ksrc/nucleus/pod.c >>>>> +++ b/ksrc/nucleus/pod.c >>>>> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, >>>>> xnsched_putback(thread); >>>>> >>>>> #ifdef CONFIG_XENO_OPT_PERVASIVE >>>>> - /* >>>>> - * A non-real-time shadow may upgrade to real-time FIFO >>>>> - * scheduling, but the latter may never downgrade to >>>>> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear >>>>> - * XNOTHER to reflect the change. Note that we keep handling >>>>> - * non real-time shadow specifics in higher code layers, not >>>>> - * to pollute the core scheduler with peculiarities. >>>>> - */ >>>>> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) >>>>> - xnthread_clear_state(thread, XNOTHER); >>>>> if (propagate) { >>>>> if (xnthread_test_state(thread, XNRELAX)) >>>>> xnshadow_renice(thread); >>>>> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c >>>>> index fd37c21..ffc9bab 100644 >>>>> --- a/ksrc/nucleus/sched-sporadic.c >>>>> +++ b/ksrc/nucleus/sched-sporadic.c >>>>> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, >>>>> } >>>>> } >>>>> >>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>> + xnthread_clear_state(thread, XNOTHER); >>>>> thread->cprio = p->pss.current_prio; >>>>> } >>>>> >>>>> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c >>>>> index 43a548e..a2af1d3 100644 >>>>> --- a/ksrc/nucleus/sched-tp.c >>>>> +++ b/ksrc/nucleus/sched-tp.c >>>>> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, >>>>> { >>>>> struct xnsched *sched = thread->sched; >>>>> >>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>> + xnthread_clear_state(thread, XNOTHER); >>>>> thread->tps = &sched->tp.partitions[p->tp.ptid]; >>>>> thread->cprio = p->tp.prio; >>>>> } >>>>> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c >>>>> index b956e46..47bc0c5 100644 >>>>> --- a/ksrc/nucleus/synch.c >>>>> +++ b/ksrc/nucleus/synch.c >>>>> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) >>>>> >>>>> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); >>>>> >>>>> - if (xnthread_test_state(lastowner, XNOTHER)) >>>>> - xnthread_dec_rescnt(lastowner); >>>>> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); >>>>> + if (xnthread_test_state(lastowner, XNOTHER)) { >>>>> + if (xnthread_get_rescnt(lastowner) == 0) >>>>> + xnshadow_send_sig(lastowner, SIGDEBUG, >>>>> + SIGDEBUG_MIGRATE_PRIOINV, 1); >>>>> + else >>>>> + xnthread_dec_rescnt(lastowner); >>>>> + } >>>>> lastownerh = xnthread_handle(lastowner); >>>>> >>>>> if (use_fastlock && >>>>> >>>>> >>>>> >>>> >>>> Agreed, the logic of this patch sounds right. Switching from -rt to -nrt >>>> while holding a -rt mutex is pathological behavior. We don't have to >>>> support apps implementing voluntary priority inversion. >>>> >>> >>> No concerns either. >>> >>> Now we just need >>> >>> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c >>> index 21cc191..27bc829 100644 >>> --- a/ksrc/nucleus/shadow.c >>> +++ b/ksrc/nucleus/shadow.c >>> @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) >>> union xnsched_policy_param param; >>> struct xnsched *sched; >>> >>> - if (!thread || p->policy != SCHED_FIFO) >>> + if (!thread) >>> return; >>> >>> + if (p->policy == SCHED_FIFO) >> ^^ >> inverted? > > Of course. Thinking about SCHED_RR or other policies, this still looks fishy and needs some thoughts. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 15:13 ` Jan Kiszka @ 2011-09-18 15:18 ` Gilles Chanteperdrix 2011-09-18 15:24 ` Jan Kiszka 0 siblings, 1 reply; 14+ messages in thread From: Gilles Chanteperdrix @ 2011-09-18 15:18 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On 09/18/2011 05:13 PM, Jan Kiszka wrote: > On 2011-09-18 17:11, Jan Kiszka wrote: >> On 2011-09-18 17:10, Philippe Gerum wrote: >>> On Sun, 2011-09-18 at 16:34 +0200, Jan Kiszka wrote: >>>> On 2011-09-18 16:02, Philippe Gerum wrote: >>>>> On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: >>>>>> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: >>>>>>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: >>>>>>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>>>>>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>>>>>>>> Hi all, >>>>>>>>>> >>>>>>>>>> just looked into the hrescnt issue again, specifically the corner case >>>>>>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>>>>>>>> >>>>>>>>> Doing this while holding a mutex looks invalid. >>>>>>>> >>>>>>>> Looking at POSIX e.g., is there anything in the spec that makes this >>>>>>>> invalid? If the kernel preserves or established proper priority >>>>>>>> boosting, I do not see what could break in principle. >>>>>>>> >>>>>>>> It is nothing I would design into some app, but we should somehow handle >>>>>>>> it (doc update or code adjustments). >>>>>>>> >>>>>>>>> If we do not do it, the current code is valid. >>>>>>>> >>>>>>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >>>>>>>> transitions. >>>>>>> >>>>>>> The fact that this update did not take place made the code work. No >>>>>>> negative rescnt could happen with that code. >>>>>>> >>>>>>> Anyway, here is a patch to allow switching back from RT to NORMAL, but >>>>>>> send a SIGDEBUG to a thread attempting to release a mutex while its >>>>>>> counter is already 0. We end up avoiding a big chunk of code that would >>>>>>> have been useful for a really strange corner case. >>>>>>> >>>>>> >>>>>> Here comes version 2: >>>>>> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h >>>>>> index 6399a17..417170f 100644 >>>>>> --- a/include/nucleus/sched-idle.h >>>>>> +++ b/include/nucleus/sched-idle.h >>>>>> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; >>>>>> static inline void __xnsched_idle_setparam(struct xnthread *thread, >>>>>> const union xnsched_policy_param *p) >>>>>> { >>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>> thread->cprio = p->idle.prio; >>>>>> } >>>>>> >>>>>> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h >>>>>> index 71f655c..cc1cefa 100644 >>>>>> --- a/include/nucleus/sched-rt.h >>>>>> +++ b/include/nucleus/sched-rt.h >>>>>> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, >>>>>> const union xnsched_policy_param *p) >>>>>> { >>>>>> thread->cprio = p->rt.prio; >>>>>> + if (xnthread_test_state(thread, XNSHADOW)) { >>>>>> + if (thread->cprio) >>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>> + else >>>>>> + xnthread_set_state(thread, XNOTHER); >>>>>> + } >>>>>> } >>>>>> >>>>>> static inline void __xnsched_rt_getparam(struct xnthread *thread, >>>>>> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c >>>>>> index 9a02e80..d19999f 100644 >>>>>> --- a/ksrc/nucleus/pod.c >>>>>> +++ b/ksrc/nucleus/pod.c >>>>>> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, >>>>>> xnsched_putback(thread); >>>>>> >>>>>> #ifdef CONFIG_XENO_OPT_PERVASIVE >>>>>> - /* >>>>>> - * A non-real-time shadow may upgrade to real-time FIFO >>>>>> - * scheduling, but the latter may never downgrade to >>>>>> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear >>>>>> - * XNOTHER to reflect the change. Note that we keep handling >>>>>> - * non real-time shadow specifics in higher code layers, not >>>>>> - * to pollute the core scheduler with peculiarities. >>>>>> - */ >>>>>> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) >>>>>> - xnthread_clear_state(thread, XNOTHER); >>>>>> if (propagate) { >>>>>> if (xnthread_test_state(thread, XNRELAX)) >>>>>> xnshadow_renice(thread); >>>>>> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c >>>>>> index fd37c21..ffc9bab 100644 >>>>>> --- a/ksrc/nucleus/sched-sporadic.c >>>>>> +++ b/ksrc/nucleus/sched-sporadic.c >>>>>> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, >>>>>> } >>>>>> } >>>>>> >>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>> thread->cprio = p->pss.current_prio; >>>>>> } >>>>>> >>>>>> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c >>>>>> index 43a548e..a2af1d3 100644 >>>>>> --- a/ksrc/nucleus/sched-tp.c >>>>>> +++ b/ksrc/nucleus/sched-tp.c >>>>>> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, >>>>>> { >>>>>> struct xnsched *sched = thread->sched; >>>>>> >>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>> thread->tps = &sched->tp.partitions[p->tp.ptid]; >>>>>> thread->cprio = p->tp.prio; >>>>>> } >>>>>> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c >>>>>> index b956e46..47bc0c5 100644 >>>>>> --- a/ksrc/nucleus/synch.c >>>>>> +++ b/ksrc/nucleus/synch.c >>>>>> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) >>>>>> >>>>>> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); >>>>>> >>>>>> - if (xnthread_test_state(lastowner, XNOTHER)) >>>>>> - xnthread_dec_rescnt(lastowner); >>>>>> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); >>>>>> + if (xnthread_test_state(lastowner, XNOTHER)) { >>>>>> + if (xnthread_get_rescnt(lastowner) == 0) >>>>>> + xnshadow_send_sig(lastowner, SIGDEBUG, >>>>>> + SIGDEBUG_MIGRATE_PRIOINV, 1); >>>>>> + else >>>>>> + xnthread_dec_rescnt(lastowner); >>>>>> + } >>>>>> lastownerh = xnthread_handle(lastowner); >>>>>> >>>>>> if (use_fastlock && >>>>>> >>>>>> >>>>>> >>>>> >>>>> Agreed, the logic of this patch sounds right. Switching from -rt to -nrt >>>>> while holding a -rt mutex is pathological behavior. We don't have to >>>>> support apps implementing voluntary priority inversion. >>>>> >>>> >>>> No concerns either. >>>> >>>> Now we just need >>>> >>>> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c >>>> index 21cc191..27bc829 100644 >>>> --- a/ksrc/nucleus/shadow.c >>>> +++ b/ksrc/nucleus/shadow.c >>>> @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) >>>> union xnsched_policy_param param; >>>> struct xnsched *sched; >>>> >>>> - if (!thread || p->policy != SCHED_FIFO) >>>> + if (!thread) >>>> return; >>>> >>>> + if (p->policy == SCHED_FIFO) >>> ^^ >>> inverted? >> >> Of course. > > Thinking about SCHED_RR or other policies, this still looks fishy and > needs some thoughts. What about: diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c index 21cc191..7fe44a1 100644 --- a/ksrc/nucleus/shadow.c +++ b/ksrc/nucleus/shadow.c @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) union xnsched_policy_param param; struct xnsched *sched; - if (!thread || p->policy != SCHED_FIFO) + if (!thread || (p->policy != SCHED_FIFO && p->policy != SCHED_OTHER)) return; + if (p->policy == SCHED_OTHER) + priority = 0; + /* * Linux's priority scale is a subset of the core pod's * priority scale, so there is no need to bound the priority -- Gilles. ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 15:18 ` Gilles Chanteperdrix @ 2011-09-18 15:24 ` Jan Kiszka 2011-09-18 15:47 ` Gilles Chanteperdrix 0 siblings, 1 reply; 14+ messages in thread From: Jan Kiszka @ 2011-09-18 15:24 UTC (permalink / raw) To: Gilles Chanteperdrix; +Cc: xenomai-core [-- Attachment #1: Type: text/plain, Size: 8102 bytes --] On 2011-09-18 17:18, Gilles Chanteperdrix wrote: > On 09/18/2011 05:13 PM, Jan Kiszka wrote: >> On 2011-09-18 17:11, Jan Kiszka wrote: >>> On 2011-09-18 17:10, Philippe Gerum wrote: >>>> On Sun, 2011-09-18 at 16:34 +0200, Jan Kiszka wrote: >>>>> On 2011-09-18 16:02, Philippe Gerum wrote: >>>>>> On Fri, 2011-09-16 at 22:39 +0200, Gilles Chanteperdrix wrote: >>>>>>> On 09/16/2011 10:13 PM, Gilles Chanteperdrix wrote: >>>>>>>> On 09/11/2011 04:29 PM, Jan Kiszka wrote: >>>>>>>>> On 2011-09-11 16:24, Gilles Chanteperdrix wrote: >>>>>>>>>> On 09/11/2011 12:50 PM, Jan Kiszka wrote: >>>>>>>>>>> Hi all, >>>>>>>>>>> >>>>>>>>>>> just looked into the hrescnt issue again, specifically the corner case >>>>>>>>>>> of a shadow thread switching from real-time policy to SCHED_OTHER. >>>>>>>>>> >>>>>>>>>> Doing this while holding a mutex looks invalid. >>>>>>>>> >>>>>>>>> Looking at POSIX e.g., is there anything in the spec that makes this >>>>>>>>> invalid? If the kernel preserves or established proper priority >>>>>>>>> boosting, I do not see what could break in principle. >>>>>>>>> >>>>>>>>> It is nothing I would design into some app, but we should somehow handle >>>>>>>>> it (doc update or code adjustments). >>>>>>>>> >>>>>>>>>> If we do not do it, the current code is valid. >>>>>>>>> >>>>>>>>> Except for its dependency on XNOTHER which is not updated on RT->NORMAL >>>>>>>>> transitions. >>>>>>>> >>>>>>>> The fact that this update did not take place made the code work. No >>>>>>>> negative rescnt could happen with that code. >>>>>>>> >>>>>>>> Anyway, here is a patch to allow switching back from RT to NORMAL, but >>>>>>>> send a SIGDEBUG to a thread attempting to release a mutex while its >>>>>>>> counter is already 0. We end up avoiding a big chunk of code that would >>>>>>>> have been useful for a really strange corner case. >>>>>>>> >>>>>>> >>>>>>> Here comes version 2: >>>>>>> diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h >>>>>>> index 6399a17..417170f 100644 >>>>>>> --- a/include/nucleus/sched-idle.h >>>>>>> +++ b/include/nucleus/sched-idle.h >>>>>>> @@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle; >>>>>>> static inline void __xnsched_idle_setparam(struct xnthread *thread, >>>>>>> const union xnsched_policy_param *p) >>>>>>> { >>>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>>> thread->cprio = p->idle.prio; >>>>>>> } >>>>>>> >>>>>>> diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h >>>>>>> index 71f655c..cc1cefa 100644 >>>>>>> --- a/include/nucleus/sched-rt.h >>>>>>> +++ b/include/nucleus/sched-rt.h >>>>>>> @@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread *thread, >>>>>>> const union xnsched_policy_param *p) >>>>>>> { >>>>>>> thread->cprio = p->rt.prio; >>>>>>> + if (xnthread_test_state(thread, XNSHADOW)) { >>>>>>> + if (thread->cprio) >>>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>>> + else >>>>>>> + xnthread_set_state(thread, XNOTHER); >>>>>>> + } >>>>>>> } >>>>>>> >>>>>>> static inline void __xnsched_rt_getparam(struct xnthread *thread, >>>>>>> diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c >>>>>>> index 9a02e80..d19999f 100644 >>>>>>> --- a/ksrc/nucleus/pod.c >>>>>>> +++ b/ksrc/nucleus/pod.c >>>>>>> @@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread *thread, >>>>>>> xnsched_putback(thread); >>>>>>> >>>>>>> #ifdef CONFIG_XENO_OPT_PERVASIVE >>>>>>> - /* >>>>>>> - * A non-real-time shadow may upgrade to real-time FIFO >>>>>>> - * scheduling, but the latter may never downgrade to >>>>>>> - * SCHED_NORMAL Xenomai-wise. In the valid case, we clear >>>>>>> - * XNOTHER to reflect the change. Note that we keep handling >>>>>>> - * non real-time shadow specifics in higher code layers, not >>>>>>> - * to pollute the core scheduler with peculiarities. >>>>>>> - */ >>>>>>> - if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0) >>>>>>> - xnthread_clear_state(thread, XNOTHER); >>>>>>> if (propagate) { >>>>>>> if (xnthread_test_state(thread, XNRELAX)) >>>>>>> xnshadow_renice(thread); >>>>>>> diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c >>>>>>> index fd37c21..ffc9bab 100644 >>>>>>> --- a/ksrc/nucleus/sched-sporadic.c >>>>>>> +++ b/ksrc/nucleus/sched-sporadic.c >>>>>>> @@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread *thread, >>>>>>> } >>>>>>> } >>>>>>> >>>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>>> thread->cprio = p->pss.current_prio; >>>>>>> } >>>>>>> >>>>>>> diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c >>>>>>> index 43a548e..a2af1d3 100644 >>>>>>> --- a/ksrc/nucleus/sched-tp.c >>>>>>> +++ b/ksrc/nucleus/sched-tp.c >>>>>>> @@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread, >>>>>>> { >>>>>>> struct xnsched *sched = thread->sched; >>>>>>> >>>>>>> + if (xnthread_test_state(thread, XNSHADOW)) >>>>>>> + xnthread_clear_state(thread, XNOTHER); >>>>>>> thread->tps = &sched->tp.partitions[p->tp.ptid]; >>>>>>> thread->cprio = p->tp.prio; >>>>>>> } >>>>>>> diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c >>>>>>> index b956e46..47bc0c5 100644 >>>>>>> --- a/ksrc/nucleus/synch.c >>>>>>> +++ b/ksrc/nucleus/synch.c >>>>>>> @@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct xnthread *lastowner) >>>>>>> >>>>>>> XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER)); >>>>>>> >>>>>>> - if (xnthread_test_state(lastowner, XNOTHER)) >>>>>>> - xnthread_dec_rescnt(lastowner); >>>>>>> - XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0); >>>>>>> + if (xnthread_test_state(lastowner, XNOTHER)) { >>>>>>> + if (xnthread_get_rescnt(lastowner) == 0) >>>>>>> + xnshadow_send_sig(lastowner, SIGDEBUG, >>>>>>> + SIGDEBUG_MIGRATE_PRIOINV, 1); >>>>>>> + else >>>>>>> + xnthread_dec_rescnt(lastowner); >>>>>>> + } >>>>>>> lastownerh = xnthread_handle(lastowner); >>>>>>> >>>>>>> if (use_fastlock && >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> Agreed, the logic of this patch sounds right. Switching from -rt to -nrt >>>>>> while holding a -rt mutex is pathological behavior. We don't have to >>>>>> support apps implementing voluntary priority inversion. >>>>>> >>>>> >>>>> No concerns either. >>>>> >>>>> Now we just need >>>>> >>>>> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c >>>>> index 21cc191..27bc829 100644 >>>>> --- a/ksrc/nucleus/shadow.c >>>>> +++ b/ksrc/nucleus/shadow.c >>>>> @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) >>>>> union xnsched_policy_param param; >>>>> struct xnsched *sched; >>>>> >>>>> - if (!thread || p->policy != SCHED_FIFO) >>>>> + if (!thread) >>>>> return; >>>>> >>>>> + if (p->policy == SCHED_FIFO) >>>> ^^ >>>> inverted? >>> >>> Of course. >> >> Thinking about SCHED_RR or other policies, this still looks fishy and >> needs some thoughts. > > What about: > > diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c > index 21cc191..7fe44a1 100644 > --- a/ksrc/nucleus/shadow.c > +++ b/ksrc/nucleus/shadow.c > @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) > union xnsched_policy_param param; > struct xnsched *sched; > > - if (!thread || p->policy != SCHED_FIFO) > + if (!thread || (p->policy != SCHED_FIFO && p->policy != SCHED_OTHER)) > return; > > + if (p->policy == SCHED_OTHER) > + priority = 0; > + > /* > * Linux's priority scale is a subset of the core pod's > * priority scale, so there is no need to bound the priority No other policies can be issued against the Linux part of a shadow? Then it's OK. I just don't recall the details here ATM. Jan [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 262 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [Xenomai-core] Policy switching and XNOTHER maintenance 2011-09-18 15:24 ` Jan Kiszka @ 2011-09-18 15:47 ` Gilles Chanteperdrix 0 siblings, 0 replies; 14+ messages in thread From: Gilles Chanteperdrix @ 2011-09-18 15:47 UTC (permalink / raw) To: Jan Kiszka; +Cc: xenomai-core On 09/18/2011 05:24 PM, Jan Kiszka wrote: > On 2011-09-18 17:18, Gilles Chanteperdrix wrote: >> What about: >> >> diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c >> index 21cc191..7fe44a1 100644 >> --- a/ksrc/nucleus/shadow.c >> +++ b/ksrc/nucleus/shadow.c >> @@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct *p, int priority) >> union xnsched_policy_param param; >> struct xnsched *sched; >> >> - if (!thread || p->policy != SCHED_FIFO) >> + if (!thread || (p->policy != SCHED_FIFO && p->policy != SCHED_OTHER)) >> return; >> >> + if (p->policy == SCHED_OTHER) >> + priority = 0; >> + >> /* >> * Linux's priority scale is a subset of the core pod's >> * priority scale, so there is no need to bound the priority > > No other policies can be issued against the Linux part of a shadow? Then > it's OK. I just don't recall the details here ATM. > > Jan > This should be OK, according to the comment: * BIG FAT WARNING: Change of scheduling parameters from the * Linux side are propagated only to threads that belong to * the Xenomai RT scheduling class. Threads from other classes * are remain unaffected, since we could not map this * information 1:1 between Linux and Xenomai. */ -- Gilles. ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-09-18 15:47 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-09-11 10:50 [Xenomai-core] Policy switching and XNOTHER maintenance Jan Kiszka 2011-09-11 11:49 ` Jan Kiszka 2011-09-11 14:24 ` Gilles Chanteperdrix 2011-09-11 14:29 ` Jan Kiszka 2011-09-16 20:13 ` Gilles Chanteperdrix 2011-09-16 20:39 ` Gilles Chanteperdrix 2011-09-18 14:02 ` Philippe Gerum 2011-09-18 14:34 ` Jan Kiszka 2011-09-18 15:10 ` Philippe Gerum 2011-09-18 15:11 ` Jan Kiszka 2011-09-18 15:13 ` Jan Kiszka 2011-09-18 15:18 ` Gilles Chanteperdrix 2011-09-18 15:24 ` Jan Kiszka 2011-09-18 15:47 ` Gilles Chanteperdrix
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.