Patchwork [1/2] UBUNTU: SAUCE: ATOP statistical counters for process-administration

login
register
mail settings
Submitter John Johansen
Date June 24, 2010, 7:16 p.m.
Message ID <1277407008-24543-2-git-send-email-john.johansen@canonical.com>
Download mbox | patch
Permalink /patch/56821/
State Rejected
Delegated to: Leann Ogasawara
Headers show

Comments

John Johansen - June 24, 2010, 7:16 p.m.
From: John Johansen <john.johansen@canonical.com>

ATOP patchset request by server team currently out of tree.

OriginalAuthor: Marko Zagožen
OriginalLocation: http://www.atoptool.nl/download/atoppatch-kernel-2.6.33.tar.gz

  01patch-2.6.33_atopcnt
        This patch takes care that statistical counters are added
        to the process-administration (task_struct) and that these
        counters are incremented per process.
        The additional counters are shown via the process'
        /proc/PID/stat file as a second line of counters.
        The meaning of these counters:
          - disk read transfers
          - disk accumulated number of sectors read
          - disk write transfers
          - disk accumulated number of sectors written
          - tcp  send requests
          - tcp  accumulated number of bytes transmitted
          - tcp  receive requests
          - tcp  accumulated number of bytes received
          - udp  send requests
          - udp  accumulated number of bytes transmitted
          - udp  receive requests
          - udp  accumulated number of bytes received
          - raw  send requests (e.g. echo requests by ping)
          - raw  receive requests

        When this patch is installed, ATOP automatically shows
        another layout for the generic screen (including disk-
        and network-transfers for active processes). However for
        terminated process these additional counters are not shown,
        because the conventional layout of the process-accounting
        record has not been adapted.

  Gerlof Langeveld <gerlof@atoptool.nl>
  Credits for this specific port: Marko Zagožen

Signed-off-by: John Johansen <john.johansen@canonical.com>
---
 block/blk-core.c      |   11 ++++++++++
 fs/proc/array.c       |   19 ++++++++++++++++++
 include/linux/sched.h |   11 ++++++++++
 kernel/acct.c         |    2 +-
 kernel/fork.c         |    8 +++++++
 net/socket.c          |   50 ++++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 95 insertions(+), 6 deletions(-)
