Deleted Added
full compact
kern_rctl.c (298330) kern_rctl.c (298414)
1/*-
2 * Copyright (c) 2010 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 2010 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/kern/kern_rctl.c 298330 2016-04-20 02:09:38Z cem $
29 * $FreeBSD: head/sys/kern/kern_rctl.c 298414 2016-04-21 16:22:52Z trasz $
30 */
31
32#include <sys/cdefs.h>
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/kern/kern_rctl.c 298330 2016-04-20 02:09:38Z cem $");
33__FBSDID("$FreeBSD: head/sys/kern/kern_rctl.c 298414 2016-04-21 16:22:52Z trasz $");
34
35#include <sys/param.h>
36#include <sys/bus.h>
37#include <sys/malloc.h>
38#include <sys/queue.h>
39#include <sys/refcount.h>
40#include <sys/jail.h>
41#include <sys/kernel.h>

--- 165 unchanged lines hidden (view full) ---

207 { "throttle", RCTL_ACTION_THROTTLE },
208 { NULL, -1 }};
209
210static void rctl_init(void);
211SYSINIT(rctl, SI_SUB_RACCT, SI_ORDER_FIRST, rctl_init, NULL);
212
213static uma_zone_t rctl_rule_zone;
214static uma_zone_t rctl_rule_link_zone;
34
35#include <sys/param.h>
36#include <sys/bus.h>
37#include <sys/malloc.h>
38#include <sys/queue.h>
39#include <sys/refcount.h>
40#include <sys/jail.h>
41#include <sys/kernel.h>

--- 165 unchanged lines hidden (view full) ---

