Author: mjg
Date: Wed Feb 12 11:16:55 2020
New Revision: 357808
URL: https://svnweb.freebsd.org/changeset/base/357808

Log:
  Add smp_rendezvous_cpus_retry
  
  This is a wrapper around smp_rendezvous_cpus which enables use of IPI
  handlers which can fail and require retrying.
  
  wait_func argument is added to to provide a routine which can be used to
  poll CPU of interest for when the IPI can be retried.
  
  Handlers which succeed must call smp_rendezvous_cpus_done to denote that
  fact.
  
  Discussed with:        jeff
  Differential Revision:        https://reviews.freebsd.org/D23582

Modified:
  head/sys/kern/subr_smp.c
  head/sys/sys/smp.h

Modified: head/sys/kern/subr_smp.c
==============================================================================
--- head/sys/kern/subr_smp.c    Wed Feb 12 11:15:33 2020        (r357807)
+++ head/sys/kern/subr_smp.c    Wed Feb 12 11:16:55 2020        (r357808)
@@ -884,6 +884,47 @@ smp_no_rendezvous_barrier(void *dummy)
 #endif
 }
 
+void
+smp_rendezvous_cpus_retry(cpuset_t map,
+       void (* setup_func)(void *),
+       void (* action_func)(void *),
+       void (* teardown_func)(void *),
+       void (* wait_func)(void *, int),
+       struct smp_rendezvous_cpus_retry_arg *arg)
+{
+       int cpu;
+
+       /*
+        * Execute an action on all specified CPUs while retrying until they
+        * all acknowledge completion.
+        */
+       CPU_COPY(&map, &arg->cpus);
+       for (;;) {
+               smp_rendezvous_cpus(
+                   arg->cpus,
+                   setup_func,
+                   action_func,
+                   teardown_func,
+                   arg);
+
+               if (CPU_EMPTY(&arg->cpus))
+                       break;
+
+               CPU_FOREACH(cpu) {
+                       if (!CPU_ISSET(cpu, &arg->cpus))
+                               continue;
+                       wait_func(arg, cpu);
+               }
+       }
+}
+
+void
+smp_rendezvous_cpus_done(struct smp_rendezvous_cpus_retry_arg *arg)
+{
+
+       CPU_CLR_ATOMIC(curcpu, &arg->cpus);
+}
+
 /*
  * Wait for specified idle threads to switch once.  This ensures that even
  * preempted threads have cycled through the switch function once,

Modified: head/sys/sys/smp.h
==============================================================================
--- head/sys/sys/smp.h  Wed Feb 12 11:15:33 2020        (r357807)
+++ head/sys/sys/smp.h  Wed Feb 12 11:16:55 2020        (r357808)
@@ -276,6 +276,19 @@ void       smp_rendezvous_cpus(cpuset_t,
                       void (*)(void *),
                       void (*)(void *),
                       void *arg);
+
+struct smp_rendezvous_cpus_retry_arg {
+       cpuset_t cpus;
+};
+void   smp_rendezvous_cpus_retry(cpuset_t,
+                      void (*)(void *),
+                      void (*)(void *),
+                      void (*)(void *),
+                      void (*)(void *, int),
+                      struct smp_rendezvous_cpus_retry_arg *);
+
+void   smp_rendezvous_cpus_done(struct smp_rendezvous_cpus_retry_arg *);
+
 #endif /* !LOCORE */
 #endif /* _KERNEL */
 #endif /* _SYS_SMP_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to