Changeset 2845930 in mainline for kernel/generic/src/ipc/irq.c


Ignore:
Timestamp:
2009-04-06T22:05:15Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6071a8f
Parents:
3636964
Message:

Address issues with IRQ notifications.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/irq.c

    r3636964 r2845930  
    143143        irq_code_t *code;
    144144        irq_t *irq;
     145        link_t *hlp;
    145146        unative_t key[] = {
    146147                (unative_t) inr,
     
    177178        ipl = interrupts_disable();
    178179        spinlock_lock(&irq_uspace_hash_table_lock);
    179         spinlock_lock(&irq->lock);
    180         spinlock_lock(&box->irq_lock);
    181         if (hash_table_find(&irq_uspace_hash_table, key)) {
     180        hlp = hash_table_find(&irq_uspace_hash_table, key);
     181        if (hlp) {
     182                irq_t *hirq = hash_table_get_instance(hlp, irq_t, link);
     183                /* hirq is locked */
     184                spinlock_unlock(&hirq->lock);
    182185                code_free(code);
    183                 spinlock_unlock(&box->irq_lock);
    184                 spinlock_unlock(&irq->lock);
    185186                spinlock_unlock(&irq_uspace_hash_table_lock);
    186187                free(irq);
     
    188189                return EEXISTS;
    189190        }
     191        spinlock_lock(&irq->lock);      /* not really necessary, but paranoid */
     192        spinlock_lock(&box->irq_lock);
    190193        hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
    191194        list_append(&irq->notif_cfg.link, &box->irq_head);
     
    223226        }
    224227        irq = hash_table_get_instance(lnk, irq_t, link);
    225         spinlock_lock(&irq->lock);
     228        /* irq is locked */
    226229        spinlock_lock(&box->irq_lock);
    227230       
     
    234237        list_remove(&irq->notif_cfg.link);
    235238
     239        /*
     240         * We need to drop the IRQ lock now because hash_table_remove() will try
     241         * to reacquire it. That basically violates the natural locking order,
     242         * but a deadlock in hash_table_remove() is prevented by the fact that
     243         * we already held the IRQ lock and didn't drop the hash table lock in
     244         * the meantime.
     245         */
     246        spinlock_unlock(&irq->lock);
     247
    236248        /* Remove the IRQ from the uspace IRQ hash table. */
    237249        hash_table_remove(&irq_uspace_hash_table, key, 2);
    238250       
    239251        spinlock_unlock(&irq_uspace_hash_table_lock);
    240         spinlock_unlock(&irq->lock);
    241252        spinlock_unlock(&box->irq_lock);
    242253       
     
    295306                code_free(irq->notif_cfg.code);
    296307               
     308                /*
     309                 * We need to drop the IRQ lock now because hash_table_remove()
     310                 * will try to reacquire it. That basically violates the natural
     311                 * locking order, but a deadlock in hash_table_remove() is
     312                 * prevented by the fact that we already held the IRQ lock and
     313                 * didn't drop the hash table lock in the meantime.
     314                 */
    297315                spinlock_unlock(&irq->lock);
    298316               
Note: See TracChangeset for help on using the changeset viewer.