Stefan Bader - June 25, 2010, 9:14 a.m.
On 06/24/2010 09:16 PM, john.johansen@canonical.com wrote:
> From: John Johansen <john.johansen@canonical.com>
> 
> ATOP patchset request by server team currently out of tree.
> 
> OriginalAuthor: Marko Zagožen
> OriginalLocation: http://www.atoptool.nl/download/atoppatch-kernel-2.6.33.tar.gz
> 
>   01patch-2.6.33_atopcnt
>         This patch takes care that statistical counters are added
>         to the process-administration (task_struct) and that these
>         counters are incremented per process.
>         The additional counters are shown via the process'
>         /proc/PID/stat file as a second line of counters.
>         The meaning of these counters:
>           - disk read transfers
>           - disk accumulated number of sectors read
>           - disk write transfers
>           - disk accumulated number of sectors written
>           - tcp  send requests
>           - tcp  accumulated number of bytes transmitted
>           - tcp  receive requests
>           - tcp  accumulated number of bytes received
>           - udp  send requests
>           - udp  accumulated number of bytes transmitted
>           - udp  receive requests
>           - udp  accumulated number of bytes received
>           - raw  send requests (e.g. echo requests by ping)
>           - raw  receive requests
> 
>         When this patch is installed, ATOP automatically shows
>         another layout for the generic screen (including disk-
>         and network-transfers for active processes). However for
>         terminated process these additional counters are not shown,
>         because the conventional layout of the process-accounting
>         record has not been adapted.
> 
>   Gerlof Langeveld <gerlof@atoptool.nl>
>   Credits for this specific port: Marko Zagožen
> 
> Signed-off-by: John Johansen <john.johansen@canonical.com>
> ---
>  block/blk-core.c      |   11 ++++++++++
>  fs/proc/array.c       |   19 ++++++++++++++++++
>  include/linux/sched.h |   11 ++++++++++
>  kernel/acct.c         |    2 +-
>  kernel/fork.c         |    8 +++++++
>  net/socket.c          |   50 ++++++++++++++++++++++++++++++++++++++++++++----
>  6 files changed, 95 insertions(+), 6 deletions(-)
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index f84cce4..d1b5295 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -73,6 +73,17 @@ static void drive_stat_acct(struct request *rq, int new_io)
>  		part_inc_in_flight(part, rw);
>  	}
>  
> + switch (rw) {             /* ATOP */
> +   case READ:              /* ATOP */
> +     current->group_leader->stat.dsk_rio += new_io;    /* ATOP */
> +     current->group_leader->stat.dsk_rsz += blk_rq_sectors(rq);  /* ATOP */
> +     break;                /* ATOP */
> +   case WRITE:             /* ATOP */
> +     current->group_leader->stat.dsk_wio += new_io;          /* ATOP */
> +     current->group_leader->stat.dsk_wsz += blk_rq_sectors(rq);  /* ATOP */
> +     break;        /* ATOP */
> + }                 /* ATOP */
> +
>  	part_stat_unlock();
>  }
>  
> diff --git a/fs/proc/array.c b/fs/proc/array.c
> index 9b58d38..39e6be6 100644
> --- a/fs/proc/array.c
> +++ b/fs/proc/array.c
> @@ -515,6 +515,25 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
>  		(unsigned long long)delayacct_blkio_ticks(task),
>  		cputime_to_clock_t(gtime),
>  		cputime_to_clock_t(cgtime));
> +
> +		seq_printf(m,                                /* ATOP */
> +			"%lu %llu %lu %llu %lu %llu %lu "    /* ATOP */
> +			"%llu %lu %llu %lu %llu %lu %lu\n",  /* ATOP */
> +			task->stat.dsk_rio,                  /* ATOP */
> +			task->stat.dsk_rsz,                  /* ATOP */
> +			task->stat.dsk_wio,                  /* ATOP */
> +			task->stat.dsk_wsz,                  /* ATOP */
> +			task->stat.tcp_snd,                  /* ATOP */
> +			task->stat.tcp_ssz,                  /* ATOP */
> +			task->stat.tcp_rcv,                  /* ATOP */
> +			task->stat.tcp_rsz,                  /* ATOP */
> +			task->stat.udp_snd,                  /* ATOP */
> +			task->stat.udp_ssz,                  /* ATOP */
> +			task->stat.udp_rcv,                  /* ATOP */
> +			task->stat.udp_rsz,                  /* ATOP */
> +			task->stat.raw_snd,                  /* ATOP */
> +			task->stat.raw_rcv);                 /* ATOP */
> + 
>  	if (mm)
>  		mmput(mm);
>  	return 0;
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index afaa173..954104d 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -1459,6 +1459,17 @@ struct task_struct {
>  #endif
>  	atomic_t fs_excl;	/* holding fs exclusive resources */
>  	struct rcu_head rcu;
> + 
> +	struct {                                   /* ATOP */
> +		unsigned long      dsk_rio, dsk_wio;   /* ATOP */
> +		unsigned long long dsk_rsz, dsk_wsz;   /* ATOP */
> +		unsigned long      tcp_snd, tcp_rcv;   /* ATOP */
> +		unsigned long long tcp_ssz, tcp_rsz;   /* ATOP */
> +		unsigned long      udp_snd, udp_rcv;   /* ATOP */
> +		unsigned long long udp_ssz, udp_rsz;   /* ATOP */
> +		unsigned long      raw_snd, raw_rcv;   /* ATOP */
> +	} stat;                                    /* ATOP */
> +
>  
>  	/*
>  	 * cache last used pipe for splice
> diff --git a/kernel/acct.c b/kernel/acct.c
> index 385b884..87cfa24 100644
> --- a/kernel/acct.c
> +++ b/kernel/acct.c
> @@ -556,7 +556,7 @@ static void do_acct_process(struct bsd_acct_struct *acct,
>  	ac.ac_exitcode = pacct->ac_exitcode;
>  	spin_unlock_irq(&current->sighand->siglock);
>  	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
> -	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
> +  ac.ac_rw = encode_comp_t(current->stat.dsk_rio + current->stat.dsk_wio); /* ATOP */

Would not ac.ac_io be what is accounted in dsk_rio+dsk.wio and ac.ac_rw be
related to dsk_rsz+dsk_wrz?

>  	ac.ac_swaps = encode_comp_t(0);
>  
>  	/*
> diff --git a/kernel/fork.c b/kernel/fork.c
> index b6cce14..4a154af 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -707,6 +707,14 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
>  
>  	tsk->min_flt = tsk->maj_flt = 0;
>  	tsk->nvcsw = tsk->nivcsw = 0;
> +	tsk->stat.dsk_rio = tsk->stat.dsk_wio = 0;    /* ATOP */
> +	tsk->stat.dsk_rsz = tsk->stat.dsk_wsz = 0;    /* ATOP */
> +	tsk->stat.tcp_snd = tsk->stat.tcp_rcv = 0;    /* ATOP */
> +	tsk->stat.tcp_ssz = tsk->stat.tcp_rsz = 0;    /* ATOP */
> +	tsk->stat.udp_snd = tsk->stat.udp_rcv = 0;    /* ATOP */
> +	tsk->stat.udp_ssz = tsk->stat.udp_rsz = 0;    /* ATOP */
> +	tsk->stat.raw_snd = tsk->stat.raw_rcv = 0;    /* ATOP */
> +
>  #ifdef CONFIG_DETECT_HUNG_TASK
>  	tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
>  #endif
> diff --git a/net/socket.c b/net/socket.c
> index 367d547..c1f6a87 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -567,10 +567,28 @@ static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
>  	si->size = size;
>  
>  	err = security_socket_sendmsg(sock, msg, size);
> -	if (err)
> -		return err;
> -
> -	return sock->ops->sendmsg(iocb, sock, msg, size);
> +  if (!err)
> +    err = sock->ops->sendmsg(iocb, sock, msg, size);
> +
> +	if (err >= 0 && sock->sk) {                                   /* ATOP */
> +		switch (sock->sk->sk_family) {                        /* ATOP */
> +		   case PF_INET:                                      /* ATOP */
> +		   case PF_INET6:                                     /* ATOP */
> +			switch (sock->sk->sk_type) {                   /* ATOP */
> +			   case SOCK_STREAM:                           /* ATOP */
> +           current->group_leader->stat.tcp_snd++;    /* ATOP */
> +			     current->group_leader->stat.tcp_ssz+=size;/* ATOP */
> +			     break;                                    /* ATOP */
> +			   case SOCK_DGRAM:                            /* ATOP */
> +			     current->group_leader->stat.udp_snd++;    /* ATOP */
> +           current->group_leader->stat.udp_ssz+=size;/* ATOP */
> +			     break;                                    /* ATOP */
> +			   case SOCK_RAW:                              /* ATOP */
> +			     current->group_leader->stat.raw_snd++;    /* ATOP */
> +		  }                                              /* ATOP */
> +   }                                                /* ATOP */
> + }                                                  /* ATOP */
> +       return err;
>  }
>  
>  int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
> @@ -703,7 +721,29 @@ static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
>  {
>  	int err = security_socket_recvmsg(sock, msg, size, flags);
>  
> -	return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
> +	if (!err)
> +		err = __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
> +
> +	if (err >= 0 && sock->sk) {					/* ATOP */
> +		switch (sock->sk->sk_family) {				/* ATOP */
> +			case PF_INET:					/* ATOP */
> +		   	case PF_INET6:					/* ATOP */
> +				switch (sock->sk->sk_type) {		/* ATOP */
> +			   		case SOCK_STREAM:		/* ATOP */
> +			    			current->group_leader->stat.tcp_rcv++;		/* ATOP */
> +						current->group_leader->stat.tcp_rsz+=err;	/* ATOP */
> +						break;			/* ATOP */
> +					case SOCK_DGRAM:		/* ATOP */
> +						current->group_leader->stat.udp_rcv++;		/* ATOP */
> +						current->group_leader->stat.udp_rsz+=err;	/* ATOP */
> +						break;			/* ATOP */
> +					case SOCK_RAW:			/* ATOP */
> +						current->group_leader->stat.raw_rcv++;		/* ATOP */
> +						break;			/* ATOP */
> +				}					/* ATOP */
> +		}							/* ATOP */
> +	}								/* ATOP */
> +	return err;
>  }
>  
>  int sock_recvmsg(struct socket *sock, struct msghdr *msg,

Otherwise this seems only add accounting code, so should be ok beside of adding
a bit of overhead. Pending the one question I had: ACK.

Stefan

Patch

diff --git a/block/blk-core.c b/block/blk-core.c
index f84cce4..d1b5295 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -73,6 +73,17 @@  static void drive_stat_acct(struct request *rq, int new_io)
 		part_inc_in_flight(part, rw);
 	}
 
