From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751450AbbJAWZA (ORCPT ); Thu, 1 Oct 2015 18:25:00 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:47392 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751055AbbJAWY7 (ORCPT ); Thu, 1 Oct 2015 18:24:59 -0400 Date: Thu, 1 Oct 2015 15:24:58 -0700 From: Andrew Morton To: Oleg Nesterov Cc: David Rientjes , Kyle Walker , Michal Hocko , Stanislav Kozina , Tetsuo Handa , linux-kernel@vger.kernel.org Subject: Re: [PATCH -mm v2 3/3] mm/oom_kill: fix the wrong task->mm == mm checks in oom_kill_process() Message-Id: <20151001152458.941343718de09a6b2dfba8b1@linux-foundation.org> In-Reply-To: <20150930182411.GA15250@redhat.com> References: <20150930182341.GA15047@redhat.com> <20150930182411.GA15250@redhat.com> X-Mailer: Sylpheed 3.4.1 (GTK+ 2.24.23; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 30 Sep 2015 20:24:11 +0200 Oleg Nesterov wrote: > Both "child->mm == mm" and "p->mm != mm" checks in oom_kill_process() > are wrong. task->mm can be NULL if the task is the exited group leader. > This means in particular that "kill sharing same memory" loop can miss > a process with a zombie leader which uses the same ->mm. > > Note: the process_has_mm(child, p->mm) check is still not 100% correct, > p->mm can be NULL too. This is minor, but probably deserves a fix or a > comment anyway. > > ... > > +static bool process_shares_mm(struct task_struct *p, struct mm_struct *mm) > +{ > + struct task_struct *t; > + > + for_each_thread(p, t) { > + struct mm_struct *t_mm = READ_ONCE(t->mm); > + if (t_mm) > + return t_mm == mm; > + } > + return false; > +} Guys, please don't write write-only code. This function is deeply unobvious and I don't think a typical reader will have a hope of understanding why things are this way. I had a lame attempt: --- a/mm/oom_kill.c~mm-oom_kill-fix-the-wrong-task-mm-==-mm-checks-in-oom_kill_process-fix +++ a/mm/oom_kill.c @@ -483,6 +483,12 @@ void oom_killer_enable(void) oom_killer_disabled = false; } +/* + * task->mm can be NULL if the task is the exited group leader. So to + * determine whether the task is using a particular mm, we examine all the + * task's threads: if one of those is using this mm then this task was also + * using it. + */ static bool process_shares_mm(struct task_struct *p, struct mm_struct *mm) { struct task_struct *t; _ Which makes me wonder if "process_shared_mm" or even "process_used_to_share_mm" would be better names...