Skip to contentSkip to conversation

CSA csa_io: accounting IO data gathering

PATCH In review Jay Lan 2 participants 5 messages Sep 9, 2004 – Sep 17, 2004

Subsystems (9)
lore
Share & tools
lore
author
#1 lore raw

PATCH 2/4 CSA csa_mm: accounting mm data gathering

In reply to Jay Lan

Linux Comprehensive System Accounting (CSA) is a set of C programs and shell scripts that, like other accounting packages, provide methods for collecting per-process resource usage data, monitoring disk usage, and charging fees to specific login accounts.

The CSA patchset includes csa_io, csa_mm, csa_eop and csa_module. Patches csa_io, csa_mm, and csa_eop are responsible for system accounting data collection and are independent of each other.

The csa_mm is a patch that gathers mm activity data.

Please find CSA project at http://oss.sgi.com/projects/csa. This set of csa patches has been tested with the pagg and job kernel patches. The information of pagg and job project can be found at
http://oss.sgi.com/projects/pagg/

fs/exec.c +4 -0
Index: linux/fs/exec.c
===================================================================
@@ -47,6 +47,7 @@
 #include <linux/syscalls.h>
 #include <linux/rmap.h>
 #include <linux/pagg.h>
+#include <linux/csa_internal.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1145,6 +1146,9 @@
 
 		/* execve success */
 		security_bprm_free(&bprm);
+		/* no-op if CONFIG_CSA not set */
+                csa_update_integrals();
+                update_mem_hiwater();
 		return retval;
 	}
 
include/linux/csa_internal.h new file +70 -0

70 lines not on this page · raw message

include/linux/sched.h +19 -0
Index: linux/include/linux/sched.h
===================================================================
@@ -229,6 +229,8 @@
 	struct kioctx		*ioctx_list;
 
 	struct kioctx		default_kioctx;
+
+	unsigned long hiwater_rss, hiwater_vm;
 };
 
 extern int mmlist_nr;
@@ -525,6 +527,10 @@
 
 /* i/o counters(bytes read/written, #syscalls, waittime */
         unsigned long rchar, wchar, syscr, syscw, bwtime;
+#if defined(CONFIG_CSA) || defined(CONFIG_CSA_MODULE)
+	u64 csa_rss_mem1, csa_vm_mem1;
+	clock_t csa_stimexpd;
+#endif
 
 #ifdef CONFIG_NUMA
   	struct mempolicy *mempolicy;
@@ -873,6 +879,19 @@
 /* Remove the current tasks stale references to the old mm_struct */
 extern void mm_release(struct task_struct *, struct mm_struct *);
 
+/* Update highwater values */
+static inline void update_mem_hiwater(void)
+{
+	if (current->mm) {
+		if (current->mm->hiwater_rss < current->mm->rss) {
+			current->mm->hiwater_rss = current->mm->rss;
+		}
+		if (current->mm->hiwater_vm < current->mm->total_vm) {
+			current->mm->hiwater_vm = current->mm->total_vm;
+		}
+	}
+}
+
 extern int  copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
 extern void flush_thread(void);
 extern void exit_thread(void);
kernel/exit.c +4 -0
Index: linux/kernel/exit.c
===================================================================
@@ -24,6 +24,7 @@
 #include <linux/proc_fs.h>
 #include <linux/mempolicy.h>
 #include <linux/pagg.h>
+#include <linux/csa_internal.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -821,6 +822,9 @@
 		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
 	}
 
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
 	acct_process(code);
 	__exit_mm(tsk);
 
kernel/fork.c +6 -1
Index: linux/kernel/fork.c
===================================================================
@@ -37,7 +37,7 @@
 #include <linux/audit.h>
 #include <linux/rmap.h>
 #include <linux/pagg.h>
-
+#include <linux/csa_internal.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -576,6 +576,9 @@
 	if (retval)
 		goto free_pt;
 
+	mm->hiwater_rss = mm->rss;
+	mm->hiwater_vm = mm->total_vm;	
+
 good_mm:
 	tsk->mm = mm;
 	tsk->active_mm = mm;
@@ -966,6 +969,8 @@
 	p->cutime = p->cstime = 0;
 	p->rchar = p->wchar = p->syscr = p->syscw = 0;
 	p->bwtime = 0;
+	/* no-op if CONFIG_CSA not set */
+	csa_clear_integrals(p);
 	p->lock_depth = -1;		/* -1 = no lock */
 	p->start_time = get_jiffies_64();
 	p->security = NULL;
mm/memory.c +19 -2
Index: linux/mm/memory.c
===================================================================
@@ -44,6 +44,7 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/rmap.h>
+#include <linux/csa_internal.h>
 #include <linux/module.h>
 #include <linux/init.h>
 
@@ -605,6 +606,8 @@
 	tlb = tlb_gather_mmu(mm, 0);
 	unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
 	tlb_finish_mmu(tlb, address, end);
+	/* no-op unless CONFIG_CSA is set */
+        csa_update_integrals();
 	spin_unlock(&mm->page_table_lock);
 }
 
