Ignore:
File:
1 edited

Legend:

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

    r98000fb rda1bafb  
    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{
     
    6659
    6760#ifdef CONFIG_SMP
     61
     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);
    6869
    6970/** Send TLB shootdown message.
     
    7879 * @param page Virtual page address, if required by type.
    7980 * @param count Number of pages, if required by type.
     81 *
    8082 */
    8183void 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        CPU->tlb_active = false;
     87        irq_spinlock_lock(&tlblock, false);
    8888       
     89        size_t i;
    8990        for (i = 0; i < config.cpu_count; i++) {
    9091                cpu_t *cpu;
     
    9293                if (i == CPU->id)
    9394                        continue;
    94 
     95               
    9596                cpu = &cpus[i];
    96                 spinlock_lock(&cpu->lock);
     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:     
     122       
     123busy_wait:
    123124        for (i = 0; i < config.cpu_count; i++)
    124125                if (cpus[i].tlb_active)
     
    126127}
    127128
    128 /** Finish TLB shootdown sequence. */
     129/** Finish TLB shootdown sequence.
     130 *
     131 */
    129132void tlb_shootdown_finalize(void)
    130133{
    131         spinlock_unlock(&tlblock);
    132         CPU->tlb_active = 1;
     134        irq_spinlock_unlock(&tlblock, false);
     135        CPU->tlb_active = true;
    133136}
    134137
     
    138141}
    139142
    140 /** Receive TLB shootdown message. */
     143/** Receive TLB shootdown message.
     144 *
     145 */
    141146void tlb_shootdown_ipi_recv(void)
    142147{
    143         tlb_invalidate_type_t type;
    144         asid_t asid;
    145         uintptr_t page;
    146         size_t count;
    147         unsigned int i;
    148        
    149148        ASSERT(CPU);
    150149       
    151         CPU->tlb_active = 0;
    152         spinlock_lock(&tlblock);
    153         spinlock_unlock(&tlblock);
     150        CPU->tlb_active = false;
     151        irq_spinlock_lock(&tlblock, false);
     152        irq_spinlock_unlock(&tlblock, false);
    154153       
    155         spinlock_lock(&CPU->lock);
     154        irq_spinlock_lock(&CPU->lock, false);
    156155        ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
    157 
     156       
     157        size_t i;
    158158        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 
     159                tlb_invalidate_type_t type = CPU->tlb_messages[i].type;
     160                asid_t asid = CPU->tlb_messages[i].asid;
     161                uintptr_t page = CPU->tlb_messages[i].page;
     162                size_t count = CPU->tlb_messages[i].count;
     163               
    164164                switch (type) {
    165165                case TLB_INVL_ALL:
     
    170170                        break;
    171171                case TLB_INVL_PAGES:
    172                         ASSERT(count);
     172                        ASSERT(count);
    173173                        tlb_invalidate_pages(asid, page, count);
    174174                        break;
     
    177177                        break;
    178178                }
     179               
    179180                if (type == TLB_INVL_ALL)
    180181                        break;
    181182        }
    182183       
    183         spinlock_unlock(&CPU->lock);
    184         CPU->tlb_active = 1;
     184        irq_spinlock_unlock(&CPU->lock, false);
     185        CPU->tlb_active = true;
    185186}
    186187
Note: See TracChangeset for help on using the changeset viewer.