Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/mm/tlb.c

    r98000fb r49eb681  
    3333/**
    3434 * @file
    35  * @brief       Generic TLB shootdown algorithm.
     35 * @brief Generic TLB shootdown algorithm.
    3636 *
    3737 * The algorithm implemented here is based on the CMU TLB shootdown
     
    5353#include <cpu.h>
    5454
    55 /**
    56  * This lock is used for synchronisation between sender and
    57  * recipients of TLB shootdown message. It must be acquired
    58  * before CPU structure lock.
    59  */
    60 SPINLOCK_INITIALIZE(tlblock);
    61 
    6255void tlb_init(void)
    6356{
     
    6760#ifdef CONFIG_SMP
    6861
     62/**
     63 * This lock is used for synchronisation between sender and
     64 * recipients of TLB shootdown message. It must be acquired
     65 * before CPU structure lock.
     66 *
     67 */
     68IRQ_SPINLOCK_STATIC_INITIALIZE(tlblock);
     69
    6970/** Send TLB shootdown message.
    7071 *
     
    7273 * to all other processors.
    7374 *
    74  * This function must be called with interrupts disabled.
     75 * @param type  Type describing scope of shootdown.
     76 * @param asid  Address space, if required by type.
     77 * @param page  Virtual page address, if required by type.
     78 * @param count Number of pages, if required by type.
    7579 *
    76  * @param type Type describing scope of shootdown.
    77  * @param asid Address space, if required by type.
    78  * @param page Virtual page address, if required by type.
    79  * @param count Number of pages, if required by type.
     80 * @return The interrupt priority level as it existed prior to this call.
     81 *
    8082 */
    81 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
     83ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
    8284    uintptr_t page, size_t count)
    8385{
    84         unsigned int i;
    85 
    86         CPU->tlb_active = 0;
    87         spinlock_lock(&tlblock);
     86        ipl_t ipl = interrupts_disable();
     87        CPU->tlb_active = false;
     88        irq_spinlock_lock(&tlblock, false);
    8889       
     90        size_t i;
    8991        for (i = 0; i < config.cpu_count; i++) {
    90                 cpu_t *cpu;
    91                
    9292                if (i == CPU->id)
    9393                        continue;
    94 
    95                 cpu = &cpus[i];
    96                 spinlock_lock(&cpu->lock);
     94               
     95                cpu_t *cpu = &cpus[i];
     96               
     97                irq_spinlock_lock(&cpu->lock, false);
    9798                if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) {
    9899                        /*
     
    115116                        cpu->tlb_messages[idx].count = count;
    116117                }
    117                 spinlock_unlock(&cpu->lock);
     118                irq_spinlock_unlock(&cpu->lock, false);
    118119        }
    119120       
    120121        tlb_shootdown_ipi_send();
    121 
    122 busy_wait:     
    123         for (i = 0; i < config.cpu_count; i++)
     122       
     123busy_wait:
     124        for (i = 0; i < config.cpu_count; i++) {
    124125                if (cpus[i].tlb_active)
    125126                        goto busy_wait;
     127        }
     128       
     129        return ipl;
    126130}
    127131
    128 /** Finish TLB shootdown sequence. */
    129 void tlb_shootdown_finalize(void)
     132/** Finish TLB shootdown sequence.
     133 *
     134 * @param ipl Previous interrupt priority level.
     135 *
     136 */
     137void tlb_shootdown_finalize(ipl_t ipl)
    130138{
    131         spinlock_unlock(&tlblock);
    132         CPU->tlb_active = 1;
     139        irq_spinlock_unlock(&tlblock, false);
     140        CPU->tlb_active = true;
     141        interrupts_restore(ipl);
    133142}
    134143
     
    138147}
    139148
    140 /** Receive TLB shootdown message. */
     149/** Receive TLB shootdown message.
     150 *
     151 */
    141152void tlb_shootdown_ipi_recv(void)
    142153{
    143         tlb_invalidate_type_t type;
    144         asid_t asid;
    145         uintptr_t page;
    146         size_t count;
    147         unsigned int i;
    148        
    149154        ASSERT(CPU);
    150155       
    151         CPU->tlb_active = 0;
    152         spinlock_lock(&tlblock);
    153         spinlock_unlock(&tlblock);
     156        CPU->tlb_active = false;
     157        irq_spinlock_lock(&tlblock, false);
     158        irq_spinlock_unlock(&tlblock, false);
    154159       
    155         spinlock_lock(&CPU->lock);
     160        irq_spinlock_lock(&CPU->lock, false);
    156161        ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
    157 
     162       
     163        size_t i;
    158164        for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
    159                 type = CPU->tlb_messages[i].type;
    160                 asid = CPU->tlb_messages[i].asid;
    161                 page = CPU->tlb_messages[i].page;
    162                 count = CPU->tlb_messages[i].count;
    163 
     165                tlb_invalidate_type_t type = CPU->tlb_messages[i].type;
     166                asid_t asid = CPU->tlb_messages[i].asid;
     167                uintptr_t page = CPU->tlb_messages[i].page;
     168                size_t count = CPU->tlb_messages[i].count;
     169               
    164170                switch (type) {
    165171                case TLB_INVL_ALL:
     
    170176                        break;
    171177                case TLB_INVL_PAGES:
    172                         ASSERT(count);
     178                        ASSERT(count);
    173179                        tlb_invalidate_pages(asid, page, count);
    174180                        break;
     
    177183                        break;
    178184                }
     185               
    179186                if (type == TLB_INVL_ALL)
    180187                        break;
    181188        }
    182189       
    183         spinlock_unlock(&CPU->lock);
    184         CPU->tlb_active = 1;
     190        irq_spinlock_unlock(&CPU->lock, false);
     191        CPU->tlb_active = true;
    185192}
    186193
Note: See TracChangeset for help on using the changeset viewer.