@@ -1095,9 +1098,12 @@
 	spin_lock(&mm->page_table_lock);
 	page_table = pte_offset_map(pmd, address);
 	if (likely(pte_same(*page_table, pte))) {
-		if (PageReserved(old_page))
+		if (PageReserved(old_page)) {
 			++mm->rss;
-		else
+			/* no-op if CONFIG_CSA not set */
+			csa_update_integrals();
+			update_mem_hiwater();
+		} else
 			page_remove_rmap(old_page);
 		break_cow(vma, new_page, address, page_table);
 		lru_cache_add_active(new_page);
@@ -1378,6 +1384,10 @@
 		remove_exclusive_swap_page(page);
 
 	mm->rss++;
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
+  
 	pte = mk_pte(page, vma->vm_page_prot);
 	if (write_access && can_share_swap_page(page)) {
 		pte = maybe_mkwrite(pte_mkdirty(pte), vma);
@@ -1443,6 +1453,9 @@
 			goto out;
 		}
 		mm->rss++;
+		/* no-op if CONFIG_CSA not set */
+		csa_update_integrals();
+		update_mem_hiwater();
 		entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
 							 vma->vm_page_prot)),
 				      vma);
@@ -1552,6 +1565,10 @@
 	if (pte_none(*page_table)) {
 		if (!PageReserved(new_page))
 			++mm->rss;
+		/* no-op if CONFIG_CSA not set */
+		csa_update_integrals();
+		update_mem_hiwater();
+
 		flush_icache_page(vma, new_page);
 		entry = mk_pte(new_page, vma->vm_page_prot);
 		if (write_access)
mm/mmap.c +10 -0
Index: linux/mm/mmap.c
===================================================================
@@ -20,6 +20,7 @@
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
+#include <linux/csa_internal.h>
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
@@ -988,6 +989,9 @@
 					pgoff, flags & MAP_NONBLOCK);
 		down_write(&mm->mmap_sem);
 	}
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
 	return addr;
 
 unmap_and_free_vma:
@@ -1227,6 +1231,9 @@
 	vma->vm_mm->total_vm += grow;
 	if (vma->vm_flags & VM_LOCKED)
 		vma->vm_mm->locked_vm += grow;
+	/* no-op if CONFIG_CSA_JOB_ACCT not set */
+	csa_update_integrals();
+	update_mem_hiwater();
 	anon_vma_unlock(vma);
 	return 0;
 }
@@ -1688,6 +1695,9 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
 	return addr;
 }
 
mm/mremap.c +8 -0
Index: linux/mm/mremap.c
===================================================================
@@ -16,6 +16,7 @@
 #include <linux/fs.h>
 #include <linux/highmem.h>
 #include <linux/security.h>
+#include <linux/csa_internal.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -231,6 +232,10 @@
 					   new_addr + new_len);
 	}
 
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
+
 	return new_addr;
 }
 
@@ -363,6 +368,9 @@
 				make_pages_present(addr + old_len,
 						   addr + new_len);
 			}
+			/* no-op if CONFIG_CSA not set */
+			csa_update_integrals();
+			update_mem_hiwater();
 			ret = addr;
 			goto out;
 		}
mm/rmap.c +5 -0
Index: linux/mm/rmap.c
===================================================================
@@ -29,6 +29,7 @@
 #include <linux/swapops.h>
 #include <linux/slab.h>
 #include <linux/init.h>
+#include <linux/csa_internal.h>
 #include <linux/rmap.h>
 
 #include <asm/tlbflush.h>
@@ -515,6 +516,8 @@
 	mm->rss--;
 	BUG_ON(!page->mapcount);
 	page->mapcount--;
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
 	page_cache_release(page);
 
 out_unmap:
@@ -614,6 +617,8 @@
 
 		page_remove_rmap(page);
 		page_cache_release(page);
+		/* no-op if CONFIG_CSA not set */
+		csa_update_integrals();
 		mm->rss--;
 		(*mapcount)--;
 	}
mm/swapfile.c +4 -0
Index: linux/mm/swapfile.c
===================================================================
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/rmap.h>
 #include <linux/security.h>
+#include <linux/csa_internal.h>
 #include <linux/backing-dev.h>
 
 #include <asm/pgtable.h>
@@ -435,6 +436,9 @@
 	set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot)));
 	page_add_anon_rmap(page, vma, address);
 	swap_free(entry);
+	/* no-op if CONFIG_CSA not set */
+	csa_update_integrals();
+	update_mem_hiwater();
 }
 
 /* vma->vm_mm->page_table_lock is held */
author
#2 lore raw

PATCH 3/4 CSA csa_eop: accounting end-of-process hook

In reply to Jay Lan

Linux Comprehensive System Accounting (CSA) is a set of C programs and shell scripts that, like other accounting packages, provide methods for collecting per-process resource usage data, monitoring disk usage, and charging fees to specific login accounts.

The CSA patchset includes csa_io, csa_mm, csa_eop and csa_module. Patches csa_io, csa_mm, and csa_eop are responsible for system accounting data collection and are independent of each other.

csa_eop is a patch that provides a hook for end-of-process handling.

Please find CSA project at http://oss.sgi.com/projects/csa. This set of csa patches has been tested with the pagg and job kernel patches. The information of pagg and job project can be found at
http://oss.sgi.com/projects/pagg/

kernel/exit.c +5 -0
Index: linux/kernel/exit.c
===================================================================
@@ -33,6 +33,8 @@
 
 extern void sem_exit (void);
 extern struct task_struct *child_reaper;