207 { "throttle", RCTL_ACTION_THROTTLE },
208 { NULL, -1 }};
209
210static void rctl_init(void);
211SYSINIT(rctl, SI_SUB_RACCT, SI_ORDER_FIRST, rctl_init, NULL);
212
213static uma_zone_t rctl_rule_zone;
214static uma_zone_t rctl_rule_link_zone;
215static struct rwlock rctl_lock;
216RW_SYSINIT(rctl_lock, &rctl_lock, "RCTL lock");
217
215
218#define RCTL_RLOCK() rw_rlock(&rctl_lock)
219#define RCTL_RUNLOCK() rw_runlock(&rctl_lock)
220#define RCTL_WLOCK() rw_wlock(&rctl_lock)
221#define RCTL_WUNLOCK() rw_wunlock(&rctl_lock)
222#define RCTL_LOCK_ASSERT() rw_assert(&rctl_lock, RA_LOCKED)
223#define RCTL_WLOCK_ASSERT() rw_assert(&rctl_lock, RA_WLOCKED)
224
225static int rctl_rule_fully_specified(const struct rctl_rule *rule);
226static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule);
227
228static MALLOC_DEFINE(M_RCTL, "rctl", "Resource Limits");
229
230static int rctl_throttle_min_sysctl(SYSCTL_HANDLER_ARGS)
231{
232 int error, val = rctl_throttle_min;
233
234 error = sysctl_handle_int(oidp, &val, 0, req);
235 if (error || !req->newptr)
236 return (error);
237 if (val < 1 || val > rctl_throttle_max)
238 return (EINVAL);
239
216static int rctl_rule_fully_specified(const struct rctl_rule *rule);
217static void rctl_rule_to_sbuf(struct sbuf *sb, const struct rctl_rule *rule);
218
219static MALLOC_DEFINE(M_RCTL, "rctl", "Resource Limits");
220
221static int rctl_throttle_min_sysctl(SYSCTL_HANDLER_ARGS)
222{
223 int error, val = rctl_throttle_min;
224
225 error = sysctl_handle_int(oidp, &val, 0, req);
226 if (error || !req->newptr)
227 return (error);
228 if (val < 1 || val > rctl_throttle_max)
229 return (EINVAL);
230
240 RCTL_WLOCK();
231 RACCT_LOCK();
241 rctl_throttle_min = val;
232 rctl_throttle_min = val;
242 RCTL_WUNLOCK();
233 RACCT_UNLOCK();
243
244 return (0);
245}
246
247static int rctl_throttle_max_sysctl(SYSCTL_HANDLER_ARGS)
248{
249 int error, val = rctl_throttle_max;
250
251 error = sysctl_handle_int(oidp, &val, 0, req);
252 if (error || !req->newptr)
253 return (error);
254 if (val < rctl_throttle_min)
255 return (EINVAL);
256
234
235 return (0);
236}
237
238static int rctl_throttle_max_sysctl(SYSCTL_HANDLER_ARGS)
239{
240 int error, val = rctl_throttle_max;
241
242 error = sysctl_handle_int(oidp, &val, 0, req);
243 if (error || !req->newptr)
244 return (error);
245 if (val < rctl_throttle_min)
246 return (EINVAL);
247
257 RCTL_WLOCK();
248 RACCT_LOCK();
258 rctl_throttle_max = val;
249 rctl_throttle_max = val;
259 RCTL_WUNLOCK();
250 RACCT_UNLOCK();
260
261 return (0);
262}
263
264static int rctl_throttle_pct_sysctl(SYSCTL_HANDLER_ARGS)
265{
266 int error, val = rctl_throttle_pct;
267
268 error = sysctl_handle_int(oidp, &val, 0, req);
269 if (error || !req->newptr)
270 return (error);
271 if (val < 0)
272 return (EINVAL);
273
251
252 return (0);
253}
254
255static int rctl_throttle_pct_sysctl(SYSCTL_HANDLER_ARGS)
256{
257 int error, val = rctl_throttle_pct;
258
259 error = sysctl_handle_int(oidp, &val, 0, req);
260 if (error || !req->newptr)
261 return (error);
262 if (val < 0)
263 return (EINVAL);
264
274 RCTL_WLOCK();
265 RACCT_LOCK();
275 rctl_throttle_pct = val;
266 rctl_throttle_pct = val;
276 RCTL_WUNLOCK();
267 RACCT_UNLOCK();
277
278 return (0);
279}
280
281static int rctl_throttle_pct2_sysctl(SYSCTL_HANDLER_ARGS)
282{
283 int error, val = rctl_throttle_pct2;
284
285 error = sysctl_handle_int(oidp, &val, 0, req);
286 if (error || !req->newptr)
287 return (error);
288 if (val < 0)
289 return (EINVAL);
290
268
269 return (0);
270}
271
272static int rctl_throttle_pct2_sysctl(SYSCTL_HANDLER_ARGS)
273{
274 int error, val = rctl_throttle_pct2;
275
276 error = sysctl_handle_int(oidp, &val, 0, req);
277 if (error || !req->newptr)
278 return (error);
279 if (val < 0)
280 return (EINVAL);
281
291 RCTL_WLOCK();
282 RACCT_LOCK();
292 rctl_throttle_pct2 = val;
283 rctl_throttle_pct2 = val;
293 RCTL_WUNLOCK();
284 RACCT_UNLOCK();
294
295 return (0);
296}
297
298static const char *
299rctl_subject_type_name(int subject)
300{
301 int i;

--- 33 unchanged lines hidden (view full) ---

335}
336
337static struct racct *
338rctl_proc_rule_to_racct(const struct proc *p, const struct rctl_rule *rule)
339{
340 struct ucred *cred = p->p_ucred;
341
342 ASSERT_RACCT_ENABLED();
285
286 return (0);
287}
288
289static const char *
290rctl_subject_type_name(int subject)
291{
292 int i;

--- 33 unchanged lines hidden (view full) ---

326}
327
328static struct racct *
329rctl_proc_rule_to_racct(const struct proc *p, const struct rctl_rule *rule)
330{
331 struct ucred *cred = p->p_ucred;
332
333 ASSERT_RACCT_ENABLED();
343 RCTL_LOCK_ASSERT();
334 RACCT_LOCK_ASSERT();
344
345 switch (rule->rr_per) {
346 case RCTL_SUBJECT_TYPE_PROCESS:
347 return (p->p_racct);
348 case RCTL_SUBJECT_TYPE_USER:
349 return (cred->cr_ruidinfo->ui_racct);
350 case RCTL_SUBJECT_TYPE_LOGINCLASS:
351 return (cred->cr_loginclass->lc_racct);

--- 10 unchanged lines hidden (view full) ---

362 */
363static int64_t
364rctl_available_resource(const struct proc *p, const struct rctl_rule *rule)
365{
366 const struct racct *racct;
367 int64_t available;
368
369 ASSERT_RACCT_ENABLED();
335
336 switch (rule->rr_per) {
337 case RCTL_SUBJECT_TYPE_PROCESS:
338 return (p->p_racct);
339 case RCTL_SUBJECT_TYPE_USER:
340 return (cred->cr_ruidinfo->ui_racct);
341 case RCTL_SUBJECT_TYPE_LOGINCLASS:
342 return (cred->cr_loginclass->lc_racct);

--- 10 unchanged lines hidden (view full) ---

353 */
354static int64_t
355rctl_available_resource(const struct proc *p, const struct rctl_rule *rule)
356{
357 const struct racct *racct;
358 int64_t available;
359
360 ASSERT_RACCT_ENABLED();
370 RCTL_LOCK_ASSERT();
361 RACCT_LOCK_ASSERT();
371
372 racct = rctl_proc_rule_to_racct(p, rule);
373 available = rule->rr_amount - racct->r_resources[rule->rr_resource];
374
375 return (available);
376}
377
378/*

--- 6 unchanged lines hidden (view full) ---

385void
386rctl_throttle_decay(struct racct *racct, int resource)
387{
388 struct rctl_rule *rule;
389 struct rctl_rule_link *link;
390 int64_t minavailable;
391
392 ASSERT_RACCT_ENABLED();
362
363 racct = rctl_proc_rule_to_racct(p, rule);
364 available = rule->rr_amount - racct->r_resources[rule->rr_resource];
365
366 return (available);
367}
368
369/*

--- 6 unchanged lines hidden (view full) ---

376void
377rctl_throttle_decay(struct racct *racct, int resource)
378{
379 struct rctl_rule *rule;
380 struct rctl_rule_link *link;
381 int64_t minavailable;
382
383 ASSERT_RACCT_ENABLED();
384 RACCT_LOCK_ASSERT();
393
394 minavailable = INT64_MAX;
395
385
386 minavailable = INT64_MAX;
387
396 RCTL_RLOCK();
397
398 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
399 rule = link->rrl_rule;
400
401 if (rule->rr_resource != resource)
402 continue;
403 if (rule->rr_action != RCTL_ACTION_THROTTLE)
404 continue;
405
406 if (rule->rr_amount < minavailable)
407 minavailable = rule->rr_amount;
408 }
409
388 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
389 rule = link->rrl_rule;
390
391 if (rule->rr_resource != resource)
392 continue;
393 if (rule->rr_action != RCTL_ACTION_THROTTLE)
394 continue;
395
396 if (rule->rr_amount < minavailable)
397 minavailable = rule->rr_amount;
398 }
399
410 RCTL_RUNLOCK();
411
412 if (racct->r_resources[resource] < minavailable) {
413 racct->r_resources[resource] = 0;
414 } else {
415 /*
416 * Cap utilization counter at ten times the limit. Otherwise,
417 * if we changed the rule lowering the allowed amount, it could
418 * take unreasonably long time for the accumulated resource
419 * usage to drop.

--- 11 unchanged lines hidden (view full) ---

431 */
432int64_t
433rctl_pcpu_available(const struct proc *p) {
434 struct rctl_rule *rule;
435 struct rctl_rule_link *link;
436 int64_t available, minavailable, limit;
437
438 ASSERT_RACCT_ENABLED();
400 if (racct->r_resources[resource] < minavailable) {
401 racct->r_resources[resource] = 0;
402 } else {
403 /*
404 * Cap utilization counter at ten times the limit. Otherwise,
405 * if we changed the rule lowering the allowed amount, it could
406 * take unreasonably long time for the accumulated resource
407 * usage to drop.

--- 11 unchanged lines hidden (view full) ---

419 */
420int64_t
421rctl_pcpu_available(const struct proc *p) {
422 struct rctl_rule *rule;
423 struct rctl_rule_link *link;
424 int64_t available, minavailable, limit;
425
426 ASSERT_RACCT_ENABLED();
427 RACCT_LOCK_ASSERT();
439
440 minavailable = INT64_MAX;
441 limit = 0;
442
428
429 minavailable = INT64_MAX;
430 limit = 0;
431
443 RCTL_RLOCK();
444
445 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
446 rule = link->rrl_rule;
447 if (rule->rr_resource != RACCT_PCTCPU)
448 continue;
449 if (rule->rr_action != RCTL_ACTION_DENY)
450 continue;
451 available = rctl_available_resource(p, rule);
452 if (available < minavailable) {
453 minavailable = available;
454 limit = rule->rr_amount;
455 }
456 }
457
432 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
433 rule = link->rrl_rule;
434 if (rule->rr_resource != RACCT_PCTCPU)
435 continue;
436 if (rule->rr_action != RCTL_ACTION_DENY)
437 continue;
438 available = rctl_available_resource(p, rule);
439 if (available < minavailable) {
440 minavailable = available;
441 limit = rule->rr_amount;
442 }
443 }
444
458 RCTL_RUNLOCK();
459
460 /*
461 * Return slightly less than actual value of the available
462 * %cpu resource. This makes %cpu throttling more agressive
463 * and lets us act sooner than the limits are already exceeded.
464 */
465 if (limit != 0) {
466 if (limit > 2 * RCTL_PCPU_SHIFT)
467 minavailable -= RCTL_PCPU_SHIFT;

--- 43 unchanged lines hidden (view full) ---

511 struct rctl_rule *rule;
512 struct rctl_rule_link *link;
513 struct sbuf sb;
514 char *buf;
515 int64_t available;
516 uint64_t sleep_ms, sleep_ratio;
517 int should_deny = 0;
518
445 /*
446 * Return slightly less than actual value of the available
447 * %cpu resource. This makes %cpu throttling more agressive
448 * and lets us act sooner than the limits are already exceeded.
449 */
450 if (limit != 0) {
451 if (limit > 2 * RCTL_PCPU_SHIFT)
452 minavailable -= RCTL_PCPU_SHIFT;

--- 43 unchanged lines hidden (view full) ---

496 struct rctl_rule *rule;
497 struct rctl_rule_link *link;
498 struct sbuf sb;
499 char *buf;
500 int64_t available;
501 uint64_t sleep_ms, sleep_ratio;
502 int should_deny = 0;
503
519
520 ASSERT_RACCT_ENABLED();
504 ASSERT_RACCT_ENABLED();
505 RACCT_LOCK_ASSERT();
521
506
522 RCTL_RLOCK();
523
524 /*
525 * There may be more than one matching rule; go through all of them.
526 * Denial should be done last, after logging and sending signals.
527 */
528 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
529 rule = link->rrl_rule;
530 if (rule->rr_resource != resource)
531 continue;

--- 156 unchanged lines hidden (view full) ---

688 * are equal to their counterparts from sys/signal.h.
689 */
690 kern_psignal(p, rule->rr_action);
691 link->rrl_exceeded = 1;
692 continue;
693 }
694 }
695
507 /*
508 * There may be more than one matching rule; go through all of them.
509 * Denial should be done last, after logging and sending signals.
510 */
511 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
512 rule = link->rrl_rule;
513 if (rule->rr_resource != resource)
514 continue;

--- 156 unchanged lines hidden (view full) ---

671 * are equal to their counterparts from sys/signal.h.
672 */
673 kern_psignal(p, rule->rr_action);
674 link->rrl_exceeded = 1;
675 continue;
676 }
677 }
678
696 RCTL_RUNLOCK();
697
698 if (should_deny) {
699 /*
700 * Return fake error code; the caller should change it
701 * into one proper for the situation - EFSIZ, ENOMEM etc.
702 */
703 return (EDOOFUS);
704 }
705
706 return (0);
707}
708
709uint64_t
710rctl_get_limit(struct proc *p, int resource)
711{
712 struct rctl_rule *rule;
713 struct rctl_rule_link *link;
714 uint64_t amount = UINT64_MAX;
715
716 ASSERT_RACCT_ENABLED();
679 if (should_deny) {
680 /*
681 * Return fake error code; the caller should change it
682 * into one proper for the situation - EFSIZ, ENOMEM etc.
683 */
684 return (EDOOFUS);
685 }
686
687 return (0);
688}
689
690uint64_t
691rctl_get_limit(struct proc *p, int resource)
692{
693 struct rctl_rule *rule;
694 struct rctl_rule_link *link;
695 uint64_t amount = UINT64_MAX;
696
697 ASSERT_RACCT_ENABLED();
698 RACCT_LOCK_ASSERT();
717
699
718 RCTL_RLOCK();
719
720 /*
721 * There may be more than one matching rule; go through all of them.
722 * Denial should be done last, after logging and sending signals.
723 */
724 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
725 rule = link->rrl_rule;
726 if (rule->rr_resource != resource)
727 continue;
728 if (rule->rr_action != RCTL_ACTION_DENY)
729 continue;
730 if (rule->rr_amount < amount)
731 amount = rule->rr_amount;
732 }
733
700 /*
701 * There may be more than one matching rule; go through all of them.
702 * Denial should be done last, after logging and sending signals.
703 */
704 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
705 rule = link->rrl_rule;
706 if (rule->rr_resource != resource)
707 continue;
708 if (rule->rr_action != RCTL_ACTION_DENY)
709 continue;
710 if (rule->rr_amount < amount)
711 amount = rule->rr_amount;
712 }
713
734 RCTL_RUNLOCK();
735
736 return (amount);
737}
738
739uint64_t
740rctl_get_available(struct proc *p, int resource)
741{
742 struct rctl_rule *rule;
743 struct rctl_rule_link *link;
744 int64_t available, minavailable, allocated;
745
746 minavailable = INT64_MAX;
747
748 ASSERT_RACCT_ENABLED();
714 return (amount);
715}
716
717uint64_t
718rctl_get_available(struct proc *p, int resource)
719{
720 struct rctl_rule *rule;
721 struct rctl_rule_link *link;
722 int64_t available, minavailable, allocated;
723
724 minavailable = INT64_MAX;
725
726 ASSERT_RACCT_ENABLED();
727 RACCT_LOCK_ASSERT();
749
728
750 RCTL_RLOCK();
751
752 /*
753 * There may be more than one matching rule; go through all of them.
754 * Denial should be done last, after logging and sending signals.
755 */
756 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
757 rule = link->rrl_rule;
758 if (rule->rr_resource != resource)
759 continue;
760 if (rule->rr_action != RCTL_ACTION_DENY)
761 continue;
762 available = rctl_available_resource(p, rule);
763 if (available < minavailable)
764 minavailable = available;
765 }
766
729 /*
730 * There may be more than one matching rule; go through all of them.
731 * Denial should be done last, after logging and sending signals.
732 */
733 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
734 rule = link->rrl_rule;
735 if (rule->rr_resource != resource)
736 continue;
737 if (rule->rr_action != RCTL_ACTION_DENY)
738 continue;
739 available = rctl_available_resource(p, rule);
740 if (available < minavailable)
741 minavailable = available;
742 }
743
767 RCTL_RUNLOCK();
768
769 /*
770 * XXX: Think about this _hard_.
771 */
772 allocated = p->p_racct->r_resources[resource];
773 if (minavailable < INT64_MAX - allocated)
774 minavailable += allocated;
775 if (minavailable < 0)
776 minavailable = 0;
744 /*
745 * XXX: Think about this _hard_.
746 */
747 allocated = p->p_racct->r_resources[resource];
748 if (minavailable < INT64_MAX - allocated)
749 minavailable += allocated;
750 if (minavailable < 0)
751 minavailable = 0;
752
777 return (minavailable);
778}
779
780static int
781rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter)
782{
783
784 ASSERT_RACCT_ENABLED();

--- 118 unchanged lines hidden (view full) ---

903 ASSERT_RACCT_ENABLED();
904 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
905
906 rctl_rule_acquire(rule);
907 link = uma_zalloc(rctl_rule_link_zone, M_WAITOK);
908 link->rrl_rule = rule;
909 link->rrl_exceeded = 0;
910
753 return (minavailable);
754}
755
756static int
757rctl_rule_matches(const struct rctl_rule *rule, const struct rctl_rule *filter)
758{
759
760 ASSERT_RACCT_ENABLED();

--- 118 unchanged lines hidden (view full) ---

879 ASSERT_RACCT_ENABLED();
880 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
881
882 rctl_rule_acquire(rule);
883 link = uma_zalloc(rctl_rule_link_zone, M_WAITOK);
884 link->rrl_rule = rule;
885 link->rrl_exceeded = 0;
886
911 RCTL_WLOCK();
887 RACCT_LOCK();
912 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
888 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
913 RCTL_WUNLOCK();
889 RACCT_UNLOCK();
914}
915
916static int
917rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule)
918{
919 struct rctl_rule_link *link;
920
921 ASSERT_RACCT_ENABLED();
922 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
890}
891
892static int
893rctl_racct_add_rule_locked(struct racct *racct, struct rctl_rule *rule)
894{
895 struct rctl_rule_link *link;
896
897 ASSERT_RACCT_ENABLED();
898 KASSERT(rctl_rule_fully_specified(rule), ("rule not fully specified"));
923 RCTL_WLOCK_ASSERT();
899 RACCT_LOCK_ASSERT();
924
925 link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT);
926 if (link == NULL)
927 return (ENOMEM);
928 rctl_rule_acquire(rule);
929 link->rrl_rule = rule;
930 link->rrl_exceeded = 0;
931
932 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
900
901 link = uma_zalloc(rctl_rule_link_zone, M_NOWAIT);
902 if (link == NULL)
903 return (ENOMEM);
904 rctl_rule_acquire(rule);
905 link->rrl_rule = rule;
906 link->rrl_exceeded = 0;
907
908 LIST_INSERT_HEAD(&racct->r_rule_links, link, rrl_next);
909
933 return (0);
934}
935
936/*
937 * Remove limits for a rules matching the filter and release
938 * the refcounts for the rules, possibly freeing them. Returns
939 * the number of limit structures removed.
940 */
941static int
942rctl_racct_remove_rules(struct racct *racct,
943 const struct rctl_rule *filter)
944{
945 struct rctl_rule_link *link, *linktmp;
946 int removed = 0;
947
948 ASSERT_RACCT_ENABLED();
910 return (0);
911}
912
913/*
914 * Remove limits for a rules matching the filter and release
915 * the refcounts for the rules, possibly freeing them. Returns
916 * the number of limit structures removed.
917 */
918static int
919rctl_racct_remove_rules(struct racct *racct,
920 const struct rctl_rule *filter)
921{
922 struct rctl_rule_link *link, *linktmp;
923 int removed = 0;
924
925 ASSERT_RACCT_ENABLED();
949 RCTL_WLOCK_ASSERT();
926 RACCT_LOCK_ASSERT();
950
951 LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) {
952 if (!rctl_rule_matches(link->rrl_rule, filter))
953 continue;
954
955 LIST_REMOVE(link, rrl_next);
956 rctl_rule_release(link->rrl_rule);
957 uma_zfree(rctl_rule_link_zone, link);

--- 454 unchanged lines hidden (view full) ---

1412
1413 return (0);
1414}
1415
1416static void
1417rctl_rule_pre_callback(void)
1418{
1419
927
928 LIST_FOREACH_SAFE(link, &racct->r_rule_links, rrl_next, linktmp) {
929 if (!rctl_rule_matches(link->rrl_rule, filter))
930 continue;
931
932 LIST_REMOVE(link, rrl_next);
933 rctl_rule_release(link->rrl_rule);
934 uma_zfree(rctl_rule_link_zone, link);

--- 454 unchanged lines hidden (view full) ---

1389
1390 return (0);
1391}
1392
1393static void
1394rctl_rule_pre_callback(void)
1395{
1396
1420 RCTL_WLOCK();
1397 RACCT_LOCK();
1421}
1422
1423static void
1424rctl_rule_post_callback(void)
1425{
1426
1398}
1399
1400static void
1401rctl_rule_post_callback(void)
1402{
1403
1427 RCTL_WUNLOCK();
1404 RACCT_UNLOCK();
1428}
1429
1430static void
1431rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3)
1432{
1433 struct rctl_rule *filter = (struct rctl_rule *)arg2;
1434 int found = 0;
1435
1436 ASSERT_RACCT_ENABLED();
1405}
1406
1407static void
1408rctl_rule_remove_callback(struct racct *racct, void *arg2, void *arg3)
1409{
1410 struct rctl_rule *filter = (struct rctl_rule *)arg2;
1411 int found = 0;
1412
1413 ASSERT_RACCT_ENABLED();
1437 RCTL_WLOCK_ASSERT();
1414 RACCT_LOCK_ASSERT();
1438
1439 found += rctl_racct_remove_rules(racct, filter);
1440
1441 *((int *)arg3) += found;
1442}
1443
1444/*
1445 * Remove all rules that match the filter.

--- 4 unchanged lines hidden (view full) ---

1450 struct proc *p;
1451 int found = 0;
1452
1453 ASSERT_RACCT_ENABLED();
1454
1455 if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS &&
1456 filter->rr_subject.rs_proc != NULL) {
1457 p = filter->rr_subject.rs_proc;
1415
1416 found += rctl_racct_remove_rules(racct, filter);
1417
1418 *((int *)arg3) += found;
1419}
1420
1421/*
1422 * Remove all rules that match the filter.

--- 4 unchanged lines hidden (view full) ---

1427 struct proc *p;
1428 int found = 0;
1429
1430 ASSERT_RACCT_ENABLED();
1431
1432 if (filter->rr_subject_type == RCTL_SUBJECT_TYPE_PROCESS &&
1433 filter->rr_subject.rs_proc != NULL) {
1434 p = filter->rr_subject.rs_proc;
1458 RCTL_WLOCK();
1435 RACCT_LOCK();
1459 found = rctl_racct_remove_rules(p->p_racct, filter);
1436 found = rctl_racct_remove_rules(p->p_racct, filter);
1460 RCTL_WUNLOCK();
1437 RACCT_UNLOCK();
1461 if (found)
1462 return (0);
1463 return (ESRCH);
1464 }
1465
1466 loginclass_racct_foreach(rctl_rule_remove_callback,
1467 rctl_rule_pre_callback, rctl_rule_post_callback,
1468 filter, (void *)&found);
1469 ui_racct_foreach(rctl_rule_remove_callback,
1470 rctl_rule_pre_callback, rctl_rule_post_callback,
1471 filter, (void *)&found);
1472 prison_racct_foreach(rctl_rule_remove_callback,
1473 rctl_rule_pre_callback, rctl_rule_post_callback,
1474 filter, (void *)&found);
1475
1476 sx_assert(&allproc_lock, SA_LOCKED);
1438 if (found)
1439 return (0);
1440 return (ESRCH);
1441 }
1442
1443 loginclass_racct_foreach(rctl_rule_remove_callback,
1444 rctl_rule_pre_callback, rctl_rule_post_callback,
1445 filter, (void *)&found);
1446 ui_racct_foreach(rctl_rule_remove_callback,
1447 rctl_rule_pre_callback, rctl_rule_post_callback,
1448 filter, (void *)&found);
1449 prison_racct_foreach(rctl_rule_remove_callback,
1450 rctl_rule_pre_callback, rctl_rule_post_callback,
1451 filter, (void *)&found);
1452
1453 sx_assert(&allproc_lock, SA_LOCKED);
1477 RCTL_WLOCK();
1454 RACCT_LOCK();
1478 FOREACH_PROC_IN_SYSTEM(p) {
1479 found += rctl_racct_remove_rules(p->p_racct, filter);
1480 }
1455 FOREACH_PROC_IN_SYSTEM(p) {
1456 found += rctl_racct_remove_rules(p->p_racct, filter);
1457 }
1481 RCTL_WUNLOCK();
1458 RACCT_UNLOCK();
1482
1483 if (found)
1484 return (0);
1485 return (ESRCH);
1486}
1487
1488/*
1489 * Appends a rule to the sbuf.

--- 115 unchanged lines hidden (view full) ---

1605 int i;
1606
1607 ASSERT_RACCT_ENABLED();
1608
1609 sb = sbuf_new_auto();
1610 for (i = 0; i <= RACCT_MAX; i++) {
1611 if (sloppy == 0 && RACCT_IS_SLOPPY(i))
1612 continue;
1459
1460 if (found)
1461 return (0);
1462 return (ESRCH);
1463}
1464
1465/*
1466 * Appends a rule to the sbuf.

--- 115 unchanged lines hidden (view full) ---

1582 int i;
1583
1584 ASSERT_RACCT_ENABLED();
1585
1586 sb = sbuf_new_auto();
1587 for (i = 0; i <= RACCT_MAX; i++) {
1588 if (sloppy == 0 && RACCT_IS_SLOPPY(i))
1589 continue;
1590 RACCT_LOCK();
1613 amount = racct->r_resources[i];
1591 amount = racct->r_resources[i];
1592 RACCT_UNLOCK();
1614 if (RACCT_IS_IN_MILLIONS(i))
1615 amount /= 1000000;
1616 sbuf_printf(sb, "%s=%jd,", rctl_resource_name(i), amount);
1617 }
1618 sbuf_setpos(sb, sbuf_len(sb) - 1);
1619 return (sb);
1620}
1621

--- 78 unchanged lines hidden (view full) ---

1700static void
1701rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3)
1702{
1703 struct rctl_rule *filter = (struct rctl_rule *)arg2;
1704 struct rctl_rule_link *link;
1705 struct sbuf *sb = (struct sbuf *)arg3;
1706
1707 ASSERT_RACCT_ENABLED();
1593 if (RACCT_IS_IN_MILLIONS(i))
1594 amount /= 1000000;
1595 sbuf_printf(sb, "%s=%jd,", rctl_resource_name(i), amount);
1596 }
1597 sbuf_setpos(sb, sbuf_len(sb) - 1);
1598 return (sb);
1599}
1600

--- 78 unchanged lines hidden (view full) ---

1679static void
1680rctl_get_rules_callback(struct racct *racct, void *arg2, void *arg3)
1681{
1682 struct rctl_rule *filter = (struct rctl_rule *)arg2;
1683 struct rctl_rule_link *link;
1684 struct sbuf *sb = (struct sbuf *)arg3;
1685
1686 ASSERT_RACCT_ENABLED();
1708 RCTL_LOCK_ASSERT();
1687 RACCT_LOCK_ASSERT();
1709
1710 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
1711 if (!rctl_rule_matches(link->rrl_rule, filter))
1712 continue;
1713 rctl_rule_to_sbuf(sb, link->rrl_rule);
1714 sbuf_printf(sb, ",");
1715 }
1716}

--- 34 unchanged lines hidden (view full) ---

1751 return (E2BIG);
1752 }
1753
1754 buf = malloc(bufsize, M_RCTL, M_WAITOK);
1755 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
1756 KASSERT(sb != NULL, ("sbuf_new failed"));
1757
1758 FOREACH_PROC_IN_SYSTEM(p) {
1688
1689 LIST_FOREACH(link, &racct->r_rule_links, rrl_next) {
1690 if (!rctl_rule_matches(link->rrl_rule, filter))
1691 continue;
1692 rctl_rule_to_sbuf(sb, link->rrl_rule);
1693 sbuf_printf(sb, ",");
1694 }
1695}

--- 34 unchanged lines hidden (view full) ---

1730 return (E2BIG);
1731 }
1732
1733 buf = malloc(bufsize, M_RCTL, M_WAITOK);
1734 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
1735 KASSERT(sb != NULL, ("sbuf_new failed"));
1736
1737 FOREACH_PROC_IN_SYSTEM(p) {
1759 RCTL_RLOCK();
1738 RACCT_LOCK();
1760 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
1761 /*
1762 * Non-process rules will be added to the buffer later.
1763 * Adding them here would result in duplicated output.
1764 */
1765 if (link->rrl_rule->rr_subject_type !=
1766 RCTL_SUBJECT_TYPE_PROCESS)
1767 continue;
1768 if (!rctl_rule_matches(link->rrl_rule, filter))
1769 continue;
1770 rctl_rule_to_sbuf(sb, link->rrl_rule);
1771 sbuf_printf(sb, ",");
1772 }
1739 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
1740 /*
1741 * Non-process rules will be added to the buffer later.
1742 * Adding them here would result in duplicated output.
1743 */
1744 if (link->rrl_rule->rr_subject_type !=
1745 RCTL_SUBJECT_TYPE_PROCESS)
1746 continue;
1747 if (!rctl_rule_matches(link->rrl_rule, filter))
1748 continue;
1749 rctl_rule_to_sbuf(sb, link->rrl_rule);
1750 sbuf_printf(sb, ",");
1751 }
1773 RCTL_RUNLOCK();
1752 RACCT_UNLOCK();
1774 }
1775
1776 loginclass_racct_foreach(rctl_get_rules_callback,
1777 rctl_rule_pre_callback, rctl_rule_post_callback,
1778 filter, sb);
1779 ui_racct_foreach(rctl_get_rules_callback,
1780 rctl_rule_pre_callback, rctl_rule_post_callback,
1781 filter, sb);

