From patchwork Thu Nov 6 08:16:38 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: wangyijing X-Patchwork-Id: 40252 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f71.google.com (mail-wg0-f71.google.com [74.125.82.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2BD1E240B2 for ; Thu, 6 Nov 2014 07:35:11 +0000 (UTC) Received: by mail-wg0-f71.google.com with SMTP id b13sf259629wgh.6 for ; Wed, 05 Nov 2014 23:35:10 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe:content-type; bh=bvzdGpfPOCTnm/qvhedBeSLLv8OpWED+Vqk4w0mYmsA=; b=jXuPjhMf1204X0qpgtBxMZRqVayh04h7YQta93DddYBKxkU28oq5uHlSkI8lK4As+w PBZf9+Gb//o+KmsUgH6pGn3SpnJkObSrcVmzsnEyQJNSOqpxBv1srh0p7kF3GV8p18j6 AFedh226RGo1cDl/2zai6ytnWYAwDDuZbtzbK8GIp4Hy5I8Tx8nHbonPDK1pbN7CCRzI fHRtiVMjfmhNTp65dudm7ZO4R8Fl/+0vt2SSn/r++XNjQR17aVtr6myqWRiN/jmdwGRo rFEHzP7yq+5Xyzg6VzdUoo5AT1q8uAU3Af5sSP7QOD3Lcy4GnFULFFpLz5LEIUsmBWZq nPtQ== X-Gm-Message-State: ALoCoQljkCT7CmmKYlNU83xWCEQ0ICT4cU6Ewhp49mR7eiM7zQ+ggj41V1FuoXZytGyRbVQrj6zJ X-Received: by 10.180.219.40 with SMTP id pl8mr1655426wic.3.1415259310428; Wed, 05 Nov 2014 23:35:10 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.8.194 with SMTP id t2ls45225laa.14.gmail; Wed, 05 Nov 2014 23:35:10 -0800 (PST) X-Received: by 10.152.37.104 with SMTP id x8mr2922831laj.74.1415259310022; Wed, 05 Nov 2014 23:35:10 -0800 (PST) Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com. [209.85.217.172]) by mx.google.com with ESMTPS id li6si10077201lbc.87.2014.11.05.23.35.09 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 05 Nov 2014 23:35:09 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) client-ip=209.85.217.172; Received: by mail-lb0-f172.google.com with SMTP id w7so425896lbi.3 for ; Wed, 05 Nov 2014 23:35:09 -0800 (PST) X-Received: by 10.152.42.226 with SMTP id r2mr2830161lal.29.1415259309781; Wed, 05 Nov 2014 23:35:09 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.184.201 with SMTP id ew9csp7189lbc; Wed, 5 Nov 2014 23:35:08 -0800 (PST) X-Received: by 10.68.137.101 with SMTP id qh5mr2574695pbb.13.1415259308168; Wed, 05 Nov 2014 23:35:08 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id af5si4995963pbd.256.2014.11.05.23.35.07 for ; Wed, 05 Nov 2014 23:35:08 -0800 (PST) Received-SPF: none (google.com: stable-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751262AbaKFHfG (ORCPT + 1 other); Thu, 6 Nov 2014 02:35:06 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:15364 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750963AbaKFHfE (ORCPT ); Thu, 6 Nov 2014 02:35:04 -0500 Received: from 172.24.2.119 (EHLO szxeml416-hub.china.huawei.com) ([172.24.2.119]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id AWS09268; Thu, 06 Nov 2014 15:35:01 +0800 (CST) Received: from localhost.localdomain (10.175.100.166) by szxeml416-hub.china.huawei.com (10.82.67.155) with Microsoft SMTP Server id 14.3.158.1; Thu, 6 Nov 2014 15:34:53 +0800 From: Yijing Wang To: CC: , , , Yijing Wang , Weng Meiling , Subject: [PATCH] sysfs: driver core: Fix glue dir race condition Date: Thu, 6 Nov 2014 16:16:38 +0800 Message-ID: <1415261798-9671-1-git-send-email-wangyijing@huawei.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-Originating-IP: [10.175.100.166] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020205.545B24A6.00F4, ss=1, re=0.001, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 20b3d989dede07c2f78a37b892592c5b Sender: stable-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: stable@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: wangyijing@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There is a race condition when removing glue directory. It can be reproduced in following test: path 1: Add first child device device_add() get_device_parent() /*find parent from glue_dirs.list*/ list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) if (k->parent == parent_kobj) { kobj = kobject_get(k); break; } .... class_dir_create_and_add() path2: Remove last child device under glue dir device_del() cleanup_device_parent() cleanup_glue_dir() kobject_put(glue_dir); If path2 has been called cleanup_glue_dir(), but not call kobject_put(glue_dir), the glue dir is still in parent's kset list. Meanwhile, path1 find the glue dir from the glue_dirs.list. Path2 may release glue dir before path1 call kobject_get(). So kernel will report the warning and bug_on. This fix keep glue dir around once it created suggested by Tejun Heo. The following calltrace is captured in kernel 3.4, but the latest kernel still has this bug. ----------------------------------------------------- <4>[ 3965.441471] WARNING: at ...include/linux/kref.h:41 kobject_get+0x33/0x40() <4>[ 3965.441474] Hardware name: Romley <4>[ 3965.441475] Modules linked in: isd_iop(O) isd_xda(O)... ... <4>[ 3965.441605] Call Trace: <4>[ 3965.441611] [] warn_slowpath_common+0x7a/0xb0 <4>[ 3965.441615] [] warn_slowpath_null+0x15/0x20 <4>[ 3965.441618] [] kobject_get+0x33/0x40 <4>[ 3965.441624] [] get_device_parent.isra.11+0x135/0x1f0 <4>[ 3965.441627] [] device_add+0xd4/0x6d0 <4>[ 3965.441631] [] ? dev_set_name+0x3c/0x40 .... <2>[ 3965.441912] kernel BUG at ..../fs/sysfs/group.c:65! <4>[ 3965.441915] invalid opcode: 0000 [#1] SMP ... <4>[ 3965.686743] [] sysfs_create_group+0xe/0x10 <4>[ 3965.686748] [] blk_trace_init_sysfs+0x14/0x20 <4>[ 3965.686753] [] blk_register_queue+0x3b/0x120 <4>[ 3965.686756] [] add_disk+0x1cc/0x490 .... ------------------------------------------------------- Signed-off-by: Yijing Wang Signed-off-by: Weng Meiling Cc: #3.4+ Reviewed-by: Tejun Heo --- drivers/base/core.c | 21 +-------------------- 1 files changed, 1 insertions(+), 20 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 14d1629..5b7a3e9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -761,7 +761,7 @@ static struct kobject *get_device_parent(struct device *dev, spin_lock(&dev->class->p->glue_dirs.list_lock); list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) if (k->parent == parent_kobj) { - kobj = kobject_get(k); + kobj = k; break; } spin_unlock(&dev->class->p->glue_dirs.list_lock); @@ -786,21 +786,6 @@ static struct kobject *get_device_parent(struct device *dev, return NULL; } -static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) -{ - /* see if we live in a "glue" directory */ - if (!glue_dir || !dev->class || - glue_dir->kset != &dev->class->p->glue_dirs) - return; - - kobject_put(glue_dir); -} - -static void cleanup_device_parent(struct device *dev) -{ - cleanup_glue_dir(dev, dev->kobj.parent); -} - static int device_add_class_symlinks(struct device *dev) { int error; @@ -1094,7 +1079,6 @@ done: kobject_uevent(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); Error: - cleanup_device_parent(dev); if (parent) put_device(parent); name_error: @@ -1215,7 +1199,6 @@ void device_del(struct device *dev) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_REMOVED_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_REMOVE); - cleanup_device_parent(dev); kobject_del(&dev->kobj); put_device(parent); } @@ -1873,7 +1856,6 @@ int device_move(struct device *dev, struct device *new_parent, __func__, new_parent ? dev_name(new_parent) : ""); error = kobject_move(&dev->kobj, new_parent_kobj); if (error) { - cleanup_glue_dir(dev, new_parent_kobj); put_device(new_parent); goto out; } @@ -1902,7 +1884,6 @@ int device_move(struct device *dev, struct device *new_parent, set_dev_node(dev, dev_to_node(old_parent)); } } - cleanup_glue_dir(dev, new_parent_kobj); put_device(new_parent); goto out; }