+void (*do_eop_acct) (int, struct task_struct *) = NULL;
+EXPORT_SYMBOL(do_eop_acct);
 
 int getrusage(struct task_struct *, int, struct rusage __user *);
 
@@ -826,6 +828,9 @@
 	csa_update_integrals();
 	update_mem_hiwater();
 	acct_process(code);
+	/* Handle end-of-process accounting */
+	if (do_eop_acct != NULL)
+		do_eop_acct(code, tsk);
 	__exit_mm(tsk);
 
 	exit_sem(tsk);
include/linux/acct.h +7 -0
Index: linux/include/linux/acct.h
===================================================================
@@ -185,6 +185,13 @@
        return x;
 }
 
+/*
+ * extern declaration that provides the hook needed for processing of
+ * end-of-process accounting record
+ *
+ */
+extern void (*do_eop_acct) (int, struct task_struct *);
+
 #endif  /* __KERNEL */
 
 #endif	/* _LINUX_ACCT_H */
author
#4 lore raw

PATCH 4/4 CSA csa_module: CSA loadable module

In reply to Jay Lan

Linux Comprehensive System Accounting (CSA) is a set of C programs and shell scripts that, like other accounting packages, provide methods for collecting per-process resource usage data, monitoring disk usage, and charging fees to specific login accounts.

The CSA patchset includes csa_io, csa_mm, csa_eop and csa_module. Patches csa_io, csa_mm, and csa_eop are responsible for system accounting data collection and are independent of each other.

csa_module is a patch to build a CSA loadable module. This module works with csa-2.0.0 (or later) to report system accounting data of the host system.

Please find CSA project at http://oss.sgi.com/projects/csa. This set of csa patches has been tested with the pagg and job kernel patches. The information of pagg and job project can be found at
http://oss.sgi.com/projects/pagg/

