Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp5229235ybl; Tue, 27 Aug 2019 01:10:25 -0700 (PDT) X-Google-Smtp-Source: APXvYqz1hnIe+k82QfRKpw4GTNjG2zGZFJGJjR0spU5r6u6A3LGvSlTlcgTjZam7ZeJX0IEiJZhK X-Received: by 2002:a17:902:1027:: with SMTP id b36mr21398437pla.203.1566893425635; Tue, 27 Aug 2019 01:10:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566893425; cv=none; d=google.com; s=arc-20160816; b=NT1CBCb4I6fZvNbPN66KvjapCG57i+Wj6XqGzrcWGPT0CIPvWQsbUzFHmsrtVVLAGL JqpQEBLNaaKoqGfvaM2+EFHUV/zZUkHl4fjiXu6CWxcLoM52sku67mfo5NVz+Ap9TCDy GJVcEe8kUqWKnfkOFxGhBACrOdsAxlarSNSXVPI6FYYaXTAaw4/9iePG0k1RFFg5DQPn wCJATP+BbiVYp48cWnblbn+rLticlVU9X8fOeTHFTHwjROzZn3EBVkOEF3U51rXqzbbc jralGLH4+XV8Ws9v+8ULL7U3IUaZLa6XT0mtoel2TOTL+/iqvnFiQCmYGozf4gaYmpwn 0y4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=dQ4faDSzngFxZzoaV1y7nr7wulIToLpybwK/VQtPTCQ=; b=d5e4KwQLlRIBf8iKJGLHbL4bFfdUYQFuG27SDSAg2jVHX/E7XOXDo8YFqZESFedmLH XVtBbm7XG5Y0vx5oVnVSglX9nkqDodynpEVNXP45yt76J3a6L+0G46DAMKoDiJr2l4Ps hdVuKWAmENUs6RRYLmSvwi6D6p0rpgI/+piI7nrDGpSuaj9cizM2d0stTcZmYz4fCE8N J/5+9Zvpw3h7rAUmWpmoIU+Yd7nOr6qtMILEwMDvtWmaAIfvfy3upoHjwyVPThiM0HAS J5Va7Si4PrDquI4TdJCD4WtfS7+tYIhn2ybuARK2FklCmSJJI0/SPjkxsYUnHa80t9Qu L2Yg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=yDjB4wUe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bh6si11987183plb.285.2019.08.27.01.10.10; Tue, 27 Aug 2019 01:10:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=yDjB4wUe; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731412AbfH0IFC (ORCPT + 99 others); Tue, 27 Aug 2019 04:05:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:34596 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731444AbfH0IE6 (ORCPT ); Tue, 27 Aug 2019 04:04:58 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id F403621872; Tue, 27 Aug 2019 08:04:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1566893097; bh=nr+XhdCJv5KdUbvjEpdXWa5YBu+SA2axb6GLhdsPhOM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yDjB4wUeIzQFQT79+G4Hkn800ntKwQm6dHfJE97nlRypNuXM6J2cYeQ/TdYoxDV9h PUwtxAUBKLgpVQDxmSmBZ/Oh5HqX+S80l5BwogwuTjZKKS2v3eot9Puez6DNyVuwbU sWplBPN/w7XdxfzweX8zywKfoGlrxATq/+eFv0bM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lyude Paul , Ben Skeggs Subject: [PATCH 5.2 120/162] drm/nouveau: Dont retry infinitely when receiving no data on i2c over AUX Date: Tue, 27 Aug 2019 09:50:48 +0200 Message-Id: <20190827072742.631504865@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190827072738.093683223@linuxfoundation.org> References: <20190827072738.093683223@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lyude Paul commit c358ebf59634f06d8ed176da651ec150df3c8686 upstream. While I had thought I had fixed this issue in: commit 342406e4fbba ("drm/nouveau/i2c: Disable i2c bus access after ->fini()") It turns out that while I did fix the error messages I was seeing on my P50 when trying to access i2c busses with the GPU in runtime suspend, I accidentally had missed one important detail that was mentioned on the bug report this commit was supposed to fix: that the CPU would only lock up when trying to access i2c busses _on connected devices_ _while the GPU is not in runtime suspend_. Whoops. That definitely explains why I was not able to get my machine to hang with i2c bus interactions until now, as plugging my P50 into it's dock with an HDMI monitor connected allowed me to finally reproduce this locally. Now that I have managed to reproduce this issue properly, it looks like the problem is much simpler then it looks. It turns out that some connected devices, such as MST laptop docks, will actually ACK i2c reads even if no data was actually read: [ 275.063043] nouveau 0000:01:00.0: i2c: aux 000a: 1: 0000004c 1 [ 275.063447] nouveau 0000:01:00.0: i2c: aux 000a: 00 01101000 10040000 [ 275.063759] nouveau 0000:01:00.0: i2c: aux 000a: rd 00000001 [ 275.064024] nouveau 0000:01:00.0: i2c: aux 000a: rd 00000000 [ 275.064285] nouveau 0000:01:00.0: i2c: aux 000a: rd 00000000 [ 275.064594] nouveau 0000:01:00.0: i2c: aux 000a: rd 00000000 Because we don't handle the situation of i2c ack without any data, we end up entering an infinite loop in nvkm_i2c_aux_i2c_xfer() since the value of cnt always remains at 0. This finally properly explains how this could result in a CPU hang like the ones observed in the aforementioned commit. So, fix this by retrying transactions if no data is written or received, and give up and fail the transaction if we continue to not write or receive any data after 32 retries. Signed-off-by: Lyude Paul Cc: stable@vger.kernel.org Signed-off-by: Ben Skeggs Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c @@ -40,8 +40,7 @@ nvkm_i2c_aux_i2c_xfer(struct i2c_adapter u8 *ptr = msg->buf; while (remaining) { - u8 cnt = (remaining > 16) ? 16 : remaining; - u8 cmd; + u8 cnt, retries, cmd; if (msg->flags & I2C_M_RD) cmd = 1; @@ -51,10 +50,19 @@ nvkm_i2c_aux_i2c_xfer(struct i2c_adapter if (mcnt || remaining > 16) cmd |= 4; /* MOT */ - ret = aux->func->xfer(aux, true, cmd, msg->addr, ptr, &cnt); - if (ret < 0) { - nvkm_i2c_aux_release(aux); - return ret; + for (retries = 0, cnt = 0; + retries < 32 && !cnt; + retries++) { + cnt = min_t(u8, remaining, 16); + ret = aux->func->xfer(aux, true, cmd, + msg->addr, ptr, &cnt); + if (ret < 0) + goto out; + } + if (!cnt) { + AUX_TRACE(aux, "no data after 32 retries"); + ret = -EIO; + goto out; } ptr += cnt; @@ -64,8 +72,10 @@ nvkm_i2c_aux_i2c_xfer(struct i2c_adapter msg++; } + ret = num; +out: nvkm_i2c_aux_release(aux); - return num; + return ret; } static u32