* [PATCH -rt] catch put_task_struct RCU handling up to mainline
@ 2006-07-07 19:29 Paul E. McKenney
2006-07-07 22:56 ` Esben Nielsen
2006-07-26 8:34 ` Ingo Molnar
0 siblings, 2 replies; 10+ messages in thread
From: Paul E. McKenney @ 2006-07-07 19:29 UTC (permalink / raw)
To: mingo; +Cc: oleg, linux-kernel, dino, tytso, dvhltc
Hello!
Due to the separate -rt and mainline evolution of RCU signal handling,
the -rt patchset now makes each task struct go through two RCU grace
periods, with one call_rcu() in release_task() and with another
in put_task_struct(). Only the call_rcu() in release_task() is
required, since this is the one that is associated with tearing down
the task structure.
This patch removes the extra call_rcu() in put_task_struct(), synching
this up with mainline. Tested lightly on i386.
CC: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com>
---
include/linux/sched.h | 10 ----------
kernel/fork.c | 21 ---------------------
2 files changed, 31 deletions(-)
diff -urpNa -X dontdiff linux-2.6.17-rt5/include/linux/sched.h linux-2.6.17-rt5-2RCU/include/linux/sched.h
--- linux-2.6.17-rt5/include/linux/sched.h 2006-07-02 12:37:14.000000000 -0700
+++ linux-2.6.17-rt5-2RCU/include/linux/sched.h 2006-07-06 18:11:49.000000000 -0700
@@ -1105,15 +1105,6 @@ static inline int pid_alive(struct task_
extern void free_task(struct task_struct *tsk);
#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
-#ifdef CONFIG_PREEMPT_RT
-extern void __put_task_struct_cb(struct rcu_head *rhp);
-
-static inline void put_task_struct(struct task_struct *t)
-{
- if (atomic_dec_and_test(&t->usage))
- call_rcu(&t->rcu, __put_task_struct_cb);
-}
-#else
extern void __put_task_struct(struct task_struct *t);
static inline void put_task_struct(struct task_struct *t)
@@ -1121,7 +1112,6 @@ static inline void put_task_struct(struc
if (atomic_dec_and_test(&t->usage))
__put_task_struct(t);
}
-#endif
/*
* Per process flags
diff -urpNa -X dontdiff linux-2.6.17-rt5/kernel/fork.c linux-2.6.17-rt5-2RCU/kernel/fork.c
--- linux-2.6.17-rt5/kernel/fork.c 2006-07-02 12:37:15.000000000 -0700
+++ linux-2.6.17-rt5-2RCU/kernel/fork.c 2006-07-07 07:44:36.000000000 -0700
@@ -120,26 +120,6 @@ void free_task(struct task_struct *tsk)
}
EXPORT_SYMBOL(free_task);
-#ifdef CONFIG_PREEMPT_RT
-void __put_task_struct_cb(struct rcu_head *rhp)
-{
- struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
-
- BUG_ON(atomic_read(&tsk->usage));
- WARN_ON(!(tsk->flags & PF_DEAD));
- WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
- WARN_ON(tsk == current);
-
- security_task_free(tsk);
- free_uid(tsk->user);
- put_group_info(tsk->group_info);
-
- if (!profile_handoff_task(tsk))
- free_task(tsk);
-}
-
-#else
-
void __put_task_struct(struct task_struct *tsk)
{
WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
@@ -154,7 +134,6 @@ void __put_task_struct(struct task_struc
if (!profile_handoff_task(tsk))
free_task(tsk);
}
-#endif
void __init fork_init(unsigned long mempages)
{
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-07 19:29 [PATCH -rt] catch put_task_struct RCU handling up to mainline Paul E. McKenney @ 2006-07-07 22:56 ` Esben Nielsen 2006-07-07 23:15 ` Paul E. McKenney 2006-07-26 8:34 ` Ingo Molnar 1 sibling, 1 reply; 10+ messages in thread From: Esben Nielsen @ 2006-07-07 22:56 UTC (permalink / raw) To: Paul E. McKenney; +Cc: mingo, oleg, linux-kernel, dino, tytso, dvhltc On Fri, 7 Jul 2006, Paul E. McKenney wrote: > Hello! > > Due to the separate -rt and mainline evolution of RCU signal handling, > the -rt patchset now makes each task struct go through two RCU grace > periods, with one call_rcu() in release_task() and with another > in put_task_struct(). Only the call_rcu() in release_task() is > required, since this is the one that is associated with tearing down > the task structure. > > This patch removes the extra call_rcu() in put_task_struct(), synching > this up with mainline. Tested lightly on i386. > The extra call_rcu() has an advantage: It defers work away from the task doing the last put_task_struct(). It could be a priority 99 task with hard latency requirements doing some PI boosting, forinstance. The extra call_rcu() defers non-RT work to a low priority task. This is in generally a very good idea in a real-time system. So unless you can argue that the work defered is as small as the work of doing a call_rcu() I would prefer the extra call_rcu(). Esben > CC: Oleg Nesterov <oleg@tv-sign.ru> > Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> > --- > > include/linux/sched.h | 10 ---------- > kernel/fork.c | 21 --------------------- > 2 files changed, 31 deletions(-) > > diff -urpNa -X dontdiff linux-2.6.17-rt5/include/linux/sched.h linux-2.6.17-rt5-2RCU/include/linux/sched.h > --- linux-2.6.17-rt5/include/linux/sched.h 2006-07-02 12:37:14.000000000 -0700 > +++ linux-2.6.17-rt5-2RCU/include/linux/sched.h 2006-07-06 18:11:49.000000000 -0700 > @@ -1105,15 +1105,6 @@ static inline int pid_alive(struct task_ > extern void free_task(struct task_struct *tsk); > #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) > > -#ifdef CONFIG_PREEMPT_RT > -extern void __put_task_struct_cb(struct rcu_head *rhp); > - > -static inline void put_task_struct(struct task_struct *t) > -{ > - if (atomic_dec_and_test(&t->usage)) > - call_rcu(&t->rcu, __put_task_struct_cb); > -} > -#else > extern void __put_task_struct(struct task_struct *t); > > static inline void put_task_struct(struct task_struct *t) > @@ -1121,7 +1112,6 @@ static inline void put_task_struct(struc > if (atomic_dec_and_test(&t->usage)) > __put_task_struct(t); > } > -#endif > > /* > * Per process flags > diff -urpNa -X dontdiff linux-2.6.17-rt5/kernel/fork.c linux-2.6.17-rt5-2RCU/kernel/fork.c > --- linux-2.6.17-rt5/kernel/fork.c 2006-07-02 12:37:15.000000000 -0700 > +++ linux-2.6.17-rt5-2RCU/kernel/fork.c 2006-07-07 07:44:36.000000000 -0700 > @@ -120,26 +120,6 @@ void free_task(struct task_struct *tsk) > } > EXPORT_SYMBOL(free_task); > > -#ifdef CONFIG_PREEMPT_RT > -void __put_task_struct_cb(struct rcu_head *rhp) > -{ > - struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); > - > - BUG_ON(atomic_read(&tsk->usage)); > - WARN_ON(!(tsk->flags & PF_DEAD)); > - WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); > - WARN_ON(tsk == current); > - > - security_task_free(tsk); > - free_uid(tsk->user); > - put_group_info(tsk->group_info); > - > - if (!profile_handoff_task(tsk)) > - free_task(tsk); > -} > - > -#else > - > void __put_task_struct(struct task_struct *tsk) > { > WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); > @@ -154,7 +134,6 @@ void __put_task_struct(struct task_struc > if (!profile_handoff_task(tsk)) > free_task(tsk); > } > -#endif > > void __init fork_init(unsigned long mempages) > { > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-07 22:56 ` Esben Nielsen @ 2006-07-07 23:15 ` Paul E. McKenney 2006-07-08 13:59 ` Esben Nielsen 0 siblings, 1 reply; 10+ messages in thread From: Paul E. McKenney @ 2006-07-07 23:15 UTC (permalink / raw) To: Esben Nielsen; +Cc: mingo, oleg, linux-kernel, dino, tytso, dvhltc On Fri, Jul 07, 2006 at 11:56:00PM +0100, Esben Nielsen wrote: > On Fri, 7 Jul 2006, Paul E. McKenney wrote: > > >Hello! > > > >Due to the separate -rt and mainline evolution of RCU signal handling, > >the -rt patchset now makes each task struct go through two RCU grace > >periods, with one call_rcu() in release_task() and with another > >in put_task_struct(). Only the call_rcu() in release_task() is > >required, since this is the one that is associated with tearing down > >the task structure. > > > >This patch removes the extra call_rcu() in put_task_struct(), synching > >this up with mainline. Tested lightly on i386. > > > > The extra call_rcu() has an advantage: > It defers work away from the task doing the last put_task_struct(). > It could be a priority 99 task with hard latency requirements doing > some PI boosting, forinstance. The extra call_rcu() defers non-RT work to > a low priority task. This is in generally a very good idea in a real-time > system. > So unless you can argue that the work defered is as small as the work of > doing a call_rcu() I would prefer the extra call_rcu(). I would instead argue that the only way that the last put_task_struct() is an unrelated high-priority task is if it manipulating an already-exited task. In particular, I believe that the sys_exit() path prohibits your example of priority-boosting an already-exited task by removing the exiting task from the various lists before doing the release_task() on itself. Please let me know what I am missing here! Thanx, Paul ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-07 23:15 ` Paul E. McKenney @ 2006-07-08 13:59 ` Esben Nielsen 2006-07-10 15:51 ` Paul E. McKenney 0 siblings, 1 reply; 10+ messages in thread From: Esben Nielsen @ 2006-07-08 13:59 UTC (permalink / raw) To: Paul E. McKenney Cc: Esben Nielsen, mingo, oleg, linux-kernel, dino, tytso, dvhltc On Fri, 7 Jul 2006, Paul E. McKenney wrote: > On Fri, Jul 07, 2006 at 11:56:00PM +0100, Esben Nielsen wrote: >> On Fri, 7 Jul 2006, Paul E. McKenney wrote: >> >>> Hello! >>> >>> Due to the separate -rt and mainline evolution of RCU signal handling, >>> the -rt patchset now makes each task struct go through two RCU grace >>> periods, with one call_rcu() in release_task() and with another >>> in put_task_struct(). Only the call_rcu() in release_task() is >>> required, since this is the one that is associated with tearing down >>> the task structure. >>> >>> This patch removes the extra call_rcu() in put_task_struct(), synching >>> this up with mainline. Tested lightly on i386. >>> >> >> The extra call_rcu() has an advantage: >> It defers work away from the task doing the last put_task_struct(). >> It could be a priority 99 task with hard latency requirements doing >> some PI boosting, forinstance. The extra call_rcu() defers non-RT work to >> a low priority task. This is in generally a very good idea in a real-time >> system. >> So unless you can argue that the work defered is as small as the work of >> doing a call_rcu() I would prefer the extra call_rcu(). > > I would instead argue that the only way that the last put_task_struct() > is an unrelated high-priority task is if it manipulating an already-exited > task. In particular, I believe that the sys_exit() path prohibits your > example of priority-boosting an already-exited task by removing the > exiting task from the various lists before doing the release_task() > on itself. > > Please let me know what I am missing here! You could very well be right (I don't know the details that well). But in that case the get/put_task_struct() in the PI code is not needed? I think, however, it is needed because the task doing the (de)boosting gets a pointer to a task, enables preemption and drops all locks. It then uses the pointer. The task could have been deleted a long time ago if it wasn't used protected by get/put_task_struct(). This is an examble of why using reference counting in a RT system is a bad idea: Suddenly a highpriority task can end up doing the cleanup for low priority tasks. The work should be defered to a low priority task. Using rcu is probably overkill because it also introduces other delays. A tasklet or a dedicated task would be better. Esben > > Thanx, Paul > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-08 13:59 ` Esben Nielsen @ 2006-07-10 15:51 ` Paul E. McKenney 2006-07-10 18:10 ` Esben Nielsen 0 siblings, 1 reply; 10+ messages in thread From: Paul E. McKenney @ 2006-07-10 15:51 UTC (permalink / raw) To: Esben Nielsen; +Cc: mingo, oleg, linux-kernel, dino, tytso, dvhltc On Sat, Jul 08, 2006 at 02:59:37PM +0100, Esben Nielsen wrote: > On Fri, 7 Jul 2006, Paul E. McKenney wrote: > > >On Fri, Jul 07, 2006 at 11:56:00PM +0100, Esben Nielsen wrote: > >>On Fri, 7 Jul 2006, Paul E. McKenney wrote: > >> > >>>Hello! > >>> > >>>Due to the separate -rt and mainline evolution of RCU signal handling, > >>>the -rt patchset now makes each task struct go through two RCU grace > >>>periods, with one call_rcu() in release_task() and with another > >>>in put_task_struct(). Only the call_rcu() in release_task() is > >>>required, since this is the one that is associated with tearing down > >>>the task structure. > >>> > >>>This patch removes the extra call_rcu() in put_task_struct(), synching > >>>this up with mainline. Tested lightly on i386. > >>> > >> > >>The extra call_rcu() has an advantage: > >>It defers work away from the task doing the last put_task_struct(). > >>It could be a priority 99 task with hard latency requirements doing > >>some PI boosting, forinstance. The extra call_rcu() defers non-RT work to > >>a low priority task. This is in generally a very good idea in a real-time > >>system. > >>So unless you can argue that the work defered is as small as the work of > >>doing a call_rcu() I would prefer the extra call_rcu(). > > > >I would instead argue that the only way that the last put_task_struct() > >is an unrelated high-priority task is if it manipulating an already-exited > >task. In particular, I believe that the sys_exit() path prohibits your > >example of priority-boosting an already-exited task by removing the > >exiting task from the various lists before doing the release_task() > >on itself. > > > >Please let me know what I am missing here! > > You could very well be right (I don't know the details that well). But in > that case the get/put_task_struct() in the PI code is not needed? > I think, however, it is needed because the task doing the (de)boosting > gets a pointer to a task, enables preemption and drops all locks. It then > uses the pointer. The task could have been deleted a long time ago if it > wasn't used protected by get/put_task_struct(). > > This is an examble of why using reference counting in a RT system is a bad > idea: Suddenly a highpriority task can end up doing the cleanup for low > priority tasks. My belief is that the scenarios that lead to this situation involve error situations -- in which case the dying task will be missing whatever deadlines it had anyway, because it died before it could complete its work. So, I agree that we need the get/put_task_struct() calls, but I believe that their job is to keep the system running in face of application errors. Otherwise, it would be really hard to debug the application, right? That said, it is entirely possible that I am missing a code path where a correctly written application could legitimately force a high-priority task to do cleanup work on behalf of a low-priority path. > The work should be defered to a low priority task. Using rcu is > probably overkill because it also introduces other delays. A tasklet > or a dedicated task would be better. Agreed -- if there is in fact a legitimate non-error code path, then a patch that used some deferral mechanism would be good. But RCU is overkill, and misleading overkill at that! Thanx, Paul ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-10 15:51 ` Paul E. McKenney @ 2006-07-10 18:10 ` Esben Nielsen 2006-07-10 17:48 ` Paul E. McKenney 0 siblings, 1 reply; 10+ messages in thread From: Esben Nielsen @ 2006-07-10 18:10 UTC (permalink / raw) To: Paul E. McKenney Cc: Esben Nielsen, mingo, oleg, linux-kernel, dino, tytso, dvhltc On Mon, 10 Jul 2006, Paul E. McKenney wrote: > On Sat, Jul 08, 2006 at 02:59:37PM +0100, Esben Nielsen wrote: >> On Fri, 7 Jul 2006, Paul E. McKenney wrote: >> >>> On Fri, Jul 07, 2006 at 11:56:00PM +0100, Esben Nielsen wrote: >>>> On Fri, 7 Jul 2006, Paul E. McKenney wrote: >>>> >>>>> Hello! >>>>> >>>>> Due to the separate -rt and mainline evolution of RCU signal handling, >>>>> the -rt patchset now makes each task struct go through two RCU grace >>>>> periods, with one call_rcu() in release_task() and with another >>>>> in put_task_struct(). Only the call_rcu() in release_task() is >>>>> required, since this is the one that is associated with tearing down >>>>> the task structure. >>>>> >>>>> This patch removes the extra call_rcu() in put_task_struct(), synching >>>>> this up with mainline. Tested lightly on i386. >>>>> >>>> >>>> The extra call_rcu() has an advantage: >>>> It defers work away from the task doing the last put_task_struct(). >>>> It could be a priority 99 task with hard latency requirements doing >>>> some PI boosting, forinstance. The extra call_rcu() defers non-RT work to >>>> a low priority task. This is in generally a very good idea in a real-time >>>> system. >>>> So unless you can argue that the work defered is as small as the work of >>>> doing a call_rcu() I would prefer the extra call_rcu(). >>> >>> I would instead argue that the only way that the last put_task_struct() >>> is an unrelated high-priority task is if it manipulating an already-exited >>> task. In particular, I believe that the sys_exit() path prohibits your >>> example of priority-boosting an already-exited task by removing the >>> exiting task from the various lists before doing the release_task() >>> on itself. >>> >>> Please let me know what I am missing here! >> >> You could very well be right (I don't know the details that well). But in >> that case the get/put_task_struct() in the PI code is not needed? >> I think, however, it is needed because the task doing the (de)boosting >> gets a pointer to a task, enables preemption and drops all locks. It then >> uses the pointer. The task could have been deleted a long time ago if it >> wasn't used protected by get/put_task_struct(). >> >> This is an examble of why using reference counting in a RT system is a bad >> idea: Suddenly a highpriority task can end up doing the cleanup for low >> priority tasks. > > My belief is that the scenarios that lead to this situation involve error > situations -- in which case the dying task will be missing whatever > deadlines it had anyway, because it died before it could complete > its work. So, I agree that we need the get/put_task_struct() calls, > but I believe that their job is to keep the system running in face of > application errors. Otherwise, it would be really hard to debug the > application, right? > > That said, it is entirely possible that I am missing a code path where > a correctly written application could legitimately force a high-priority > task to do cleanup work on behalf of a low-priority path. > >> The work should be defered to a low priority task. Using rcu is >> probably overkill because it also introduces other delays. A tasklet >> or a dedicated task would be better. > > Agreed -- if there is in fact a legitimate non-error code path, then > a patch that used some deferral mechanism would be good. But RCU is > overkill, and misleading overkill at that! > I think this is a legitimate situation. lock 1 is owned by B which is blocked on lock 2 which is owned by C CPU1: CPU2 RT task A locks lock 1 C runs something A boosts B to RT A does get_task_struct B A enables interrupts C unlocks lock 2 An very long interrupt is running B unlocks lock 2 B unlocks lock 1 B is deboosted B exits A gets CPU1 again A does put_task_struct B I don't know if the timing is realistic, but theoretically it is possible. It might also be possible the B exits on another CPU even without the long interrupt handler. If A has cpu affinity to CPU1 it is enough if a higher priority task preempts it on CPU1. Esben > Thanx, Paul > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-10 18:10 ` Esben Nielsen @ 2006-07-10 17:48 ` Paul E. McKenney 2006-07-10 20:09 ` Esben Nielsen 0 siblings, 1 reply; 10+ messages in thread From: Paul E. McKenney @ 2006-07-10 17:48 UTC (permalink / raw) To: Esben Nielsen; +Cc: mingo, oleg, linux-kernel, dino, tytso, dvhltc On Mon, Jul 10, 2006 at 07:10:49PM +0100, Esben Nielsen wrote: > On Mon, 10 Jul 2006, Paul E. McKenney wrote: > >On Sat, Jul 08, 2006 at 02:59:37PM +0100, Esben Nielsen wrote: [ . . . ] > >>The work should be defered to a low priority task. Using rcu is > >>probably overkill because it also introduces other delays. A tasklet > >>or a dedicated task would be better. > > > >Agreed -- if there is in fact a legitimate non-error code path, then > >a patch that used some deferral mechanism would be good. But RCU is > >overkill, and misleading overkill at that! > > > > I think this is a legitimate situation. lock 1 is owned by B which is > blocked on lock 2 which is owned by C > > CPU1: CPU2 > RT task A locks lock 1 C runs something > A boosts B to RT > A does get_task_struct B > A enables interrupts C unlocks lock 2 > An very long interrupt is running B unlocks lock 2 > B unlocks lock 1 > B is deboosted > B exits > A gets CPU1 again > A does put_task_struct B > > I don't know if the timing is realistic, but theoretically it is possible. > It might also be possible the B exits on another CPU even without the long > interrupt handler. If A has cpu affinity to CPU1 it is enough if a higher > priority task preempts it on CPU1. For this to happen, either A has to be at a lower priority than the irq tasks or the interrupt has to be a hard irq (e.g., scheduling clock interrupt). In the first case, the added cleanup processing seems inconsequential compared to (say) an interrupt doing network protocol processing. In the second case, B does not do its put_task_struct() until after the hard irq returns (because the put_task_struct() is invoked from a call_rcu() callback), which makes the above scenario unlikely, though perhaps not impossible. If the second scenario is in fact possible, would you be willing to supply the appropriate deferral code? I believe we both agree that RCU is not really the right deferral mechanism in this situation. Thanx, Paul ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-10 17:48 ` Paul E. McKenney @ 2006-07-10 20:09 ` Esben Nielsen 2006-07-11 17:45 ` Paul E. McKenney 0 siblings, 1 reply; 10+ messages in thread From: Esben Nielsen @ 2006-07-10 20:09 UTC (permalink / raw) To: Paul E. McKenney Cc: Esben Nielsen, mingo, oleg, linux-kernel, dino, tytso, dvhltc On Mon, 10 Jul 2006, Paul E. McKenney wrote: > On Mon, Jul 10, 2006 at 07:10:49PM +0100, Esben Nielsen wrote: >> On Mon, 10 Jul 2006, Paul E. McKenney wrote: >>> On Sat, Jul 08, 2006 at 02:59:37PM +0100, Esben Nielsen wrote: > > [ . . . ] > >>>> The work should be defered to a low priority task. Using rcu is >>>> probably overkill because it also introduces other delays. A tasklet >>>> or a dedicated task would be better. >>> >>> Agreed -- if there is in fact a legitimate non-error code path, then >>> a patch that used some deferral mechanism would be good. But RCU is >>> overkill, and misleading overkill at that! >>> >> >> I think this is a legitimate situation. lock 1 is owned by B which is >> blocked on lock 2 which is owned by C >> >> CPU1: CPU2 >> RT task A locks lock 1 C runs something >> A boosts B to RT >> A does get_task_struct B >> A enables interrupts C unlocks lock 2 >> An very long interrupt is running B unlocks lock 2 >> B unlocks lock 1 >> B is deboosted >> B exits >> A gets CPU1 again >> A does put_task_struct B >> >> I don't know if the timing is realistic, but theoretically it is possible. >> It might also be possible the B exits on another CPU even without the long >> interrupt handler. If A has cpu affinity to CPU1 it is enough if a higher >> priority task preempts it on CPU1. > > For this to happen, either A has to be at a lower priority than the irq > tasks or the interrupt has to be a hard irq (e.g., scheduling clock > interrupt). In the first case, the added cleanup processing seems > inconsequential compared to (say) an interrupt doing network protocol > processing. In the second case, B does not do its put_task_struct() > until after the hard irq returns (because the put_task_struct() is invoked > from a call_rcu() callback), which makes the above scenario unlikely, > though perhaps not impossible. > > If the second scenario is in fact possible, would you be willing to > supply the appropriate deferral code? I believe we both agree that RCU > is not really the right deferral mechanism in this situation. > Let your patch go through. I'll stop complaining :-) Is there anywhere where we can make a list of known issues like this? I can't promise I will get time to fix this one :-( Esben > Thanx, Paul > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-10 20:09 ` Esben Nielsen @ 2006-07-11 17:45 ` Paul E. McKenney 0 siblings, 0 replies; 10+ messages in thread From: Paul E. McKenney @ 2006-07-11 17:45 UTC (permalink / raw) To: Esben Nielsen; +Cc: mingo, oleg, linux-kernel, dino, tytso, dvhltc On Mon, Jul 10, 2006 at 09:09:35PM +0100, Esben Nielsen wrote: > On Mon, 10 Jul 2006, Paul E. McKenney wrote: > >On Mon, Jul 10, 2006 at 07:10:49PM +0100, Esben Nielsen wrote: > >>On Mon, 10 Jul 2006, Paul E. McKenney wrote: > >>>On Sat, Jul 08, 2006 at 02:59:37PM +0100, Esben Nielsen wrote: > > > >[ . . . ] > > > >>>>The work should be defered to a low priority task. Using rcu is > >>>>probably overkill because it also introduces other delays. A tasklet > >>>>or a dedicated task would be better. > >>> > >>>Agreed -- if there is in fact a legitimate non-error code path, then > >>>a patch that used some deferral mechanism would be good. But RCU is > >>>overkill, and misleading overkill at that! > >>> > >> > >>I think this is a legitimate situation. lock 1 is owned by B which is > >>blocked on lock 2 which is owned by C > >> > >> CPU1: CPU2 > >> RT task A locks lock 1 C runs something > >> A boosts B to RT > >> A does get_task_struct B > >> A enables interrupts C unlocks lock 2 > >> An very long interrupt is running B unlocks lock 2 > >> B unlocks lock 1 > >> B is deboosted > >> B exits > >> A gets CPU1 again > >> A does put_task_struct B > >> > >>I don't know if the timing is realistic, but theoretically it is possible. > >>It might also be possible the B exits on another CPU even without the long > >>interrupt handler. If A has cpu affinity to CPU1 it is enough if a higher > >>priority task preempts it on CPU1. > > > >For this to happen, either A has to be at a lower priority than the irq > >tasks or the interrupt has to be a hard irq (e.g., scheduling clock > >interrupt). In the first case, the added cleanup processing seems > >inconsequential compared to (say) an interrupt doing network protocol > >processing. In the second case, B does not do its put_task_struct() > >until after the hard irq returns (because the put_task_struct() is invoked > >from a call_rcu() callback), which makes the above scenario unlikely, > >though perhaps not impossible. > > > >If the second scenario is in fact possible, would you be willing to > >supply the appropriate deferral code? I believe we both agree that RCU > >is not really the right deferral mechanism in this situation. > > > > Let your patch go through. I'll stop complaining :-) > Is there anywhere where we can make a list of known issues like this? > I can't promise I will get time to fix this one :-( ;-) One possibility would be a file in the Documentation directory. Another would be something on the web, but a file in the Documentation directory would have the advantage of being synched with the -rt version. Thanx, Paul ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH -rt] catch put_task_struct RCU handling up to mainline 2006-07-07 19:29 [PATCH -rt] catch put_task_struct RCU handling up to mainline Paul E. McKenney 2006-07-07 22:56 ` Esben Nielsen @ 2006-07-26 8:34 ` Ingo Molnar 1 sibling, 0 replies; 10+ messages in thread From: Ingo Molnar @ 2006-07-26 8:34 UTC (permalink / raw) To: Paul E. McKenney; +Cc: oleg, linux-kernel, dino, tytso, dvhltc, Thomas Gleixner * Paul E. McKenney <paulmck@us.ibm.com> wrote: > Hello! > > Due to the separate -rt and mainline evolution of RCU signal handling, > the -rt patchset now makes each task struct go through two RCU grace > periods, with one call_rcu() in release_task() and with another in > put_task_struct(). Only the call_rcu() in release_task() is required, > since this is the one that is associated with tearing down the task > structure. > > This patch removes the extra call_rcu() in put_task_struct(), synching > this up with mainline. Tested lightly on i386. i've applied your patch to the -rt tree - we'll see how it goes. Ingo ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-07-26 8:40 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-07-07 19:29 [PATCH -rt] catch put_task_struct RCU handling up to mainline Paul E. McKenney 2006-07-07 22:56 ` Esben Nielsen 2006-07-07 23:15 ` Paul E. McKenney 2006-07-08 13:59 ` Esben Nielsen 2006-07-10 15:51 ` Paul E. McKenney 2006-07-10 18:10 ` Esben Nielsen 2006-07-10 17:48 ` Paul E. McKenney 2006-07-10 20:09 ` Esben Nielsen 2006-07-11 17:45 ` Paul E. McKenney 2006-07-26 8:34 ` Ingo Molnar
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox