diff --git a/block/blk-core.c b/block/blk-core.c index d1a9a0a..8b54acb 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 13b5d07..cac522e 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 78efe7c..22391bf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1512,6 +1512,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 a6605ca..d5df53a 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -565,7 +565,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 f88bd98..bab2085 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -683,6 +683,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 769c386..3ba19f6 100644 --- a/net/socket.c +++ b/net/socket.c @@ -547,10 +547,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) @@ -682,7 +700,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,