From patchwork Thu Apr 25 08:23:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 1090631 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=none (p=none dis=none) header.from=sang-engineering.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44qVZ05nTyz9s47 for ; Thu, 25 Apr 2019 18:23:20 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726330AbfDYIXT (ORCPT ); Thu, 25 Apr 2019 04:23:19 -0400 Received: from sauhun.de ([88.99.104.3]:43880 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727055AbfDYIXT (ORCPT ); Thu, 25 Apr 2019 04:23:19 -0400 Received: from localhost (p5486CE26.dip0.t-ipconnect.de [84.134.206.38]) by pokefinder.org (Postfix) with ESMTPSA id 6C22A2CF687; Thu, 25 Apr 2019 10:23:17 +0200 (CEST) From: Wolfram Sang To: linux-i2c@vger.kernel.org Cc: Hans de Goede , linux-renesas-soc@vger.kernel.org, Wolfram Sang Subject: [PATCH] i2c: core: ratelimit 'transfer when suspended' errors Date: Thu, 25 Apr 2019 10:23:10 +0200 Message-Id: <20190425082310.17109-1-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.11.0 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org There are two problems with WARN_ON() here. One: It is not ratelimited. Two: We don't see which adapter was used when trying to transfer something when already suspended. Implement a custom ratelimit once per adapter and use dev_WARN there. This fixes both issues. Drawback is that we don't see if multiple drivers are trying to transfer with the same adapter while suspended. They need to be discovered one after the other now. This is better than a high CPU load because a really broken driver might try to resend endlessly. Signed-off-by: Wolfram Sang --- So, Simon had a point with his review comment back then, and I think we now found a properly balanced way. Tested with a Renesas Lager board (R-Car H2). I decided against dev_WARN_ONCE because that seems too coarse grained for my taste (once per system) and the custom implementation is small. drivers/i2c/i2c-core-base.c | 5 ++++- include/linux/i2c.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 4e6300dc2c4e..f8e85983cb04 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1867,8 +1867,11 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (WARN_ON(!msgs || num < 1)) return -EINVAL; - if (WARN_ON(test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags))) + if (test_bit(I2C_ALF_IS_SUSPENDED, &adap->locked_flags)) { + if (!test_and_set_bit(I2C_ALF_SUSPEND_REPORTED, &adap->locked_flags)) + dev_WARN(&adap->dev, "Transfer while suspended\n"); return -ESHUTDOWN; + } if (adap->quirks && i2c_check_for_quirks(adap, msgs, num)) return -EOPNOTSUPP; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 03755d4c9229..be27062f8ed1 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -694,7 +694,8 @@ struct i2c_adapter { int retries; struct device dev; /* the adapter device */ unsigned long locked_flags; /* owned by the I2C core */ -#define I2C_ALF_IS_SUSPENDED 0 +#define I2C_ALF_IS_SUSPENDED 0 +#define I2C_ALF_SUSPEND_REPORTED 1 int nr; char name[48];