From 8a6d48c0542876eb3acfc0970c0ab7872db08d5f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 6 Dec 2009 05:26:23 +0100 Subject: check in the original version of dde linux26. --- libdde_linux26/include/linux/spinlock.h | 467 ++++++++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 libdde_linux26/include/linux/spinlock.h (limited to 'libdde_linux26/include/linux/spinlock.h') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h new file mode 100644 index 00000000..ab862f99 --- /dev/null +++ b/libdde_linux26/include/linux/spinlock.h @@ -0,0 +1,467 @@ +#ifndef __LINUX_SPINLOCK_H +#define __LINUX_SPINLOCK_H + +/* + * include/linux/spinlock.h - generic spinlock/rwlock declarations + * + * here's the role of the various spinlock/rwlock related include files: + * + * on SMP builds: + * + * asm/spinlock_types.h: contains the raw_spinlock_t/raw_rwlock_t and the + * initializers + * + * linux/spinlock_types.h: + * defines the generic type and initializers + * + * asm/spinlock.h: contains the __raw_spin_*()/etc. lowlevel + * implementations, mostly inline assembly code + * + * (also included on UP-debug builds:) + * + * linux/spinlock_api_smp.h: + * contains the prototypes for the _spin_*() APIs. + * + * linux/spinlock.h: builds the final spin_*() APIs. + * + * on UP builds: + * + * linux/spinlock_type_up.h: + * contains the generic, simplified UP spinlock type. + * (which is an empty structure on non-debug builds) + * + * linux/spinlock_types.h: + * defines the generic type and initializers + * + * linux/spinlock_up.h: + * contains the __raw_spin_*()/etc. version of UP + * builds. (which are NOPs on non-debug, non-preempt + * builds) + * + * (included on UP-non-debug builds:) + * + * linux/spinlock_api_up.h: + * builds the _spin_*() APIs. + * + * linux/spinlock.h: builds the final spin_*() APIs. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Must define these before including other files, inline functions need them + */ +#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME + +#define LOCK_SECTION_START(extra) \ + ".subsection 1\n\t" \ + extra \ + ".ifndef " LOCK_SECTION_NAME "\n\t" \ + LOCK_SECTION_NAME ":\n\t" \ + ".endif\n" + +#define LOCK_SECTION_END \ + ".previous\n\t" + +#define __lockfunc __attribute__((section(".spinlock.text"))) + +/* + * Pull the raw_spinlock_t and raw_rwlock_t definitions: + */ +#include + +#ifndef DDE_LINUX +extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock); + +/* + * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them): + */ +#ifdef CONFIG_SMP +# include +#else +# include +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void __spin_lock_init(spinlock_t *lock, const char *name, + struct lock_class_key *key); +# define spin_lock_init(lock) \ +do { \ + static struct lock_class_key __key; \ + \ + __spin_lock_init((lock), #lock, &__key); \ +} while (0) + +#else +# define spin_lock_init(lock) \ + do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0) +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void __rwlock_init(rwlock_t *lock, const char *name, + struct lock_class_key *key); +# define rwlock_init(lock) \ +do { \ + static struct lock_class_key __key; \ + \ + __rwlock_init((lock), #lock, &__key); \ +} while (0) +#else +# define rwlock_init(lock) \ + do { *(lock) = RW_LOCK_UNLOCKED; } while (0) +#endif + +#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock) + +#ifdef CONFIG_GENERIC_LOCKBREAK +#define spin_is_contended(lock) ((lock)->break_lock) +#else + +#ifdef __raw_spin_is_contended +#define spin_is_contended(lock) __raw_spin_is_contended(&(lock)->raw_lock) +#else +#define spin_is_contended(lock) (((void)(lock), 0)) +#endif /*__raw_spin_is_contended*/ +#endif + +/** + * spin_unlock_wait - wait until the spinlock gets unlocked + * @lock: the spinlock in question. + */ +#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock) + +/* + * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: + */ +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +# include +#else +# include +#endif + +#ifdef CONFIG_DEBUG_SPINLOCK + extern void _raw_spin_lock(spinlock_t *lock); +#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) + extern int _raw_spin_trylock(spinlock_t *lock); + extern void _raw_spin_unlock(spinlock_t *lock); + extern void _raw_read_lock(rwlock_t *lock); + extern int _raw_read_trylock(rwlock_t *lock); + extern void _raw_read_unlock(rwlock_t *lock); + extern void _raw_write_lock(rwlock_t *lock); + extern int _raw_write_trylock(rwlock_t *lock); + extern void _raw_write_unlock(rwlock_t *lock); +#else +# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock) +# define _raw_spin_lock_flags(lock, flags) \ + __raw_spin_lock_flags(&(lock)->raw_lock, *(flags)) +# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock) +# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock) +# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock) +# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock) +# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock) +# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock) +# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock) +# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock) +#endif + +#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock) +#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock) + +/* + * Define the various spin_lock and rw_lock methods. Note we define these + * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various + * methods are defined as nops in the case they are not required. + */ +#define spin_trylock(lock) __cond_lock(lock, _spin_trylock(lock)) +#define read_trylock(lock) __cond_lock(lock, _read_trylock(lock)) +#define write_trylock(lock) __cond_lock(lock, _write_trylock(lock)) + +#define spin_lock(lock) _spin_lock(lock) + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +# define spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass) +# define spin_lock_nest_lock(lock, nest_lock) \ + do { \ + typecheck(struct lockdep_map *, &(nest_lock)->dep_map);\ + _spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ + } while (0) +#else +# define spin_lock_nested(lock, subclass) _spin_lock(lock) +# define spin_lock_nest_lock(lock, nest_lock) _spin_lock(lock) +#endif + +#define write_lock(lock) _write_lock(lock) +#define read_lock(lock) _read_lock(lock) + +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + +#define spin_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _spin_lock_irqsave(lock); \ + } while (0) +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _read_lock_irqsave(lock); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _write_lock_irqsave(lock); \ + } while (0) + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +#define spin_lock_irqsave_nested(lock, flags, subclass) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _spin_lock_irqsave_nested(lock, subclass); \ + } while (0) +#else +#define spin_lock_irqsave_nested(lock, flags, subclass) \ + do { \ + typecheck(unsigned long, flags); \ + flags = _spin_lock_irqsave(lock); \ + } while (0) +#endif + +#else + +#define spin_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _spin_lock_irqsave(lock, flags); \ + } while (0) +#define read_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _read_lock_irqsave(lock, flags); \ + } while (0) +#define write_lock_irqsave(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _write_lock_irqsave(lock, flags); \ + } while (0) +#define spin_lock_irqsave_nested(lock, flags, subclass) \ + spin_lock_irqsave(lock, flags) + +#endif + +#define spin_lock_irq(lock) _spin_lock_irq(lock) +#define spin_lock_bh(lock) _spin_lock_bh(lock) + +#define read_lock_irq(lock) _read_lock_irq(lock) +#define read_lock_bh(lock) _read_lock_bh(lock) + +#define write_lock_irq(lock) _write_lock_irq(lock) +#define write_lock_bh(lock) _write_lock_bh(lock) + +/* + * We inline the unlock functions in the nondebug case: + */ +#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || \ + !defined(CONFIG_SMP) +# define spin_unlock(lock) _spin_unlock(lock) +# define read_unlock(lock) _read_unlock(lock) +# define write_unlock(lock) _write_unlock(lock) +# define spin_unlock_irq(lock) _spin_unlock_irq(lock) +# define read_unlock_irq(lock) _read_unlock_irq(lock) +# define write_unlock_irq(lock) _write_unlock_irq(lock) +#else +# define spin_unlock(lock) \ + do {__raw_spin_unlock(&(lock)->raw_lock); __release(lock); } while (0) +# define read_unlock(lock) \ + do {__raw_read_unlock(&(lock)->raw_lock); __release(lock); } while (0) +# define write_unlock(lock) \ + do {__raw_write_unlock(&(lock)->raw_lock); __release(lock); } while (0) +# define spin_unlock_irq(lock) \ +do { \ + __raw_spin_unlock(&(lock)->raw_lock); \ + __release(lock); \ + local_irq_enable(); \ +} while (0) +# define read_unlock_irq(lock) \ +do { \ + __raw_read_unlock(&(lock)->raw_lock); \ + __release(lock); \ + local_irq_enable(); \ +} while (0) +# define write_unlock_irq(lock) \ +do { \ + __raw_write_unlock(&(lock)->raw_lock); \ + __release(lock); \ + local_irq_enable(); \ +} while (0) +#endif + +#define spin_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _spin_unlock_irqrestore(lock, flags); \ + } while (0) +#define spin_unlock_bh(lock) _spin_unlock_bh(lock) + +#define read_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _read_unlock_irqrestore(lock, flags); \ + } while (0) +#define read_unlock_bh(lock) _read_unlock_bh(lock) + +#define write_unlock_irqrestore(lock, flags) \ + do { \ + typecheck(unsigned long, flags); \ + _write_unlock_irqrestore(lock, flags); \ + } while (0) +#define write_unlock_bh(lock) _write_unlock_bh(lock) + +#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) + +#define spin_trylock_irq(lock) \ +({ \ + local_irq_disable(); \ + spin_trylock(lock) ? \ + 1 : ({ local_irq_enable(); 0; }); \ +}) + +#define spin_trylock_irqsave(lock, flags) \ +({ \ + local_irq_save(flags); \ + spin_trylock(lock) ? \ + 1 : ({ local_irq_restore(flags); 0; }); \ +}) + +#define write_trylock_irqsave(lock, flags) \ +({ \ + local_irq_save(flags); \ + write_trylock(lock) ? \ + 1 : ({ local_irq_restore(flags); 0; }); \ +}) + +/* + * Pull the atomic_t declaration: + * (asm-mips/atomic.h needs above definitions) + */ +#include +/** + * atomic_dec_and_lock - lock on reaching reference count zero + * @atomic: the atomic counter + * @lock: the spinlock in question + * + * Decrements @atomic by 1. If the result is 0, returns true and locks + * @lock. Returns false for all other cases. + */ +extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); +#define atomic_dec_and_lock(atomic, lock) \ + __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) + +/** + * spin_can_lock - would spin_trylock() succeed? + * @lock: the spinlock in question. + */ +#define spin_can_lock(lock) (!spin_is_locked(lock)) + +#else /* DDE_LINUX */ + +#define spin_lock_init(l) \ + do { \ + ddekit_lock_init(&(l)->ddekit_lock); \ + (l)->need_init = 0; \ + } while (0); + +#define rwlock_init(l) spin_lock_init(l) + +#define COND_INIT_LOCK(l) \ + do { \ + if ((l)->need_init) spin_lock_init(l); \ + } while (0); + +#define spin_lock(lock) \ + do { \ + COND_INIT_LOCK(lock); \ + preempt_disable(); \ + ddekit_lock_lock(&(lock)->ddekit_lock); \ + } while (0) + +#define read_lock(lock) spin_lock(lock) +#define write_lock(lock) 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) +#define write_lock_irq(lock) spin_lock_irq(lock) +#define write_lock_bh(lock) spin_lock_bh(lock) + +#define spin_unlock(lock) \ + do { \ + COND_INIT_LOCK(lock); \ + ddekit_lock_unlock(&(lock)->ddekit_lock); \ + preempt_enable(); \ + } while (0) + +#define read_unlock(lock) spin_unlock(lock) +#define write_unlock(lock) spin_unlock(lock) + +#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) +#define write_unlock_irq(lock) spin_unlock_irq(lock) +#define write_unlock_bh(lock) spin_unlock_bh(lock) + +#define spin_lock_irqsave(lock, flags) \ + do { \ + local_irq_save(flags); \ + spin_lock(lock);\ + } while (0); + +#define read_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags) +#define write_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags) + +#define spin_unlock_irqrestore(lock, flags) \ + do { \ + spin_unlock(lock); \ + local_irq_restore(flags); \ + } while (0); + +#define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) +#define write_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) + +static int __lockfunc spin_trylock(spinlock_t *lock) +{ + COND_INIT_LOCK(lock); + return ddekit_lock_try_lock(&lock->ddekit_lock) == 0; +} + +#define _raw_spin_lock(l) spin_lock(l) +#define _raw_spin_unlock(l) spin_unlock(l) +#define _raw_spin_trylock(l) spin_trylock(l) + +#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) + +#define spin_is_locked(x) \ + (ddekit_lock_owner(&(x)->ddekit_lock) != 0) + +#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x)) + + +#endif /* DDE_LINUX */ + +#endif /* __LINUX_SPINLOCK_H */ -- cgit v1.2.3 From fbb1c9f5d35a8b89bbebb55a4a49c3da2f189c05 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 28 Feb 2010 05:24:57 +0100 Subject: implement cli/sti with a lock. In order to avoid dead lock caused by spin_lock_irq or spin_lock_irqsave, I remove irq disabling in them. It's really unnecessary to do spin_lock_irq and spin_lock_irqsave any more because interrupt isn't handled in a real interrupt context. --- libdde_linux26/include/linux/spinlock.h | 7 ++--- libdde_linux26/lib/src/arch/l4/cli_sti.c | 49 +++++++++++++++++++++++++++++++- libdde_linux26/lib/src/arch/l4/softirq.c | 16 +++-------- libdde_linux26/lib/src/net/core/dev.c | 9 ++---- 4 files changed, 56 insertions(+), 25 deletions(-) (limited to 'libdde_linux26/include/linux/spinlock.h') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h index ab862f99..7fb7a251 100644 --- a/libdde_linux26/include/linux/spinlock.h +++ b/libdde_linux26/include/linux/spinlock.h @@ -394,7 +394,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_lock(lock) spin_lock(lock) #define write_lock(lock) spin_lock(lock) -#define spin_lock_irq(lock) local_irq_disable(); spin_lock(lock) +#define spin_lock_irq(lock) 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) @@ -411,7 +411,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_unlock(lock) spin_unlock(lock) #define write_unlock(lock) spin_unlock(lock) -#define spin_unlock_irq(lock) spin_unlock(lock); local_irq_enable() +#define spin_unlock_irq(lock) spin_unlock(lock) #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) @@ -420,7 +420,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_lock_irqsave(lock, flags) \ do { \ - local_irq_save(flags); \ spin_lock(lock);\ } while (0); @@ -430,7 +429,6 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_unlock_irqrestore(lock, flags) \ do { \ spin_unlock(lock); \ - local_irq_restore(flags); \ } while (0); #define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) @@ -448,7 +446,6 @@ static int __lockfunc spin_trylock(spinlock_t *lock) #define spin_trylock_irqsave(lock, flags) \ ({ \ - local_irq_save(flags); \ spin_trylock(lock) ? \ 1 : ({ local_irq_restore(flags); 0; }); \ }) diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c index 81c4feea..3f5ba4cf 100644 --- a/libdde_linux26/lib/src/arch/l4/cli_sti.c +++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c @@ -4,6 +4,7 @@ /* IRQ lock reference counter */ static atomic_t _refcnt = ATOMIC_INIT(0); +static ddekit_lock_t cli_lock; /* Check whether IRQs are currently disabled. * @@ -15,6 +16,29 @@ 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; +} + /* Store the current flags state. * * This is done by returning the current refcnt. @@ -24,25 +48,48 @@ int raw_irqs_disabled_flags(unsigned long flags) */ unsigned long __raw_local_save_flags(void) { - return (unsigned long)atomic_read(&_refcnt); + 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; } /* Restore IRQ state. */ void raw_local_irq_restore(unsigned long flags) { + Assert(cli_lock != NULL); atomic_set(&_refcnt, flags); + if (flags == 0) + ddekit_lock_unlock(&cli_lock); } /* 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); + + nested_lock(cli_lock); 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 be13422b..67e8f5aa 100644 --- a/libdde_linux26/lib/src/arch/l4/softirq.c +++ b/libdde_linux26/lib/src/arch/l4/softirq.c @@ -172,8 +172,6 @@ static void tasklet_hi_action(struct softirq_action *a) } } -ddekit_lock_t cli_lock; - #define MAX_SOFTIRQ_RETRIES 10 /** Run softirq handlers @@ -187,8 +185,7 @@ void __do_softirq(void) /* reset softirq count */ set_softirq_pending(0); - ddekit_lock_unlock(&cli_lock); -// local_irq_enable(); + local_irq_enable(); /* While we have a softirq pending... */ while (pending) { @@ -200,8 +197,7 @@ void __do_softirq(void) /* remove pending flag for last softirq */ pending >>= 1; } -// local_irq_disable(); - ddekit_lock_lock(&cli_lock); + local_irq_disable(); /* Somebody might have scheduled another softirq in between * (e.g., an IRQ thread or another tasklet). */ @@ -214,14 +210,10 @@ void do_softirq(void) { unsigned long flags; - if (cli_lock == NULL) - ddekit_lock_init_unlocked(&cli_lock); - ddekit_lock_lock(&cli_lock); -// local_irq_save(flags); + local_irq_save(flags); if (local_softirq_pending()) __do_softirq(); -// local_irq_restore(flags); - ddekit_lock_unlock(&cli_lock); + local_irq_restore(flags); } /** Softirq thread function. diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 128f4d73..64917332 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -2611,16 +2611,11 @@ out: void __napi_schedule(struct napi_struct *n) { unsigned long flags; - extern ddekit_lock_t cli_lock; - if (cli_lock == NULL) - ddekit_lock_init_unlocked(&cli_lock); - ddekit_lock_lock(&cli_lock); -// local_irq_save(flags); + local_irq_save(flags); list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); __raise_softirq_irqoff(NET_RX_SOFTIRQ); -// local_irq_restore(flags); - ddekit_lock_unlock(&cli_lock); + local_irq_restore(flags); } EXPORT_SYMBOL(__napi_schedule); -- cgit v1.2.3 From 865820a3df8f78274522b8c55585a61c13889bd3 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Thu, 6 May 2010 10:56:11 +0200 Subject: remove local_irq_restore in spin_trylock_irqsave. --- libdde_linux26/include/linux/spinlock.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'libdde_linux26/include/linux/spinlock.h') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h index 7fb7a251..f038d145 100644 --- a/libdde_linux26/include/linux/spinlock.h +++ b/libdde_linux26/include/linux/spinlock.h @@ -444,11 +444,7 @@ 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) ? \ - 1 : ({ local_irq_restore(flags); 0; }); \ -}) +#define spin_trylock_irqsave(lock, flags) spin_trylock(lock) #define read_trylock(l) spin_trylock(l) #define write_trylock(l) read_trylock(l) -- cgit v1.2.3 From 529d8041be254a2ba56543953b1daf8f1c83a204 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Mon, 9 Aug 2010 12:32:17 +0200 Subject: fake irq disable and enable. Some functions such as blk_plug_device checks whether irqs are disabled. So I need to fake irq diable in spin_lock_irq and spin_lock_irqsave. --- libdde_linux26/include/linux/spinlock.h | 10 ++++++++-- libdde_linux26/lib/src/arch/l4/cli_sti.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'libdde_linux26/include/linux/spinlock.h') diff --git a/libdde_linux26/include/linux/spinlock.h b/libdde_linux26/include/linux/spinlock.h index f038d145..6830752b 100644 --- a/libdde_linux26/include/linux/spinlock.h +++ b/libdde_linux26/include/linux/spinlock.h @@ -372,6 +372,10 @@ 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); \ @@ -394,7 +398,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_lock(lock) spin_lock(lock) #define write_lock(lock) spin_lock(lock) -#define spin_lock_irq(lock) spin_lock(lock) +#define spin_lock_irq(lock) fake_local_irq_disable_flags(); 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) @@ -411,7 +415,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define read_unlock(lock) spin_unlock(lock) #define write_unlock(lock) spin_unlock(lock) -#define spin_unlock_irq(lock) spin_unlock(lock) +#define spin_unlock_irq(lock) spin_unlock(lock); fake_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) @@ -420,6 +424,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_lock_irqsave(lock, flags) \ do { \ + flags = fake_local_irq_disable_flags(); \ spin_lock(lock);\ } while (0); @@ -429,6 +434,7 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define spin_unlock_irqrestore(lock, flags) \ do { \ spin_unlock(lock); \ + fake_local_irq_restore (flags); \ } while (0); #define read_unlock_irqrestore(lock, flags) spin_unlock_irqrestore(lock, flags) diff --git a/libdde_linux26/lib/src/arch/l4/cli_sti.c b/libdde_linux26/lib/src/arch/l4/cli_sti.c index 3f5ba4cf..051f2598 100644 --- a/libdde_linux26/lib/src/arch/l4/cli_sti.c +++ b/libdde_linux26/lib/src/arch/l4/cli_sti.c @@ -39,6 +39,21 @@ static int nested_lock(ddekit_lock_t lock) 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. -- cgit v1.2.3