summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2012-04-08 23:01:14 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2012-04-08 23:01:14 +0000
commitd4ff172e35f61a84262b76cf8950cb4fea0d4fa2 (patch)
treee99cc6cf93d8e80692c318af4cc5109689b58143
parent78d5b21a6b873f6f8e86bce90f2f187d036cb394 (diff)
parent269dd0992a850c9d1a28e636977c4a4955a33212 (diff)
Merge branch 'dde-upstream' into dde
-rw-r--r--libdde_linux26/include/linux/spinlock.h19
-rw-r--r--libdde_linux26/lib/src/arch/l4/cli_sti.c85
-rw-r--r--libdde_linux26/lib/src/arch/l4/softirq.c3
3 files changed, 13 insertions, 94 deletions
diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h
index 6830752b..ab862f99 100644
--- a/libdde_linux26/include/linux/spinlock.h
+++ b/libdde_linux26/include/linux/spinlock.h
@@ -372,10 +372,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
#else /* DDE_LINUX */
-unsigned long fake_local_irq_disable_flags(void);
-void fake_local_irq_enable(void);
-void fake_local_irq_restore(unsigned long flags);
-
#define spin_lock_init(l) \
do { \
ddekit_lock_init(&(l)->ddekit_lock); \
@@ -398,7 +394,7 @@ void fake_local_irq_restore(unsigned long flags);
#define read_lock(lock) spin_lock(lock)
#define write_lock(lock) spin_lock(lock)
-#define spin_lock_irq(lock) fake_local_irq_disable_flags(); spin_lock(lock)
+#define spin_lock_irq(lock) local_irq_disable(); spin_lock(lock)
#define spin_lock_bh(lock) spin_lock(lock)
#define read_lock_irq(lock) spin_lock_irq(lock)
#define read_lock_bh(lock) spin_lock_bh(lock)
@@ -415,7 +411,7 @@ void fake_local_irq_restore(unsigned long flags);
#define read_unlock(lock) spin_unlock(lock)
#define write_unlock(lock) spin_unlock(lock)
-#define spin_unlock_irq(lock) spin_unlock(lock); fake_local_irq_enable()
+#define spin_unlock_irq(lock) spin_unlock(lock); local_irq_enable()
#define spin_unlock_bh(lock) spin_unlock(lock)
#define read_unlock_irq(lock) spin_unlock_irq(lock)
#define read_unlock_bh(lock) spin_unlock_bh(lock)
@@ -424,7 +420,7 @@ void fake_local_irq_restore(unsigned long flags);
#define spin_lock_irqsave(lock, flags) \
do { \
- flags = fake_local_irq_disable_flags(); \
+ local_irq_save(flags); \
spin_lock(lock);\
} while (0);
@@ -434,7 +430,7 @@ void fake_local_irq_restore(unsigned long flags);
#define spin_unlock_irqrestore(lock, flags) \
do { \
spin_unlock(lock); \
- fake_local_irq_restore (flags); \
+ local_irq_restore(flags); \
} while (0);
#define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags)
@@ -450,7 +446,12 @@ static int __lockfunc spin_trylock(spinlock_t *lock)
#define _raw_spin_unlock(l) spin_unlock(l)
#define _raw_spin_trylock(l) spin_trylock(l)
-#define spin_trylock_irqsave(lock, flags) spin_trylock(lock)
+#define spin_trylock_irqsave(lock, flags) \
+({ \
+ local_irq_save(flags); \
+ spin_trylock(lock) ? \
+ 1 : ({ local_irq_restore(flags); 0; }); \
+})
#define read_trylock(l) spin_trylock(l)
#define write_trylock(l) read_trylock(l)
diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c
index e55e6401..81864ebb 100644
--- a/libdde_linux26/lib/src/arch/l4/cli_sti.c
+++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c
@@ -3,10 +3,7 @@
#include <linux/kernel.h>
/* IRQ lock reference counter */
-static atomic_t _refcnt = ATOMIC_INIT(0);
-/* Refcnt value at which unlocking the cli_lock (it's not always 0) */
-static int unlock_refcnt;
-static ddekit_lock_t cli_lock;
+static __thread atomic_t _refcnt = ATOMIC_INIT(0);
/* Check whether IRQs are currently disabled.
*
@@ -18,109 +15,31 @@ int raw_irqs_disabled_flags(unsigned long flags)
return ((int)flags > 0);
}
-/* If it does lock operation successfully, return > 0. Otherwise, 0. */
-static int nested_lock(ddekit_lock_t lock)
-{
- int do_lock = 0;
-
- if (ddekit_lock_try_lock(&lock)) { /* if we cannot lock */
- /* check who hold the lock. */
- if (_ddekit_lock_owner(&lock) != (int) ddekit_thread_myself()) {
- /* Someone else holds the lock,
- * or by the time I try to lock again,
- * the person has release the lock. */
- ddekit_lock_lock(&lock);
- do_lock = 1;
- }
- /* If I hold the lock myself, I don't need to worry
- * the lock will be released somewhere before I do it. */
- }
- else
- do_lock = 2;
-
- return do_lock;
-}
-
-unsigned long fake_local_irq_disable_flags(void)
-{
- return atomic_add_return (1, &_refcnt) - 1;
-}
-
-void fake_local_irq_enable(void)
-{
- atomic_set(&_refcnt, 0);
-}
-
-void fake_local_irq_restore(unsigned long flags)
-{
- atomic_set(&_refcnt, flags);
-}
-
/* Store the current flags state.
*
* This is done by returning the current refcnt.
*/
unsigned long __raw_local_save_flags(void)
{
- unsigned long flags;
- int do_lock = 0;
-
- if (cli_lock == NULL)
- ddekit_lock_init_unlocked(&cli_lock);
- /* It's important to do lock here.
- * Otherwise, a thread might not get correct flags. */
- do_lock = nested_lock(cli_lock);
- flags = (unsigned long)atomic_read(&_refcnt);
- if (do_lock)
- ddekit_lock_unlock(&cli_lock);
- return flags;
+ return (unsigned long)atomic_read(&_refcnt);
}
/* Restore IRQ state. */
void raw_local_irq_restore(unsigned long flags)
{
- Assert(cli_lock != NULL);
atomic_set(&_refcnt, flags);
- if (flags == unlock_refcnt) {
- ddekit_lock_unlock(&cli_lock);
- unlock_refcnt = 0;
- }
}
/* Disable IRQs by grabbing the IRQ lock. */
void raw_local_irq_disable(void)
{
- struct ddekit_thread *helder;
- int is_print = 0;
-
- if (cli_lock == NULL)
- ddekit_lock_init_unlocked(&cli_lock);
-
- if (nested_lock(cli_lock)) {
- /* Tell the corresponding restorer to release cli_lock,
- * but do not update the value if there has been a re-enable in
- * between, that would store a bogus value.
- * XXX: scenario that will still break:
- * save
- * disable
- * enable
- * save
- * disable
- * restore
- * restore
- */
- if (unlock_refcnt < atomic_read(&_refcnt))
- unlock_refcnt = atomic_read(&_refcnt);
- }
atomic_inc(&_refcnt);
}
/* Unlock the IRQ lock until refcnt is 0. */
void raw_local_irq_enable(void)
{
- Assert(cli_lock != NULL);
atomic_set(&_refcnt, 0);
- ddekit_lock_unlock(&cli_lock);
}
diff --git a/libdde_linux26/lib/src/arch/l4/softirq.c b/libdde_linux26/lib/src/arch/l4/softirq.c
index 67e8f5aa..21b36d17 100644
--- a/libdde_linux26/lib/src/arch/l4/softirq.c
+++ b/libdde_linux26/lib/src/arch/l4/softirq.c
@@ -172,6 +172,7 @@ static void tasklet_hi_action(struct softirq_action *a)
}
}
+
#define MAX_SOFTIRQ_RETRIES 10
/** Run softirq handlers
@@ -185,7 +186,6 @@ void __do_softirq(void)
/* reset softirq count */
set_softirq_pending(0);
- local_irq_enable();
/* While we have a softirq pending... */
while (pending) {
@@ -197,7 +197,6 @@ void __do_softirq(void)
/* remove pending flag for last softirq */
pending >>= 1;
}
- local_irq_disable();
/* Somebody might have scheduled another softirq in between
* (e.g., an IRQ thread or another tasklet). */