Module: xenomai-jki
Branch: for-upstream
Commit: 883bd9f2779e33d951b80abf1cd40a5788cd7b7d
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=883bd9f2779e33d951b80abf1cd40a5788cd7b7d

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Mon Dec  7 14:04:26 2009 +0100

nucleus: Try to send SIGXCPU to runaway threads first

Runaway shadow threads that perform syscalls need not be killed
immediately by the watchdog. We can first try to send out SIGXCPU and
trigger a migration on syscall return in order to let normal signal
handling / gdb process the failure. This eases the identification of
overruns and also reduces the risk of inconsistent system states due to
hard terminations.

If the target thread does not react (ie. migrate) within another
watchdog timeout period, we kill it nevertheless.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/nucleus/thread.h |    8 ++++++++
 ksrc/nucleus/sched.c     |   19 +++++++++++++++++--
 ksrc/nucleus/shadow.c    |    4 +++-
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/include/nucleus/thread.h b/include/nucleus/thread.h
index 31c33d6..b2baccb 100644
--- a/include/nucleus/thread.h
+++ b/include/nucleus/thread.h
@@ -116,6 +116,7 @@
 #define XNPRIOSET 0x00000100 /**< Priority changed from primary mode */
 #define XNABORT   0x00000200 /**< Thread is being aborted */
 #define XNCANPND  0x00000400 /**< Cancellation request is pending */
+#define XNAMOK    0x00000800 /**< Runaway, watchdog signal pending (shadow 
only) */
 
 /* These information flags are available to the real-time interfaces */
 #define XNTHREAD_INFO_SPARE0  0x10000000
@@ -392,6 +393,13 @@ typedef struct xnhook {
 #define xnthread_set_sigpending(thread, pending) \
        ((thread)->u_sigpending = (pending))
 #endif /* CONFIG_XENO_OPT_PERVASIVE */
+#ifdef CONFIG_XENO_OPT_WATCHDOG
+#define xnthread_amok_p(thread)            xnthread_test_info(thread, XNAMOK)
+#define xnthread_clear_amok(thread)        xnthread_clear_info(thread, XNAMOK)
+#else /* !CONFIG_XENO_OPT_WATCHDOG */
+#define xnthread_amok_p(thread)            (0)
+#define xnthread_clear_amok(thread)        do { } while (0)
+#endif /* !CONFIG_XENO_OPT_WATCHDOG */
 
 /* Class-level operations for threads. */
 static inline int xnthread_get_denormalized_prio(struct xnthread *t, int 
coreprio)
diff --git a/ksrc/nucleus/sched.c b/ksrc/nucleus/sched.c
index 0a4f7b2..aa6c288 100644
--- a/ksrc/nucleus/sched.c
+++ b/ksrc/nucleus/sched.c
@@ -87,14 +87,29 @@ static void xnsched_watchdog_handler(struct xntimer *timer)
                return;
        }
 
-       if (unlikely(++sched->wdcount >= wd_timeout_arg)) {
+       if (likely(++sched->wdcount < wd_timeout_arg))
+               return;
+
+#ifdef CONFIG_XENO_OPT_PERVASIVE
+       if (xnthread_test_state(thread, XNSHADOW) &&
+           !xnthread_amok_p(thread)) {
+               trace_mark(xn_nucleus, watchdog_signal,
+                          "thread %p thread_name %s",
+                          thread, xnthread_name(thread));
+               xnprintf("watchdog triggered -- signaling runaway thread "
+                        "'%s'\n", xnthread_name(thread));
+               xnthread_set_info(thread, XNAMOK | XNKICKED);
+               xnshadow_send_sig(thread, SIGXCPU, 0, 1);
+       } else
+#endif /* CONFIG_XENO_OPT_PERVASIVE */
+       {
                trace_mark(xn_nucleus, watchdog, "thread %p thread_name %s",
                           thread, xnthread_name(thread));
                xnprintf("watchdog triggered -- killing runaway thread '%s'\n",
                         xnthread_name(thread));
                xnpod_delete_thread(thread);
-               xnsched_reset_watchdog(sched);
        }
+       xnsched_reset_watchdog(sched);
 }
 
 #endif /* CONFIG_XENO_OPT_WATCHDOG */
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index 0c94a60..d0cb416 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -2151,8 +2151,10 @@ static inline int do_hisyscall_event(unsigned event, 
unsigned domid, void *data)
        __xn_status_return(regs, err);
 
        sigs = 0;
-       if (xnpod_shadow_p() && signal_pending(p)) {
+       if (xnpod_shadow_p() &&
+           (signal_pending(p) || xnthread_amok_p(thread))) {
                sigs = 1;
+               xnthread_clear_amok(thread);
                request_syscall_restart(thread, regs, sysflags);
        }
        if (thread && xnthread_sigpending(thread)) {


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to