Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2845930 in mainline


Ignore:
Timestamp:
2009-04-06T22:05:15Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
6071a8f
Parents:
3636964
Message:

Address issues with IRQ notifications.

Location:
kernel/generic/src
Files:
2 edited

Legend:

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

    r3636964 r2845930  
    102102static index_t irq_ht_hash(unative_t *key);
    103103static bool irq_ht_compare(unative_t *key, count_t keys, link_t *item);
     104static void irq_ht_remove(link_t *item);
    104105
    105106static hash_table_operations_t irq_ht_ops = {
    106107        .hash = irq_ht_hash,
    107108        .compare = irq_ht_compare,
    108         .remove_callback = NULL         /* not used */
     109        .remove_callback = irq_ht_remove,
    109110};
    110111
     
    117118static index_t irq_lin_hash(unative_t *key);
    118119static bool irq_lin_compare(unative_t *key, count_t keys, link_t *item);
     120static void irq_lin_remove(link_t *item);
    119121
    120122static hash_table_operations_t irq_lin_ops = {
    121123        .hash = irq_lin_hash,
    122124        .compare = irq_lin_compare,
    123         .remove_callback = NULL         /* not used */
     125        .remove_callback = irq_lin_remove,
    124126};
    125127
     
    348350}
    349351
     352/** Unlock IRQ structure after hash_table_remove().
     353 *
     354 * @param lnk           Link in the removed and locked IRQ structure.
     355 */
     356void irq_ht_remove(link_t *lnk)
     357{
     358        irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
     359        spinlock_unlock(&irq->lock);
     360}
     361
    350362/** Compute hash index for the key.
    351363 *
     
    407419}
    408420
     421/** Unlock IRQ structure after hash_table_remove().
     422 *
     423 * @param lnk           Link in the removed and locked IRQ structure.
     424 */
     425void irq_lin_remove(link_t *lnk)
     426{
     427        irq_t *irq = hash_table_get_instance(lnk, irq_t, link);
     428        spinlock_unlock(&irq->lock);
     429}
     430
    409431/** @}
    410432 */
  • 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.