From patchwork Tue Dec 4 12:45:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Stepien, Slawomir (Nokia - PL/Wroclaw)" X-Patchwork-Id: 1007603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nokia.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=nokia.onmicrosoft.com header.i=@nokia.onmicrosoft.com header.b="tYx2VbZe"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 438M5w555Gz9s7W for ; Tue, 4 Dec 2018 23:45:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726246AbeLDMpW (ORCPT ); Tue, 4 Dec 2018 07:45:22 -0500 Received: from mail-eopbgr30123.outbound.protection.outlook.com ([40.107.3.123]:3806 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1725767AbeLDMpW (ORCPT ); Tue, 4 Dec 2018 07:45:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nokia.onmicrosoft.com; s=selector1-nokia-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=b42h2D+3p7BPwOUg4kkPaTR7/9NCBwIoTKb2DTwDKuI=; b=tYx2VbZeqlDbTcpGIlyGL0eoLAtIFFjcuTDIwznI4U5ClZtm+4/9yO1XdMF1MYgFGn8U0tfYur5bWiKNPBN+NE6FlQJ+8QHDpR55thLYjdJUJh+73f7TY0ry7rmTIQpEZiANWxEKRPFCM7wi3UlMXYPXtlEfGDi+gfRzuLxRmCw= Received: from AM0PR07MB4657.eurprd07.prod.outlook.com (52.135.151.158) by AM0PR07MB4419.eurprd07.prod.outlook.com (52.133.52.160) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1404.13; Tue, 4 Dec 2018 12:45:19 +0000 Received: from AM0PR07MB4657.eurprd07.prod.outlook.com ([fe80::ccfc:1c70:3a89:c344]) by AM0PR07MB4657.eurprd07.prod.outlook.com ([fe80::ccfc:1c70:3a89:c344%3]) with mapi id 15.20.1404.016; Tue, 4 Dec 2018 12:45:19 +0000 From: "Stepien, Slawomir (Nokia - PL/Wroclaw)" To: "wsa@the-dreams.de" , "linux-i2c@vger.kernel.org" CC: "Adamski, Krzysztof (Nokia - PL/Wroclaw)" , "Sverdlin, Alexander (Nokia - DE/Ulm)" , "Lewalski, Jakub (Nokia - PL/Wroclaw)" Subject: [RFC] i2c: hold the core_lock for the whole execution of i2c_register_adapter() Thread-Topic: [RFC] i2c: hold the core_lock for the whole execution of i2c_register_adapter() Thread-Index: AQHUi882KuLDAwgxKkGeUnOSqW74Gw== Date: Tue, 4 Dec 2018 12:45:19 +0000 Message-ID: <20181204124514.GD20015@sstepien> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HE1PR0901CA0051.eurprd09.prod.outlook.com (2603:10a6:3:45::19) To AM0PR07MB4657.eurprd07.prod.outlook.com (2603:10a6:208:79::30) x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [131.228.32.167] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM0PR07MB4419; 6:5Vbi4bSdshthnzrOrHncVMuQ/35ix9tZfeK4drJ8J8W17Aa5tO/1iERWyoQEahUkOuSK3UliPpCd8TyCZswOY0kWyBSvvWSaHsmjbia5hMORqj/2tiow0m1sFBSGUviGSsDUa1jk2M5cJ1OrYOzbF5w3rCem9n18wrOXx2VGGyWWKeCFH+SpUSB/6bhmKzx4zPB1JF237MffBAeaQ9ra0I/a0D4FWQXCESCFljEHlYlRm5MXzPX+Mt5IN1AG7zF0L4LNljXFYlbKNy0l4OPkGo4zsSKEom+t9CCYKcC9oIVW3R2YcvDCv2u4qiSLjz6jO//MHrrP+nRrfbUvjCj25SOMJdcYd4n0KCjt6bbQIfzzDLhOWkDgrCzj/DBFvzp21EKTfAq9L/Vt0oVEXKGtl/Um1mDJ9cKZFTXCgMAL8JT8sMfS1aAbtIjx86TaH3IcYQxPIMvchLPkSb9JB2am4w==; 5:gpz4EBXv1m1YHvlLwUp5s//xydHkPYRrKJGi6fMQSgAgejEPpB9p7Hk0IqC66J3QoYoeq1x1OtYpz1yr7TAFg/TMhvE1RxL57NdB60hELhjGlsbFg5IKq1Rn/Z/4sasTY79d0vsjefBv+PS/xtKxXunLk1TxKG9uJzUEQVynWA8=; 7:46+P00jVuTTC4n2urQ0qiU0vLeTWH7XgvJrMaPPzjHl7Fwb4nuvTZCd8lJ4oIYjSxWIT5LeVHhFrhBvgI6dwg7GGddDzB9YaWDQ+qLYVxTbcxWXwDp8JaDVlEkhbwL8LSRe71JF7Rdb6XiwmI47UmQ== x-ms-office365-filtering-correlation-id: b7267248-21e8-46f6-dfcd-08d659e65881 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390098)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7193020); SRVR:AM0PR07MB4419; x-ms-traffictypediagnostic: AM0PR07MB4419: authentication-results: spf=none (sender IP is ) smtp.mailfrom=slawomir.stepien@nokia.com; x-microsoft-antispam-prvs: x-ms-exchange-senderadcheck: 1 x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(93006095)(93001095)(3231455)(999002)(11241501185)(806100)(944501505)(52105112)(3002001)(10201501046)(6055026)(148016)(149066)(150057)(6041310)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123560045)(20161123558120)(201708071742011)(7699051)(76991095); SRVR:AM0PR07MB4419; BCL:0; PCL:0; RULEID:; SRVR:AM0PR07MB4419; x-forefront-prvs: 0876988AF0 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(7916004)(39860400002)(136003)(366004)(346002)(376002)(396003)(199004)(189003)(102836004)(2501003)(68736007)(106356001)(6506007)(97736004)(4326008)(66066001)(305945005)(386003)(71200400001)(7736002)(52116002)(33716001)(86362001)(107886003)(105586002)(33896004)(478600001)(8676002)(81156014)(81166006)(8936002)(71190400001)(256004)(66574009)(14444005)(316002)(14454004)(486006)(6512007)(54906003)(6486002)(9686003)(110136005)(33656002)(6436002)(186003)(25786009)(476003)(99286004)(6116002)(3846002)(1076002)(2906002)(53936002)(26005)(5660300001); DIR:OUT; SFP:1102; SCL:1; SRVR:AM0PR07MB4419; H:AM0PR07MB4657.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: nokia.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: Whj/mEhVCeyzvl4Ge4kmK8nhBRpM0FKo9Re0VPoiLOmXp4o7yhq8RyBXoRvOUlXx7cHR7gmzcO4kM7myWFd/LF1h1IrxzasstjavYUnMbZRwvGHKe92N2Wm3PTbdTbzuPyRXLSosH49Avbj3c1WbMoGvqyofb+MD7hF3oxtB/CgjxSmmlBKwvr0Rn8AFmwaK4SwFFMAII0onRx5SPcNDQCW52WriTM5vsWguMHcDiWkvFFlyv19GWcYA5542gk7Q/pPDWhPlSYu5AC98VXI0p5cUbUiiTF8cwziD0t2kVrdcxwSo8AqwGpyvsna2mnk6TTW7Uw6+0ZdrzUfDxloI4wj7RLMXE+he2ywcmayTa/4= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: MIME-Version: 1.0 X-OriginatorOrg: nokia.com X-MS-Exchange-CrossTenant-Network-Message-Id: b7267248-21e8-46f6-dfcd-08d659e65881 X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Dec 2018 12:45:19.0354 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 5d471751-9675-428d-917b-70f44f9630b0 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR07MB4419 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org There is a race condition between the i2c_get_adapter() and the i2c_add_adapter() if this mutex isn't hold for the whole execution of i2c_register_adapter(). If the mutex isn't locked, it is possible to find idr that points to adapter that hasn't been registered yet (i.e. it's kobj.state_initialized is still false), which will end up with warning message: "... is not initialized, yet kobject_get() is being called." This patch will change how the locking is arranged around i2c_register_adapter() call and will prevent such situations. The part of the i2c_register_adapter() that do not need to be under the lock has been moved to a new function i2c_process_adapter. Signed-off-by: Sławomir Stępień --- drivers/i2c/i2c-core-base.c | 61 +++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 28460f6a60cc..15a51f5d905a 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1264,6 +1264,21 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); +out_reg: + init_completion(&adap->dev_released); + device_unregister(&adap->dev); + wait_for_completion(&adap->dev_released); +out_list: + idr_remove(&i2c_adapter_idr, adap->nr); + return res; +} + +static void i2c_process_adapter(struct i2c_adapter *adap) +{ +#ifdef CONFIG_I2C_COMPAT + int res; +#endif + pm_runtime_no_callbacks(&adap->dev); pm_suspend_ignore_children(&adap->dev, true); pm_runtime_enable(&adap->dev); @@ -1290,18 +1305,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); mutex_unlock(&core_lock); - - return 0; - -out_reg: - init_completion(&adap->dev_released); - device_unregister(&adap->dev); - wait_for_completion(&adap->dev_released); -out_list: - mutex_lock(&core_lock); - idr_remove(&i2c_adapter_idr, adap->nr); - mutex_unlock(&core_lock); - return res; } /** @@ -1313,15 +1316,24 @@ static int i2c_register_adapter(struct i2c_adapter *adap) */ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap) { - int id; + int id, ret; mutex_lock(&core_lock); id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL); - mutex_unlock(&core_lock); - if (WARN(id < 0, "couldn't get idr")) + if (WARN(id < 0, "couldn't get idr")) { + mutex_unlock(&core_lock); return id == -ENOSPC ? -EBUSY : id; + } + + ret = i2c_register_adapter(adap); + mutex_unlock(&core_lock); + + if (ret < 0) + return ret; - return i2c_register_adapter(adap); + i2c_process_adapter(adap); + + return 0; } /** @@ -1341,7 +1353,7 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap) int i2c_add_adapter(struct i2c_adapter *adapter) { struct device *dev = &adapter->dev; - int id; + int id, ret; if (dev->of_node) { id = of_alias_get_id(dev->of_node, "i2c"); @@ -1354,13 +1366,22 @@ int i2c_add_adapter(struct i2c_adapter *adapter) mutex_lock(&core_lock); id = idr_alloc(&i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, 0, GFP_KERNEL); - mutex_unlock(&core_lock); - if (WARN(id < 0, "couldn't get idr")) + if (WARN(id < 0, "couldn't get idr")) { + mutex_unlock(&core_lock); return id; + } adapter->nr = id; - return i2c_register_adapter(adapter); + ret = i2c_register_adapter(adapter); + mutex_unlock(&core_lock); + + if (ret < 0) + return ret; + + i2c_process_adapter(adapter); + + return 0; } EXPORT_SYMBOL(i2c_add_adapter);