include/linux/csa.h new file +524 -0
Index: linux/include/linux/csa.h
===================================================================
@@ -0,0 +1,524 @@
+/*
+ * Copyright (c) 2000-2002 Silicon Graphics, Inc and LANL  All Rights Reserved.
+ * Copyright (c) 2004 Silicon Graphics, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as 
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details. 
+ *
+ * You should have received a copy of the GNU General Public License along 
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ */
+/*
+ *  CSA (Comprehensive System Accounting)
+ *  Job Accounting for Linux
+ *
+ *  This header file contains the definitions needed for job
+ *  accounting. The kernel CSA accounting module code and all
+ *  user-level programs that try to write or process the binary job 
+ *  accounting data must include this file.
+ *
+ *
+ */
+
+#ifndef _LINUX_CSA_H
+#define _LINUX_CSA_H
+
+#ifndef __KERNEL__
+#include <stdint.h>
+#include <sys/types.h>
+#endif
+
+/*
+ *  accounting flags per-process
+ */
+#define AFORK		0x01	/* fork, but did not exec */
+#define ASU		0x02	/* super-user privileges */
+#define ACKPT   	0x04	/* process has been checkpointed */
+#define ACORE		0x08	/* produced corefile */
+#define AXSIG		0x10	/* killed by a signal */
+#define AMORE		0x20	/* more CSA acct records for this process */
+#define AINC		0x40	/* incremental accounting record */
+
+/*
+ * Magic number - for achead.ah_magic in the 1st header.  The magic number
+ *                in the 2nd header is the inverse of this.
+ */
+#define ACCT_MAGIC_BIG          030510  /* big-endian */
+#define ACCT_MAGIC_LITTLE       030512  /* little-endian */
+#ifdef __LITTLE_ENDIAN
+#define ACCT_MAGIC ACCT_MAGIC_LITTLE
+#else
+#define ACCT_MAGIC ACCT_MAGIC_BIG
+#endif
+
+/*
+ * Record types - for achead.ah_type in the 1st header.
+ */
+#define	ACCT_KERNEL_CSA		0001	/* Kernel: CSA base record */
+#define	ACCT_KERNEL_MEM		0002	/* Kernel: memory record */
+#define	ACCT_KERNEL_IO		0004	/* Kernel: input/output record */
+#define	ACCT_KERNEL_MT 		0006	/* Kernel: multi-tasking record */
+#define	ACCT_KERNEL_MPP		0010	/* Kernel: multi-PE appl record */
+#define	ACCT_KERNEL_SOJ		0012	/* Kernel: start-of-job record */
+#define	ACCT_KERNEL_EOJ		0014	/* Kernel: end-of-job record */
+#define	ACCT_KERNEL_CFG		0020	/* Kernel: configuration record */
+
+#define	ACCT_KERNEL_SITE0	0100	/* Kernel: reserved for site */
+#define	ACCT_KERNEL_SITE1	0101	/* Kernel: reserved for site */
+
+#define	ACCT_DAEMON_NQS		0120	/* Daemon: NQS record */
+#define	ACCT_DAEMON_WKMG      	0122	/* Daemon: workload management record,
+					           i.e., LSF */
+#define	ACCT_DAEMON_TAPE	0124	/* Daemon: tape record */
+#define	ACCT_DAEMON_DMIG	0126	/* Daemon: data migration record */
+#define	ACCT_DAEMON_SOCKET	0130	/* Daemon: socket record */
+
+#define	ACCT_DAEMON_SITE0	0200	/* Daemon: reserved for site */
+#define	ACCT_DAEMON_SITE1	0201	/* Daemon: reserved for site */
+
+#define	ACCT_JOB_HEADER		0220	/* csabuild: job header record */
+#define	ACCT_CACCT		0222	/* cacct:    consolidated data */
+#define	ACCT_CMS		0224	/* cms:      command summary data */
+
+/* Record types - for achead.ah_type in the 2nd header. */
+#define	ACCT_MEM	1<<0	/* Process generated memory record */
+#define	ACCT_IO		1<<1	/* Process generated I/O record */
+#define	ACCT_MT		1<<2	/* Process used multi-tasking */
+#define	ACCT_MPP	1<<3	/* Process used multi-PE */
+
+/*
+ * Record revision levels.
+ *
+ * These are incremented to indicate that a record's format has changed since
+ * a previous release.
+ */
+#define	REV_CSA		02400	/* Kernel: CSA base record */
+#define	REV_MEM		02400	/* Kernel: memory record */
+#define	REV_IO		02400	/* Kernel: I/O record */
+#define	REV_MT 		02400	/* Kernel: multi-tasking record */
+#define	REV_MPP		02400	/* Kernel: multi-PE appl record */
+#define	REV_SOJ		02400	/* Kernel: start-of-job record */
+#define	REV_EOJ		02400	/* Kernel: end-of-job record */
+#define	REV_CFG		02400	/* Kernel: configuration record */
+
+#define REV_NQS		02400 	/* Daemon: NQS record */
+#define REV_WKMG	02400 	/* Daemon: workload management (i.e., LSF)
+				           record */
+#define REV_TAPE	02400	/* Daemon: tape record */
+#define REV_DMIG	02400	/* Daemon: data migration record */
+#define REV_SOCKET	02400	/* Daemon: socket record */
+
+#define REV_JOB		02400	/* csabuild: job header record */
+#define REV_CACCT	02400	/* cacct:    consolidated data */
+#define REV_CMS		02400	/* cms:      command summary data */
+
+/*
+ * Record header
+ */
+struct achead
+{
+	unsigned int	ah_magic:17;	/* Magic */
+	unsigned int	ah_revision:15;	/* Revision */
+	unsigned int	ah_type:8;	/* Record type */
+	unsigned int	ah_flag:8;	/* Record flags */
+	unsigned int	ah_size:16;	/* Size of record */
+};
+
+/*
+ *  In order to keep the accounting records the same size across different
+ *  machine types, record fields will be defined to types that won't
+ *  vary (i.e. uint_32_t instead of uid_t).
+*/
+
+/*
+ * Per process base accounting record.
+ */
+struct acctcsa
+{
+	struct achead	ac_hdr1;	/* Header */
+	struct achead	ac_hdr2;	/* 2nd header for continued records */ 
+	double 		ac_sbu;		/* System billing units */
+	unsigned int	ac_stat:8;	/* Exit status */
+	unsigned int	ac_nice:8;	/* Nice value */
+	unsigned char	ac_sched;	/* Scheduling discipline */
+	unsigned int	:8;		/* Unused */
+	uint32_t	ac_uid;		/* User ID */
+	uint32_t	ac_gid;		/* Group ID */
+	uint64_t	ac_ash;		/* Array session handle */
+	uint64_t	ac_jid;		/* Job ID */
+	uint64_t	ac_prid;	/* Project ID -> account ID */
+	uint32_t	ac_pid;		/* Process ID */
+	uint32_t	ac_ppid;	/* Parent process ID */
+	time_t		ac_btime;	/* Beginning time [sec since 1970] */
+	char		ac_comm[16];	/* Command name */
+/*	CPU resource usage information. */
+	uint64_t	ac_etime;	/* Elapsed time [usecs] */
+	uint64_t	ac_utime;	/* User CPU time [usec] */
+	uint64_t	ac_stime;	/* System CPU time [usec] */
+	uint64_t	ac_spare;	/* Spare field */
+	uint64_t        ac_spare1;	/* Spare field */
+};
+
+/*
+ * Memory accounting structure
+ * This structure is part of the acctmem record.
+ */
+struct memint
+{
+	uint64_t	himem;	/* Hiwater memory usage [Kbytes] */
+	uint64_t	mem1;	/* Memory integral 1 [Mbytes/uSec] */
+	uint64_t	mem2;	/* Memory integral 2 - not used */
+	uint64_t	mem3;	/* Memory integral 3 - not used */
+};
+
+/*
+ * Memory accounting record
+ */
+struct acctmem
+{
+	struct achead	ac_hdr;		/* Header */
+	double 		ac_sbu;		/* System billing units */
+	struct memint	ac_core;	/* Core memory integrals */
+	struct memint	ac_virt;	/* Virtual memory integrals */
+	uint64_t	ac_pgswap;	/* # of pages swapped  */
+	uint64_t	ac_minflt;	/* # of minor page faults */
+	uint64_t	ac_majflt;	/* # of major page faults */
+	uint64_t	ac_spare;	/* Spare field */
+};
+
+/*
+ * Input/Output accounting record
+ */
+struct acctio
+{
+	struct achead		ac_hdr;	   /* Header */
+	double 			ac_sbu;	   /* System billing units */
+	uint64_t	ac_bwtime; /* Block I/O wait time [usecs] */
+	uint64_t	ac_rwtime; /* Raw I/O wait time [usecs] */
+	uint64_t	ac_chr;    /* Number of chars (bytes) read */
+	uint64_t	ac_chw;	   /* Number of chars (bytes) written */
+	uint64_t	ac_bkr;	   /* Number of blocks read */
+	uint64_t	ac_bkw;	   /* Number of blocks written */
+	uint64_t	ac_scr;	   /* Number of read system calls */
+	uint64_t	ac_scw;	   /* Number of write system calls */
+	uint64_t	ac_spare;  /* Spare field */
+};
+
+/*
+ * Multi-tasking accounting structure
+ * This structure is part of the acctmt record.
+ */
+struct mtask
+{
+	uint64_t	mt;		/* CPU+1 connect time [usecs] */
+	uint64_t	spare1;		/* Spare field */
+	uint64_t	spare2;		/* Spare field */
+};
+
+/*
+ * Multi-tasking accounting record - currently not used, adapted from UNICOS.
+ */
+#define	ACCT_MAXCPUS	512	/* Maximum number of CPUs supported */
+
+struct acctmt
+{
+	struct achead	ac_hdr;		/* Header */
+	double 		ac_sbu;		/* System billing units */
+	unsigned int	ac_numcpu:16;	/* Max number of CPUs used */
+	unsigned int	ac_maxcpu:16;	/* Max number of CPUs available */
+	unsigned int	:32;		/* Unused */
+	int64_t		ac_smwtime;	/* Semaphore wait time [usec] */
+	struct mtask	ac_mttime[ACCT_MAXCPUS]; /* Time connected to (i+1)
+						    CPUs [usec] */
+};
+
+/*
+ * MPP PE accounting structure - MPP hardware specific.
+ * This structure is part of the acctmpp record.
+ */
+struct acctpe
+{
+	uint64_t	utime;	 /* User CPU time [usecs] */
+	uint64_t	srtime;	 /* System & remote CPU time [usecs] */
+	uint64_t	io;	 /* Number of chars transferred */
+};
+
+/*
+ * MPP accounting record - MPP hardware specific; currently not used.
+ */
+#define	ACCT_MAXPES	1024	/* Maximum number of PEs */
+
+struct acctmpp
+{
+	struct achead 	ac_hdr;		/* Header */
+	double 		ac_sbu;		/* System billing units */
+	unsigned int	ac_mpbesu:8;	/* Number of BESUs used	*/
+	unsigned int	ac_mppe:24;	/* Number of PEs used */
+	uint64_t	ac_himem; /* Maximum memory hiwater [Mbytes] */
+
+	struct acctpe	ac_mpp[ACCT_MAXPES];	/* Per PE information */
+};
+
+/*
+ * MPP Detailed PE accounting structure - currently not used
+ */
+struct acctdpe
+{
+	struct achead 	ac_hdr;		/* Header */
+
+	uint64_t	utime;		/* User CPU time [usecs] */
+	uint64_t	stime;		/* System CPU time [usecs] */
+	uint64_t	rtime;		/* Remote CPU time [usecs] */
+
+	uint64_t	ctime;		/* Connect CPU time [usecs] */
+	uint64_t	io;		/* Number of chars transferred */
+	uint64_t	spare;		/* Spare field */
+};
+
+/*
+ * Start-of-job record
+ * Written when a job is created.
+ */
+
+typedef enum
+{
+        AC_INIT_LOGIN,          /* Initiated by login */
+        AC_INIT_NQS,            /* Initiated by NQS */
+        AC_INIT_LSF,            /* Initiated by LSF */
+        AC_INIT_CROND,          /* Initiated by crond */
+        AC_INIT_FTPD,           /* Initiated by ftpd */
+        AC_INIT_INETD,          /* Initiated by inetd */
+        AC_INIT_TELNETD,        /* Initiated by telnetd */
+        AC_INIT_MAX
+} ac_inittype;
+
+
+#define AC_SOJ	1	/* Start-of-job record type */
+#define AC_ROJ	2	/* Restart-of-job record type */
+
+struct acctsoj
+{
+	struct achead 	ac_hdr;		/* Header */
+	unsigned int	ac_type:8;	/* Record type (AC_SOJ, AC_ROJ) */
+	ac_inittype	ac_init:8;	/* Initiator - currently not used */
+	unsigned int	:16;		/* Unused */
+	uint32_t	ac_uid;		/* User ID */
+	uint64_t	ac_jid;		/* Job ID */
+	time_t	 	ac_btime;	/* Start time [secs since 1970] */
+	time_t	 	ac_rstime;	/* Restart time [secs since 1970] */
+};
+
+/*
+ * End-of-job record
+ * Written when the last process of a job exits.
+ */
+struct accteoj
+{
+	struct achead	ac_hdr1;	/* Header */ 
+	struct achead	ac_hdr2;	/* 2nd header for continued records */ 
+	double 		ac_sbu;		/* System billing units */
+	ac_inittype	ac_init:8;	/* Initiator - currently not used */
+	unsigned int	ac_nice:8;	/* Nice value */
+	unsigned int	:16;		/* Unused */
+	uint32_t	ac_uid;		/* User ID */
+	uint32_t	ac_gid;		/* Group ID */
+	uint64_t	ac_ash;		/* Array session handle; not used */
+	uint64_t	ac_jid;		/* Job ID */
+	uint64_t	ac_prid;	/* Project ID; not used */
+	time_t	 	ac_btime;	/* Job start time [secs since 1970] */
+	time_t  	ac_etime;	/* Job end time   [secs since 1970] */
+	uint64_t	ac_corehimem;	/* Hiwater core mem [Kbytes] */
+	uint64_t	ac_virthimem;	/* Hiwater virt mem [Kbytes] */
+/*	CPU resource usage information. */
+	uint64_t	ac_utime;  /* User CPU time [usec]  */
+	uint64_t	ac_stime; /* System CPU time [usec] */
+	uint32_t	ac_spare;	
+};
+
+/*
+ * Accounting configuration uname structure
+ * This structure is part of the acctcfg record.
+ */
+struct ac_utsname
+{
+	char	 sysname[26];
+	char	 nodename[26];
+	char	 release[42];
+	char	 version[41];
+	char	 machine[26];
+};
+
+/*
+ * Accounting configuration record
+ * Written for accounting configuration changes.
+ */
+typedef enum
+{
+        AC_CONFCHG_BOOT,        /* Boot time (always first) */
+        AC_CONFCHG_FILE,        /* Reporting pacct file change */
+        AC_CONFCHG_ON,          /* Reporting xxx ON */
+        AC_CONFCHG_OFF,         /* Reporting xxx OFF */
+        AC_CONFCHG_INC_DELTA,   /* Report incremental acct clock delta change */        AC_CONFCHG_INC_EVENT,   /* Report incremental accounting event */
+        AC_CONFCHG_MAX
+} ac_eventtype;
+
+struct acctcfg
+{
+	struct achead	ac_hdr;		/* Header */
+	unsigned int	ac_kdmask;	/* Kernel and daemon config mask */
+	unsigned int	ac_rmask;	/* Record configuration mask */
+	int64_t		ac_uptimelen;	/* Bytes from the end of the boot
+					   record to the next boot record */
+	ac_eventtype	ac_event:8;	/* Accounting configuration event */
+	unsigned int	:24;		/* Unused */
+	time_t		ac_boottime;	/* System boot time [secs since 1970]*/
+	time_t		ac_curtime;	/* Current time [secs since 1970] */
+	struct ac_utsname  ac_uname;	/* Condensed uname information */
+};
+
+
+/*
+ * Accounting control status values.
+ */
+typedef	enum
+{
+	ACS_OFF,	/* Accounting stopped for this entry */
+	ACS_ERROFF,	/* Accounting turned off by kernel */
+	ACS_ON		/* Accounting started for this entry */
+} ac_status;
+
+/*
+ * Function codes for CSA library interface
+ */
+typedef	enum
+{
+	AC_START,	/* Start kernel, daemon, or record accounting */
+	AC_STOP,	/* Stop kernel, daemon, or record accounting */
+	AC_HALT,	/* Stop all kernel, daemon, and record accounting */
+	AC_CHECK,	/* Check a kernel, daemon, or record accounting state*/
+	AC_KDSTAT,	/* Check all kernel & daemon accounting states */
+	AC_RCDSTAT,	/* Check all record accounting states */
+	AC_JASTART,	/* Start user job accounting  */
+	AC_JASTOP,	/* Stop user job accounting */
+	AC_WRACCT,	/* Write accounting record for daemon */
+	AC_AUTH,	/* Verify executing user is authorized */
+	AC_INCACCT,	/* Control incremental accounting */
+	AC_MREQ
+} ac_request;
+
+/*
+ * Define the CSA accounting record type indices.
+ */
+typedef	enum
+{
+	ACCT_KERN_CSA,		/* Kernel CSA accounting */
+	ACCT_KERN_JOB_PROC,	/* Kernel job process summary accounting */
+	ACCT_KERN_ASH,		/* Kernel array session summary accounting */
+	ACCT_DMD_NQS, 		/* Daemon NQS accounting */
+	ACCT_DMD_WKMG, 		/* Daemon workload management (i.e. LSF) acct */
+	ACCT_DMD_TAPE,		/* Daemon tape accounting */
+	ACCT_DMD_DMIG,		/* Daemon data migration accounting */
+	ACCT_DMD_SOCKET,	/* Daemon socket accounting */
+	ACCT_DMD_SITE1,		/* Site reserved daemon acct */
+	ACCT_DMD_SITE2,		/* Site reserved daemon acct */
+	ACCT_MAXKDS,		/* Max # kernel and daemon entries */
+
+	ACCT_RCD_MPPDET,	/* Record acct for MPP detail exit info */
+	ACCT_RCD_MEM,		/* Record acct for memory */
+	ACCT_RCD_IO,		/* Record acct for input/output */
+	ACCT_RCD_MT,		/* Record acct for multi-tasking */
+	ACCT_RCD_MPP,		/* Record acct for MPP accumulated info */
+	ACCT_THD_MEM,		/* Record acct for memory size threshhold */
+	ACCT_THD_TIME,		/* Record acct for CPU time threshhold */
+	ACCT_RCD_INCACCT,	/* Record acct for incremental accounting */
+	ACCT_RCD_APPACCT,	/* Record acct for application accounting */
+	ACCT_RCD_SITE1,		/* Site reserved record acct */
+	ACCT_RCD_SITE2,		/* Site reserved record acct */
+	ACCT_MAXRCDS		/* Max # record entries */
+} ac_kdrcd;
+
+#define	ACCT_RCDS	ACCT_RCD_MPPDET /* Record acct low range definition */
+#define	NUM_KDS		(ACCT_MAXKDS - ACCT_KERN_CSA)
+#define	NUM_RCDS	(ACCT_MAXRCDS - ACCT_RCDS)
+#define	NUM_KDRCDS	(NUM_KDS + NUM_RCDS)
+
+
+/*
+ * The following structures are used to get status of a CSA accounting type.
+ */
+
+/*
+ * Accounting entry status structure
+ */
+struct actstat
+{
+	ac_kdrcd	ac_ind;		/* Entry index */
+	ac_status	ac_state;	/* Entry status */
+	int64_t		ac_param;	/* Entry parameter */
+};
+
+/*
+ * Accounting control and status structure
+ */
+#define	ACCT_PATH	128	/* Max path length for accounting file */
+
+struct actctl
+{
+	int	ac_sttnum;		/* Number of status array entries */
+	char	ac_path[ACCT_PATH];	/* Path name for accounting file */
+	struct actstat	ac_stat[NUM_KDRCDS];	/* Entry status array */
+};
+
+/*
+ * Function codes for incremental accounting; currently not used
+ */
+typedef	enum
+{
+	IA_NONE,	/* Zero entry place holder */
+	IA_DELTA,	/* Change clock delta for incremental accounting */
+	IA_EVENT,	/* Cause incremental accounting event now */
+	IA_MAX
+} ac_iafnc;
+
+/*
+ * Incremental accounting structure; currently not used
+ */
+struct actinc
+{
+	int		ac_ind;		/* Entry index */
+	ac_iafnc	ac_fnc;		/* Entry function */
+	int64_t		ac_param;	/* Entry parameter */
+};
+
+/*
+ * Daemon write accounting structure
+ */
+#define	MAX_WRACCT	1024	/* Maximum buffer size of wracct() */
+
+struct actwra
+{
+	int	 ac_did;		/* Daemon index */
+	int	 ac_len;		/* Length of buffer (bytes) */
+	uint64_t ac_jid;		/* Job ID */
+	char	*ac_buf;		/* Daemon accounting buffer */
+};
+
+/* These definitions are used with the CSA /proc IOCTL interface */
+#define CSA_PROC	"csa"
+#define CSA_IOCTL_NUM	'A'
+
+
+#endif	/* _LINUX_CSA_H */
kernel/Makefile +1 -0
Index: linux/kernel/Makefile
===================================================================
@@ -20,6 +20,7 @@
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_PAGG) += pagg.o
 obj-$(CONFIG_PAGG_JOB) += job.o
