2002-07-15 06:24:52

by Manik Raina

[permalink] [raw]
Subject: [PATCH, 2.5] : Adding counters to BSD process accounting


This patch keeps account of the number of bytes read/written by a
process in it's lifetime.

This may be a good estimate of how IO bound a process is.
This change is integrated with the BSD process accounting feature. Please
review the changes and if you're ok with it, please apply to the 2.5 tree.

thanks,
Manik


diff -u -U 6 -r --show-c-function -H linux-2.5.24/fs/read_write.c work/fs/read_write.c
--- linux-2.5.24/fs/read_write.c Fri Jun 21 04:23:54 2002
+++ work/fs/read_write.c Tue Jul 9 15:10:55 2002
@@ -8,12 +8,13 @@
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/file.h>
#include <linux/uio.h>
#include <linux/smp_lock.h>
#include <linux/dnotify.h>
+#include <linux/acct.h>

#include <asm/uaccess.h>

struct file_operations generic_ro_fops = {
llseek: generic_file_llseek,
read: generic_file_read,
@@ -214,12 +215,14 @@ asmlinkage ssize_t sys_read(unsigned int
file = fget(fd);
if (file) {
ret = vfs_read(file, buf, count, &file->f_pos);
fput(file);
}

+ acct_read_add(ret);
+
return ret;
}

asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
{
struct file *file;
@@ -227,12 +230,14 @@ asmlinkage ssize_t sys_write(unsigned in

file = fget(fd);
if (file) {
ret = vfs_write(file, buf, count, &file->f_pos);
fput(file);
}
+
+ acct_write_add(ret);

return ret;
}

asmlinkage ssize_t sys_pread(unsigned int fd, char *buf,
size_t count, loff_t pos)
diff -u -U 6 -r --show-c-function -H linux-2.5.24/include/linux/acct.h work/include/linux/acct.h
--- linux-2.5.24/include/linux/acct.h Fri Jun 21 04:23:46 2002
+++ work/include/linux/acct.h Tue Jul 9 15:13:08 2002
@@ -54,12 +54,14 @@ struct acct
comp_t ac_minflt; /* Accounting Minor Pagefaults */
comp_t ac_majflt; /* Accounting Major Pagefaults */
comp_t ac_swaps; /* Accounting Number of Swaps */
__u32 ac_exitcode; /* Accounting Exitcode */
char ac_comm[ACCT_COMM + 1]; /* Accounting Command Name */
char ac_pad[10]; /* Accounting Padding Bytes */
+ __u64 ac_read; /* Accounting bytes read */
+ __u64 ac_write; /* Accountind bytes written */
};

/*
* accounting flags
*/
/* bit set when the process ... */
@@ -75,14 +77,26 @@ struct acct

#include <linux/config.h>

#ifdef CONFIG_BSD_PROCESS_ACCT
extern void acct_auto_close(struct super_block *sb);
extern int acct_process(long exitcode);
+
+static inline void acct_read_add (ssize_t count)
+{
+ if (count) current->read += count;
+}
+
+static inline void acct_write_add (ssize_t count)
+{
+ if (count) current->write += count;
+}
#else
#define acct_auto_close(x) do { } while (0)
#define acct_process(x) do { } while (0)
+#define acct_read_add(x) do { } while (0)
+#define acct_write_add(x) do { } while (0)
#endif

#endif /* __KERNEL */

#endif /* _LINUX_ACCT_H */
diff -u -U 6 -r --show-c-function -H linux-2.5.24/include/linux/sched.h work/include/linux/sched.h
--- linux-2.5.24/include/linux/sched.h Fri Jun 21 04:23:44 2002
+++ work/include/linux/sched.h Tue Jul 9 14:18:14 2002
@@ -361,12 +361,17 @@ struct task_struct {
/* Protection of (de-)allocation: mm, files, fs, tty */
spinlock_t alloc_lock;

/* journalling filesystem info */
void *journal_info;
struct dentry *proc_dentry;
+
+#ifdef CONFIG_BSD_PROCESS_ACCT
+/* process accounting info */
+ u64 read, write;
+#endif /* CONFIG_BSD_PROCESS_ACCT */
};

extern void __put_task_struct(struct task_struct *tsk);
#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
#define put_task_struct(tsk) \
do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
diff -u -U 6 -r --show-c-function -H linux-2.5.24/kernel/acct.c work/kernel/acct.c
--- linux-2.5.24/kernel/acct.c Fri Jun 21 04:23:53 2002
+++ work/kernel/acct.c Tue Jul 9 15:04:41 2002
@@ -38,12 +38,15 @@
* OK, that's better. ANOTHER race and leak in BSD variant. There always
* is one more bug... 10/11/98, AV.
*
* Oh, fsck... Oopsable SMP race in do_process_acct() - we must hold
* ->mmap_sem to walk the vma list of current->mm. Nasty, since it leaks
* a struct file opened for write. Fixed. 2/6/2000, AV.
+ *
+ * Added support for number of bytes read/written per process.
+ * - Manik Raina
*/

#include <linux/config.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/acct.h>
@@ -351,13 +354,14 @@ static void do_acct_process(long exitcod
ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
ac.ac_minflt = encode_comp_t(current->min_flt);
ac.ac_majflt = encode_comp_t(current->maj_flt);
ac.ac_swaps = encode_comp_t(current->nswap);
ac.ac_exitcode = exitcode;
-
+ ac.ac_read = current->read;
+ ac.ac_write = current->write;
/*
* Kernel segment override to datasegment and write it
* to the accounting file.
*/
fs = get_fs();
set_fs(KERNEL_DS);


2002-07-15 10:47:56

by Matti Aarnio

[permalink] [raw]
Subject: Re: [PATCH, 2.5] : Adding counters to BSD process accounting

On Mon, Jul 15, 2002 at 11:57:39AM +0530, Manik Raina wrote:
> This patch keeps account of the number of bytes read/written by a
> process in it's lifetime.
>
> This may be a good estimate of how IO bound a process is.
> This change is integrated with the BSD process accounting feature. Please
> review the changes and if you're ok with it, please apply to the 2.5 tree.

Do have a deeper look into how the BSD ACCT works.

Throwing in couple 8-byte scalars isn't quite right thing.
The pacct file format (record size!) will change with this thing.

There exist already fields:

comp_t ac_io; /* Accounting Chars Transferred */
comp_t ac_rw; /* Accounting Blocks Read or Written */

Those are encoded with zero...


If you comp_t encode the read/write data, you will be able to
squeeze it into the reserved alignment bytes: ac_pad[].

Well, that encoding counts up to 16 GB, only, but is better than
nothing. The normal encoding routine handles "unsigned long"
input value, not __u64, thus you would need to write a new
encoder too. Reading the existing encode_comp_t() shows,
that its coder has mixed up EXPSIZE and EXPBASE concepts.


/*
* comp_t is a 16-bit "floating" point number with a 3-bit base 8
* exponent and a 13-bit fraction. See linux/kernel/acct.c for the
* specific encoding system used.
*/

typedef __u16 comp_t;


With 13 bits, the maximum fraction is thus 2^14 -1 = 16383
With 3 bits, and base 8 the maximum exponent is: 8^7 = 2M
With 3 bits, and base 16 the maximum exponent is: 16^7 = 256M

Combined:
Base8: 0 thru 16 GigaCounts with 10-13 bit precission
Base16: 0 thru 4096 GigaCounts with 9-13 bit precission


> thanks,
> Manik
...

/Matti Aarnio

2002-07-15 11:45:51

by Karim Yaghmour

[permalink] [raw]
Subject: Re: [PATCH, 2.5] : Adding counters to BSD process accounting


Manik Raina wrote:
> This patch keeps account of the number of bytes read/written by a
> process in it's lifetime.
>
> This may be a good estimate of how IO bound a process is.
> This change is integrated with the BSD process accounting feature. Please
> review the changes and if you're ok with it, please apply to the 2.5 tree.

This is yet another piece of information LTT already provides. If you're
interested in analyzing the I/O operations carried out by a process and
how these operations influence other processes' I/O, then LTT is a very
good place to look.

Cheers,

Karim

===================================================
Karim Yaghmour
[email protected]
Embedded and Real-Time Linux Expert
===================================================