static int racct_add_locked(struct proc *p, int resource, uint64_t amount) { #ifdef RCTL int error; #endif if (p->p_flag & P_SYSTEM) return (0); SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0); /* * We need proc lock to dereference p->p_ucred. */ PROC_LOCK_ASSERT(p, MA_OWNED); #ifdef RCTL error = rctl_enforce(p, resource, amount); if (error && RACCT_IS_DENIABLE(resource)) { SDT_PROBE(racct, kernel, rusage, add_failure, p, resource, amount, 0, 0); return (error); } #endif racct_alloc_resource(p->p_racct, resource, amount); racct_add_cred_locked(p->p_ucred, resource, amount); return (0); }
static void racct_destroy_locked(struct racct **racctp) { int i; struct racct *racct; SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0); mtx_assert(&racct_lock, MA_OWNED); KASSERT(racctp != NULL, ("NULL racctp")); KASSERT(*racctp != NULL, ("NULL racct")); racct = *racctp; for (i = 0; i <= RACCT_MAX; i++) { if (RACCT_IS_SLOPPY(i)) continue; if (!RACCT_IS_RECLAIMABLE(i)) continue; KASSERT(racct->r_resources[i] == 0, ("destroying non-empty racct: " "%ju allocated for resource %d\n", racct->r_resources[i], i)); } uma_zfree(racct_zone, racct); *racctp = NULL; }
static void ignored(const struct tesla_class *tcp, uint32_t symbol, const struct tesla_key *tkp) { SDT_PROBE(tesla, automata, event, ignored, tcp, symbol, tkp, 0, 0); }
static void no_instance(struct tesla_class *tcp, uint32_t symbol, const struct tesla_key *tkp) { char instbuf[200]; char *c = instbuf; const char *end = instbuf + sizeof(instbuf); SAFE_SPRINTF(c, end, "%d/%d instances\n", tcp->tc_limit - tcp->tc_free, tcp->tc_limit); for (uint32_t i = 0; i < tcp->tc_limit; i++) { const struct tesla_instance *inst = tcp->tc_instances + i; if (!tesla_instance_active(inst)) continue; SAFE_SPRINTF(c, end, " %2u: state %d, ", i, inst->ti_state); c = key_string(c, end, &inst->ti_key); SAFE_SPRINTF(c, end, "\n"); } char keybuf[20]; key_string(keybuf, keybuf + sizeof(keybuf), tkp); SDT_PROBE(tesla, automata, fail, no_instance, tcp, instbuf, symbol, keybuf, 0); }
/* * Decrease allocation of 'resource' by 'amount' for process 'p'. */ void racct_sub(struct proc *p, int resource, uint64_t amount) { if (p->p_flag & P_SYSTEM) return; SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0); /* * We need proc lock to dereference p->p_ucred. */ PROC_LOCK_ASSERT(p, MA_OWNED); KASSERT(RACCT_IS_RECLAIMABLE(resource), ("racct_sub: called for non-reclaimable resource %d", resource)); mtx_lock(&racct_lock); KASSERT(amount <= p->p_racct->r_resources[resource], ("racct_sub: freeing %ju of resource %d, which is more " "than allocated %jd for %s (pid %d)", amount, resource, (intmax_t)p->p_racct->r_resources[resource], p->p_comm, p->p_pid)); racct_alloc_resource(p->p_racct, resource, -amount); racct_sub_cred_locked(p->p_ucred, resource, amount); mtx_unlock(&racct_lock); }
static void clone(struct tesla_class *tcp, struct tesla_instance *origp, struct tesla_instance *copyp, const struct tesla_transition *ttp) { SDT_PROBE(tesla, automata, instance, clone, tcp, origp, copyp, ttp, 0); }
static void transition(struct tesla_class *tcp, struct tesla_instance *tip, const struct tesla_transition *ttp) { SDT_PROBE(tesla, automata, event, transition, tcp, tip, ttp, 0, 0); }
static void err(const struct tesla_automaton *tap, uint32_t symbol, int32_t errnum, const char *message) { SDT_PROBE(tesla, automata, fail, other_err, tap, symbol, errnum, message, 0); }
static void bad_transition(struct tesla_class *tcp, struct tesla_instance *tip, uint32_t symbol) { SDT_PROBE(tesla, automata, fail, bad_transition, tcp, tip, symbol, 0, 0); }
void racct_create(struct racct **racctp) { SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0); KASSERT(*racctp == NULL, ("racct already allocated")); *racctp = uma_zalloc(racct_zone, M_WAITOK | M_ZERO); }
static int racct_set_locked(struct proc *p, int resource, uint64_t amount) { int64_t diff; #ifdef RCTL int error; #endif if (p->p_flag & P_SYSTEM) return (0); SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); /* * We need proc lock to dereference p->p_ucred. */ PROC_LOCK_ASSERT(p, MA_OWNED); diff = amount - p->p_racct->r_resources[resource]; #ifdef notyet KASSERT(diff >= 0 || RACCT_IS_RECLAIMABLE(resource), ("racct_set: usage of non-reclaimable resource %d dropping", resource)); #endif #ifdef RCTL if (diff > 0) { error = rctl_enforce(p, resource, diff); if (error && RACCT_IS_DENIABLE(resource)) { SDT_PROBE(racct, kernel, rusage, set_failure, p, resource, amount, 0, 0); return (error); } } #endif racct_alloc_resource(p->p_racct, resource, diff); if (diff > 0) racct_add_cred_locked(p->p_ucred, resource, diff); else if (diff < 0) racct_sub_cred_locked(p->p_ucred, resource, -diff); return (0); }
/* * Prepare a proc for use. */ static int proc_ctor(void *mem, int size, void *arg, int flags) { struct proc *p; p = (struct proc *)mem; SDT_PROBE(proc, kernel, ctor , entry, p, size, arg, flags, 0); EVENTHANDLER_INVOKE(process_ctor, p); SDT_PROBE(proc, kernel, ctor , return, p, size, arg, flags, 0); return (0); }
static void racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount) { struct prison *pr; SDT_PROBE(racct, kernel, rusage, add_cred, cred, resource, amount, 0, 0); racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, amount); racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount); }
/* * Increase allocation of 'resource' by 'amount' for process 'p'. * Doesn't check for limits and never fails. */ void racct_add_force(struct proc *p, int resource, uint64_t amount) { SDT_PROBE(racct, kernel, rusage, add_force, p, resource, amount, 0, 0); /* * We need proc lock to dereference p->p_ucred. */ PROC_LOCK_ASSERT(p, MA_OWNED); mtx_lock(&racct_lock); racct_alloc_resource(p->p_racct, resource, amount); mtx_unlock(&racct_lock); racct_add_cred(p->p_ucred, resource, amount); }
/* * Initialize type-stable parts of a proc (when newly created). */ static int proc_init(void *mem, int size, int flags) { struct proc *p; p = (struct proc *)mem; SDT_PROBE(proc, kernel, init, entry, p, size, flags, 0, 0); p->p_sched = (struct p_sched *)&p[1]; bzero(&p->p_mtx, sizeof(struct mtx)); mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); mtx_init(&p->p_slock, "process slock", NULL, MTX_SPIN | MTX_RECURSE); cv_init(&p->p_pwait, "ppwait"); TAILQ_INIT(&p->p_threads); /* all threads in proc */ EVENTHANDLER_INVOKE(process_init, p); p->p_stats = pstats_alloc(); SDT_PROBE(proc, kernel, init, return, p, size, flags, 0, 0); return (0); }
static void racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount) { struct prison *pr; SDT_PROBE(racct, kernel, rusage, sub_cred, cred, resource, amount, 0, 0); #ifdef notyet KASSERT(RACCT_IS_RECLAIMABLE(resource), ("racct_sub_cred: called for non-reclaimable resource %d", resource)); #endif racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount); for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent) racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource, -amount); racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount); }
void racct_set_force(struct proc *p, int resource, uint64_t amount) { int64_t diff; SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0); /* * We need proc lock to dereference p->p_ucred. */ PROC_LOCK_ASSERT(p, MA_OWNED); mtx_lock(&racct_lock); diff = amount - p->p_racct->r_resources[resource]; racct_alloc_resource(p->p_racct, resource, diff); if (diff > 0) racct_add_cred_locked(p->p_ucred, resource, diff); else if (diff < 0) racct_sub_cred_locked(p->p_ucred, resource, -diff); mtx_unlock(&racct_lock); }
/* * Reclaim a proc after use. */ static void proc_dtor(void *mem, int size, void *arg) { struct proc *p; struct thread *td; /* INVARIANTS checks go here */ p = (struct proc *)mem; td = FIRST_THREAD_IN_PROC(p); SDT_PROBE(proc, kernel, dtor, entry, p, size, arg, td, 0); if (td != NULL) { #ifdef INVARIANTS KASSERT((p->p_numthreads == 1), ("bad number of threads in exiting process")); KASSERT(STAILQ_EMPTY(&p->p_ktr), ("proc_dtor: non-empty p_ktr")); #endif /* Free all OSD associated to this thread. */ osd_thread_exit(td); } EVENTHANDLER_INVOKE(process_dtor, p); if (p->p_ksi != NULL) KASSERT(! KSI_ONQ(p->p_ksi), ("SIGCHLD queue")); SDT_PROBE(proc, kernel, dtor, return, p, size, arg, 0, 0); }
static void accept(struct tesla_class *tcp, struct tesla_instance *tip) { SDT_PROBE(tesla, automata, success, accept, tcp, tip, 0, 0, 0); }
static void sunset(enum tesla_context c, const struct tesla_lifetime *tl) { SDT_PROBE(tesla, automata, lifetime, sunset, c, tl, 0, 0, 0); }
static void new_instance(struct tesla_class *tcp, struct tesla_instance *tip) { SDT_PROBE(tesla, automata, instance, create, tcp, tip, 0, 0, 0); }