+obj-$(CONFIG_CSA) += csa.o
 obj-$(CONFIG_IKCONFIG) += configs.o
 obj-$(CONFIG_IKCONFIG_PROC) += configs.o
 obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
kernel/csa.c new file +1666 -0

1,666 lines not on this page · raw message

init/Kconfig +24 -0
Index: linux/init/Kconfig
===================================================================
@@ -158,6 +158,30 @@
 	  a module, select this entry using M.  If you do not want support
 	  for jobs, select N.
 
+config CSA
+	tristate "  CSA Job Accounting"
+	depends on PAGG_JOB
+	help
+	  Comprehensive System Accounting (CSA) provides job level
+	  accounting of resource usage.  The accounting records are
+	  written by the kernel into a file.  CSA user level scripts
+	  and commands process the binary accounting records and
+	  combine them by job identifier within system boot uptime
+	  periods.  These accounting records are then used to produce
+	  reports and charge fees to users.
+
+	  Say Y here if you want job level accounting to be compiled
+	  into the kernel.  Say M here if you want the writing of
+	  accounting records portion of this feature to be a loadable
+	  module.  Say N here if you do not want job level accounting
+	  (the default).
+	
+	  The CSA commands and scripts package needs to be installed
+	  to process the CSA accounting records.  See
+	  http://oss.sgi.com/projects/csa for further information
+	  about CSA and download instructions for the CSA commands
+	  package and documentation.
+
 config SYSCTL
 	bool "Sysctl support"
 	---help---

