Module: xenomai-jki
Branch: for-forge
Commit: 67a64e164b737759cc171d3b04b05770e1450cb6
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=67a64e164b737759cc171d3b04b05770e1450cb6

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Fri Jun 26 15:11:42 2015 +0200

cobalt/kernel: Fix locking for xnthread info manipulations

nklock must be held when manipulating bits of xnthread::info. Not all
callsites of xnthread_set/clear_info follow this rule so far, directly
or indirectly, fix them (and possibly some other races along this).

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

---

 include/cobalt/kernel/rtdm/driver.h |    8 ++++----
 kernel/cobalt/posix/syscall.c       |    5 +++++
 kernel/cobalt/synch.c               |    2 ++
 kernel/cobalt/thread.c              |    5 +++++
 4 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index c14198b..de476ca 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -553,7 +553,7 @@ static inline void rtdm_lock_get(rtdm_lock_t *lock)
 {
        XENO_BUG_ON(COBALT, !spltest());
        spin_lock(lock);
-       __xnsched_lock();
+       xnsched_lock();
 }
 
 /**
@@ -566,7 +566,7 @@ static inline void rtdm_lock_get(rtdm_lock_t *lock)
 static inline void rtdm_lock_put(rtdm_lock_t *lock)
 {
        spin_unlock(lock);
-       __xnsched_unlock();
+       xnsched_unlock();
 }
 
 /**
@@ -584,7 +584,7 @@ static inline rtdm_lockctx_t 
__rtdm_lock_get_irqsave(rtdm_lock_t *lock)
 
        context = ipipe_test_and_stall_head();
        spin_lock(lock);
-       __xnsched_lock();
+       xnsched_lock();
 
        return context;
 }
@@ -603,7 +603,7 @@ static inline
 void rtdm_lock_put_irqrestore(rtdm_lock_t *lock, rtdm_lockctx_t context)
 {
        spin_unlock(lock);
-       __xnsched_unlock();
+       xnsched_unlock();
        ipipe_restore_head(context);
 }
 
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index cf93f07..e60cea8 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -84,6 +84,9 @@ static void prepare_for_signal(struct task_struct *p,
                               int sysflags)
 {
        int notify = 0;
+       spl_t s;
+
+       xnlock_get_irqsave(&nklock, s);
 
        if (xnthread_test_info(thread, XNKICKED)) {
                if (signal_pending(p)) {
@@ -96,6 +99,8 @@ static void prepare_for_signal(struct task_struct *p,
                xnthread_clear_info(thread, XNKICKED);
        }
 
+       xnlock_put_irqrestore(&nklock, s);
+
        xnthread_test_cancel();
 
        xnthread_relax(notify, SIGDEBUG_MIGRATE_SIGNAL);
diff --git a/kernel/cobalt/synch.c b/kernel/cobalt/synch.c
index 536e0a7..a1ea4b4 100644
--- a/kernel/cobalt/synch.c
+++ b/kernel/cobalt/synch.c
@@ -441,7 +441,9 @@ redo:
        if (likely(h == XN_NO_HANDLE)) {
                xnsynch_set_owner(synch, curr);
                xnthread_get_resource(curr);
+               xnlock_get_irqsave(&nklock, s);
                xnthread_clear_info(curr, XNRMID | XNTIMEO | XNBREAK);
+               xnlock_put_irqrestore(&nklock, s);
                return 0;
        }
 
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index 5adf44f..22729a8 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -1978,6 +1978,7 @@ void xnthread_relax(int notify, int reason)
        struct task_struct *p = current;
        int cpu __maybe_unused;
        siginfo_t si;
+       spl_t s;
 
        primary_mode_only();
 
@@ -2034,7 +2035,9 @@ void xnthread_relax(int notify, int reason)
                        si.si_int = reason | sigdebug_marker;
                        send_sig_info(SIGDEBUG, &si, p);
                }
+               xnlock_get_irqsave(&nklock, s);
                xnsynch_detect_claimed_relax(thread);
+               xnlock_put_irqrestore(&nklock, s);
        }
 
        /*
@@ -2045,7 +2048,9 @@ void xnthread_relax(int notify, int reason)
 
 #ifdef CONFIG_SMP
        if (xnthread_test_info(thread, XNMOVED)) {
+               xnlock_get_irqsave(&nklock, s);
                xnthread_clear_info(thread, XNMOVED);
+               xnlock_put_irqrestore(&nklock, s);
                cpu = xnsched_cpu(thread->sched);
                set_cpus_allowed(p, cpumask_of_cpu(cpu));
        }


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to