Lines Matching defs:rctl

38 #include <sys/rctl.h>
50 * The rctl subsystem provides a mechanism for kernel components to
59 * also wishing to provide additional limits on a given rctl can modify
60 * them once they have the rctl handle. Each subsystem should store the
61 * handle to their rctl for direct access.
68 * advertised to userland; all userland interactions are via the rctl
72 * no ancestor, they inherit their rctls from the rctl dict for project
79 * hash table keyed on the rctl handle assigned at registration. The entries
88 * rctl_set[key] ---> | rctl | --> value <-> value <-> system value --> NULL
93 * That is, the rctl contains a back pointer to the global resource control
95 * table mentioned earlier. The rctl contains two pointers to resource
131 * Because the rctl_val chain on each rctl must be navigable in a
159 * Within the rctl sub-system, we provide two interfaces that are only used by
163 * rctl_local_replace_all() will purge the current rctl->rc_projdb and
164 * rctl->rc_values entries, and apply the *new_values.
167 * (rctl->rc_values), but also a "cached" linked list (rctl->rc_projdb) of
170 * rctl->rc_values - a linked list of rctl_val_t. These are the active
171 * resource values associated with this rctl, and may have been set by
175 * rctl->rc_projdb - a linked list of rctl_val_t. These reflect the
177 * referenced by any other component of the rctl sub-system.
184 * rctl->rc_values.
194 kmem_cache_t *rctl_cache; /* kmem cache for rctl structures */
195 kmem_cache_t *rctl_val_cache; /* kmem cache for rctl values */
211 rcop_no_action(struct rctl *r, struct proc *p, rctl_entity_p_t *e)
217 rcop_no_usage(struct rctl *r, struct proc *p)
224 rcop_no_set(struct rctl *r, struct proc *p, rctl_entity_p_t *e, rctl_qty_t l)
231 rcop_no_test(struct rctl *r, struct proc *p, rctl_entity_p_t *e,
251 rcop_absolute_test(struct rctl *r, struct proc *p, rctl_entity_p_t *e,
335 * Copy rctl names into our buffer. If the copy length exceeds the
541 panic("unknown rctl entity type %d seen", rcd->rcd_entity);
576 panic("unknown rctl entity type %d seen", entity);
588 rctl_t *rctl = prev;
593 rctl = kmem_cache_alloc(rctl_cache, KM_SLEEP);
594 prev->rc_next = rctl;
595 prev = rctl;
598 rctl->rc_next = NULL;
635 rctl_t *rctl = rcgp->rcag_ctls;
639 rcgp->rcag_ctls = rctl->rc_next;
641 rctl->rc_next = NULL;
643 return (rctl);
651 rctl_t *rctl = rcgp->rcag_ctls;
660 while (rctl != NULL) {
661 rctl_t *next = rctl->rc_next;
663 kmem_cache_free(rctl_cache, rctl);
664 rctl = next;
976 rctl_set_insert(rctl_set_t *set, rctl_hndl_t hndl, rctl_t *rctl)
983 rctl->rc_next = NULL;
986 set->rcs_ctls[index] = rctl;
991 rctl->rc_next = set->rcs_ctls[index];
992 set->rcs_ctls[index] = rctl;
1003 rctl->rc_next = next_ctl;
1004 prev_ctl->rc_next = rctl;
1010 rctl->rc_next = next_ctl;
1011 prev_ctl->rc_next = rctl;
1113 rctl_t *rctl = rctl_gp_detach_ctl(ragp);
1115 rctl->rc_dict_entry = rde;
1116 rctl->rc_id = rde->rcd_id;
1117 rctl->rc_projdb = NULL;
1119 rctl->rc_values = rctl_val_list_dup(rde->rcd_default_value,
1121 rctl->rc_cursor = rctl->rc_values;
1123 ASSERT(rctl->rc_cursor != NULL);
1125 rctl_set_insert(rset, rde->rcd_id, rctl);
1127 RCTLOP_SET(rctl, p, e, rctl_model_value(rctl->rc_dict_entry, p,
1128 rctl->rc_cursor->rcv_value));
1138 rctl_dup(rctl_t *rctl, rctl_alloc_gp_t *ragp, struct proc *oldp,
1144 dup->rc_id = rctl->rc_id;
1145 dup->rc_dict_entry = rctl->rc_dict_entry;
1148 dup->rc_values = rctl_val_list_dup(rctl->rc_values, ragp, oldp, newp);
1152 if (rctl_val_cmp(rctl->rc_cursor, dval, 0) >= 0) {
1256 * callbacks for each rctl in the new set.
1448 rctl_set_find(rctl_set_t *set, rctl_hndl_t hndl, rctl_t **rctl)
1458 *rctl = curr_ctl;
1471 * Given a process, get the next enforced value on the rctl of the specified
1485 rctl_t *rctl;
1490 if (rctl_set_find(rset, hndl, &rctl) == -1)
1493 ret = rctl_model_value(rctl->rc_dict_entry, p,
1494 rctl->rc_cursor->rcv_value);
1505 * Copy a sanitized version of the global rctl for a given resource control
1535 * Transfer the settable fields of the named rctl to the global rctl matching
1564 rctl_t *rctl;
1583 /* using rctl's hndl, get rctl from local set */
1584 if (rctl_set_find(rset, hndl, &rctl) == -1) {
1589 ret = cbop(hndl, p, &e, rctl, oval, nval);
1598 rctl_t *rctl, rctl_val_t *oval, rctl_val_t *nval)
1604 bcopy(rctl->rc_values, nval, sizeof (rctl_val_t));
1609 rctl_val_t *tval = rctl_val_list_find(&rctl->rc_values, oval);
1626 * Get the rctl value for the given flags.
1641 rctl_t *rctl, rctl_val_t *oval, rctl_val_t *nval)
1643 if ((oval = rctl_val_list_find(&rctl->rc_values, nval)) == NULL)
1646 if (rctl->rc_cursor == oval) {
1647 rctl->rc_cursor = oval->rcv_next;
1648 rctl_val_list_reset(rctl->rc_cursor);
1649 RCTLOP_SET(rctl, p, e, rctl_model_value(rctl->rc_dict_entry, p,
1650 rctl->rc_cursor->rcv_value));
1652 ASSERT(rctl->rc_cursor != NULL);
1655 (void) rctl_val_list_delete(&rctl->rc_values, oval);
1664 * Delete the rctl value for the given flags.
1679 * Insert a new value into the rctl's val list. If an error occurs,
1690 rctl_t *rctl, rctl_val_t *oval, rctl_val_t *nval)
1697 if (rctl_val_list_insert(&rctl->rc_values, nval) != 0)
1700 if (rctl_val_cmp(nval, rctl->rc_cursor, 0) < 0) {
1701 rctl->rc_cursor = nval;
1702 rctl_val_list_reset(rctl->rc_cursor);
1703 RCTLOP_SET(rctl, p, e, rctl_model_value(rctl->rc_dict_entry, p,
1704 rctl->rc_cursor->rcv_value));
1706 ASSERT(rctl->rc_cursor != NULL);
1716 * Insert the rctl value into the appropriate rctl set for the calling
1735 * Should the *new_values linked list match the contents of the rctl's
1744 rctl_t *rctl, rctl_val_t *new_values, rctl_val_t *alloc_values)
1752 * If this the first time we've set this project rctl, then we delete
1758 if (rctl->rc_projdb == NULL) {
1759 val = rctl->rc_values;
1766 rctl->rc_values = val->rcv_next;
1784 val = rctl->rc_projdb;
1795 if (((tmp_val = rctl_val_list_find(&rctl->rc_values,
1798 (void) rctl_val_list_delete(&rctl->rc_values,
1803 (void) rctl_val_list_delete(&rctl->rc_projdb, val);
1821 if (rctl_val_list_insert(&rctl->rc_projdb, new_values) == 0) {
1827 if (rctl_val_list_insert(&rctl->rc_values,
1851 /* Reset the cursor if rctl values have been modified */
1853 rctl->rc_cursor = rctl->rc_values;
1854 rctl_val_list_reset(rctl->rc_cursor);
1855 RCTLOP_SET(rctl, p, e, rctl_model_value(rctl->rc_dict_entry, p,
1856 rctl->rc_cursor->rcv_value));
1876 * Clears the active rctl values (rc_values), and stored values from the
1889 rctl_t *rctl, rctl_val_t *new_values, rctl_val_t *alloc_values)
1896 val = rctl->rc_values;
1903 rctl->rc_values = val->rcv_next;
1917 val = rctl->rc_projdb;
1924 rctl->rc_projdb = NULL;
1932 if (rctl_val_list_insert(&rctl->rc_projdb, new_values) == 0) {
1937 if (rctl_val_list_insert(&rctl->rc_values,
1962 rctl->rc_cursor = rctl->rc_values;
1963 rctl_val_list_reset(rctl->rc_cursor);
1964 RCTLOP_SET(rctl, p, e, rctl_model_value(rctl->rc_dict_entry, p,
1965 rctl->rc_cursor->rcv_value));
1980 rctl_t *rctl, rctl_val_t *oval, rctl_val_t *nval)
1986 tmp = rctl_val_list_find(&rctl->rc_values, oval);
2004 if (ret = rctl_local_insert_cb(hndl, p, e, rctl, NULL, nval))
2007 ret = rctl_local_delete_cb(hndl, p, e, rctl, NULL, oval);
2016 * Replace the rctl value with a new one.
2039 rctl_t *rctl;
2046 if (rctl_set_find(rset, rc, &rctl) == -1) {
2051 rval = rctl->rc_values;
2053 if (rctl->rc_dict_entry->rcd_flagaction & (RCTL_GLOBAL_DENY_NEVER |
2081 rctl->rc_dict_entry, p))
2099 rval->rcv_value < rctl_model_maximum(rctl->rc_dict_entry,
2126 rval->rcv_value < rctl_model_maximum(rctl->rc_dict_entry, p))
2194 rctl_t *rctl;
2220 if (rctl_set_find(rset, rc, &rctl) == -1) {
2227 rval = rctl->rc_values;
2238 if (rctl->rc_cursor == rval) {
2239 rctl->rc_cursor = rval->rcv_next;
2240 rctl_val_list_reset(rctl->rc_cursor);
2241 RCTLOP_SET(rctl, p, &e, rctl_model_value(
2242 rctl->rc_dict_entry, p,
2243 rctl->rc_cursor->rcv_value));
2245 (void) rctl_val_list_delete(&rctl->rc_values, rval);
2255 max = rctl->rc_dict_entry->rcd_max_native;
2266 (void) rctl_val_list_insert(&rctl->rc_values, rval_priv);
2267 rctl->rc_cursor = rval_priv;
2268 rctl_val_list_reset(rctl->rc_cursor);
2269 RCTLOP_SET(rctl, p, &e, rctl_model_value(rctl->rc_dict_entry, p,
2270 rctl->rc_cursor->rcv_value));
2284 (void) rctl_val_list_insert(&rctl->rc_values, rval_basic);
2285 rctl->rc_cursor = rval_basic;
2286 rctl_val_list_reset(rctl->rc_cursor);
2287 RCTLOP_SET(rctl, p, &e, rctl_model_value(rctl->rc_dict_entry, p,
2288 rctl->rc_cursor->rcv_value));
2291 ASSERT(rctl->rc_cursor != NULL);
2304 * active on the system; if a rctl of that name is absent, an entry is
2305 * made into the dictionary. The rctl is returned with its reference
2306 * count incremented by one. If the rctl name already exists, we panic.
2311 * Each registered rctl has a requirement that a RCPRIV_SYSTEM limit be
2319 * The rctl's ID.
2333 rctl_t *rctl = kmem_cache_alloc(rctl_cache, KM_SLEEP);
2343 bzero(rctl, sizeof (rctl_t));
2369 rctl->rc_dict_entry = rctl_de;
2370 rctl->rc_values = rctl_val;
2379 panic("duplicate registration of rctl %s", name);
2381 rhndl = rctl_de->rcd_id = rctl->rc_id =
2389 panic("unable to insert rctl dict entry for %s (%u)", name,
2390 (uint_t)rctl->rc_id);
2395 if (mod_hash_find(rctl_dict, (mod_hash_key_t)(uintptr_t)rctl->rc_id,
2397 panic("duplicate rctl ID %u registered", rctl->rc_id);
2399 if (mod_hash_insert(rctl_dict, (mod_hash_key_t)(uintptr_t)rctl->rc_id,
2400 (mod_hash_val_t)rctl))
2401 panic("unable to insert rctl %s/%u (%p)", name,
2402 (uint_t)rctl->rc_id, (void *)rctl);
2419 panic("registering unknown rctl entity %d (%s)", entity,
2515 "%s rctl %s (value %llu) exceeded by %s %d.",
2521 "%s rctl %s (value %llu) exceeded by process %d"
2529 "%s rctl %s (value %llu) exceeded by process %d"
2800 * Get enforced rctl value and current usage. Test the increment
2840 * Initialize the rctl subsystem, including the primoridal rctls
2999 * 0 on success. EAGAIN if swap increment fails due an rctl value
3066 * 0 on success. EAGAIN if increment fails due an rctl value