diff options
Diffstat (limited to 'libdde_linux26/lib/src')
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/cli_sti.c | 49 | ||||
-rw-r--r-- | libdde_linux26/lib/src/arch/l4/softirq.c | 16 | ||||
-rw-r--r-- | libdde_linux26/lib/src/net/core/dev.c | 9 |
3 files changed, 54 insertions, 20 deletions
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); |