+ switch (rw) {             /* ATOP */
+   case READ:              /* ATOP */
+     current->group_leader->stat.dsk_rio += new_io;    /* ATOP */
+     current->group_leader->stat.dsk_rsz += blk_rq_sectors(rq);  /* ATOP */
+     break;                /* ATOP */
+   case WRITE:             /* ATOP */
+     current->group_leader->stat.dsk_wio += new_io;          /* ATOP */
+     current->group_leader->stat.dsk_wsz += blk_rq_sectors(rq);  /* ATOP */
+     break;        /* ATOP */
+ }                 /* ATOP */
+
 	part_stat_unlock();
 }
 
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 9b58d38..39e6be6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -515,6 +515,25 @@  static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
 		(unsigned long long)delayacct_blkio_ticks(task),
 		cputime_to_clock_t(gtime),
 		cputime_to_clock_t(cgtime));
+
+		seq_printf(m,                                /* ATOP */
+			"%lu %llu %lu %llu %lu %llu %lu "    /* ATOP */
+			"%llu %lu %llu %lu %llu %lu %lu\n",  /* ATOP */
+			task->stat.dsk_rio,                  /* ATOP */
+			task->stat.dsk_rsz,                  /* ATOP */
+			task->stat.dsk_wio,                  /* ATOP */
+			task->stat.dsk_wsz,                  /* ATOP */
+			task->stat.tcp_snd,                  /* ATOP */
+			task->stat.tcp_ssz,                  /* ATOP */
+			task->stat.tcp_rcv,                  /* ATOP */
+			task->stat.tcp_rsz,                  /* ATOP */
+			task->stat.udp_snd,                  /* ATOP */
+			task->stat.udp_ssz,                  /* ATOP */
+			task->stat.udp_rcv,                  /* ATOP */
+			task->stat.udp_rsz,                  /* ATOP */
+			task->stat.raw_snd,                  /* ATOP */
+			task->stat.raw_rcv);                 /* ATOP */
+ 
 	if (mm)
 		mmput(mm);
 	return 0;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index afaa173..954104d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1459,6 +1459,17 @@  struct task_struct {
 #endif
 	atomic_t fs_excl;	/* holding fs exclusive resources */
 	struct rcu_head rcu;
+ 
+	struct {                                   /* ATOP */
+		unsigned long      dsk_rio, dsk_wio;   /* ATOP */
+		unsigned long long dsk_rsz, dsk_wsz;   /* ATOP */
+		unsigned long      tcp_snd, tcp_rcv;   /* ATOP */
+		unsigned long long tcp_ssz, tcp_rsz;   /* ATOP */
+		unsigned long      udp_snd, udp_rcv;   /* ATOP */
+		unsigned long long udp_ssz, udp_rsz;   /* ATOP */
+		unsigned long      raw_snd, raw_rcv;   /* ATOP */
+	} stat;                                    /* ATOP */
+
 
 	/*
 	 * cache last used pipe for splice
diff --git a/kernel/acct.c b/kernel/acct.c
index 385b884..87cfa24 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -556,7 +556,7 @@  static void do_acct_process(struct bsd_acct_struct *acct,
 	ac.ac_exitcode = pacct->ac_exitcode;
 	spin_unlock_irq(&current->sighand->siglock);
 	ac.ac_io = encode_comp_t(0 /* current->io_usage */);	/* %% */
