Message ID | 20230106045537.1243887-1-wenst@chromium.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4e01:0:0:0:0:0 with SMTP id p1csp640775wrt; Thu, 5 Jan 2023 20:59:25 -0800 (PST) X-Google-Smtp-Source: AMrXdXvDBmrUdek7YCGcyB8ynmLAQB6TBceeoVx5sPyJM5Ny2S/ewsfA2qwoM60awS8zQRDNWPGt X-Received: by 2002:a17:906:380e:b0:7c0:be5d:59a9 with SMTP id v14-20020a170906380e00b007c0be5d59a9mr50040008ejc.20.1672981165306; Thu, 05 Jan 2023 20:59:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1672981165; cv=none; d=google.com; s=arc-20160816; b=Bsde2nJQUtdUzS9puRbd1IegmzoMrfkh9y+CSuYaXjs+n8oUq/vnrANKtze48KI8gh EYvtVJrYQIO/pW6z4H8k5/MLvgGl9ec0meLnsQhSPXmPih7MJZ5y2IyQmzqh27yKLwMO BPPfqecMvufD6WyNSltdBQXiqGjIIPAGG6o391ZxUwkIwsC4UoHBmiqx+ckrcNyMOlu9 bjXpE6geMmNJ6FXaZ3YHCCO6ruathjKekIyKVsvck7VSJ8I4sjFR3TBRMWs5jaLz8DQw /4elPkeHYic7hGWxPYmhbg+jTCCjd3b1HCjer4Ca0M+eX/+KTmbWH9NlOOuGRq3ivCKd o9KA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=75oGTaUkN/py11vcc7/YWZBcNN2MEQjFwocRCZ9uca4=; b=k6e/8geIZ/d1ehjX1uJEQoyG/2zBVWl4H1SKSRxr+cu34+R2mmMdT8ywXV6JaVIxCP z1yueHIxQf06f/b1X/tbApfiNukFP6RnQzbdTDquEUoRH7iQHpdWiziekOAMAcbw8IwS j1hupvHA+kOrCgD/K2CSoBH5I05EC2ujZPwdVLl/KdKYz7GHi4agPf0H2sQqMLqz7OFk cpoBNnuq8iPXGasigVrPn0l/9Fkajksgvi2cA8kDn3mEJ9BTTodhr3rkc/Z6dqjAKEQz KYx6xg7ytFU88sZ+MTF2h6IVWnjKJ83WTWOtaCb5AiD5/EkKFG0B2KMYqgG1GNEPioXt HZ+g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="jIiu/mV4"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gs18-20020a170906f19200b007c17b0c3838si111542ejb.190.2023.01.05.20.59.00; Thu, 05 Jan 2023 20:59:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="jIiu/mV4"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230353AbjAFEzt (ORCPT <rfc822;tmhikaru@gmail.com> + 99 others); Thu, 5 Jan 2023 23:55:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229628AbjAFEzp (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 5 Jan 2023 23:55:45 -0500 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C5AB625DA for <linux-kernel@vger.kernel.org>; Thu, 5 Jan 2023 20:55:43 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id c4so603195plc.5 for <linux-kernel@vger.kernel.org>; Thu, 05 Jan 2023 20:55:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=75oGTaUkN/py11vcc7/YWZBcNN2MEQjFwocRCZ9uca4=; b=jIiu/mV4pjrdZCVtNS8MvKcx2JPsnHpD/Vofw6AwdJ7Jm4qIj6H8Cyyra2vNxndO0t g9PM4Z4ZBjy7euXsOppK3mb5JGSIdSS53dfjRsB1ysxRiPGFRdJupri2tHhI/sudZs9i wJABQOh/tqy9+wt0tFTBZQj0sP6z0Kd7ulY0Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=75oGTaUkN/py11vcc7/YWZBcNN2MEQjFwocRCZ9uca4=; b=iIiHdn7JROxg0rV/3+FVoZ48vnkkje2Q/o2xXHuuxawtbdrffR0klVCmUIi2gE+BYV QB3nrkio7jrJib6x5PmlMuYQKCncs1QLqNkhvzrBk1TUIJD6pyIJaaI8YZHiMJYSL9t2 zUrnR+NyAR9KEKa9AYDa4XNq0Z9ZoLHTuHcBEtXpdTxIWtqZGL105HMPKYJ1hZCY5eQM U6YlZcoZTxuKGAgcD6DHgxwUDmuX7TqaGN0yYWazOhEqZuLOHnZJOv+eqPaU7hv5E9OW jokzfUE5emuV+8fWMAn65h1X4JPBy/dmJJHGc2J7/1v/VD4THh9BY+gvNmzv2OJnwxCq F+Vg== X-Gm-Message-State: AFqh2kow0mnAUlx7hJ0xo6K5SJ/+iiZqFJc6a4ZeOXQkMTGcL0PM6Cr5 a0g7vluVKqTc5axdB1Be6zGyQg== X-Received: by 2002:a17:902:f293:b0:192:5c84:63fa with SMTP id k19-20020a170902f29300b001925c8463famr42581960plc.65.1672980942750; Thu, 05 Jan 2023 20:55:42 -0800 (PST) Received: from wenstp920.tpe.corp.google.com ([2401:fa00:1:10:7428:62fb:34cf:24f4]) by smtp.gmail.com with ESMTPSA id q12-20020a17090311cc00b0018c990ce7fesm26969390plh.239.2023.01.05.20.55.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Jan 2023 20:55:42 -0800 (PST) From: Chen-Yu Tsai <wenst@chromium.org> To: Benson Leung <bleung@chromium.org>, Guenter Roeck <groeck@chromium.org> Cc: Chen-Yu Tsai <wenst@chromium.org>, Tzung-Bi Shih <tzungbi@kernel.org>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>, chrome-platform@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH] platform/chromeos: cros_ec: Use per-device lockdep key Date: Fri, 6 Jan 2023 12:55:37 +0800 Message-Id: <20230106045537.1243887-1-wenst@chromium.org> X-Mailer: git-send-email 2.39.0.314.g84b9a713c41-goog MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1754247898301202274?= X-GMAIL-MSGID: =?utf-8?q?1754247898301202274?= |
Series |
platform/chromeos: cros_ec: Use per-device lockdep key
|
|
Commit Message
Chen-Yu Tsai
Jan. 6, 2023, 4:55 a.m. UTC
Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to
the following lock sequences:
1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock)
2. lock(&ec_dev->lock); lock(prepare_lock);
The actual dependency chains are much longer. The shortened version
looks somewhat like:
1. cros-ec-rpmsg on mtk-scp
ec_dev->lock -> prepare_lock
2. In rt5682_i2c_probe() on native I2C bus:
prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock
3. In rt5682_i2c_probe() on native I2C bus:
regmap->lock -> i2c_adapter->bus_lock
4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec
i2c_adapter->bus_lock -> ec_dev->lock
While lockdep is correct that the shared lockdep classes have a circular
dependency, it is bogus because
a) 2+3 happen on a native I2C bus
b) 4 happens on the actual EC on ChromeOS devices
c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just
happen to expose a cros-ec interface, but do not have a passthrough
I2C bus
In short, the "dependencies" are actually on different devices.
Setup a per-device lockdep key for cros_ec devices so lockdep can tell
the two instances apart. This helps with getting rid of the bogus
lockdep warning. For ChromeOS devices that only have one cros-ec
instance this doesn't change anything.
Also add a missing mutex_destroy, just to make the teardown complete.
[1] This is likely the per I2C bus lock with shared lockdep class
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
---
drivers/platform/chrome/cros_ec.c | 14 +++++++++++---
include/linux/platform_data/cros_ec_proto.h | 2 ++
2 files changed, 13 insertions(+), 3 deletions(-)
Comments
On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > the following lock sequences: > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > 2. lock(&ec_dev->lock); lock(prepare_lock); > > The actual dependency chains are much longer. The shortened version > looks somewhat like: > > 1. cros-ec-rpmsg on mtk-scp > ec_dev->lock -> prepare_lock > 2. In rt5682_i2c_probe() on native I2C bus: > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > 3. In rt5682_i2c_probe() on native I2C bus: > regmap->lock -> i2c_adapter->bus_lock > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > i2c_adapter->bus_lock -> ec_dev->lock > > While lockdep is correct that the shared lockdep classes have a circular > dependency, it is bogus because > > a) 2+3 happen on a native I2C bus > b) 4 happens on the actual EC on ChromeOS devices > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > happen to expose a cros-ec interface, but do not have a passthrough > I2C bus > > In short, the "dependencies" are actually on different devices. Path of 4 looks weird to me. Could you point out where sbs_probe() gets to acquire ec_dev->lock? I may misunderstand: I thought there is no such I2C bus for passthrough from kernel's point of view (as the bus and devices behind the EC). See also [2]. [2]: https://elixir.bootlin.com/linux/v6.2-rc2/source/drivers/platform/chrome/cros_ec.c#L241 On a related note, for the commit title: s/chromeos/chrome/ if it gets chance to have next version.
On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > the following lock sequences: > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > The actual dependency chains are much longer. The shortened version > > looks somewhat like: > > > > 1. cros-ec-rpmsg on mtk-scp > > ec_dev->lock -> prepare_lock > > 2. In rt5682_i2c_probe() on native I2C bus: > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > 3. In rt5682_i2c_probe() on native I2C bus: > > regmap->lock -> i2c_adapter->bus_lock > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > i2c_adapter->bus_lock -> ec_dev->lock > > > > While lockdep is correct that the shared lockdep classes have a circular > > dependency, it is bogus because > > > > a) 2+3 happen on a native I2C bus > > b) 4 happens on the actual EC on ChromeOS devices > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > happen to expose a cros-ec interface, but do not have a passthrough > > I2C bus > > > > In short, the "dependencies" are actually on different devices. > > Path of 4 looks weird to me. > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? sbs_probe() calls sbs_get_battery_presence_and_health(), which -> does an I2C transfer. This SBS instance is connected on the I2C bus on the EC, so the I2C transfer -> acquires i2c_adapter->bus_lock, and -> calls ec_i2c_xfer(), which -> calls cros_ec_cmd_xfer_status(), which -> calls cros_ec_cmd_xfer(), which -> acquires ec_dev->lock > I may misunderstand: I thought there is no such I2C bus for passthrough > from kernel's point of view (as the bus and devices behind the EC). > See also [2]. It is an I2C adapter on the EC, also known as i2c-cros-ec-tunnel. Passthrough probably isn't the right word. > [2]: https://elixir.bootlin.com/linux/v6.2-rc2/source/drivers/platform/chrome/cros_ec.c#L241 > > > On a related note, for the commit title: s/chromeos/chrome/ if it gets > chance to have next version. OK. Thanks ChenYu
On Sat, Jan 07, 2023 at 01:43:57PM +0800, Chen-Yu Tsai wrote: > On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > > the following lock sequences: > > > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > > > The actual dependency chains are much longer. The shortened version > > > looks somewhat like: > > > > > > 1. cros-ec-rpmsg on mtk-scp > > > ec_dev->lock -> prepare_lock > > > 2. In rt5682_i2c_probe() on native I2C bus: > > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > > 3. In rt5682_i2c_probe() on native I2C bus: > > > regmap->lock -> i2c_adapter->bus_lock > > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > > i2c_adapter->bus_lock -> ec_dev->lock > > > > > > While lockdep is correct that the shared lockdep classes have a circular > > > dependency, it is bogus because > > > > > > a) 2+3 happen on a native I2C bus > > > b) 4 happens on the actual EC on ChromeOS devices > > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > > happen to expose a cros-ec interface, but do not have a passthrough > > > I2C bus > > > > > > In short, the "dependencies" are actually on different devices. > > > > Path of 4 looks weird to me. > > > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? > > sbs_probe() calls sbs_get_battery_presence_and_health(), which > > -> does an I2C transfer. This SBS instance is connected on the I2C bus > on the EC, so the I2C transfer > > -> acquires i2c_adapter->bus_lock, and I see. Another question: the i2c_adapter here should be different from the native I2C bus in 2 and 3. Did they really form the circular dependencies?
On Mon, Jan 9, 2023 at 1:46 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > On Sat, Jan 07, 2023 at 01:43:57PM +0800, Chen-Yu Tsai wrote: > > On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > > > the following lock sequences: > > > > > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > > > > > The actual dependency chains are much longer. The shortened version > > > > looks somewhat like: > > > > > > > > 1. cros-ec-rpmsg on mtk-scp > > > > ec_dev->lock -> prepare_lock > > > > 2. In rt5682_i2c_probe() on native I2C bus: > > > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > > > 3. In rt5682_i2c_probe() on native I2C bus: > > > > regmap->lock -> i2c_adapter->bus_lock > > > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > > > i2c_adapter->bus_lock -> ec_dev->lock > > > > > > > > While lockdep is correct that the shared lockdep classes have a circular > > > > dependency, it is bogus because > > > > > > > > a) 2+3 happen on a native I2C bus > > > > b) 4 happens on the actual EC on ChromeOS devices > > > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > > > happen to expose a cros-ec interface, but do not have a passthrough > > > > I2C bus > > > > > > > > In short, the "dependencies" are actually on different devices. > > > > > > Path of 4 looks weird to me. > > > > > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? > > > > sbs_probe() calls sbs_get_battery_presence_and_health(), which > > > > -> does an I2C transfer. This SBS instance is connected on the I2C bus > > on the EC, so the I2C transfer > > > > -> acquires i2c_adapter->bus_lock, and > > I see. > > Another question: the i2c_adapter here should be different from the native > I2C bus in 2 and 3. Did they really form the circular dependencies? That's why it's a false positive. lockdep normally doesn't track individual instances, only classes of locks. The class is declared as part of the mutex_init() macro. ChenYu
On Mon, Jan 09, 2023 at 02:19:38PM +0800, Chen-Yu Tsai wrote: > On Mon, Jan 9, 2023 at 1:46 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > On Sat, Jan 07, 2023 at 01:43:57PM +0800, Chen-Yu Tsai wrote: > > > On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > > > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > > > > the following lock sequences: > > > > > > > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > > > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > > > > > > > The actual dependency chains are much longer. The shortened version > > > > > looks somewhat like: > > > > > > > > > > 1. cros-ec-rpmsg on mtk-scp > > > > > ec_dev->lock -> prepare_lock > > > > > 2. In rt5682_i2c_probe() on native I2C bus: > > > > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > > > > 3. In rt5682_i2c_probe() on native I2C bus: > > > > > regmap->lock -> i2c_adapter->bus_lock > > > > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > > > > i2c_adapter->bus_lock -> ec_dev->lock > > > > > > > > > > While lockdep is correct that the shared lockdep classes have a circular > > > > > dependency, it is bogus because > > > > > > > > > > a) 2+3 happen on a native I2C bus > > > > > b) 4 happens on the actual EC on ChromeOS devices > > > > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > > > > happen to expose a cros-ec interface, but do not have a passthrough > > > > > I2C bus > > > > > > > > > > In short, the "dependencies" are actually on different devices. > > > > > > > > Path of 4 looks weird to me. > > > > > > > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? > > > > > > sbs_probe() calls sbs_get_battery_presence_and_health(), which > > > > > > -> does an I2C transfer. This SBS instance is connected on the I2C bus > > > on the EC, so the I2C transfer > > > > > > -> acquires i2c_adapter->bus_lock, and > > > > I see. > > > > Another question: the i2c_adapter here should be different from the native > > I2C bus in 2 and 3. Did they really form the circular dependencies? > > That's why it's a false positive. lockdep normally doesn't track individual > instances, only classes of locks. The class is declared as part of the > mutex_init() macro. Is the following understanding correct: It has 2 ways to break the "fake" circular dependencies: separate lockdep key for i2c_adapter vs. ec_dev. The patch adopts the latter one because it has limited impact for other I2C-related drivers.
On Mon, Jan 9, 2023 at 3:30 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > On Mon, Jan 09, 2023 at 02:19:38PM +0800, Chen-Yu Tsai wrote: > > On Mon, Jan 9, 2023 at 1:46 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > On Sat, Jan 07, 2023 at 01:43:57PM +0800, Chen-Yu Tsai wrote: > > > > On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > > > > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > > > > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > > > > > the following lock sequences: > > > > > > > > > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > > > > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > > > > > > > > > The actual dependency chains are much longer. The shortened version > > > > > > looks somewhat like: > > > > > > > > > > > > 1. cros-ec-rpmsg on mtk-scp > > > > > > ec_dev->lock -> prepare_lock > > > > > > 2. In rt5682_i2c_probe() on native I2C bus: > > > > > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > > > > > 3. In rt5682_i2c_probe() on native I2C bus: > > > > > > regmap->lock -> i2c_adapter->bus_lock > > > > > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > > > > > i2c_adapter->bus_lock -> ec_dev->lock > > > > > > > > > > > > While lockdep is correct that the shared lockdep classes have a circular > > > > > > dependency, it is bogus because > > > > > > > > > > > > a) 2+3 happen on a native I2C bus > > > > > > b) 4 happens on the actual EC on ChromeOS devices > > > > > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > > > > > happen to expose a cros-ec interface, but do not have a passthrough > > > > > > I2C bus > > > > > > > > > > > > In short, the "dependencies" are actually on different devices. > > > > > > > > > > Path of 4 looks weird to me. > > > > > > > > > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? > > > > > > > > sbs_probe() calls sbs_get_battery_presence_and_health(), which > > > > > > > > -> does an I2C transfer. This SBS instance is connected on the I2C bus > > > > on the EC, so the I2C transfer > > > > > > > > -> acquires i2c_adapter->bus_lock, and > > > > > > I see. > > > > > > Another question: the i2c_adapter here should be different from the native > > > I2C bus in 2 and 3. Did they really form the circular dependencies? > > > > That's why it's a false positive. lockdep normally doesn't track individual > > instances, only classes of locks. The class is declared as part of the > > mutex_init() macro. > > Is the following understanding correct: > It has 2 ways to break the "fake" circular dependencies: separate lockdep key > for i2c_adapter vs. ec_dev. The patch adopts the latter one because it has > limited impact for other I2C-related drivers. That's correct.
On Mon, Jan 09, 2023 at 03:35:08PM +0800, Chen-Yu Tsai wrote: > On Mon, Jan 9, 2023 at 3:30 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > On Mon, Jan 09, 2023 at 02:19:38PM +0800, Chen-Yu Tsai wrote: > > > On Mon, Jan 9, 2023 at 1:46 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > > > On Sat, Jan 07, 2023 at 01:43:57PM +0800, Chen-Yu Tsai wrote: > > > > > On Fri, Jan 6, 2023 at 5:08 PM Tzung-Bi Shih <tzungbi@kernel.org> wrote: > > > > > > > > > > > > On Fri, Jan 06, 2023 at 12:55:37PM +0800, Chen-Yu Tsai wrote: > > > > > > > Lockdep reports a bogus possible deadlock on MT8192 Chromebooks due to > > > > > > > the following lock sequences: > > > > > > > > > > > > > > 1. lock(i2c_register_adapter) [1]; lock(&ec_dev->lock) > > > > > > > 2. lock(&ec_dev->lock); lock(prepare_lock); > > > > > > > > > > > > > > The actual dependency chains are much longer. The shortened version > > > > > > > looks somewhat like: > > > > > > > > > > > > > > 1. cros-ec-rpmsg on mtk-scp > > > > > > > ec_dev->lock -> prepare_lock > > > > > > > 2. In rt5682_i2c_probe() on native I2C bus: > > > > > > > prepare_lock -> regmap->lock -> (possibly) i2c_adapter->bus_lock > > > > > > > 3. In rt5682_i2c_probe() on native I2C bus: > > > > > > > regmap->lock -> i2c_adapter->bus_lock > > > > > > > 4. In sbs_probe() on cros-ec-i2c (passthrough) I2C bus on cros-ec > > > > > > > i2c_adapter->bus_lock -> ec_dev->lock > > > > > > > > > > > > > > While lockdep is correct that the shared lockdep classes have a circular > > > > > > > dependency, it is bogus because > > > > > > > > > > > > > > a) 2+3 happen on a native I2C bus > > > > > > > b) 4 happens on the actual EC on ChromeOS devices > > > > > > > c) 1 happens on the SCP coprocessor on MediaTek Chromebooks that just > > > > > > > happen to expose a cros-ec interface, but do not have a passthrough > > > > > > > I2C bus > > > > > > > > > > > > > > In short, the "dependencies" are actually on different devices. > > > > > > > > > > > > Path of 4 looks weird to me. > > > > > > > > > > > > Could you point out where sbs_probe() gets to acquire ec_dev->lock? > > > > > > > > > > sbs_probe() calls sbs_get_battery_presence_and_health(), which > > > > > > > > > > -> does an I2C transfer. This SBS instance is connected on the I2C bus > > > > > on the EC, so the I2C transfer > > > > > > > > > > -> acquires i2c_adapter->bus_lock, and > > > > > > > > I see. > > > > > > > > Another question: the i2c_adapter here should be different from the native > > > > I2C bus in 2 and 3. Did they really form the circular dependencies? > > > > > > That's why it's a false positive. lockdep normally doesn't track individual > > > instances, only classes of locks. The class is declared as part of the > > > mutex_init() macro. > > > > Is the following understanding correct: > > It has 2 ways to break the "fake" circular dependencies: separate lockdep key > > for i2c_adapter vs. ec_dev. The patch adopts the latter one because it has > > limited impact for other I2C-related drivers. > > That's correct. Thanks for the explanation. The patch looks good to me. Just realized a kernel-doc warning after applying the patch: $ ./scripts/kernel-doc -none include/linux/platform_data/cros_ec_proto.h include/linux/platform_data/cros_ec_proto.h:199: warning: Function parameter or member 'lockdep_key' not described in 'cros_ec_device' Please fix the warning and commit title.
diff --git a/drivers/platform/chrome/cros_ec.c b/drivers/platform/chrome/cros_ec.c index ec733f683f34..4ae57820afd5 100644 --- a/drivers/platform/chrome/cros_ec.c +++ b/drivers/platform/chrome/cros_ec.c @@ -198,12 +198,14 @@ int cros_ec_register(struct cros_ec_device *ec_dev) if (!ec_dev->dout) return -ENOMEM; + lockdep_register_key(&ec_dev->lockdep_key); mutex_init(&ec_dev->lock); + lockdep_set_class(&ec_dev->lock, &ec_dev->lockdep_key); err = cros_ec_query_all(ec_dev); if (err) { dev_err(dev, "Cannot identify the EC: error %d\n", err); - return err; + goto destroy_mutex; } if (ec_dev->irq > 0) { @@ -215,7 +217,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) if (err) { dev_err(dev, "Failed to request IRQ %d: %d\n", ec_dev->irq, err); - return err; + goto destroy_mutex; } } @@ -226,7 +228,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) if (IS_ERR(ec_dev->ec)) { dev_err(ec_dev->dev, "Failed to create CrOS EC platform device\n"); - return PTR_ERR(ec_dev->ec); + err = PTR_ERR(ec_dev->ec); + goto destroy_mutex; } if (ec_dev->max_passthru) { @@ -292,6 +295,9 @@ int cros_ec_register(struct cros_ec_device *ec_dev) exit: platform_device_unregister(ec_dev->ec); platform_device_unregister(ec_dev->pd); +destroy_mutex: + mutex_destroy(&ec_dev->lock); + lockdep_unregister_key(&ec_dev->lockdep_key); return err; } EXPORT_SYMBOL(cros_ec_register); @@ -309,6 +315,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev) if (ec_dev->pd) platform_device_unregister(ec_dev->pd); platform_device_unregister(ec_dev->ec); + mutex_destroy(&ec_dev->lock); + lockdep_unregister_key(&ec_dev->lockdep_key); } EXPORT_SYMBOL(cros_ec_unregister); diff --git a/include/linux/platform_data/cros_ec_proto.h b/include/linux/platform_data/cros_ec_proto.h index e43107e0bee1..677d2eae1692 100644 --- a/include/linux/platform_data/cros_ec_proto.h +++ b/include/linux/platform_data/cros_ec_proto.h @@ -9,6 +9,7 @@ #define __LINUX_CROS_EC_PROTO_H #include <linux/device.h> +#include <linux/lockdep_types.h> #include <linux/mutex.h> #include <linux/notifier.h> @@ -160,6 +161,7 @@ struct cros_ec_device { struct cros_ec_command *msg); int (*pkt_xfer)(struct cros_ec_device *ec, struct cros_ec_command *msg); + struct lock_class_key lockdep_key; struct mutex lock; u8 mkbp_event_supported; bool host_sleep_v1;