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

Changeset 25ebfbd in mainline


Ignore:
Timestamp:
2012-05-06T19:34:33Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
c8d0f9e5
Parents:
1295a1da
Message:

Make slab_mag_cache_t's spinlock IRQ safe.

  • slab_cache_destroy() was taking this lock while interrupts were not disabled.
  • Some TLB shootdown sequences could allocate memory, which may involve taking the lock.
  • The above could lead to a deadlock if one CPU took the lock and another one started the TLB shootdown sequence which also takes this lock.
Location:
kernel/generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/mm/slab.h

    r1295a1da r25ebfbd  
    8181        slab_magazine_t *current;
    8282        slab_magazine_t *last;
    83         SPINLOCK_DECLARE(lock);
     83        IRQ_SPINLOCK_DECLARE(lock);
    8484} slab_mag_cache_t;
    8585
  • kernel/generic/src/mm/slab.c

    r1295a1da r25ebfbd  
    366366                atomic_dec(&cache->magazine_counter);
    367367        }
    368        
    369368        spinlock_unlock(&cache->maglock);
     369
    370370        return mag;
    371371}
     
    414414        slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
    415415       
    416         ASSERT(spinlock_locked(&cache->mag_cache[CPU->id].lock));
     416        ASSERT(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
    417417       
    418418        if (cmag) { /* First try local CPU magazines */
     
    451451                return NULL;
    452452       
    453         spinlock_lock(&cache->mag_cache[CPU->id].lock);
     453        irq_spinlock_lock(&cache->mag_cache[CPU->id].lock, true);
    454454       
    455455        slab_magazine_t *mag = get_full_current_mag(cache);
    456456        if (!mag) {
    457                 spinlock_unlock(&cache->mag_cache[CPU->id].lock);
     457                irq_spinlock_unlock(&cache->mag_cache[CPU->id].lock, true);
    458458                return NULL;
    459459        }
    460460       
    461461        void *obj = mag->objs[--mag->busy];
    462         spinlock_unlock(&cache->mag_cache[CPU->id].lock);
     462        irq_spinlock_unlock(&cache->mag_cache[CPU->id].lock, true);
    463463       
    464464        atomic_dec(&cache->cached_objs);
     
    481481        slab_magazine_t *lastmag = cache->mag_cache[CPU->id].last;
    482482       
    483         ASSERT(spinlock_locked(&cache->mag_cache[CPU->id].lock));
     483        ASSERT(irq_spinlock_locked(&cache->mag_cache[CPU->id].lock));
    484484       
    485485        if (cmag) {
     
    531531                return -1;
    532532       
    533         spinlock_lock(&cache->mag_cache[CPU->id].lock);
     533        irq_spinlock_lock(&cache->mag_cache[CPU->id].lock, true);
    534534       
    535535        slab_magazine_t *mag = make_empty_current_mag(cache);
    536536        if (!mag) {
    537                 spinlock_unlock(&cache->mag_cache[CPU->id].lock);
     537                irq_spinlock_unlock(&cache->mag_cache[CPU->id].lock, true);
    538538                return -1;
    539539        }
     
    541541        mag->objs[mag->busy++] = obj;
    542542       
    543         spinlock_unlock(&cache->mag_cache[CPU->id].lock);
     543        irq_spinlock_unlock(&cache->mag_cache[CPU->id].lock, true);
    544544       
    545545        atomic_inc(&cache->cached_objs);
     
    593593        for (i = 0; i < config.cpu_count; i++) {
    594594                memsetb(&cache->mag_cache[i], sizeof(cache->mag_cache[i]), 0);
    595                 spinlock_initialize(&cache->mag_cache[i].lock,
     595                irq_spinlock_initialize(&cache->mag_cache[i].lock,
    596596                    "slab.cache.mag_cache[].lock");
    597597        }
     
    704704                size_t i;
    705705                for (i = 0; i < config.cpu_count; i++) {
    706                         spinlock_lock(&cache->mag_cache[i].lock);
     706                        irq_spinlock_lock(&cache->mag_cache[i].lock, true);
    707707                       
    708708                        mag = cache->mag_cache[i].current;
     
    716716                        cache->mag_cache[i].last = NULL;
    717717                       
    718                         spinlock_unlock(&cache->mag_cache[i].lock);
     718                        irq_spinlock_unlock(&cache->mag_cache[i].lock, true);
    719719                }
    720720        }
Note: See TracChangeset for help on using the changeset viewer.