diff options
author | David E. Box <david.e.box@linux.intel.com> | 2022-04-20 18:56:20 +0300 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2022-04-27 17:55:54 +0300 |
commit | 679c7a3f1596e8b5493c9473da4d967de540027c (patch) | |
tree | 0a24b40a294fe0d8ee238e0e8c1226e4176d38fe /drivers/platform/x86/intel/sdsi.c | |
parent | 8d75f7b4a3dfd5714a5dc87cfdaa27bd2d14aa48 (diff) | |
download | linux-679c7a3f1596e8b5493c9473da4d967de540027c.tar.xz |
platform/x86/intel/sdsi: Handle leaky bucket
To prevent an agent from indefinitely holding the mailbox firmware has
implemented a leaky bucket algorithm. Repeated access to the mailbox may
now incur a delay of up to 2.1 seconds. Add a retry loop that tries for
up to 2.5 seconds to acquire the mailbox.
Fixes: 2546c6000430 ("platform/x86: Add Intel Software Defined Silicon driver")
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
Link: https://lore.kernel.org/r/20220420155622.1763633-2-david.e.box@linux.intel.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86/intel/sdsi.c')
-rw-r--r-- | drivers/platform/x86/intel/sdsi.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/platform/x86/intel/sdsi.c b/drivers/platform/x86/intel/sdsi.c index 11d14cc0ff0a..11f211402479 100644 --- a/drivers/platform/x86/intel/sdsi.c +++ b/drivers/platform/x86/intel/sdsi.c @@ -51,6 +51,8 @@ #define MBOX_TIMEOUT_US 2000 #define MBOX_TIMEOUT_ACQUIRE_US 1000 #define MBOX_POLLING_PERIOD_US 100 +#define MBOX_ACQUIRE_NUM_RETRIES 5 +#define MBOX_ACQUIRE_RETRY_DELAY_MS 500 #define MBOX_MAX_PACKETS 4 #define MBOX_OWNER_NONE 0x00 @@ -263,7 +265,7 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info { u64 control; u32 owner; - int ret; + int ret, retries = 0; lockdep_assert_held(&priv->mb_lock); @@ -273,13 +275,29 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info if (owner != MBOX_OWNER_NONE) return -EBUSY; - /* Write first qword of payload */ - writeq(info->payload[0], priv->mbox_addr); + /* + * If there has been no recent transaction and no one owns the mailbox, + * we should acquire it in under 1ms. However, if we've accessed it + * recently it may take up to 2.1 seconds to acquire it again. + */ + do { + /* Write first qword of payload */ + writeq(info->payload[0], priv->mbox_addr); + + /* Check for ownership */ + ret = readq_poll_timeout(priv->control_addr, control, + FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND, + MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); + + if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE && + retries++ < MBOX_ACQUIRE_NUM_RETRIES) { + msleep(MBOX_ACQUIRE_RETRY_DELAY_MS); + continue; + } - /* Check for ownership */ - ret = readq_poll_timeout(priv->control_addr, control, - FIELD_GET(CTRL_OWNER, control) & MBOX_OWNER_INBAND, - MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); + /* Either we got it or someone else did. */ + break; + } while (true); return ret; } |