Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp1788110imm; Sat, 4 Aug 2018 10:45:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdHT3jb32WIhKFEBXO4Ri2KjSd8PBUpkxjXalKjDYRI7O2sAG8c4RkZxABKTYZI1AWdJxSD X-Received: by 2002:a62:1f8c:: with SMTP id l12-v6mr10051253pfj.143.1533404746823; Sat, 04 Aug 2018 10:45:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533404746; cv=none; d=google.com; s=arc-20160816; b=h5dIfqgQWeY/8onxFZfqs/9B4q3s8RX9ePj4hTAPFQWgdTzJgbZxD1WUDDKt/B8RhK yusKdC12IdY4lb73gzTq5+ezbNG8OpBrPtqDCorzF202ywVNlqHYWxWm5aa3FmiuL21n eSVvnlN+3eOTRm2ygP9yeIvMage7LEIcwHYSjg9MBn/FCr+3mG+cMPVYyvGUvBk/MWal zlqC7CHgaTe9OT/UCotzMvbH4+LwiHhJHKfzxSBqxEf+iWQpbkQx8OjlWCR9MuzuViqI AizFB74pWpEfWddFJbEV1PHwyBG+3bbFi9bkK6Qg5FoROmN65uWXhzfXJiRtst4aO/Uk /qTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:dkim-signature:arc-authentication-results; bh=olvV/zSunBkKy+9H5S3QFrTWMFCwYD0IFo5iQpgzG4E=; b=IRhGjzuhDTKdT/sRnY0uHIMJJSres3pQHUPrmhP/MQcT4yyestzExLTR/IYVreu7cv XAqj2lZCbhUL3nRCSjv9Y4M9iA4ogHrgVeb9+aJuh2ePdYqdEoGgEmIK7ZiXwnTdeB8T UTTAxOcBhErt1KYHEiRXnA3scVWG5/1S/vEgUYc/+G7bP1WzfMaDez+bw/5cnMhoiW8s 73gjQjXQxFFP3aZPKzwaVs7HfmyRgMPChg/6BJYUgIjl7iVB55kod6KBBrZyIIw9WQvp mXGhA4X4xtcbKJPfGk4VNCXoLgyqO7CBmqWv32DXe0WocoIY5MW9STObzuOap+ZpvgHh nG6Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@de.bosch.com header.s=2015-01-21 header.b=O1ZeaXYq; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=de.bosch.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j189-v6si7281322pgd.498.2018.08.04.10.45.19; Sat, 04 Aug 2018 10:45:46 -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=fail header.i=@de.bosch.com header.s=2015-01-21 header.b=O1ZeaXYq; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=de.bosch.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729389AbeHDTpW (ORCPT + 99 others); Sat, 4 Aug 2018 15:45:22 -0400 Received: from de-out1.bosch-org.com ([139.15.230.186]:47420 "EHLO de-out1.bosch-org.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728067AbeHDTpW (ORCPT ); Sat, 4 Aug 2018 15:45:22 -0400 Received: from si0vm1947.rbesz01.com (unknown [139.15.230.188]) by si0vms0217.rbdmz01.com (Postfix) with ESMTPS id 41jWVh0VTjz4f3kky; Sat, 4 Aug 2018 19:43:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=de.bosch.com; s=2015-01-21; t=1533404636; bh=rNreBz9tcS3Q2kVTNLarcOTT5RXq5VFV0bGKMsjq8CU=; l=10; h=From:From:Reply-To:Sender; b=O1ZeaXYqdLmhOObkLAA6cpu75WDxf22J+xYLdiffsdjR1NkbWr5b9pQiEo63TLz+9 303Ik1IpV+uoKOLiAry9jsdylH6xrkixTzQm9WF9iEn22YQo1fMDYLSTcIpzovJ110 zRGfrZGKJtRGBt3q8hPjiC44b2laMW5JZdD0/T7s= Received: from fe0vm1740.rbesz01.com (unknown [10.58.172.176]) by si0vm1947.rbesz01.com (Postfix) with ESMTP id 41jWVg75gMz6CjQSR; Sat, 4 Aug 2018 19:43:55 +0200 (CEST) X-AuditID: 0a3aad14-86fff70000000cae-a7-5b65e5dc7729 Received: from fe0vm1651.rbesz01.com (Unknown_Domain [10.58.173.29]) (using TLS with cipher AES128-SHA (128/128 bits)) (Client did not present a certificate) by fe0vm1740.rbesz01.com (SMG Outbound) with SMTP id 34.6D.03246.CD5E56B5; Sat, 4 Aug 2018 19:43:56 +0200 (CEST) Received: from SI-HUB1000.de.bosch.com (si-hub1000.de.bosch.com [10.4.103.106]) by fe0vm1651.rbesz01.com (Postfix) with ESMTPS id 41jWVg4vVzzhdYX; Sat, 4 Aug 2018 19:43:55 +0200 (CEST) Received: from luchador.grb-fir.grb.de.bosch.com (10.19.187.97) by SI-HUB1000.de.bosch.com (10.4.103.106) with Microsoft SMTP Server id 14.3.408.0; Sat, 4 Aug 2018 19:43:55 +0200 From: Mark Jonas To: Bartosz Golaszewski , Arnd Bergmann , Greg Kroah-Hartman CC: , , Wang Xin , Mark Jonas Subject: [PATCH] eeprom: at24: Fix unexpected timeout under high load Date: Sat, 4 Aug 2018 19:43:40 +0200 Message-ID: <1533404620-18536-1-git-send-email-mark.jonas@de.bosch.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 Content-Type: text/plain X-Brightmail-Tracker: H4sIAAAAAAAAA22SfUwTdxzG+d315Vo4Oa5FvitgshM0IZmCQqxvxGTZ5A9ZdMlMGMnGYX+0 jX0hvUIE/xCdipAotUMDteALmDnE6MhmKtMYupcwY2ChiCBYFZF1xMX5UiMU5q4UbP/wv7vn +X2e5+65o0j2rFxDGS12bLPwJk6mlCg3XEr/aOwJLs6e/DNRO+f8Xa7tfnhVpv2m7bJMe2Tu FdL6ut2yLdKC0IwTFbQNjUoLbrZ0ygtedi3bLvlSuUmHTcZKbFudX6I0/PZyhigfTdszFJol alBzSj1SUMDkgq/rrrQeKSmWOUFA8NQPROTmBoL2yZ4F5yoCz48jZBiRMVkw0uuZv1YzVdDS 4kDhQyRTj8D/bFwSNlTMJ3DHd1BWjyhKwmRA3duSsEwzW+HJ+V9kkeplMNJXR0b0JPijeWIe JRmAnkCAdCDaFWO5YqwziOhAyWU4u9Kcsy43e5WtFAvV2TmrdlnNXSiymtqDQt4yL2IoxCXQ h4dwMSvlK4UqsxflUQSXTOf5dMXsklKrrsrAC4avbRUmLHAaGsXFxbGqd7JQUWo2CoLRavEi oEhOTb+tEaNoHV9VjW3WCOZFqZSES6EtO8RIRs/b8W6My7Ft0d1IURzQKvErskk2rMd7yowm +6LNpUc6l8Y6sbUEpfCitVSC2L08HEEL5bxZMOoX8A8iOLuoRtFb6GNq9tkJJ8lKLFYL1qTQ FydEngmfNFRY3j2BJo2eHt9VzCbHGNGUKXQXiRuq6LxweYL4c0a7gfao3EVs0oIYhda0iQzj ToDW4QwIXNgCrZ4gAnfjaQLqAj8RMNDtkkPj8145NAV/VkDA36+Awe9CCmg96VDCcPtjJbQf PU7D9b7ORGj6u4mBByOvGXBeO6kCZ8elZJg+3ZAK3879mwqzD7rS4NVAbTqEekbTxbzGD6E3 cH05+Bs6M8FxeyATeu/dWAHt06EVcK7j2Ep403lhJQyPfZ81Jc5KiLPuzZ2f1c7b3zPrghp9 N00N6v9L56kNHsrfWKS8llFCWCY3H/5n4OaVeOete03/Ndw/sDsTu9SeKT5xprBadVTuGzzX cWc8JPdNufz6yyE1E3Ts/7TwUPnz7V8scce/WKrf1PjZwc+HdjY/Cm5bP/FU2u9/9NU+B/ur 1ji8QVX4dOz15qJThaO1pviM8xfHbufTPCcRDHxOFmkT+P8BqI+ZuTQEAAA= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wang Xin Within at24_loop_until_timeout the timestamp used for timeout checking is recorded after the I2C transfer and sleep_range(). Under high CPU load either the execution time for I2C transfer or sleep_range() could actually be larger than the timeout value. Worst case the I2C transfer is only tried once because the loop will exit due to the timeout although the EEPROM is now ready. To fix this issue the timestamp is recorded at the beginning of each iteration. That is, before I2C transfer and sleep. Then the timeout is actually checked against the timestamp of the previous iteration. This makes sure that even if the timeout is reached, there is still one more chance to try the I2C transfer in case the EEPROM is ready. Signed-off-by: Wang Xin Signed-off-by: Mark Jonas --- drivers/misc/eeprom/at24.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index f5cc517..6d8c294 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -112,16 +112,26 @@ MODULE_PARM_DESC(at24_write_timeout, "Time (in ms) to try writes (default 25)"); * write to work while making sure that at least one iteration is run before * checking the break condition. * + * By recording current time at the beginning of one iteration, the timeout + * is actually checked against the time in previous iteration. It makes sure, + * even the timeout is reached, there is still one more chance to try I2C + * transfer in case EEPROM is ready. + * * It takes two parameters: a variable in which the future timeout in jiffies * will be stored and a temporary variable holding the time of the last * iteration of processing the request. Both should be unsigned integers * holding at least 32 bits. */ -#define at24_loop_until_timeout(tout, op_time) \ - for (tout = jiffies + msecs_to_jiffies(at24_write_timeout), \ - op_time = 0; \ - op_time ? time_before(op_time, tout) : true; \ - usleep_range(1000, 1500), op_time = jiffies) +#define at24_loop_until_timeout_begin(tout, op_time) \ + tout = jiffies + msecs_to_jiffies(at24_write_timeout); \ + while (true) { \ + op_time = jiffies; + +#define at24_loop_until_timeout_end(tout, op_time) \ + if (time_before(tout, op_time)) \ + break; \ + usleep_range(1000, 1500); \ + } struct at24_chip_data { /* @@ -308,13 +318,14 @@ static ssize_t at24_regmap_read(struct at24_data *at24, char *buf, /* adjust offset for mac and serial read ops */ offset += at24->offset_adj; - at24_loop_until_timeout(timeout, read_time) { + at24_loop_until_timeout_begin(timeout, read_time) { ret = regmap_bulk_read(regmap, offset, buf, count); dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", count, offset, ret, jiffies); if (!ret) return count; } + at24_loop_until_timeout_end(timeout, read_time) return -ETIMEDOUT; } @@ -359,13 +370,14 @@ static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf, client = at24_client->client; count = at24_adjust_write_count(at24, offset, count); - at24_loop_until_timeout(timeout, write_time) { + at24_loop_until_timeout_begin(timeout, write_time) { ret = regmap_bulk_write(regmap, offset, buf, count); dev_dbg(&client->dev, "write %zu@%d --> %d (%ld)\n", count, offset, ret, jiffies); if (!ret) return count; } + at24_loop_until_timeout_end(timeout, write_time) return -ETIMEDOUT; } -- 2.7.4