| 990 | } |
| 991 | |
| 992 | void |
| 993 | racct_proc_exit(struct proc *p) |
| 994 | { |
| 995 | struct timeval wallclock; |
| 996 | uint64_t pct_estimate, pct, runtime; |
| 997 | int i; |
| 998 | |
| 999 | if (!racct_enable) |
| 1000 | return; |
| 1001 | |
| 1002 | PROC_LOCK(p); |
| 1003 | /* |
| 1004 | * We don't need to calculate rux, proc_reap() has already done this. |
| 1005 | */ |
| 1006 | runtime = cputick2usec(p->p_rux.rux_runtime); |
| 1007 | #ifdef notyet |
| 1008 | KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime")); |
| 1009 | #else |
| 1010 | if (runtime < p->p_prev_runtime) |
| 1011 | runtime = p->p_prev_runtime; |
| 1012 | #endif |
| 1013 | microuptime(&wallclock); |
| 1014 | timevalsub(&wallclock, &p->p_stats->p_start); |
| 1015 | if (wallclock.tv_sec > 0 || wallclock.tv_usec > 0) { |
| 1016 | pct_estimate = (1000000 * runtime * 100) / |
| 1017 | ((uint64_t)wallclock.tv_sec * 1000000 + |
| 1018 | wallclock.tv_usec); |
| 1019 | } else |
| 1020 | pct_estimate = 0; |
| 1021 | pct = racct_getpcpu(p, pct_estimate); |
| 1022 | |
| 1023 | RACCT_LOCK(); |
| 1024 | racct_set_locked(p, RACCT_CPU, runtime, 0); |
| 1025 | racct_add_cred_locked(p->p_ucred, RACCT_PCTCPU, pct); |
| 1026 | |
| 1027 | KASSERT(p->p_racct->r_resources[RACCT_RSS] == 0, |
| 1028 | ("process reaped with %ju allocated for RSS\n", |
| 1029 | p->p_racct->r_resources[RACCT_RSS])); |
| 1030 | for (i = 0; i <= RACCT_MAX; i++) { |
| 1031 | if (p->p_racct->r_resources[i] == 0) |
| 1032 | continue; |
| 1033 | if (!RACCT_IS_RECLAIMABLE(i)) |
| 1034 | continue; |
| 1035 | racct_set_locked(p, i, 0, 0); |
| 1036 | } |
| 1037 | |
| 1038 | #ifdef RCTL |
| 1039 | rctl_racct_release(p->p_racct); |
| 1040 | #endif |
| 1041 | racct_destroy_locked(&p->p_racct); |
| 1042 | RACCT_UNLOCK(); |
| 1043 | PROC_UNLOCK(p); |
| 1044 | } |
| 1045 | |
| 1046 | /* |
| 1047 | * Called after credentials change, to move resource utilisation |
no test coverage detected