Jay Lan

author
#0 lore raw

PATCH 1/4 CSA csa_io: accounting IO data gathering

Linux Comprehensive System Accounting (CSA) is a set of C programs and shell scripts that, like other accounting packages, provide methods for collecting per-process resource usage data, monitoring disk usage, and charging fees to specific login accounts.

The CSA patchset includes csa_io, csa_mm, csa_eop and csa_module. Patches csa_io, csa_mm, and csa_eop are responsible for system accounting data collection and are independent of each other.

The csa_io is a patch that gathers I/O activity data.

Please find CSA project at http://oss.sgi.com/projects/csa. This set of csa patches has been tested with the pagg and job kernel patches. The information of pagg and job project can be found at
http://oss.sgi.com/projects/pagg/

drivers/block/ll_rw_blk.c +2 -0
Index: linux/drivers/block/ll_rw_blk.c
===================================================================
@@ -1674,6 +1674,7 @@
 {
 	DEFINE_WAIT(wait);
 	struct request *rq;
+	unsigned long start_wait = jiffies;
 
 	generic_unplug_device(q);
 	do {
@@ -1702,6 +1703,7 @@
 		finish_wait(&rl->wait[rw], &wait);
 	} while (!rq);
 
+	current->bwtime += (unsigned long) jiffies - start_wait;
 	return rq;
 }
 
