Re: [Devel] [PATCH rh7 v2 2/2] ve/fs/proc: Make per-thread and per-process allocation latencies.

2018-02-19 Thread Kirill Tkhai
On 19.02.2018 18:16, Andrey Ryabinin wrote:
> Follow-up for 6d9a9210395e ("ve/page_alloc, kstat: account allocation 
> latencies per-task")
> Make per-thread and per-process allocation latencies:
> 
>   - /proc//vz_latency - cumulative for a thread group
>   - /proc//tasks//vz_latency - thread-specific
> 
> During allocation we collect per-thread latency. When thread dies,
> it submits its own latencies into shared task->signal.alloc_lat struct.
> /proc//vz_latency - sums allocation latencies over all live threads
> plus latencies of already dead tasks from task->signal.alloc_lat.
> 
> https://jira.sw.ru/browse/PSBM-81395
> Signed-off-by: Andrey Ryabinin 
> Cc: Pavel Borzenkov 

Reviewed-by: Kirill Tkhai 

> ---
> Changes since v1:
> 
>  - Change hard-coded 3 to the ARRAY_SIZE(alloc_types)
> 
>  fs/proc/base.c| 76 
> +++
>  include/linux/sched.h |  3 ++
>  kernel/exit.c | 16 +++
>  3 files changed, 71 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 5646a351c076..88d026098f31 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -583,24 +583,23 @@ static void lastlat_seq_show(struct seq_file *m,
>   seq_printf(m, "%-12s %20Lu %20lu\n", name,
>   snap->totlat, snap->count);
>  }
> +static const char *alloc_descr[] = {
> + "allocatomic:",
> + "alloc:",
> + "allocmp:",
> +};
> +static const int alloc_types[] = {
> + KSTAT_ALLOCSTAT_ATOMIC,
> + KSTAT_ALLOCSTAT_LOW,
> + KSTAT_ALLOCSTAT_LOW_MP,
> +};
>  
> -static int vz_lat_show_proc(struct seq_file *m, void *v)
> +static int proc_tid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
> + struct pid *pid, struct task_struct *task)
>  {
>   int i;
> - struct inode *inode = m->private;
> - struct task_struct *task = get_proc_task(inode);
> - static const char *alloc_descr[] = {
> - "allocatomic:",
> - "alloc:",
> - "allocmp:",
> - };
> - static const int alloc_types[] = {
> - KSTAT_ALLOCSTAT_ATOMIC,
> - KSTAT_ALLOCSTAT_LOW,
> - KSTAT_ALLOCSTAT_LOW_MP,
> - };
>  
> - seq_printf(m, "%-11s %20s %20s\n",
> + seq_printf(m, "%-12s %20s %20s\n",
>   "Type", "Total_lat", "Calls");
>  
>   for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
> @@ -609,17 +608,43 @@ static int vz_lat_show_proc(struct seq_file *m, void *v)
>   return 0;
>  }
>  
> -static int vz_lat_open(struct inode *inode, struct file *file)
> +static int proc_tgid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
> + struct pid *pid, struct task_struct *task)
>  {
> - return single_open(file, vz_lat_show_proc, inode);
> -}
> + int i;
> + unsigned long flags;
> + u64 lat[ARRAY_SIZE(alloc_types)];
> + u64 count[ARRAY_SIZE(alloc_types)];
>  
> -static const struct file_operations proc_vz_lat_operations = {
> - .open   = vz_lat_open,
> - .read   = seq_read,
> - .llseek = seq_lseek,
> - .release= single_release,
> -};
> + for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
> + lat[i] = task->alloc_lat[alloc_types[i]].totlat;
> + count[i] = task->alloc_lat[alloc_types[i]].count;
> + }
> +
> + if (lock_task_sighand(task, )) {
> + struct task_struct *t = task;
> + while_each_thread(task, t) {
> + for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
> + lat[i] += t->alloc_lat[alloc_types[i]].totlat;
> + count[i] += t->alloc_lat[alloc_types[i]].count;
> + }
> + }
> + for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
> + lat[i] += t->signal->alloc_lat[alloc_types[i]].totlat;
> + count[i] += t->signal->alloc_lat[alloc_types[i]].count;
> + }
> + unlock_task_sighand(task, );
> + }
> +
> + seq_printf(m, "%-12s %20s %20s\n",
> + "Type", "Total_lat", "Calls");
> +
> + for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
> + seq_printf(m, "%-12s %20Lu %20Lu\n", alloc_descr[i],
> + lat[i], count[i]);
> +
> + return 0;
> +}
>  #endif
>  
>  #ifdef CONFIG_CGROUPS
> @@ -3060,7 +3085,7 @@ static const struct pid_entry tgid_base_stuff[] = {
>   REG("aio",S_IRUGO|S_IWUSR, proc_aio_operations),
>  #endif
>  #ifdef CONFIG_VE
> - REG("vz_latency", S_IRUGO, proc_vz_lat_operations),
> + ONE("vz_latency", S_IRUGO, proc_tgid_vz_lat),
>  #endif
>  };
>  
> @@ -3410,6 +3435,9 @@ static const struct pid_entry tid_base_stuff[] = {
>   REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
>   REG("setgroups",  S_IRUGO|S_IWUSR, 

[Devel] [PATCH rh7 v2 2/2] ve/fs/proc: Make per-thread and per-process allocation latencies.

2018-02-19 Thread Andrey Ryabinin
Follow-up for 6d9a9210395e ("ve/page_alloc, kstat: account allocation latencies 
per-task")
Make per-thread and per-process allocation latencies:

  - /proc//vz_latency - cumulative for a thread group
  - /proc//tasks//vz_latency - thread-specific

During allocation we collect per-thread latency. When thread dies,
it submits its own latencies into shared task->signal.alloc_lat struct.
/proc//vz_latency - sums allocation latencies over all live threads
plus latencies of already dead tasks from task->signal.alloc_lat.

https://jira.sw.ru/browse/PSBM-81395
Signed-off-by: Andrey Ryabinin 
Cc: Pavel Borzenkov 
---
Changes since v1:

 - Change hard-coded 3 to the ARRAY_SIZE(alloc_types)

 fs/proc/base.c| 76 +++
 include/linux/sched.h |  3 ++
 kernel/exit.c | 16 +++
 3 files changed, 71 insertions(+), 24 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 5646a351c076..88d026098f31 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -583,24 +583,23 @@ static void lastlat_seq_show(struct seq_file *m,
seq_printf(m, "%-12s %20Lu %20lu\n", name,
snap->totlat, snap->count);
 }
+static const char *alloc_descr[] = {
+   "allocatomic:",
+   "alloc:",
+   "allocmp:",
+};
+static const int alloc_types[] = {
+   KSTAT_ALLOCSTAT_ATOMIC,
+   KSTAT_ALLOCSTAT_LOW,
+   KSTAT_ALLOCSTAT_LOW_MP,
+};
 
-static int vz_lat_show_proc(struct seq_file *m, void *v)
+static int proc_tid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
+   struct pid *pid, struct task_struct *task)
 {
int i;
-   struct inode *inode = m->private;
-   struct task_struct *task = get_proc_task(inode);
-   static const char *alloc_descr[] = {
-   "allocatomic:",
-   "alloc:",
-   "allocmp:",
-   };
-   static const int alloc_types[] = {
-   KSTAT_ALLOCSTAT_ATOMIC,
-   KSTAT_ALLOCSTAT_LOW,
-   KSTAT_ALLOCSTAT_LOW_MP,
-   };
 
-   seq_printf(m, "%-11s %20s %20s\n",
+   seq_printf(m, "%-12s %20s %20s\n",
"Type", "Total_lat", "Calls");
 
for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
@@ -609,17 +608,43 @@ static int vz_lat_show_proc(struct seq_file *m, void *v)
return 0;
 }
 
-static int vz_lat_open(struct inode *inode, struct file *file)
+static int proc_tgid_vz_lat(struct seq_file *m, struct pid_namespace *ns,
+   struct pid *pid, struct task_struct *task)
 {
-   return single_open(file, vz_lat_show_proc, inode);
-}
+   int i;
+   unsigned long flags;
+   u64 lat[ARRAY_SIZE(alloc_types)];
+   u64 count[ARRAY_SIZE(alloc_types)];
 
-static const struct file_operations proc_vz_lat_operations = {
-   .open   = vz_lat_open,
-   .read   = seq_read,
-   .llseek = seq_lseek,
-   .release= single_release,
-};
+   for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
+   lat[i] = task->alloc_lat[alloc_types[i]].totlat;
+   count[i] = task->alloc_lat[alloc_types[i]].count;
+   }
+
+   if (lock_task_sighand(task, )) {
+   struct task_struct *t = task;
+   while_each_thread(task, t) {
+   for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
+   lat[i] += t->alloc_lat[alloc_types[i]].totlat;
+   count[i] += t->alloc_lat[alloc_types[i]].count;
+   }
+   }
+   for (i = 0; i < ARRAY_SIZE(alloc_types); i++) {
+   lat[i] += t->signal->alloc_lat[alloc_types[i]].totlat;
+   count[i] += t->signal->alloc_lat[alloc_types[i]].count;
+   }
+   unlock_task_sighand(task, );
+   }
+
+   seq_printf(m, "%-12s %20s %20s\n",
+   "Type", "Total_lat", "Calls");
+
+   for (i = 0; i < ARRAY_SIZE(alloc_types); i++)
+   seq_printf(m, "%-12s %20Lu %20Lu\n", alloc_descr[i],
+   lat[i], count[i]);
+
+   return 0;
+}
 #endif
 
 #ifdef CONFIG_CGROUPS
@@ -3060,7 +3085,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("aio",S_IRUGO|S_IWUSR, proc_aio_operations),
 #endif
 #ifdef CONFIG_VE
-   REG("vz_latency", S_IRUGO, proc_vz_lat_operations),
+   ONE("vz_latency", S_IRUGO, proc_tgid_vz_lat),
 #endif
 };
 
@@ -3410,6 +3435,9 @@ static const struct pid_entry tid_base_stuff[] = {
REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
REG("setgroups",  S_IRUGO|S_IWUSR, proc_setgroups_operations),
 #endif
+#ifdef CONFIG_VE
+   ONE("vz_latency", S_IRUGO, proc_tid_vz_lat),
+#endif
 };
 
 static int proc_tid_base_readdir(struct file * filp,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index