* Notify a remote cpu of new work. Sends an IPI if criteria are met. */
| 1065 | * Notify a remote cpu of new work. Sends an IPI if criteria are met. |
| 1066 | */ |
| 1067 | static void |
| 1068 | tdq_notify(struct tdq *tdq, struct thread *td) |
| 1069 | { |
| 1070 | struct thread *ctd; |
| 1071 | int pri; |
| 1072 | int cpu; |
| 1073 | |
| 1074 | if (tdq->tdq_owepreempt) |
| 1075 | return; |
| 1076 | cpu = td_get_sched(td)->ts_cpu; |
| 1077 | pri = td->td_priority; |
| 1078 | ctd = pcpu_find(cpu)->pc_curthread; |
| 1079 | if (!sched_shouldpreempt(pri, ctd->td_priority, 1)) |
| 1080 | return; |
| 1081 | |
| 1082 | /* |
| 1083 | * Make sure that our caller's earlier update to tdq_load is |
| 1084 | * globally visible before we read tdq_cpu_idle. Idle thread |
| 1085 | * accesses both of them without locks, and the order is important. |
| 1086 | */ |
| 1087 | atomic_thread_fence_seq_cst(); |
| 1088 | |
| 1089 | if (TD_IS_IDLETHREAD(ctd)) { |
| 1090 | /* |
| 1091 | * If the MD code has an idle wakeup routine try that before |
| 1092 | * falling back to IPI. |
| 1093 | */ |
| 1094 | if (!tdq->tdq_cpu_idle || cpu_idle_wakeup(cpu)) |
| 1095 | return; |
| 1096 | } |
| 1097 | |
| 1098 | /* |
| 1099 | * The run queues have been updated, so any switch on the remote CPU |
| 1100 | * will satisfy the preemption request. |
| 1101 | */ |
| 1102 | tdq->tdq_owepreempt = 1; |
| 1103 | ipi_cpu(cpu, IPI_PREEMPT); |
| 1104 | } |
| 1105 | |
| 1106 | /* |
| 1107 | * Steals load from a timeshare queue. Honors the rotating queue head |
no test coverage detected