Message ID | 1277407008-24543-2-git-send-email-john.johansen@canonical.com |
---|---|
State | Rejected |
Delegated to: | Leann Ogasawara |
Headers | show |
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(¤t->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
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(¤t->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,