Author: trasz
Date: Sun Nov 15 12:10:51 2015
New Revision: 290857
URL: https://svnweb.freebsd.org/changeset/base/290857
Log:
Speed up rctl operation with large rulesets, by holding the lock
during iteration instead of relocking it for each traversed rule.
Reviewed by: mjg@
MFC after:1 month
Sponsored by: The FreeBSD Foundation
Differential Revision:https://reviews.freebsd.org/D4110
Modified:
head/sys/kern/kern_jail.c
head/sys/kern/kern_loginclass.c
head/sys/kern/kern_racct.c
head/sys/kern/kern_rctl.c
head/sys/kern/kern_resource.c
Modified: head/sys/kern/kern_jail.c
==
--- head/sys/kern/kern_jail.c Sun Nov 15 11:18:37 2015(r290856)
+++ head/sys/kern/kern_jail.c Sun Nov 15 12:10:51 2015(r290857)
@@ -4480,15 +4480,20 @@ SYSCTL_JAIL_PARAM(_allow_mount, zfs, CTL
#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(_lock);
+ if (pre != NULL)
+ (pre)();
LIST_FOREACH(prr, _racct, prr_next)
(callback)(prr->prr_racct, arg2, arg3);
+ if (post != NULL)
+ (post)();
sx_sunlock(_lock);
}
Modified: head/sys/kern/kern_loginclass.c
==
--- head/sys/kern/kern_loginclass.c Sun Nov 15 11:18:37 2015
(r290856)
+++ head/sys/kern/kern_loginclass.c Sun Nov 15 12:10:51 2015
(r290857)
@@ -234,12 +234,17 @@ sys_setloginclass(struct thread *td, str
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(_lock);
+ if (pre != NULL)
+ (pre)();
LIST_FOREACH(lc, , lc_next)
(callback)(lc->lc_racct, arg2, arg3);
+ if (post != NULL)
+ (post)();
rw_runlock(_lock);
}
Modified: head/sys/kern/kern_racct.c
==
--- head/sys/kern/kern_racct.c Sun Nov 15 11:18:37 2015(r290856)
+++ head/sys/kern/kern_racct.c Sun Nov 15 12:10:51 2015(r290857)
@@ -1156,6 +1156,7 @@ racct_decay_resource(struct racct *racct
int64_t r_old, r_new;
ASSERT_RACCT_ENABLED();
+ mtx_assert(_lock, MA_OWNED);
resource = *(int *)res;
r_old = racct->r_resources[resource];
@@ -1164,9 +1165,21 @@ racct_decay_resource(struct racct *racct
if (r_old <= 0)
return;
- mtx_lock(_lock);
r_new = r_old * RACCT_DECAY_FACTOR / FSCALE;
racct->r_resources[resource] = r_new;
+}
+
+static void
+racct_decay_pre(void)
+{
+
+ mtx_lock(_lock);
+}
+
+static void
+racct_decay_post(void)
+{
+
mtx_unlock(_lock);
}
@@ -1176,9 +1189,12 @@ racct_decay(int resource)
ASSERT_RACCT_ENABLED();
- ui_racct_foreach(racct_decay_resource, , NULL);
- loginclass_racct_foreach(racct_decay_resource, , NULL);
- prison_racct_foreach(racct_decay_resource, , NULL);
+ ui_racct_foreach(racct_decay_resource, racct_decay_pre,
+ racct_decay_post, , NULL);
+ loginclass_racct_foreach(racct_decay_resource, racct_decay_pre,
+ racct_decay_post, , NULL);
+ prison_racct_foreach(racct_decay_resource, racct_decay_pre,
+ racct_decay_post, , NULL);
}
static void
Modified: head/sys/kern/kern_rctl.c
==
--- head/sys/kern/kern_rctl.c Sun Nov 15 11:18:37 2015(r290856)
+++ head/sys/kern/kern_rctl.c Sun Nov 15 12:10:51 2015(r290857)
@@ -1150,16 +1150,29 @@ rctl_rule_add(struct rctl_rule *rule)
}
static void
+rctl_rule_pre_callback(void)
+{
+
+ rw_wlock(_lock);
+}
+
+static void
+rctl_rule_post_callback(void)
+{
+
+ rw_wunlock(_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(_lock, RA_WLOCKED);
- rw_wlock(_lock);
found += rctl_racct_remove_rules(racct, filter);
- rw_wunlock(_lock);
*((int *)arg3) += found;
}
@@ -1186,12 +1199,15 @@ rctl_rule_remove(struct rctl_rule *filte
return (ESRCH);
}
- loginclass_racct_foreach(rctl_rule_remove_callback, filter,
- (void *));
- ui_racct_foreach(rctl_rule_remove_callback, filter,
- (void *));
-