| 1271 | } |
| 1272 | |
| 1273 | void |
| 1274 | ipi_bitmap_handler(struct trapframe frame) |
| 1275 | { |
| 1276 | struct trapframe *oldframe; |
| 1277 | struct thread *td; |
| 1278 | int cpu = PCPU_GET(cpuid); |
| 1279 | u_int ipi_bitmap; |
| 1280 | |
| 1281 | td = curthread; |
| 1282 | ipi_bitmap = atomic_readandclear_int(&cpuid_to_pcpu[cpu]-> |
| 1283 | pc_ipi_bitmap); |
| 1284 | |
| 1285 | /* |
| 1286 | * sched_preempt() must be called to clear the pending preempt |
| 1287 | * IPI to enable delivery of further preempts. However, the |
| 1288 | * critical section will cause extra scheduler lock thrashing |
| 1289 | * when used unconditionally. Only critical_enter() if |
| 1290 | * hardclock must also run, which requires the section entry. |
| 1291 | */ |
| 1292 | if (ipi_bitmap & (1 << IPI_HARDCLOCK)) |
| 1293 | critical_enter(); |
| 1294 | |
| 1295 | td->td_intr_nesting_level++; |
| 1296 | oldframe = td->td_intr_frame; |
| 1297 | td->td_intr_frame = &frame; |
| 1298 | #if defined(STACK) || defined(DDB) |
| 1299 | if (ipi_bitmap & (1 << IPI_TRACE)) |
| 1300 | stack_capture_intr(); |
| 1301 | #endif |
| 1302 | if (ipi_bitmap & (1 << IPI_PREEMPT)) { |
| 1303 | #ifdef COUNT_IPIS |
| 1304 | (*ipi_preempt_counts[cpu])++; |
| 1305 | #endif |
| 1306 | sched_preempt(td); |
| 1307 | } |
| 1308 | if (ipi_bitmap & (1 << IPI_AST)) { |
| 1309 | #ifdef COUNT_IPIS |
| 1310 | (*ipi_ast_counts[cpu])++; |
| 1311 | #endif |
| 1312 | /* Nothing to do for AST */ |
| 1313 | } |
| 1314 | if (ipi_bitmap & (1 << IPI_HARDCLOCK)) { |
| 1315 | #ifdef COUNT_IPIS |
| 1316 | (*ipi_hardclock_counts[cpu])++; |
| 1317 | #endif |
| 1318 | hardclockintr(); |
| 1319 | } |
| 1320 | td->td_intr_frame = oldframe; |
| 1321 | td->td_intr_nesting_level--; |
| 1322 | if (ipi_bitmap & (1 << IPI_HARDCLOCK)) |
| 1323 | critical_exit(); |
| 1324 | } |
| 1325 | |
| 1326 | /* |
| 1327 | * send an IPI to a set of cpus. |
no test coverage detected