diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index be81f97847d..b1ce9526d4c 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -1276,6 +1276,33 @@ lim_freen(struct plimit *limp, int n) free((void *)limp, M_PLIMIT); } +void +limbatch_add(struct limbatch *lb, struct thread *td) +{ + struct plimit *limp; + + MPASS(td->td_limit != NULL); + limp = td->td_limit; + + if (lb->limp != limp) { + if (lb->count != 0) { + lim_freen(lb->limp, lb->count); + lb->count = 0; + } + lb->limp = limp; + } + + lb->count++; +} + +void +limbatch_final(struct limbatch *lb) +{ + + MPASS(lb->count != 0); + lim_freen(lb->limp, lb->count); +} + /* * Make a copy of the plimit structure. * We share these structures copy-on-write after fork. diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index b62bfafa58b..585531d3ab3 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -588,9 +588,8 @@ thread_reap_domain(struct thread_domain_data *tdd) struct thread *itd, *ntd; struct tidbatch tidbatch; struct credbatch credbatch; + struct limbatch limbatch; int tdcount; - struct plimit *lim; - int limcount; /* * Reading upfront is pessimal if followed by concurrent atomic_swap, @@ -612,42 +611,37 @@ thread_reap_domain(struct thread_domain_data *tdd) tidbatch_prep(&tidbatch); credbatch_prep(&credbatch); + limbatch_prep(&limbatch); tdcount = 0; - lim = NULL; - limcount = 0; while (itd != NULL) { ntd = itd->td_zombie; EVENTHANDLER_DIRECT_INVOKE(thread_dtor, itd); + tidbatch_add(&tidbatch, itd); credbatch_add(&credbatch, itd); - MPASS(itd->td_limit != NULL); - if (lim != itd->td_limit) { - if (limcount != 0) { - lim_freen(lim, limcount); - limcount = 0; - } - } - lim = itd->td_limit; - limcount++; + limbatch_add(&limbatch, itd); + thread_free_batched(itd); + tidbatch_process(&tidbatch); credbatch_process(&credbatch); + limbatch_process(&limbatch); tdcount++; if (tdcount == 32) { thread_count_sub(tdcount); tdcount = 0; } + itd = ntd; } tidbatch_final(&tidbatch); credbatch_final(&credbatch); + limbatch_final(&limbatch); if (tdcount != 0) { thread_count_sub(tdcount); } - MPASS(limcount != 0); - lim_freen(lim, limcount); } /* diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h index bd57211c75f..8b88c9321e7 100644 --- a/sys/sys/resourcevar.h +++ b/sys/sys/resourcevar.h @@ -82,6 +82,28 @@ struct plimit { int pl_refcnt; /* number of references */ }; +struct limbatch { + struct plimit *limp; + int count; +}; + +static inline void +limbatch_prep(struct limbatch *lb) +{ + lb->limp = NULL; + lb->count = 0; +} + +void limbatch_add(struct limbatch *lb, struct thread *td); + +static inline void +limbatch_process(struct limbatch *lb __unused) +{ + +} + +void limbatch_final(struct limbatch *lb); + struct racct; /*-