summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/os/project.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/os/project.c')
-rw-r--r--usr/src/uts/common/os/project.c58
1 files changed, 57 insertions, 1 deletions
diff --git a/usr/src/uts/common/os/project.c b/usr/src/uts/common/os/project.c
index 3c17a0dc38..b5f96a8dd7 100644
--- a/usr/src/uts/common/os/project.c
+++ b/usr/src/uts/common/os/project.c
@@ -41,6 +41,7 @@
#include <sys/port_kernel.h>
#include <sys/task.h>
#include <sys/zone.h>
+#include <sys/cpucaps.h>
int project_hash_size = 64;
static kmutex_t project_hash_lock;
@@ -49,6 +50,7 @@ static mod_hash_t *projects_hash;
static kproject_t *projects_list;
rctl_hndl_t rc_project_cpu_shares;
+rctl_hndl_t rc_project_cpu_cap;
rctl_hndl_t rc_project_nlwps;
rctl_hndl_t rc_project_ntasks;
rctl_hndl_t rc_project_msgmni;
@@ -156,6 +158,7 @@ project_hash_val_dtor(mod_hash_val_t val)
kproject_t *kp = (kproject_t *)val;
ASSERT(kp->kpj_count == 0);
+ ASSERT(kp->kpj_cpucap == NULL);
kmem_free(kp, sizeof (kproject_t));
}
@@ -251,6 +254,7 @@ project_hold_by_id(projid_t id, zone_t *zone, int flag)
p = spare_p;
p->kpj_id = id;
+ p->kpj_zone = zone;
p->kpj_zoneid = zone->zone_id;
p->kpj_count = 0;
p->kpj_shares = 1;
@@ -304,6 +308,13 @@ project_hold_by_id(projid_t id, zone_t *zone, int flag)
* across reboots.
*/
if (create == B_TRUE) {
+ /*
+ * Inform CPU caps framework of the new project
+ */
+ cpucaps_project_add(p);
+ /*
+ * Set up project kstats
+ */
ksp = project_kstat_create(p, zone);
mutex_enter(&project_hash_lock);
ASSERT(p->kpj_data.kpd_lockedmem_kstat == NULL);
@@ -343,6 +354,8 @@ project_rele(kproject_t *p)
projects_list = p->kpj_next;
mutex_exit(&projects_list_lock);
+ cpucaps_project_remove(p);
+
rctl_set_free(p->kpj_rctls);
project_kstat_delete(p);
@@ -431,7 +444,6 @@ project_cpu_shares_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
return (0);
}
-
static rctl_ops_t project_cpu_shares_ops = {
rcop_no_action,
project_cpu_shares_usage,
@@ -439,6 +451,43 @@ static rctl_ops_t project_cpu_shares_ops = {
rcop_no_test
};
+
+/*
+ * project.cpu-cap resource control support.
+ */
+/*ARGSUSED*/
+static rctl_qty_t
+project_cpu_cap_get(rctl_t *rctl, struct proc *p)
+{
+ ASSERT(MUTEX_HELD(&p->p_lock));
+ return (cpucaps_project_get(p->p_task->tk_proj));
+}
+
+/*ARGSUSED*/
+static int
+project_cpu_cap_set(rctl_t *rctl, struct proc *p, rctl_entity_p_t *e,
+ rctl_qty_t nv)
+{
+ kproject_t *kpj = e->rcep_p.proj;
+
+ ASSERT(MUTEX_HELD(&p->p_lock));
+ ASSERT(e->rcep_t == RCENTITY_PROJECT);
+ if (kpj == NULL)
+ return (0);
+
+ /*
+ * set cap to the new value.
+ */
+ return (cpucaps_project_set(kpj, nv));
+}
+
+static rctl_ops_t project_cpu_cap_ops = {
+ rcop_no_action,
+ project_cpu_cap_get,
+ project_cpu_cap_set,
+ rcop_no_test
+};
+
/*ARGSUSED*/
static rctl_qty_t
project_lwps_usage(rctl_t *r, proc_t *p)
@@ -804,6 +853,13 @@ project_init(void)
rctl_add_default_limit("project.cpu-shares", 1, RCPRIV_PRIVILEGED,
RCTL_LOCAL_NOACTION);
+ rc_project_cpu_cap = rctl_register("project.cpu-cap",
+ RCENTITY_PROJECT, RCTL_GLOBAL_SIGNAL_NEVER |
+ RCTL_GLOBAL_DENY_ALWAYS | RCTL_GLOBAL_NOBASIC |
+ RCTL_GLOBAL_COUNT | RCTL_GLOBAL_SYSLOG_NEVER |
+ RCTL_GLOBAL_INFINITE,
+ MAXCAP, MAXCAP, &project_cpu_cap_ops);
+
rc_project_nlwps = rctl_register("project.max-lwps", RCENTITY_PROJECT,
RCTL_GLOBAL_NOACTION | RCTL_GLOBAL_NOBASIC | RCTL_GLOBAL_COUNT,
INT_MAX, INT_MAX, &project_lwps_ops);