1f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan/* 2f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * tsacct.c - System accounting over taskstats interface 3f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * 4f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * Copyright (C) Jay Lan, <jlan@sgi.com> 5f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * 6f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * 7f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * This program is free software; you can redistribute it and/or modify 8f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * it under the terms of the GNU General Public License as published by 9f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * the Free Software Foundation; either version 2 of the License, or 10f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * (at your option) any later version. 11f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * 12f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * This program is distributed in the hope that it will be useful, 13f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * but WITHOUT ANY WARRANTY; without even the implied warranty of 14f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * GNU General Public License for more details. 16f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * 17f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan */ 18f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 19f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan#include <linux/kernel.h> 20f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan#include <linux/sched.h> 21f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan#include <linux/tsacct_kern.h> 22f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan#include <linux/acct.h> 23db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan#include <linux/jiffies.h> 24d559db086ff5be9bcc259e5aa50bf3d881eaf1d1KAMEZAWA Hiroyuki#include <linux/mm.h> 25f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 26f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan/* 27f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan * fill in basic accounting fields 28f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan */ 294bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biedermanvoid bacct_add_tsk(struct user_namespace *user_ns, 304bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman struct pid_namespace *pid_ns, 314bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman struct taskstats *stats, struct task_struct *tsk) 32f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan{ 33c69e8d9c01db2adc503464993c358901c9af9de4David Howells const struct cred *tcred; 346fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker cputime_t utime, stime, utimescaled, stimescaled; 35ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner u64 delta; 36f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 37f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan BUILD_BUG_ON(TS_COMM_LEN < TASK_COMM_LEN); 38f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 39ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner /* calculate task elapsed time in nsec */ 40ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner delta = ktime_get_ns() - tsk->start_time; 41ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner /* Convert to micro seconds */ 42ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner do_div(delta, NSEC_PER_USEC); 43ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner stats->ac_etime = delta; 44ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner /* Convert to seconds for btime */ 45ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner do_div(delta, USEC_PER_SEC); 46ccbf62d8a284cf181ac28c8e8407dd077d90dd4bThomas Gleixner stats->ac_btime = get_seconds() - delta; 47f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan if (thread_group_leader(tsk)) { 48f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_exitcode = tsk->exit_code; 49f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan if (tsk->flags & PF_FORKNOEXEC) 50f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_flag |= AFORK; 51f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan } 52f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan if (tsk->flags & PF_SUPERPRIV) 53f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_flag |= ASU; 54f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan if (tsk->flags & PF_DUMPCORE) 55f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_flag |= ACORE; 56f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan if (tsk->flags & PF_SIGNALED) 57f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_flag |= AXSIG; 58f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_nice = task_nice(tsk); 59f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_sched = tsk->policy; 604bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman stats->ac_pid = task_pid_nr_ns(tsk, pid_ns); 6105d5bcd60e8202e5c7b28cf61186043a4d612623Oleg Nesterov rcu_read_lock(); 62c69e8d9c01db2adc503464993c358901c9af9de4David Howells tcred = __task_cred(tsk); 634bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman stats->ac_uid = from_kuid_munged(user_ns, tcred->uid); 644bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman stats->ac_gid = from_kgid_munged(user_ns, tcred->gid); 6505d5bcd60e8202e5c7b28cf61186043a4d612623Oleg Nesterov stats->ac_ppid = pid_alive(tsk) ? 664bd6e32acec66c55c6c1af4672f3216b2ac88e35Eric W. Biederman task_tgid_nr_ns(rcu_dereference(tsk->real_parent), pid_ns) : 0; 6705d5bcd60e8202e5c7b28cf61186043a4d612623Oleg Nesterov rcu_read_unlock(); 686fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 696fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker task_cputime(tsk, &utime, &stime); 706fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker stats->ac_utime = cputime_to_usecs(utime); 716fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker stats->ac_stime = cputime_to_usecs(stime); 726fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 736fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker task_cputime_scaled(tsk, &utimescaled, &stimescaled); 746fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker stats->ac_utimescaled = cputime_to_usecs(utimescaled); 756fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker stats->ac_stimescaled = cputime_to_usecs(stimescaled); 766fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 77f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_minflt = tsk->min_flt; 78f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan stats->ac_majflt = tsk->maj_flt; 79f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 80f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan strncpy(stats->ac_comm, tsk->comm, sizeof(stats->ac_comm)); 81f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan} 82f3cef7a99469afc159fec3a61b42dc7ca5b6824fJay Lan 839acc1853519a0473620d424105f9d49ea5b4e62eJay Lan 849acc1853519a0473620d424105f9d49ea5b4e62eJay Lan#ifdef CONFIG_TASK_XACCT 85db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan 86db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan#define KB 1024 87db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan#define MB (1024*KB) 8858c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds#define KB_MASK (~(KB-1)) 899acc1853519a0473620d424105f9d49ea5b4e62eJay Lan/* 909acc1853519a0473620d424105f9d49ea5b4e62eJay Lan * fill in extended accounting fields 919acc1853519a0473620d424105f9d49ea5b4e62eJay Lan */ 929acc1853519a0473620d424105f9d49ea5b4e62eJay Lanvoid xacct_add_tsk(struct taskstats *stats, struct task_struct *p) 939acc1853519a0473620d424105f9d49ea5b4e62eJay Lan{ 94f0ec1aaf54caddd21c259aea8b2ecfbde4ee4fb9Oleg Nesterov struct mm_struct *mm; 95f0ec1aaf54caddd21c259aea8b2ecfbde4ee4fb9Oleg Nesterov 9649b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim /* convert pages-usec to Mbyte-usec */ 9749b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim stats->coremem = p->acct_rss_mem1 * PAGE_SIZE / MB; 9849b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim stats->virtmem = p->acct_vm_mem1 * PAGE_SIZE / MB; 99f0ec1aaf54caddd21c259aea8b2ecfbde4ee4fb9Oleg Nesterov mm = get_task_mm(p); 100f0ec1aaf54caddd21c259aea8b2ecfbde4ee4fb9Oleg Nesterov if (mm) { 101db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan /* adjust to KB unit */ 102901608d9045146aec6f14a7777ea4b1501c379f0Oleg Nesterov stats->hiwater_rss = get_mm_hiwater_rss(mm) * PAGE_SIZE / KB; 103901608d9045146aec6f14a7777ea4b1501c379f0Oleg Nesterov stats->hiwater_vm = get_mm_hiwater_vm(mm) * PAGE_SIZE / KB; 104f0ec1aaf54caddd21c259aea8b2ecfbde4ee4fb9Oleg Nesterov mmput(mm); 1059acc1853519a0473620d424105f9d49ea5b4e62eJay Lan } 10658c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->read_char = p->ioac.rchar & KB_MASK; 10758c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->write_char = p->ioac.wchar & KB_MASK; 10858c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->read_syscalls = p->ioac.syscr & KB_MASK; 10958c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->write_syscalls = p->ioac.syscw & KB_MASK; 1104a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton#ifdef CONFIG_TASK_IO_ACCOUNTING 11158c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->read_bytes = p->ioac.read_bytes & KB_MASK; 11258c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->write_bytes = p->ioac.write_bytes & KB_MASK; 11358c3c3aa01b455ecb99d61ce73f1444274af696bLinus Torvalds stats->cancelled_write_bytes = p->ioac.cancelled_write_bytes & KB_MASK; 1144a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton#else 1154a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton stats->read_bytes = 0; 1164a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton stats->write_bytes = 0; 1174a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton stats->cancelled_write_bytes = 0; 1184a7864ca638e0a38307962ee8ef122822a351b65Andrew Morton#endif 1199acc1853519a0473620d424105f9d49ea5b4e62eJay Lan} 120db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan#undef KB 121db5fed26b2e0beed939b773dd5896077a1794d65Jay Lan#undef MB 1228f0ab5147951267134612570604cf8341901a80cJay Lan 1236fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbeckerstatic void __acct_update_integrals(struct task_struct *tsk, 1246fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker cputime_t utime, cputime_t stime) 1258f0ab5147951267134612570604cf8341901a80cJay Lan{ 1268f0ab5147951267134612570604cf8341901a80cJay Lan if (likely(tsk->mm)) { 12749b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim cputime_t time, dtime; 12849b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim struct timeval value; 1296d5b5acca9e566515ef3f1ed617e7295c4f94345Heiko Carstens unsigned long flags; 13049b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim u64 delta; 13149b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim 1326d5b5acca9e566515ef3f1ed617e7295c4f94345Heiko Carstens local_irq_save(flags); 1336fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker time = stime + utime; 134648616343cdbe904c585a6c12e323d3b3c72e46fMartin Schwidefsky dtime = time - tsk->acct_timexpd; 13549b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim jiffies_to_timeval(cputime_to_jiffies(dtime), &value); 13649b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim delta = value.tv_sec; 13749b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim delta = delta * USEC_PER_SEC + value.tv_usec; 1388f0ab5147951267134612570604cf8341901a80cJay Lan 1398f0ab5147951267134612570604cf8341901a80cJay Lan if (delta == 0) 1406d5b5acca9e566515ef3f1ed617e7295c4f94345Heiko Carstens goto out; 14149b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim tsk->acct_timexpd = time; 1428f0ab5147951267134612570604cf8341901a80cJay Lan tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm); 1438f0ab5147951267134612570604cf8341901a80cJay Lan tsk->acct_vm_mem1 += delta * tsk->mm->total_vm; 1446d5b5acca9e566515ef3f1ed617e7295c4f94345Heiko Carstens out: 1456d5b5acca9e566515ef3f1ed617e7295c4f94345Heiko Carstens local_irq_restore(flags); 1468f0ab5147951267134612570604cf8341901a80cJay Lan } 1478f0ab5147951267134612570604cf8341901a80cJay Lan} 1488f0ab5147951267134612570604cf8341901a80cJay Lan 1498f0ab5147951267134612570604cf8341901a80cJay Lan/** 1506fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker * acct_update_integrals - update mm integral fields in task_struct 1516fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker * @tsk: task_struct for accounting 1526fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker */ 1536fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbeckervoid acct_update_integrals(struct task_struct *tsk) 1546fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker{ 1556fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker cputime_t utime, stime; 1566fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 1576fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker task_cputime(tsk, &utime, &stime); 1586fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker __acct_update_integrals(tsk, utime, stime); 1596fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker} 1606fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 1616fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker/** 1626fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker * acct_account_cputime - update mm integral after cputime update 1636fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker * @tsk: task_struct for accounting 1646fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker */ 1656fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbeckervoid acct_account_cputime(struct task_struct *tsk) 1666fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker{ 1676fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker __acct_update_integrals(tsk, tsk->utime, tsk->stime); 1686fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker} 1696fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker 1706fac4829ce0ef9b7f24369086ce5f0e9f38d37bcFrederic Weisbecker/** 1718f0ab5147951267134612570604cf8341901a80cJay Lan * acct_clear_integrals - clear the mm integral fields in task_struct 1728f0ab5147951267134612570604cf8341901a80cJay Lan * @tsk: task_struct whose accounting fields are cleared 1738f0ab5147951267134612570604cf8341901a80cJay Lan */ 1748f0ab5147951267134612570604cf8341901a80cJay Lanvoid acct_clear_integrals(struct task_struct *tsk) 1758f0ab5147951267134612570604cf8341901a80cJay Lan{ 17649b5cf34727a6c1be1568ab28e89a2d9a6bf51e0Jonathan Lim tsk->acct_timexpd = 0; 1778f0ab5147951267134612570604cf8341901a80cJay Lan tsk->acct_rss_mem1 = 0; 1788f0ab5147951267134612570604cf8341901a80cJay Lan tsk->acct_vm_mem1 = 0; 1798f0ab5147951267134612570604cf8341901a80cJay Lan} 1809acc1853519a0473620d424105f9d49ea5b4e62eJay Lan#endif 181