fs/read_write.c +23 -2
Index: linux/fs/read_write.c
===================================================================
@@ -216,8 +216,11 @@
 				ret = file->f_op->read(file, buf, count, pos);
 			else
 				ret = do_sync_read(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_ACCESS);
+				current->rchar += ret;
+			}
+			current->syscr++;
 		}
 	}
 
@@ -260,8 +263,11 @@
 				ret = file->f_op->write(file, buf, count, pos);
 			else
 				ret = do_sync_write(file, buf, count, pos);
-			if (ret > 0)
+			if (ret > 0) {
 				dnotify_parent(file->f_dentry, DN_MODIFY);
+				current->wchar += ret;
+			}
+			current->syscw++;
 		}
 	}
 
@@ -540,6 +546,10 @@
 		fput_light(file, fput_needed);
 	}
 
+	if (ret > 0) {
+		current->rchar += ret;
+	}
+	current->syscr++;
 	return ret;
 }
 
@@ -558,6 +568,10 @@
 		fput_light(file, fput_needed);
 	}
 
+	if (ret > 0) {
+		current->wchar += ret;
+	}
+	current->syscw++;
 	return ret;
 }
 
@@ -636,6 +650,13 @@
 
 	retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
 
+	if (retval > 0) {
+		current->rchar += retval;
+		current->wchar += retval;
+	}
+	current->syscr++;
+	current->syscw++;
+
 	if (*ppos > max)
 		retval = -EOVERFLOW;
 
