[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAJrWOzASKoy6CAVXitm8si+1BbgHqLyur+90HGMeSjW3bK94UA@mail.gmail.com>
Date: Mon, 24 Oct 2016 21:37:32 +0200
From: Roman Penyaev <roman.penyaev@...fitbricks.com>
To: Andy Lutomirski <luto@...capital.net>
Cc: Andy Lutomirski <luto@...nel.org>, Oleg Nesterov <oleg@...hat.com>,
Peter Zijlstra <peterz@...radead.org>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, Tejun Heo <tj@...nel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v2 1/2] kthread: allocate kthread structure using kmalloc
On Mon, Oct 24, 2016 at 7:08 PM, Andy Lutomirski <luto@...capital.net> wrote:
> On Mon, Oct 24, 2016 at 9:08 AM, Roman Pen
> <roman.penyaev@...fitbricks.com> wrote:
>> This patch avoids allocation of kthread structure on a stack, and simply
>> uses kmalloc. Allocation on a stack became a huge problem (with memory
>> corruption and all other not nice consequences) after the commit 2deb4be28
>> by Andy Lutomirski, which rewinds the stack on oops, thus ooopsed kthread
>> steps on a garbage memory while completion of task->vfork_done structure
>> on the following path:
>
> This is IMO a *huge* improvement.
>
> Shouldn't the patch also remove the try_get_task_stack() /
> put_task_stack() hackery in kthread.c, though?
Do you mean that commit from Oleg https://patchwork.kernel.org/patch/9335295/ ?
Hm, I missed that to_live_kthread() function completely. So, yes, we can remove
put/get_task_stack(), but only replacing on get/put_kthread. So still need to
be careful with the refs.
Oleg, could you please take a look on the hunk below, just a quick thought.
(get_kthread is simple atomic kthread->refs++).
--
Roman
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -64,9 +64,20 @@ static inline struct kthread *to_kthread(struct
task_struct *k)
static struct kthread *to_live_kthread(struct task_struct *k)
{
struct completion *vfork = ACCESS_ONCE(k->vfork_done);
- if (likely(vfork) && try_get_task_stack(k))
- return __to_kthread(vfork);
- return NULL;
+ struct kthread *kthread = NULL;
+
+ BUG_ON(!(k->flags & PF_KTHREAD));
+ if (likely(vfork)) {
+ task_lock(k);
+ vfork = ACCESS_ONCE(k->vfork_done);
+ if (likely(vfork)) {
+ kthread = __to_kthread(vfork);
+ get_kthread(kthread);
+ }
+ task_unlock(k);
+ }
+
+ return kthread;
}
Powered by blists - more mailing lists