-	ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
+  ac.ac_rw = encode_comp_t(current->stat.dsk_rio + current->stat.dsk_wio); /* ATOP */
 	ac.ac_swaps = encode_comp_t(0);
 
 	/*
diff --git a/kernel/fork.c b/kernel/fork.c
index b6cce14..4a154af 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -707,6 +707,14 @@  static int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
 
 	tsk->min_flt = tsk->maj_flt = 0;
 	tsk->nvcsw = tsk->nivcsw = 0;
+	tsk->stat.dsk_rio = tsk->stat.dsk_wio = 0;    /* ATOP */
+	tsk->stat.dsk_rsz = tsk->stat.dsk_wsz = 0;    /* ATOP */
+	tsk->stat.tcp_snd = tsk->stat.tcp_rcv = 0;    /* ATOP */
+	tsk->stat.tcp_ssz = tsk->stat.tcp_rsz = 0;    /* ATOP */
+	tsk->stat.udp_snd = tsk->stat.udp_rcv = 0;    /* ATOP */
+	tsk->stat.udp_ssz = tsk->stat.udp_rsz = 0;    /* ATOP */
+	tsk->stat.raw_snd = tsk->stat.raw_rcv = 0;    /* ATOP */
+
 #ifdef CONFIG_DETECT_HUNG_TASK
 	tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
 #endif
