diff options
author | sl108498 <none@none> | 2006-09-19 15:49:28 -0700 |
---|---|---|
committer | sl108498 <none@none> | 2006-09-19 15:49:28 -0700 |
commit | c6939658adb0a356a77bc28f7df252ceb4a8f6cc (patch) | |
tree | 2e24cb01bd59e15cda6ad68fa5d778b4cf571fa7 /usr/src/uts/common/os/rctl.c | |
parent | 69889278ff50c08a6682a39ce6b5d97c5f0c2387 (diff) | |
download | illumos-joyent-c6939658adb0a356a77bc28f7df252ceb4a8f6cc.tar.gz |
PSARC/2004/580 zone/project.max-locked-memory Resource Controls
PSARC/2006/463 Amendment_to_zone_project.max-locked-memory_Resource_Controls
5053609 RFE: need zone.max-locked-memory rctl
4691104 Need mlock capability without requiring superuser privileges
Diffstat (limited to 'usr/src/uts/common/os/rctl.c')
-rw-r--r-- | usr/src/uts/common/os/rctl.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/usr/src/uts/common/os/rctl.c b/usr/src/uts/common/os/rctl.c index dd6230ad7b..4de4c74fe8 100644 --- a/usr/src/uts/common/os/rctl.c +++ b/usr/src/uts/common/os/rctl.c @@ -2566,3 +2566,110 @@ rctl_init(void) rctlproc_init(); } + +/* + * rctl_incr_locked_mem(proc_t *p, kproject_t *proj, rctl_qty_t inc) + * + * Increments the amount of locked memory on a project, and + * zone. If proj is NULL, the proj and zone of proc_t p is used. If + * chargeproc is non-zero, then the charged amount is cached on p->p_locked_mem + * so that the charge can be migrated when a process changes projects. + * + * Return values + * 0 - success + * EAGAIN - attempting to increment locked memory is denied by one + * or more resource entities. + */ +int +rctl_incr_locked_mem(proc_t *p, kproject_t *proj, rctl_qty_t inc, + int chargeproc) +{ + kproject_t *projp; + zone_t *zonep; + rctl_entity_p_t e; + int ret = 0; + + ASSERT(p != NULL); + ASSERT(MUTEX_HELD(&p->p_lock)); + if (proj != NULL) { + projp = proj; + zonep = zone_find_by_id(projp->kpj_zoneid); + } else { + projp = p->p_task->tk_proj; + zonep = p->p_zone; + } + + mutex_enter(&zonep->zone_rctl_lock); + + e.rcep_p.proj = projp; + e.rcep_t = RCENTITY_PROJECT; + if (projp->kpj_data.kpd_locked_mem + inc > + projp->kpj_data.kpd_locked_mem_ctl) { + if (rctl_test_entity(rc_project_locked_mem, projp->kpj_rctls, + p, &e, inc, 0) & RCT_DENY) { + ret = EAGAIN; + goto out; + } + } + e.rcep_p.zone = zonep; + e.rcep_t = RCENTITY_ZONE; + if (zonep->zone_locked_mem + inc > zonep->zone_locked_mem_ctl) { + if (rctl_test_entity(rc_zone_locked_mem, zonep->zone_rctls, + p, &e, inc, 0) & RCT_DENY) { + ret = EAGAIN; + goto out; + } + } + + zonep->zone_locked_mem += inc; + projp->kpj_data.kpd_locked_mem += inc; + if (chargeproc != 0) { + p->p_locked_mem += inc; + } +out: + mutex_exit(&zonep->zone_rctl_lock); + if (proj != NULL) + zone_rele(zonep); + return (ret); +} + +/* + * rctl_decr_locked_mem(proc_t *p, kproject_t *proj, rctl_qty_t inc) + * + * Decrements the amount of locked memory on a project and + * zone. If proj is NULL, the proj and zone of proc_t p is used. If + * creditproc is non-zero, then the quantity of locked memory is subtracted + * from p->p_locked_mem. + * + * Return values + * none + */ +void +rctl_decr_locked_mem(proc_t *p, kproject_t *proj, rctl_qty_t inc, + int creditproc) +{ + kproject_t *projp; + zone_t *zonep; + + if (proj != NULL) { + projp = proj; + zonep = zone_find_by_id(projp->kpj_zoneid); + } else { + ASSERT(p != NULL); + ASSERT(MUTEX_HELD(&p->p_lock)); + projp = p->p_task->tk_proj; + zonep = p->p_zone; + } + + mutex_enter(&zonep->zone_rctl_lock); + zonep->zone_locked_mem -= inc; + projp->kpj_data.kpd_locked_mem -= inc; + if (creditproc != 0) { + ASSERT(p != NULL); + ASSERT(MUTEX_HELD(&p->p_lock)); + p->p_locked_mem -= inc; + } + mutex_exit(&zonep->zone_rctl_lock); + if (proj != NULL) + zone_rele(zonep); +} |