Commit 3ceadcf6 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds

coredump: kill call_count, add core_name_size

Imho, "atomic_t call_count" is ugly and should die.  It buys nothing and
in fact it can grow more than necessary, expand doesn't check if it was
already incremented by another task.

Kill it, and introduce "static int core_name_size" updated by
expand_corename().  This is obviously racy too but harmless, and
core_name_size never grows for no reason.

We do not bother to to calculate the "right" new size, we simply do
kmalloc(size_we_need) and use ksize() to rely on kmalloc_index's decision.

Finally change format_corename() to use expand_corename(), krealloc(NULL)
is fine.
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Colin Walters <walters@verbum.org>
Cc: Denys Vlasenko <vda.linux@googlemail.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Lennart Poettering <mzxreary@0pointer.de>
Cc: Lucas De Marchi <lucas.de.marchi@gmail.com>
Acked-by: default avatarNeil Horman <nhorman@tuxdriver.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 923bed03
...@@ -45,26 +45,28 @@ ...@@ -45,26 +45,28 @@
#include <trace/events/sched.h> #include <trace/events/sched.h>
int core_uses_pid; int core_uses_pid;
char core_pattern[CORENAME_MAX_SIZE] = "core";
unsigned int core_pipe_limit; unsigned int core_pipe_limit;
char core_pattern[CORENAME_MAX_SIZE] = "core";
static int core_name_size = CORENAME_MAX_SIZE;
struct core_name { struct core_name {
char *corename; char *corename;
int used, size; int used, size;
}; };
static atomic_t call_count = ATOMIC_INIT(1);
/* The maximal length of core_pattern is also specified in sysctl.c */ /* The maximal length of core_pattern is also specified in sysctl.c */
static int expand_corename(struct core_name *cn) static int expand_corename(struct core_name *cn, int size)
{ {
int size = CORENAME_MAX_SIZE * atomic_inc_return(&call_count);
char *corename = krealloc(cn->corename, size, GFP_KERNEL); char *corename = krealloc(cn->corename, size, GFP_KERNEL);
if (!corename) if (!corename)
return -ENOMEM; return -ENOMEM;
cn->size = size; if (size > core_name_size) /* racy but harmless */
core_name_size = size;
cn->size = ksize(corename);
cn->corename = corename; cn->corename = corename;
return 0; return 0;
} }
...@@ -81,7 +83,7 @@ static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg) ...@@ -81,7 +83,7 @@ static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg)
return 0; return 0;
} }
if (!expand_corename(cn)) if (!expand_corename(cn, cn->size + need - free + 1))
goto again; goto again;
return -ENOMEM; return -ENOMEM;
...@@ -160,9 +162,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm) ...@@ -160,9 +162,8 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm)
int err = 0; int err = 0;
cn->used = 0; cn->used = 0;
cn->size = CORENAME_MAX_SIZE * atomic_read(&call_count); cn->corename = NULL;
cn->corename = kmalloc(cn->size, GFP_KERNEL); if (expand_corename(cn, core_name_size))
if (!cn->corename)
return -ENOMEM; return -ENOMEM;
/* Repeat as long as we have more pattern to process and more output /* Repeat as long as we have more pattern to process and more output
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment