tpmdd-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Haris Okanovic <haris.okanovic@ni.com>
To: linux-rt-users@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: tpmdd-devel@lists.sourceforge.net, haris.okanovic@ni.com,
	harisokn@gmail.com, julia.cartwright@ni.com,
	gratian.crisan@ni.com, scott.hartman@ni.com, chris.graf@ni.com,
	brad.mouring@ni.com, jonathan.david@ni.com, peterhuewe@gmx.de,
	tpmdd@selhorst.net, jarkko.sakkinen@linux.intel.com,
	jgunthorpe@obsidianresearch.com, eric.gardiner@ni.com
Subject: [PATCH] tpm_tis: fix stall after iowrite*()s
Date: Mon, 14 Aug 2017 17:53:47 -0500	[thread overview]
Message-ID: <20170814225347.30670-1-haris.okanovic@ni.com> (raw)
In-Reply-To: <20170804215651.29247-1-haris.okanovic@ni.com>

ioread8() operations to TPM MMIO addresses can stall the cpu when
immediately following a sequence of iowrite*()'s to the same region.

For example, cyclitest measures ~400us latency spikes when a non-RT
usermode application communicates with an SPI-based TPM chip (Intel Atom
E3940 system, PREEMPT_RT_FULL kernel). The spikes are caused by a
stalling ioread8() operation following a sequence of 30+ iowrite8()s to
the same address. I believe this happens because the write sequence is
buffered (in cpu or somewhere along the bus), and gets flushed on the
first LOAD instruction (ioread*()) that follows.

The enclosed change appears to fix this issue: read the TPM chip's
access register (status code) after every iowrite*() operation to
amortize the cost of flushing data to chip across multiple instructions.

Signed-off-by: Haris Okanovic <haris.okanovic@ni.com>
---
https://patchwork.kernel.org/patch/9882119/
https://github.com/harisokanovic/linux/tree/dev/hokanovi/tpm-latency-spike-fix
---
 drivers/char/tpm/tpm_tis.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index c7e1384f1b08..3be2755d0514 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -52,6 +52,22 @@ static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *da
 	return container_of(data, struct tpm_tis_tcg_phy, priv);
 }
 
+static inline void tpm_tis_iowrite8(u8 b, void __iomem *iobase, u32 addr)
+{
+	iowrite8(b, iobase + addr);
+#ifdef CONFIG_PREEMPT_RT_FULL
+	ioread8(iobase + TPM_ACCESS(0));
+#endif
+}
+
+static inline void tpm_tis_iowrite32(u32 b, void __iomem *iobase, u32 addr)
+{
+	iowrite32(b, iobase + addr);
+#ifdef CONFIG_PREEMPT_RT_FULL
+	ioread8(iobase + TPM_ACCESS(0));
+#endif
+}
+
 static bool interrupts = true;
 module_param(interrupts, bool, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");
@@ -105,7 +121,7 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
 	struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
 
 	while (len--)
-		iowrite8(*value++, phy->iobase + addr);
+		tpm_tis_iowrite8(*value++, phy->iobase, addr);
 	return 0;
 }
 
@@ -129,7 +145,7 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value)
 {
 	struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
 
-	iowrite32(value, phy->iobase + addr);
+	tpm_tis_iowrite32(value, phy->iobase, addr);
 	return 0;
 }
 
-- 
2.13.2

       reply	other threads:[~2017-08-14 22:53 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20170804215651.29247-1-haris.okanovic@ni.com>
2017-08-14 22:53 ` Haris Okanovic [this message]
2017-08-15  6:11   ` Alexander Stein
2017-08-15 20:10     ` Haris Okanovic
     [not found] ` <20170804215651.29247-1-haris.okanovic-acOepvfBmUk@public.gmane.org>
2017-08-15 20:13   ` [PATCH v2] " Haris Okanovic
2017-08-16 21:15     ` [tpmdd-devel] " Ken Goldman
2017-08-17  5:57       ` Alexander Stein
2017-08-17 10:38       ` Sebastian Andrzej Siewior
     [not found]         ` <20170817103807.ubrbylnud6wxod3s-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
2017-08-17 17:17           ` Jason Gunthorpe
     [not found]             ` <20170817171732.GA22792-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-08-17 20:12               ` Haris Okanovic
2017-08-19 17:03             ` [tpmdd-devel] " Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170814225347.30670-1-haris.okanovic@ni.com \
    --to=haris.okanovic@ni.com \
    --cc=brad.mouring@ni.com \
    --cc=chris.graf@ni.com \
    --cc=eric.gardiner@ni.com \
    --cc=gratian.crisan@ni.com \
    --cc=harisokn@gmail.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jgunthorpe@obsidianresearch.com \
    --cc=jonathan.david@ni.com \
    --cc=julia.cartwright@ni.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rt-users@vger.kernel.org \
    --cc=peterhuewe@gmx.de \
    --cc=scott.hartman@ni.com \
    --cc=tpmdd-devel@lists.sourceforge.net \
    --cc=tpmdd@selhorst.net \
    --subject='Re: [PATCH] tpm_tis: fix stall after iowrite*()s' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).