diff --git a/net/socket.c b/net/socket.c
index 367d547..c1f6a87 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -567,10 +567,28 @@  static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 	si->size = size;
 
 	err = security_socket_sendmsg(sock, msg, size);
-	if (err)
-		return err;
-
-	return sock->ops->sendmsg(iocb, sock, msg, size);
+  if (!err)
+    err = sock->ops->sendmsg(iocb, sock, msg, size);
+
+	if (err >= 0 && sock->sk) {                                   /* ATOP */
+		switch (sock->sk->sk_family) {                        /* ATOP */
+		   case PF_INET:                                      /* ATOP */
+		   case PF_INET6:                                     /* ATOP */
+			switch (sock->sk->sk_type) {                   /* ATOP */
+			   case SOCK_STREAM:                           /* ATOP */
+           current->group_leader->stat.tcp_snd++;    /* ATOP */
+			     current->group_leader->stat.tcp_ssz+=size;/* ATOP */
+			     break;                                    /* ATOP */
+			   case SOCK_DGRAM:                            /* ATOP */
+			     current->group_leader->stat.udp_snd++;    /* ATOP */
+           current->group_leader->stat.udp_ssz+=size;/* ATOP */
+			     break;                                    /* ATOP */
+			   case SOCK_RAW:                              /* ATOP */
+			     current->group_leader->stat.raw_snd++;    /* ATOP */
+		  }                                              /* ATOP */
+   }                                                /* ATOP */
+ }                                                  /* ATOP */
+       return err;
 }
 
 int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
@@ -703,7 +721,29 @@  static inline int __sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
 	int err = security_socket_recvmsg(sock, msg, size, flags);
 
-	return err ?: __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
+	if (!err)
+		err = __sock_recvmsg_nosec(iocb, sock, msg, size, flags);
+
+	if (err >= 0 && sock->sk) {					/* ATOP */
+		switch (sock->sk->sk_family) {				/* ATOP */
+			case PF_INET:					/* ATOP */
+		   	case PF_INET6:					/* ATOP */
+				switch (sock->sk->sk_type) {		/* ATOP */
+			   		case SOCK_STREAM:		/* ATOP */
+			    			current->group_leader->stat.tcp_rcv++;		/* ATOP */
+						current->group_leader->stat.tcp_rsz+=err;	/* ATOP */
+						break;			/* ATOP */
+					case SOCK_DGRAM:		/* ATOP */
+						current->group_leader->stat.udp_rcv++;		/* ATOP */
+						current->group_leader->stat.udp_rsz+=err;	/* ATOP */
+						break;			/* ATOP */
+					case SOCK_RAW:			/* ATOP */
+						current->group_leader->stat.raw_rcv++;		/* ATOP */
+						break;			/* ATOP */
+				}					/* ATOP */
+		}							/* ATOP */
+	}								/* ATOP */
+	return err;
 }
 
 int sock_recvmsg(struct socket *sock, struct msghdr *msg,