<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Sep 14, 2012, at 8:21 PM, Jonathan Herman <<a href="mailto:hermanjl@cs.unc.edu">hermanjl@cs.unc.edu</a>> wrote:</div><div><br></div><blockquote type="cite"><br>On Fri, Sep 14, 2012 at 7:57 PM, Glenn Elliott <<a href="mailto:gelliott@cs.unc.edu">gelliott@cs.unc.edu</a>> wrote:<br><blockquote type="cite">Well, I am stuck in a strange case where a task is linked but never<br>scheduled (G-EDF):<br><br>3903 P0 [check_for_preemptions@litmus/sched_gsn_edf.c:365]:<br>check_for_preemptions: attempting to link task 1795 to 0<br>3904 P0 [gsnedf_get_nearest_available_cpu@litmus/sched_gsn_edf.c:347]: Could<br>not find an available CPU close to P0<br>3905 P0 [__add_ready@litmus/rt_domain.c:312]: rt: adding aux_threads/1799<br>(0, 4611686018427387903, 4611686018427387903) [inh_task: (nil)/0 (0, 0 0)]<br>rel=59812157846 to ready queue at 60312058176<br>3907 P0 [link_task_to_cpu@litmus/sched_gsn_edf.c:218]: (aux_threads/1799:1)<br>linked = aux_threads/1795<br>3908 P0 [link_task_to_cpu@litmus/sched_gsn_edf.c:219]: (aux_threads/1799:1)<br>entry->linked = aux_threads/1799<br>3909 P0 [link_task_to_cpu@litmus/sched_gsn_edf.c:261]: (aux_threads/1795:2)<br>linked to 0.<br>3914 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1796:1) tick<br>3915 P2 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1797:1) tick<br>3916 P3 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1798:1) tick<br>3917 P0 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1799:1) tick<br>3918 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1796:1) tick<br>3919 P2 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1797:1) tick<br>3920 P3 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1798:1) tick<br>3921 P0 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1799:1) tick<br>3922 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1796:1) tick<br>3923 P2 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1797:1) tick<br>3924 P3 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1798:1) tick<br>3925 P0 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1799:1) tick<br>3926 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1796:1) tick<br>3927 P2 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1797:1) tick<br>3928 P3 [gsnedf_tick@litmus/sched_gsn_edf.c:472]: (aux_threads/1798:1) tick<br><br><br>I updated gsnedf_tick to print the currently scheduled real-time task. Task<br>1795 should be running on P0 instead of 1799.<br><br>Has anyone ever seen something like this before?<br><br>Thanks,<br>Glenn<br><br>p.s. Ignore the crazy period/relative_deadline for 1799. Those are just<br>place holders. 1799 is really just a worker thread that has a statically<br>low priority and should only run when the system is idle (or according to an<br>inherited priority).<br><br>p.p.s. I think there is a bug in litmus.c::litmus_fork(). is_realtime() is<br>returning false for forked children of a real-time task (expected), so the<br>fork-copied rt_param state is not reset. Thus, the child gets the same<br>rt_params as the parent. This is probably harmless if we're sure to re-init<br>any children that transition to real-time. However, for the sake of<br>completeness, I wonder if we should execute "reinit_litmus_state(p,0);" for<br>all children. I am doing some where tasks are forced to become real-time<br>from within the kernel (worker threads), and this possible bug bit me.<br><br>_______________________________________________<br>litmus-dev mailing list<br><a href="mailto:litmus-dev@lists.litmus-rt.org">litmus-dev@lists.litmus-rt.org</a><br>https://lists.litmus-rt.org/listinfo/litmus-dev<br><br></blockquote><br>I would bet cashmoney that your task is not preemptable. Your</blockquote><blockquote type="cite">check_for_preempt calls preempt()->preempt_if_preemptable after<br>linking the task, which calls litmus_reschedule if the task is not<br>preemptable. litmus_reschedule ALWAYS hits line 98 of your preempt.c<br>and traces state.</blockquote><blockquote type="cite"><br>-- <br>Jonathan Herman<br>Department of Computer Science at UNC Chapel Hill<br></blockquote><br></div><div><br></div><div><div>I think something else could be going wrong. I believe the task is preemptible. litmus_reschedule() is indeed being called. Here's the code, with some trace statements added in. I've put the code path that is being followed in bold.</div><div><br></div><div><div> 66 void litmus_reschedule(int cpu)</div><div> 67 {</div><div> 68 int picked_transition_ok = 0;</div><div> 69 int scheduled_transition_ok = 0;</div><div> 70 </div><div> 71 /* The (remote) CPU could be in any state. */</div><div> 72 </div><div> 73 /* The critical states are TASK_PICKED and TASK_SCHEDULED, as the CPU</div><div> 74 * is not aware of the need to reschedule at this point. */</div><div> 75 </div><div> 76 /* is a context switch in progress? */</div><div><b> 77 if (cpu_is_in_sched_state(cpu, TASK_PICKED)) {</b></div><div><b> 78 picked_transition_ok = sched_state_transition_on(</b></div><div><b> 79 cpu, TASK_PICKED, PICKED_WRONG_TASK);</b></div><div><b> 80 </b></div><div><b> 81 TRACE_CUR("cpu %d: picked_transition_ok = %d\n", cpu, picked_transition_ok);</b></div><div> 82 }</div><div> 83 else {</div><div> 84 TRACE_CUR("cpu %d: picked_transition_ok = 0 (static)\n", cpu);</div><div> 85 }</div><div> 86 </div><div> 87 if (!picked_transition_ok &&</div><div> 88 cpu_is_in_sched_state(cpu, TASK_SCHEDULED)) {</div><div> 89 /* We either raced with the end of the context switch, or the</div><div> 90 * CPU was in TASK_SCHEDULED anyway. */</div><div> 91 scheduled_transition_ok = sched_state_transition_on(</div><div> 92 cpu, TASK_SCHEDULED, SHOULD_SCHEDULE);</div><div> 93 TRACE_CUR("cpu %d: scheduled_transition_ok = %d\n", cpu, scheduled_transition_ok);</div><div> 94 }</div><div><b> 95 else {</b></div><div><b> 96 TRACE_CUR("cpu %d: scheduled_transition_ok = 0 (static)\n", cpu);</b></div><div><b> 97 }</b></div><div> 98 </div><div> 99 /* If the CPU was in state TASK_SCHEDULED, then we need to cause the</div><div>100 * scheduler to be invoked. */</div><div>101 if (scheduled_transition_ok) {</div><div>102 if (smp_processor_id() == cpu) {</div><div>103 set_tsk_need_resched(current);</div><div>104 }</div><div>105 else {</div><div>106 smp_send_reschedule(cpu);</div><div>107 }</div><div>108 }</div><div>109 </div><div>110 TRACE_STATE("%s picked-ok:%d sched-ok:%d\n",</div><div>111 __FUNCTION__,</div><div>112 picked_transition_ok,</div><div>113 scheduled_transition_ok);</div><div>114 }</div><div><br></div></div><div>Trace output:</div><div><div>3956 P1 [link_task_to_cpu@litmus/sched_gsn_edf.c:218]: (aux_threads/1820:1) linked = aux_threads/1816</div><div>3957 P1 [link_task_to_cpu@litmus/sched_gsn_edf.c:219]: (aux_threads/1820:1) entry->linked = aux_threads/1820</div><div>3958 P1 [link_task_to_cpu@litmus/sched_gsn_edf.c:261]: (aux_threads/1816:2) linked to 1. </div><div>3962 P1 [preempt_if_preemptable@litmus/sched_plugin.c:36]: (aux_threads/1820:1) preempt_if_preemptable: aux_threads/1820</div><div>3963 P1 [preempt_if_preemptable@litmus/sched_plugin.c:45]: (aux_threads/1820:1) preempt local cpu.</div><div>3964 P1 [preempt_if_preemptable@litmus/sched_plugin.c:71]: (aux_threads/1820:1) calling litmus_reschedule()</div><div><b>3965 P1 [litmus_reschedule@litmus/preempt.c:81]: (aux_threads/1820:1) cpu 1: picked_transition_ok = 1</b></div><div><b>3966 P1 [litmus_reschedule@litmus/preempt.c:96]: (aux_threads/1820:1) cpu 1: scheduled_transition_ok = 0 (static)</b></div><div>3968 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:474]: (aux_threads/1820:1) tick 67358153479</div><div>3972 P1 [gsnedf_tick@litmus/sched_gsn_edf.c:474]: (aux_threads/1820:1) tick 67359153359</div><div><br></div></div><div><br></div><div><br></div><div>So it looks like my linked task is not scheduled because the CPU state is TASK_PICKED and picked_transition_ok is set to 1. I've never worked with this part of Litmus before, so I don't know what is "normal." Is there supposed to be some sort of deferred safety-net that will schedule the linked task when picked_transition_ok==1 that is not being invoked?</div><div><br></div><div>-Glenn</div><div><br></div></div><br></body></html>