Ignore:
File:
1 edited

Legend:

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

    r49eb681 r98000fb  
    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 */
     60SPINLOCK_INITIALIZE(tlblock);
     61
    5562void tlb_init(void)
    5663{
     
    6067#ifdef CONFIG_SMP
    6168
    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  */
    68 IRQ_SPINLOCK_STATIC_INITIALIZE(tlblock);
    69 
    7069/** Send TLB shootdown message.
    7170 *
     
    7372 * to all other processors.
    7473 *
    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.
     74 * This function must be called with interrupts disabled.
     75 *
     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.
    7879 * @param count Number of pages, if required by type.
    79  *
    80  * @return The interrupt priority level as it existed prior to this call.
    81  *
    8280 */
    83 ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
     81void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
    8482    uintptr_t page, size_t count)
    8583{
    86         ipl_t ipl = interrupts_disable();
    87         CPU->tlb_active = false;
    88         irq_spinlock_lock(&tlblock, false);
     84        unsigned int i;
     85
     86        CPU->tlb_active = 0;
     87        spinlock_lock(&tlblock);
    8988       
    90         size_t i;
    9189        for (i = 0; i < config.cpu_count; i++) {
     90                cpu_t *cpu;
     91               
    9292                if (i == CPU->id)
    9393                        continue;
    94                
    95                 cpu_t *cpu = &cpus[i];
    96                
    97                 irq_spinlock_lock(&cpu->lock, false);
     94
     95                cpu = &cpus[i];
     96                spinlock_lock(&cpu->lock);
    9897                if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) {
    9998                        /*
     
    116115                        cpu->tlb_messages[idx].count = count;
    117116                }
    118                 irq_spinlock_unlock(&cpu->lock, false);
     117                spinlock_unlock(&cpu->lock);
    119118        }
    120119       
    121120        tlb_shootdown_ipi_send();
    122        
    123 busy_wait:
    124         for (i = 0; i < config.cpu_count; i++) {
     121
     122busy_wait:     
     123        for (i = 0; i < config.cpu_count; i++)
    125124                if (cpus[i].tlb_active)
    126125                        goto busy_wait;
    127         }
    128        
    129         return ipl;
    130126}
    131127
    132 /** Finish TLB shootdown sequence.
    133  *
    134  * @param ipl Previous interrupt priority level.
    135  *
    136  */
    137 void tlb_shootdown_finalize(ipl_t ipl)
     128/** Finish TLB shootdown sequence. */
     129void tlb_shootdown_finalize(void)
    138130{
    139         irq_spinlock_unlock(&tlblock, false);
    140         CPU->tlb_active = true;
    141         interrupts_restore(ipl);
     131        spinlock_unlock(&tlblock);
     132        CPU->tlb_active = 1;
    142133}
    143134
     
    147138}
    148139
    149 /** Receive TLB shootdown message.
    150  *
    151  */
     140/** Receive TLB shootdown message. */
    152141void tlb_shootdown_ipi_recv(void)
    153142{
     143        tlb_invalidate_type_t type;
     144        asid_t asid;
     145        uintptr_t page;
     146        size_t count;
     147        unsigned int i;
     148       
    154149        ASSERT(CPU);
    155150       
    156         CPU->tlb_active = false;
    157         irq_spinlock_lock(&tlblock, false);
    158         irq_spinlock_unlock(&tlblock, false);
     151        CPU->tlb_active = 0;
     152        spinlock_lock(&tlblock);
     153        spinlock_unlock(&tlblock);
    159154       
    160         irq_spinlock_lock(&CPU->lock, false);
     155        spinlock_lock(&CPU->lock);
    161156        ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN);
    162        
    163         size_t i;
     157
    164158        for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
    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                
     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
    170164                switch (type) {
    171165                case TLB_INVL_ALL:
     
    176170                        break;
    177171                case TLB_INVL_PAGES:
    178                         ASSERT(count);
     172                        ASSERT(count);
    179173                        tlb_invalidate_pages(asid, page, count);
    180174                        break;
     
    183177                        break;
    184178                }
    185                
    186179                if (type == TLB_INVL_ALL)
    187180                        break;
    188181        }
    189182       
    190         irq_spinlock_unlock(&CPU->lock, false);
    191         CPU->tlb_active = true;
     183        spinlock_unlock(&CPU->lock);
     184        CPU->tlb_active = 1;
    192185}
    193186
Note: See TracChangeset for help on using the changeset viewer.