From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751216Ab1ITPS3 (ORCPT ); Tue, 20 Sep 2011 11:18:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:27531 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750806Ab1ITPS2 (ORCPT ); Tue, 20 Sep 2011 11:18:28 -0400 Date: Tue, 20 Sep 2011 17:14:10 +0200 From: Oleg Nesterov To: "Serge E. Hallyn" , Andrew Morton , David Howells , "Paul E. McKenney" , Tobias Klauser , Greg Kroah-Hartman , Matt Mooney Cc: "Serge E. Hallyn" , lkml , richard@nod.at, "Eric W. Biederman" , Tejun Heo Subject: drivers/staging/usbip/ abuses task_is_dead/exit_state Message-ID: <20110920151410.GA16569@redhat.com> References: <20110919214531.GA18085@sergelap> <20110920122202.GA26504@redhat.com> <20110920124419.GA10759@hallyn.com> <20110920134108.GA30749@redhat.com> <20110920143920.GA15859@redhat.com> <20110920143942.GB15859@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110920143942.GB15859@redhat.com> User-Agent: Mutt/1.5.18 (2008-05-17) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org (add more cc's) On 09/20, Oleg Nesterov wrote: > > Unfortunately, we can't kill task_is_dead() right now, it has already > found the users in drivers/staging/, and I bet the usage is wrong. It is used by drivers/staging/usbip/ For what? The code: if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx)) kthread_stop(vdev->ud.tcp_rx); And how task_is_dead() can help? This helper is really "special", it shouldn't be used anyway. But why do we check ->exit_state? Without tasklist the check is racy anyway, the task can exit right after the check. And. It is safe to use kthread_stop(t) even if t has already exited. OK, this was added by 8547d4cc2b616e4f1dafebe2c673fc986422b506 "Staging: usbip: vhci-hcd: Do not kill already dead RX/TX kthread" When unbinding a device on the host which was still attached on the client, I got a NULL pointer dereference on the client. Where? This turned out to be due to kthread_stop() being called on an already dead kthread. This should work. I'm afraid this can only fix the symptom. Probably, the problem is that we do not have the reference and thus even task_is_dead(t) is not safe. This kthread was created by kthread_run(). If it exits, nothing protects this task_struct. In any case, please do not use ->exit_state. It should not be used outside of exit.c/etc paths, "exit_state != 0" means "exit_notify() was called". Oleg.