Index: sys/kern/kern_jail.c =================================================================== --- sys/kern/kern_jail.c +++ sys/kern/kern_jail.c @@ -4480,15 +4480,20 @@ #ifdef RACCT void prison_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3) + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3) { struct prison_racct *prr; ASSERT_RACCT_ENABLED(); sx_slock(&allprison_lock); + if (pre != NULL) + (pre)(); LIST_FOREACH(prr, &allprison_racct, prr_next) (callback)(prr->prr_racct, arg2, arg3); + if (post != NULL) + (post)(); sx_sunlock(&allprison_lock); } Index: sys/kern/kern_loginclass.c =================================================================== --- sys/kern/kern_loginclass.c +++ sys/kern/kern_loginclass.c @@ -234,12 +234,17 @@ void loginclass_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3) + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3) { struct loginclass *lc; rw_rlock(&loginclasses_lock); + if (pre != NULL) + (pre)(); LIST_FOREACH(lc, &loginclasses, lc_next) (callback)(lc->lc_racct, arg2, arg3); + if (post != NULL) + (post)(); rw_runlock(&loginclasses_lock); } Index: sys/kern/kern_racct.c =================================================================== --- sys/kern/kern_racct.c +++ sys/kern/kern_racct.c @@ -1156,6 +1156,7 @@ int64_t r_old, r_new; ASSERT_RACCT_ENABLED(); + mtx_assert(&racct_lock, MA_OWNED); resource = *(int *)res; r_old = racct->r_resources[resource]; @@ -1164,9 +1165,21 @@ if (r_old <= 0) return; - mtx_lock(&racct_lock); r_new = r_old * RACCT_DECAY_FACTOR / FSCALE; racct->r_resources[resource] = r_new; +} + +static void +racct_decay_pre(void) +{ + + mtx_lock(&racct_lock); +} + +static void +racct_decay_post(void) +{ + mtx_unlock(&racct_lock); } @@ -1176,9 +1189,12 @@ ASSERT_RACCT_ENABLED(); - ui_racct_foreach(racct_decay_resource, &resource, NULL); - loginclass_racct_foreach(racct_decay_resource, &resource, NULL); - prison_racct_foreach(racct_decay_resource, &resource, NULL); + ui_racct_foreach(racct_decay_resource, racct_decay_pre, + racct_decay_post, &resource, NULL); + loginclass_racct_foreach(racct_decay_resource, racct_decay_pre, + racct_decay_post, &resource, NULL); + prison_racct_foreach(racct_decay_resource, racct_decay_pre, + racct_decay_post, &resource, NULL); } static void Index: sys/kern/kern_rctl.c =================================================================== --- sys/kern/kern_rctl.c +++ sys/kern/kern_rctl.c @@ -1150,16 +1150,29 @@ } static void +rctl_rule_pre_callback(void) +{ + + rw_wlock(&rctl_lock); +} + +static void +rctl_rule_post_callback(void) +{ + + rw_wunlock(&rctl_lock); +} + +static void rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3) { struct rctl_rule *filter = (struct rctl_rule *)arg2; int found = 0; ASSERT_RACCT_ENABLED(); + rw_assert(&rctl_lock, RA_WLOCKED); - rw_wlock(&rctl_lock); found += rctl_racct_remove_rules(racct, filter); - rw_wunlock(&rctl_lock); *((int *)arg3) += found; } @@ -1186,12 +1199,15 @@ return (ESRCH); } - loginclass_racct_foreach(rctl_rule_remove_callback, filter, - (void *)&found); - ui_racct_foreach(rctl_rule_remove_callback, filter, - (void *)&found); - prison_racct_foreach(rctl_rule_remove_callback, filter, - (void *)&found); + loginclass_racct_foreach(rctl_rule_remove_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, (void *)&found); + ui_racct_foreach(rctl_rule_remove_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, (void *)&found); + prison_racct_foreach(rctl_rule_remove_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, (void *)&found); sx_assert(&allproc_lock, SA_LOCKED); rw_wlock(&rctl_lock); @@ -1425,15 +1441,14 @@ struct sbuf *sb = (struct sbuf *)arg3; ASSERT_RACCT_ENABLED(); + rw_assert(&rctl_lock, RA_LOCKED); - rw_rlock(&rctl_lock); LIST_FOREACH(link, &racct->r_rule_links, rrl_next) { if (!rctl_rule_matches(link->rrl_rule, filter)) continue; rctl_rule_to_sbuf(sb, link->rrl_rule); sbuf_printf(sb, ","); } - rw_runlock(&rctl_lock); } int @@ -1494,9 +1509,15 @@ rw_runlock(&rctl_lock); } - loginclass_racct_foreach(rctl_get_rules_callback, filter, sb); - ui_racct_foreach(rctl_get_rules_callback, filter, sb); - prison_racct_foreach(rctl_get_rules_callback, filter, sb); + loginclass_racct_foreach(rctl_get_rules_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, sb); + ui_racct_foreach(rctl_get_rules_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, sb); + prison_racct_foreach(rctl_get_rules_callback, + rctl_rule_pre_callback, rctl_rule_post_callback, + filter, sb); if (sbuf_error(sb) == ENOMEM) { error = ERANGE; goto out; Index: sys/kern/kern_resource.c =================================================================== --- sys/kern/kern_resource.c +++ sys/kern/kern_resource.c @@ -1356,17 +1356,22 @@ #ifdef RACCT void ui_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3) + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3) { struct uidinfo *uip; struct uihashhead *uih; rw_rlock(&uihashtbl_lock); + if (pre != NULL) + (pre)(); for (uih = &uihashtbl[uihash]; uih >= uihashtbl; uih--) { LIST_FOREACH(uip, uih, ui_hash) { (callback)(uip->ui_racct, arg2, arg3); } } + if (post != NULL) + (post)(); rw_runlock(&uihashtbl_lock); } #endif Index: sys/sys/jail.h =================================================================== --- sys/sys/jail.h +++ sys/sys/jail.h @@ -405,7 +405,8 @@ int prison_priv_check(struct ucred *cred, int priv); int sysctl_jail_param(SYSCTL_HANDLER_ARGS); void prison_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3); + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3); struct prison_racct *prison_racct_find(const char *name); void prison_racct_hold(struct prison_racct *prr); void prison_racct_free(struct prison_racct *prr); Index: sys/sys/loginclass.h =================================================================== --- sys/sys/loginclass.h +++ sys/sys/loginclass.h @@ -48,6 +48,7 @@ void loginclass_free(struct loginclass *lc); struct loginclass *loginclass_find(const char *name); void loginclass_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3); + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3); #endif /* !_SYS_LOGINCLASS_H_ */ Index: sys/sys/resourcevar.h =================================================================== --- sys/sys/resourcevar.h +++ sys/sys/resourcevar.h @@ -156,7 +156,8 @@ void uihold(struct uidinfo *uip); #ifdef RACCT void ui_racct_foreach(void (*callback)(struct racct *racct, - void *arg2, void *arg3), void *arg2, void *arg3); + void *arg2, void *arg3), void (*pre)(void), void (*post)(void), + void *arg2, void *arg3); #endif #endif /* _KERNEL */