262 kmem_free(msg, sizeof (*msg));
263 }
264 }
265
266 #define XC_FLUSH_MAX_WAITS 1000
267
268 /* Flush inflight message buffers. */
269 int
270 xc_flush_cpu(struct cpu *cpup)
271 {
272 int i;
273
274 ASSERT((cpup->cpu_flags & CPU_READY) == 0);
275
276 /*
277 * Pause all working CPUs, which ensures that there's no CPU in
278 * function xc_common().
279 * This is used to work around a race condition window in xc_common()
280 * between checking CPU_READY flag and increasing working item count.
281 */
282 pause_cpus(cpup);
283 start_cpus();
284
285 for (i = 0; i < XC_FLUSH_MAX_WAITS; i++) {
286 if (cpup->cpu_m.xc_work_cnt == 0) {
287 break;
288 }
289 DELAY(1);
290 }
291 for (; i < XC_FLUSH_MAX_WAITS; i++) {
292 if (!BT_TEST(xc_priority_set, cpup->cpu_id)) {
293 break;
294 }
295 DELAY(1);
296 }
297
298 return (i >= XC_FLUSH_MAX_WAITS ? ETIME : 0);
299 }
300
301 /*
302 * X-call message processing routine. Note that this is used by both
|
262 kmem_free(msg, sizeof (*msg));
263 }
264 }
265
266 #define XC_FLUSH_MAX_WAITS 1000
267
268 /* Flush inflight message buffers. */
269 int
270 xc_flush_cpu(struct cpu *cpup)
271 {
272 int i;
273
274 ASSERT((cpup->cpu_flags & CPU_READY) == 0);
275
276 /*
277 * Pause all working CPUs, which ensures that there's no CPU in
278 * function xc_common().
279 * This is used to work around a race condition window in xc_common()
280 * between checking CPU_READY flag and increasing working item count.
281 */
282 pause_cpus(cpup, NULL);
283 start_cpus();
284
285 for (i = 0; i < XC_FLUSH_MAX_WAITS; i++) {
286 if (cpup->cpu_m.xc_work_cnt == 0) {
287 break;
288 }
289 DELAY(1);
290 }
291 for (; i < XC_FLUSH_MAX_WAITS; i++) {
292 if (!BT_TEST(xc_priority_set, cpup->cpu_id)) {
293 break;
294 }
295 DELAY(1);
296 }
297
298 return (i >= XC_FLUSH_MAX_WAITS ? ETIME : 0);
299 }
300
301 /*
302 * X-call message processing routine. Note that this is used by both
|