Changes in kernel/generic/src/mm/tlb.c [98000fb:49eb681] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/tlb.c
r98000fb r49eb681 33 33 /** 34 34 * @file 35 * @brief 35 * @brief Generic TLB shootdown algorithm. 36 36 * 37 37 * The algorithm implemented here is based on the CMU TLB shootdown … … 53 53 #include <cpu.h> 54 54 55 /**56 * This lock is used for synchronisation between sender and57 * recipients of TLB shootdown message. It must be acquired58 * before CPU structure lock.59 */60 SPINLOCK_INITIALIZE(tlblock);61 62 55 void tlb_init(void) 63 56 { … … 67 60 #ifdef CONFIG_SMP 68 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 */ 68 IRQ_SPINLOCK_STATIC_INITIALIZE(tlblock); 69 69 70 /** Send TLB shootdown message. 70 71 * … … 72 73 * to all other processors. 73 74 * 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. 75 79 * 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 * 80 82 */ 81 voidtlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,83 ipl_t tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, 82 84 uintptr_t page, size_t count) 83 85 { 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); 88 89 90 size_t i; 89 91 for (i = 0; i < config.cpu_count; i++) { 90 cpu_t *cpu;91 92 92 if (i == CPU->id) 93 93 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); 97 98 if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) { 98 99 /* … … 115 116 cpu->tlb_messages[idx].count = count; 116 117 } 117 spinlock_unlock(&cpu->lock);118 irq_spinlock_unlock(&cpu->lock, false); 118 119 } 119 120 120 121 tlb_shootdown_ipi_send(); 121 122 busy_wait: 123 for (i = 0; i < config.cpu_count; i++) 122 123 busy_wait: 124 for (i = 0; i < config.cpu_count; i++) { 124 125 if (cpus[i].tlb_active) 125 126 goto busy_wait; 127 } 128 129 return ipl; 126 130 } 127 131 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 */ 137 void tlb_shootdown_finalize(ipl_t ipl) 130 138 { 131 spinlock_unlock(&tlblock); 132 CPU->tlb_active = 1; 139 irq_spinlock_unlock(&tlblock, false); 140 CPU->tlb_active = true; 141 interrupts_restore(ipl); 133 142 } 134 143 … … 138 147 } 139 148 140 /** Receive TLB shootdown message. */ 149 /** Receive TLB shootdown message. 150 * 151 */ 141 152 void tlb_shootdown_ipi_recv(void) 142 153 { 143 tlb_invalidate_type_t type;144 asid_t asid;145 uintptr_t page;146 size_t count;147 unsigned int i;148 149 154 ASSERT(CPU); 150 155 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); 154 159 155 spinlock_lock(&CPU->lock);160 irq_spinlock_lock(&CPU->lock, false); 156 161 ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN); 157 162 163 size_t i; 158 164 for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) { 159 t ype = 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 164 170 switch (type) { 165 171 case TLB_INVL_ALL: … … 170 176 break; 171 177 case TLB_INVL_PAGES: 172 178 ASSERT(count); 173 179 tlb_invalidate_pages(asid, page, count); 174 180 break; … … 177 183 break; 178 184 } 185 179 186 if (type == TLB_INVL_ALL) 180 187 break; 181 188 } 182 189 183 spinlock_unlock(&CPU->lock);184 CPU->tlb_active = 1;190 irq_spinlock_unlock(&CPU->lock, false); 191 CPU->tlb_active = true; 185 192 } 186 193
Note:
See TracChangeset
for help on using the changeset viewer.