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