--- 70 unchanged lines hidden (view full) ---

1852 sx_sunlock(&allproc_lock);
1853 return (E2BIG);
1854 }
1855
1856 buf = malloc(bufsize, M_RCTL, M_WAITOK);
1857 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
1858 KASSERT(sb != NULL, ("sbuf_new failed"));
1859
1753 }
1754
1755 loginclass_racct_foreach(rctl_get_rules_callback,
1756 rctl_rule_pre_callback, rctl_rule_post_callback,
1757 filter, sb);
1758 ui_racct_foreach(rctl_get_rules_callback,
1759 rctl_rule_pre_callback, rctl_rule_post_callback,
1760 filter, sb);

--- 70 unchanged lines hidden (view full) ---

1831 sx_sunlock(&allproc_lock);
1832 return (E2BIG);
1833 }
1834
1835 buf = malloc(bufsize, M_RCTL, M_WAITOK);
1836 sb = sbuf_new(NULL, buf, bufsize, SBUF_FIXEDLEN);
1837 KASSERT(sb != NULL, ("sbuf_new failed"));
1838
1860 RCTL_RLOCK();
1839 RACCT_LOCK();
1861 LIST_FOREACH(link, &filter->rr_subject.rs_proc->p_racct->r_rule_links,
1862 rrl_next) {
1863 rctl_rule_to_sbuf(sb, link->rrl_rule);
1864 sbuf_printf(sb, ",");
1865 }
1840 LIST_FOREACH(link, &filter->rr_subject.rs_proc->p_racct->r_rule_links,
1841 rrl_next) {
1842 rctl_rule_to_sbuf(sb, link->rrl_rule);
1843 sbuf_printf(sb, ",");
1844 }
1866 RCTL_RUNLOCK();
1845 RACCT_UNLOCK();
1867 if (sbuf_error(sb) == ENOMEM) {
1868 error = ERANGE;
1869 sbuf_delete(sb);
1870 goto out;
1871 }
1872
1873 /*
1874 * Remove trailing ",".

--- 109 unchanged lines hidden (view full) ---

1984 LIST_INIT(&newrules);
1985
1986again:
1987 /*
1988 * First, count the rules that apply to the process with new
1989 * credentials.
1990 */
1991 rulecnt = 0;
1846 if (sbuf_error(sb) == ENOMEM) {
1847 error = ERANGE;
1848 sbuf_delete(sb);
1849 goto out;
1850 }
1851
1852 /*
1853 * Remove trailing ",".

--- 109 unchanged lines hidden (view full) ---

1963 LIST_INIT(&newrules);
1964
1965again:
1966 /*
1967 * First, count the rules that apply to the process with new
1968 * credentials.
1969 */
1970 rulecnt = 0;
1992 RCTL_RLOCK();
1971 RACCT_LOCK();
1993 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
1994 if (link->rrl_rule->rr_subject_type ==
1995 RCTL_SUBJECT_TYPE_PROCESS)
1996 rulecnt++;
1997 }
1998 LIST_FOREACH(link, &newuip->ui_racct->r_rule_links, rrl_next)
1999 rulecnt++;
2000 LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next)
2001 rulecnt++;
2002 LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next)
2003 rulecnt++;
1972 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
1973 if (link->rrl_rule->rr_subject_type ==
1974 RCTL_SUBJECT_TYPE_PROCESS)
1975 rulecnt++;
1976 }
1977 LIST_FOREACH(link, &newuip->ui_racct->r_rule_links, rrl_next)
1978 rulecnt++;
1979 LIST_FOREACH(link, &newlc->lc_racct->r_rule_links, rrl_next)
1980 rulecnt++;
1981 LIST_FOREACH(link, &newprr->prr_racct->r_rule_links, rrl_next)
1982 rulecnt++;
2004 RCTL_RUNLOCK();
1983 RACCT_UNLOCK();
2005
2006 /*
2007 * Create temporary list. We've dropped the rctl_lock in order
2008 * to use M_WAITOK.
2009 */
2010 for (i = 0; i < rulecnt; i++) {
2011 newlink = uma_zalloc(rctl_rule_link_zone, M_WAITOK);
2012 newlink->rrl_rule = NULL;
2013 newlink->rrl_exceeded = 0;
2014 LIST_INSERT_HEAD(&newrules, newlink, rrl_next);
2015 }
2016
2017 newlink = LIST_FIRST(&newrules);
2018
2019 /*
2020 * Assign rules to the newly allocated list entries.
2021 */
1984
1985 /*
1986 * Create temporary list. We've dropped the rctl_lock in order
1987 * to use M_WAITOK.
1988 */
1989 for (i = 0; i < rulecnt; i++) {
1990 newlink = uma_zalloc(rctl_rule_link_zone, M_WAITOK);
1991 newlink->rrl_rule = NULL;
1992 newlink->rrl_exceeded = 0;
1993 LIST_INSERT_HEAD(&newrules, newlink, rrl_next);
1994 }
1995
1996 newlink = LIST_FIRST(&newrules);
1997
1998 /*
1999 * Assign rules to the newly allocated list entries.
2000 */
2022 RCTL_WLOCK();
2001 RACCT_LOCK();
2023 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
2024 if (link->rrl_rule->rr_subject_type ==
2025 RCTL_SUBJECT_TYPE_PROCESS) {
2026 if (newlink == NULL)
2027 goto goaround;
2028 rctl_rule_acquire(link->rrl_rule);
2029 newlink->rrl_rule = link->rrl_rule;
2030 newlink->rrl_exceeded = link->rrl_exceeded;

--- 51 unchanged lines hidden (view full) ---

2082 */
2083 while (!LIST_EMPTY(&newrules)) {
2084 newlink = LIST_FIRST(&newrules);
2085 LIST_REMOVE(newlink, rrl_next);
2086 LIST_INSERT_HEAD(&p->p_racct->r_rule_links,
2087 newlink, rrl_next);
2088 }
2089
2002 LIST_FOREACH(link, &p->p_racct->r_rule_links, rrl_next) {
2003 if (link->rrl_rule->rr_subject_type ==
2004 RCTL_SUBJECT_TYPE_PROCESS) {
2005 if (newlink == NULL)
2006 goto goaround;
2007 rctl_rule_acquire(link->rrl_rule);
2008 newlink->rrl_rule = link->rrl_rule;
2009 newlink->rrl_exceeded = link->rrl_exceeded;

--- 51 unchanged lines hidden (view full) ---

2061 */
2062 while (!LIST_EMPTY(&newrules)) {
2063 newlink = LIST_FIRST(&newrules);
2064 LIST_REMOVE(newlink, rrl_next);
2065 LIST_INSERT_HEAD(&p->p_racct->r_rule_links,
2066 newlink, rrl_next);
2067 }
2068
2090 RCTL_WUNLOCK();
2069 RACCT_UNLOCK();
2091
2092 return;
2093 }
2094
2095goaround:
2070
2071 return;
2072 }
2073
2074goaround:
2096 RCTL_WUNLOCK();
2075 RACCT_UNLOCK();
2097
2098 /*
2099 * Rule list changed while we were not holding the rctl_lock.
2100 * Free the new list and try again.
2101 */
2102 while (!LIST_EMPTY(&newrules)) {
2103 newlink = LIST_FIRST(&newrules);
2104 LIST_REMOVE(newlink, rrl_next);

--- 10 unchanged lines hidden (view full) ---

2115 */
2116int
2117rctl_proc_fork(struct proc *parent, struct proc *child)
2118{
2119 struct rctl_rule *rule;
2120 struct rctl_rule_link *link;
2121 int error;
2122
2076
2077 /*
2078 * Rule list changed while we were not holding the rctl_lock.
2079 * Free the new list and try again.
2080 */
2081 while (!LIST_EMPTY(&newrules)) {
2082 newlink = LIST_FIRST(&newrules);
2083 LIST_REMOVE(newlink, rrl_next);

--- 10 unchanged lines hidden (view full) ---

2094 */
2095int
2096rctl_proc_fork(struct proc *parent, struct proc *child)
2097{
2098 struct rctl_rule *rule;
2099 struct rctl_rule_link *link;
2100 int error;
2101
2123 LIST_INIT(&child->p_racct->r_rule_links);
2124
2125 ASSERT_RACCT_ENABLED();
2102 ASSERT_RACCT_ENABLED();
2103 RACCT_LOCK_ASSERT();
2126 KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent));
2127
2104 KASSERT(parent->p_racct != NULL, ("process without racct; p = %p", parent));
2105
2128 RCTL_WLOCK();
2106 LIST_INIT(&child->p_racct->r_rule_links);
2129
2130 /*
2131 * Go through limits applicable to the parent and assign them
2132 * to the child. Rules with 'process' subject have to be duplicated
2133 * in order to make their rr_subject point to the new process.
2134 */
2135 LIST_FOREACH(link, &parent->p_racct->r_rule_links, rrl_next) {
2136 if (link->rrl_rule->rr_subject_type ==

--- 12 unchanged lines hidden (view full) ---

2149 } else {
2150 error = rctl_racct_add_rule_locked(child->p_racct,
2151 link->rrl_rule);
2152 if (error != 0)
2153 goto fail;
2154 }
2155 }
2156
2107
2108 /*
2109 * Go through limits applicable to the parent and assign them
2110 * to the child. Rules with 'process' subject have to be duplicated
2111 * in order to make their rr_subject point to the new process.
2112 */
2113 LIST_FOREACH(link, &parent->p_racct->r_rule_links, rrl_next) {
2114 if (link->rrl_rule->rr_subject_type ==

--- 12 unchanged lines hidden (view full) ---

2127 } else {
2128 error = rctl_racct_add_rule_locked(child->p_racct,
2129 link->rrl_rule);
2130 if (error != 0)
2131 goto fail;
2132 }
2133 }
2134
2157 RCTL_WUNLOCK();
2158 return (0);
2159
2160fail:
2161 while (!LIST_EMPTY(&child->p_racct->r_rule_links)) {
2162 link = LIST_FIRST(&child->p_racct->r_rule_links);
2163 LIST_REMOVE(link, rrl_next);
2164 rctl_rule_release(link->rrl_rule);
2165 uma_zfree(rctl_rule_link_zone, link);
2166 }
2135 return (0);
2136
2137fail:
2138 while (!LIST_EMPTY(&child->p_racct->r_rule_links)) {
2139 link = LIST_FIRST(&child->p_racct->r_rule_links);
2140 LIST_REMOVE(link, rrl_next);
2141 rctl_rule_release(link->rrl_rule);
2142 uma_zfree(rctl_rule_link_zone, link);
2143 }
2167 RCTL_WUNLOCK();
2144
2168 return (EAGAIN);
2169}
2170
2171/*
2172 * Release rules attached to the racct.
2173 */
2174void
2175rctl_racct_release(struct racct *racct)
2176{
2177 struct rctl_rule_link *link;
2178
2179 ASSERT_RACCT_ENABLED();
2145 return (EAGAIN);
2146}
2147
2148/*
2149 * Release rules attached to the racct.
2150 */
2151void
2152rctl_racct_release(struct racct *racct)
2153{
2154 struct rctl_rule_link *link;
2155
2156 ASSERT_RACCT_ENABLED();
2157 RACCT_LOCK_ASSERT();
2180
2158
2181 RCTL_WLOCK();
2182 while (!LIST_EMPTY(&racct->r_rule_links)) {
2183 link = LIST_FIRST(&racct->r_rule_links);
2184 LIST_REMOVE(link, rrl_next);
2185 rctl_rule_release(link->rrl_rule);
2186 uma_zfree(rctl_rule_link_zone, link);
2187 }
2159 while (!LIST_EMPTY(&racct->r_rule_links)) {
2160 link = LIST_FIRST(&racct->r_rule_links);
2161 LIST_REMOVE(link, rrl_next);
2162 rctl_rule_release(link->rrl_rule);
2163 uma_zfree(rctl_rule_link_zone, link);
2164 }
2188 RCTL_WUNLOCK();
2189}
2190
2191static void
2192rctl_init(void)
2193{
2194
2195 if (!racct_enable)
2196 return;

--- 61 unchanged lines hidden ---
2165}
2166
2167static void
2168rctl_init(void)
2169{
2170
2171 if (!racct_enable)
2172 return;

--- 61 unchanged lines hidden ---