kernel/fork.c +2 -0
Index: linux/kernel/fork.c
===================================================================
@@ -964,6 +964,8 @@
 
 	p->utime = p->stime = 0;
 	p->cutime = p->cstime = 0;
+	p->rchar = p->wchar = p->syscr = p->syscw = 0;
+	p->bwtime = 0;
 	p->lock_depth = -1;		/* -1 = no lock */
 	p->start_time = get_jiffies_64();
 	p->security = NULL;
include/linux/sched.h +3 -0
Index: linux/include/linux/sched.h
===================================================================
@@ -523,6 +523,9 @@
 	unsigned long ptrace_message;
 	siginfo_t *last_siginfo; /* For ptrace use.  */
 
+/* i/o counters(bytes read/written, #syscalls, waittime */
+        unsigned long rchar, wchar, syscr, syscw, bwtime;
+
 #ifdef CONFIG_NUMA
   	struct mempolicy *mempolicy;
   	short il_next;		/* could be shared with used_math */
#3 lore raw

Re: [PATCH 2.6.8.1 3/4] CSA csa_eop: accounting end-of-process hook

In reply to Jay Lan

Hi Andrew and Tim,

I found i can eliminate this csa_eop patch.

Two ways to do this, depending on whether we want to view linux/kernel/acct.c as a non-essential part of kernel and another accounting package that CSA will replace.

If we decide we do not need to have acct.c in the kernel, it can be controlled by a new config flag, say CONFIG_BSD_ACCT, and do this:

    do_eop_acct = acct_process;

at BSD acct initialization.

If we decide to always have BSD acct on, i can propose a new patch to move do_eop_acct declaration into acct.c and at the beginning of acct_process() routine, which is invoked at do_exit(), i will check
do_eop_acctL: if do_eop_acct is not NULL, do_eop_acct() would be called and exits acct_process() upon return (ie, a competing accounting package is running); otherwise, it continues do BSD acct processing.

What do you think? Which path i should walk down?

Thanks,
- jay

Quoted 63 lines · Jay Lan

Linux Comprehensive System Accounting (CSA) is a set of C programs and shell scripts that, like other accounting packages, provide methods for collecting per-process resource usage data, monitoring disk usage, and charging fees to specific login accounts.

The CSA patchset includes csa_io, csa_mm, csa_eop and csa_module. Patches csa_io, csa_mm, and csa_eop are responsible for system accounting data collection and are independent of each other.

csa_eop is a patch that provides a hook for end-of-process handling.

Please find CSA project at http://oss.sgi.com/projects/csa. This set of csa patches has been tested with the pagg and job kernel patches. The information of pagg and job project can be found at
http://oss.sgi.com/projects/pagg/

------------------------------------------------------------------------

Index: linux/kernel/exit.c
===================================================================

kernel/exit.c +5 -0
@@ -33,6 +33,8 @@
 
 extern void sem_exit (void);
 extern struct task_struct *child_reaper;
+void (*do_eop_acct) (int, struct task_struct *) = NULL;
+EXPORT_SYMBOL(do_eop_acct);
 
 int getrusage(struct task_struct *, int, struct rusage __user *);
 
@@ -826,6 +828,9 @@
 	csa_update_integrals();
 	update_mem_hiwater();
 	acct_process(code);
+	/* Handle end-of-process accounting */
+	if (do_eop_acct != NULL)
+		do_eop_acct(code, tsk);
 	__exit_mm(tsk);
 
 	exit_sem(tsk);

Index: linux/include/linux/acct.h
===================================================================

include/linux/acct.h +7 -0
@@ -185,6 +185,13 @@
        return x;
 }
 
+/*
+ * extern declaration that provides the hook needed for processing of
+ * end-of-process accounting record
+ *
+ */
+extern void (*do_eop_acct) (int, struct task_struct *);
+
 #endif  /* __KERNEL */
 
 #endif	/* _LINUX_ACCT_H */