Changes in kernel/generic/src/mm/tlb.c [49eb681:98000fb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/tlb.c
r49eb681 r98000fb 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 and 57 * recipients of TLB shootdown message. It must be acquired 58 * before CPU structure lock. 59 */ 60 SPINLOCK_INITIALIZE(tlblock); 61 55 62 void tlb_init(void) 56 63 { … … 60 67 #ifdef CONFIG_SMP 61 68 62 /**63 * This lock is used for synchronisation between sender and64 * recipients of TLB shootdown message. It must be acquired65 * before CPU structure lock.66 *67 */68 IRQ_SPINLOCK_STATIC_INITIALIZE(tlblock);69 70 69 /** Send TLB shootdown message. 71 70 * … … 73 72 * to all other processors. 74 73 * 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. 78 79 * @param count Number of pages, if required by type. 79 *80 * @return The interrupt priority level as it existed prior to this call.81 *82 80 */ 83 ipl_ttlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,81 void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid, 84 82 uintptr_t page, size_t count) 85 83 { 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); 89 88 90 size_t i;91 89 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_t *cpu = &cpus[i]; 96 97 irq_spinlock_lock(&cpu->lock, false); 94 95 cpu = &cpus[i]; 96 spinlock_lock(&cpu->lock); 98 97 if (cpu->tlb_messages_count == TLB_MESSAGE_QUEUE_LEN) { 99 98 /* … … 116 115 cpu->tlb_messages[idx].count = count; 117 116 } 118 irq_spinlock_unlock(&cpu->lock, false);117 spinlock_unlock(&cpu->lock); 119 118 } 120 119 121 120 tlb_shootdown_ipi_send(); 122 123 busy_wait: 124 for (i = 0; i < config.cpu_count; i++) {121 122 busy_wait: 123 for (i = 0; i < config.cpu_count; i++) 125 124 if (cpus[i].tlb_active) 126 125 goto busy_wait; 127 }128 129 return ipl;130 126 } 131 127 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. */ 129 void tlb_shootdown_finalize(void) 138 130 { 139 irq_spinlock_unlock(&tlblock, false); 140 CPU->tlb_active = true; 141 interrupts_restore(ipl); 131 spinlock_unlock(&tlblock); 132 CPU->tlb_active = 1; 142 133 } 143 134 … … 147 138 } 148 139 149 /** Receive TLB shootdown message. 150 * 151 */ 140 /** Receive TLB shootdown message. */ 152 141 void tlb_shootdown_ipi_recv(void) 153 142 { 143 tlb_invalidate_type_t type; 144 asid_t asid; 145 uintptr_t page; 146 size_t count; 147 unsigned int i; 148 154 149 ASSERT(CPU); 155 150 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); 159 154 160 irq_spinlock_lock(&CPU->lock, false);155 spinlock_lock(&CPU->lock); 161 156 ASSERT(CPU->tlb_messages_count <= TLB_MESSAGE_QUEUE_LEN); 162 163 size_t i; 157 164 158 for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) { 165 t lb_invalidate_type_t type = CPU->tlb_messages[i].type;166 asid _t asid= CPU->tlb_messages[i].asid;167 uintptr_tpage = CPU->tlb_messages[i].page;168 size_tcount = 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 170 164 switch (type) { 171 165 case TLB_INVL_ALL: … … 176 170 break; 177 171 case TLB_INVL_PAGES: 178 ASSERT(count);172 ASSERT(count); 179 173 tlb_invalidate_pages(asid, page, count); 180 174 break; … … 183 177 break; 184 178 } 185 186 179 if (type == TLB_INVL_ALL) 187 180 break; 188 181 } 189 182 190 irq_spinlock_unlock(&CPU->lock, false);191 CPU->tlb_active = true;183 spinlock_unlock(&CPU->lock); 184 CPU->tlb_active = 1; 192 185 } 193 186
Note:
See TracChangeset
for help on using the changeset viewer.