The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=3a68546d2377d6e9776060043372d66f07022543
commit 3a68546d2377d6e9776060043372d66f07022543 Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2021-05-28 17:10:47 +0000 Commit: Konstantin Belousov <k...@freebsd.org> CommitDate: 2021-05-31 15:09:22 +0000 quisce_cpus(): add special handling for PDROP Currently passing PDROP to the quisce_cpus() function does not make sense. Add special meaning for it, by not waiting for the idle thread to schedule. Also avoid allocating u_int[MAXCPU] on the stack. Reviewed by: hselasky, markj Sponsored by: Mellanox Technologies/NVidia Networking MFC after: 1 week Differential revision: https://reviews.freebsd.org/D30468 --- sys/kern/subr_smp.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index d4f8aac9e751..935fb6ee977c 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -943,25 +943,31 @@ smp_rendezvous_cpus_done(struct smp_rendezvous_cpus_retry_arg *arg) } /* + * If (prio & PDROP) == 0: * Wait for specified idle threads to switch once. This ensures that even * preempted threads have cycled through the switch function once, * exiting their codepaths. This allows us to change global pointers * with no other synchronization. + * If (prio & PDROP) != 0: + * Force the specified CPUs to switch context at least once. */ int quiesce_cpus(cpuset_t map, const char *wmesg, int prio) { struct pcpu *pcpu; - u_int gen[MAXCPU]; + u_int *gen; int error; int cpu; error = 0; - for (cpu = 0; cpu <= mp_maxid; cpu++) { - if (!CPU_ISSET(cpu, &map) || CPU_ABSENT(cpu)) - continue; - pcpu = pcpu_find(cpu); - gen[cpu] = pcpu->pc_idlethread->td_generation; + if ((prio & PDROP) == 0) { + gen = malloc(sizeof(u_int) * MAXCPU, M_TEMP, M_WAITOK); + for (cpu = 0; cpu <= mp_maxid; cpu++) { + if (!CPU_ISSET(cpu, &map) || CPU_ABSENT(cpu)) + continue; + pcpu = pcpu_find(cpu); + gen[cpu] = pcpu->pc_idlethread->td_generation; + } } for (cpu = 0; cpu <= mp_maxid; cpu++) { if (!CPU_ISSET(cpu, &map) || CPU_ABSENT(cpu)) @@ -970,8 +976,10 @@ quiesce_cpus(cpuset_t map, const char *wmesg, int prio) thread_lock(curthread); sched_bind(curthread, cpu); thread_unlock(curthread); + if ((prio & PDROP) != 0) + continue; while (gen[cpu] == pcpu->pc_idlethread->td_generation) { - error = tsleep(quiesce_cpus, prio, wmesg, 1); + error = tsleep(quiesce_cpus, prio & ~PDROP, wmesg, 1); if (error != EWOULDBLOCK) goto out; error = 0; @@ -981,6 +989,8 @@ out: thread_lock(curthread); sched_unbind(curthread); thread_unlock(curthread); + if ((prio & PDROP) == 0) + free(gen, M_TEMP); return (error); } _______________________________________________ dev-commits-src-main@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"