@@ -365,6 +365,12 @@ fn send_ipi(target_set: IpiTarget<'_>, ipi_helper: &mut dyn IpiHelper) {
365365 let mut interrupt_target = target_set;
366366 let mut interrupt_set: MaybeUninit < CpuSet > = MaybeUninit :: uninit ( ) ;
367367
368+ // There should be no pending activity for the current IPI board. This is
369+ // a debug assert because it does not affect safety, and it should normally
370+ // be guaranteed by the design of the IPI logic without depending on the
371+ // behavior of any routine that invokes the IPI logic.
372+ debug_assert_eq ! ( ipi_board. pending. load( Ordering :: Relaxed ) , 0 ) ;
373+
368374 // Enumerate all CPUs in the target set to advise that an IPI message has
369375 // been posted.
370376 let mut include_self = false ;
@@ -374,7 +380,7 @@ fn send_ipi(target_set: IpiTarget<'_>, ipi_helper: &mut dyn IpiHelper) {
374380 if cpu_index == sender_cpu_index {
375381 include_self = true ;
376382 } else {
377- ipi_board. pending . store ( 1 , Ordering :: Relaxed ) ;
383+ ipi_board. pending . fetch_add ( 1 , Ordering :: Relaxed ) ;
378384 // SAFETY: advertising an IPI message from this CPU is safe
379385 // because the IPI board is fully constructed.
380386 unsafe {
@@ -385,11 +391,12 @@ fn send_ipi(target_set: IpiTarget<'_>, ipi_helper: &mut dyn IpiHelper) {
385391 }
386392 }
387393 IpiTarget :: Multiple ( cpu_set) => {
394+ let mut target_count: usize = 0 ;
388395 for cpu_index in cpu_set. iter ( ) {
389396 if cpu_index == sender_cpu_index {
390397 include_self = true ;
391398 } else {
392- ipi_board . pending . fetch_add ( 1 , Ordering :: Relaxed ) ;
399+ target_count += 1 ;
393400 // SAFETY: advertising an IPI message from this CPU is safe
394401 // because the IPI board is fully constructed.
395402 unsafe {
@@ -398,6 +405,11 @@ fn send_ipi(target_set: IpiTarget<'_>, ipi_helper: &mut dyn IpiHelper) {
398405 send_interrupt = true ;
399406 }
400407 }
408+
409+ // Record the count of targets that will need to respond before
410+ // this IPI can complete.
411+ ipi_board. pending . fetch_add ( target_count, Ordering :: Relaxed ) ;
412+
401413 if include_self {
402414 // The CPU set used to send the interrupt must be modified to
403415 // remove the current CPU. This cannot be done in place,
@@ -425,7 +437,7 @@ fn send_ipi(target_set: IpiTarget<'_>, ipi_helper: &mut dyn IpiHelper) {
425437
426438 // Record the count of targets that will need to respond before
427439 // this IPI can complete.
428- ipi_board. pending . store ( target_count, Ordering :: Relaxed ) ;
440+ ipi_board. pending . fetch_add ( target_count, Ordering :: Relaxed ) ;
429441
430442 // Send an interrupt only if there are targets to receive it.
431443 send_interrupt = target_count != 0 ;
0 commit comments