Skip to content

Commit

Permalink
ltq-vdsl-mei: add locking to interrupt handler
Browse files Browse the repository at this point in the history
Some users noticed repeated resyncs at random intervals, which go away
when the MEI driver is configured to use polling instead of interrupts.
Debugging shows that this seems to be caused by concurrent calls to
MEI_ReadMailbox (in the interrupt handler) and MEI_WriteMailbox. This
appears to be mostly triggered when there is an interrupt for vectoring
error reports.

In polling mode, calls to MEI_ReadMailbox are protected by the same
semaphore as is used in MEI_WriteMailbox. When interrupts are used,
MEI_WriteMailbox appears to rely on MEI_DisableDeviceInt and
MEI_EnableDeviceInt to provide mutual exclusion with the interrupt
handler. These functions mask/unmask interrupts, and there is an
additional check of the mask in the interrupt handler itself. However,
this is not sufficient on systems with SMP, as the interrupt handler
may be running in parallel, and could already be past the interrupt
mask check at this point.

This adds a lock to the interrupt handler, and also acquires this lock
in MEI_DisableDeviceInt. This should make sure that after a call to
MEI_DisableDeviceInt the interrupt is masked, and the interrupt handler
is either not running, has alread finished its work, or is still before
the interrupt mask check, and is thus going to detect the change.

Tested-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
  • Loading branch information
janh authored and dangowrt committed Mar 21, 2022
1 parent b35d33c commit 1700424
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package/kernel/lantiq/ltq-vdsl-mei/Makefile
Expand Up @@ -9,7 +9,7 @@ include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=ltq-vdsl-vr9-mei
PKG_VERSION:=1.5.17.6
PKG_RELEASE:=5
PKG_RELEASE:=6

PKG_BASE_NAME:=drv_mei_cpe
PKG_SOURCE:=$(PKG_BASE_NAME)-$(PKG_VERSION).tar.gz
Expand Down
@@ -0,0 +1,45 @@
--- a/src/drv_mei_cpe_common.c
+++ b/src/drv_mei_cpe_common.c
@@ -104,6 +104,8 @@ IFX_uint32_t MEI_FsmStateSetMsgPreAction
MEI_DEVCFG_DATA_T MEI_DevCfgData;
#endif

+static DEFINE_SPINLOCK(MEI_InterruptLock);
+
/* ============================================================================
Proc-FS and debug variable definitions
========================================================================= */
@@ -2134,6 +2136,9 @@ IFX_int32_t MEI_ProcessIntPerIrq(MEIX_CN
#if (MEI_SUPPORT_DEBUG_STREAMS == 1)
IFX_int_t extraDbgStreamLoop = 0;
#endif
+ unsigned long flags;
+
+ spin_lock_irqsave(&MEI_InterruptLock, flags);

/* get the actual chip device from the list and step through the VRX devices */
while(pNextXCntrl)
@@ -2167,6 +2172,8 @@ IFX_int32_t MEI_ProcessIntPerIrq(MEIX_CN
}
#endif

+ spin_unlock_irqrestore(&MEI_InterruptLock, flags);
+
return meiIntCnt;
}

@@ -2639,9 +2646,14 @@ IFX_int32_t MEI_MsgSendPreAction(
*/
IFX_void_t MEI_DisableDeviceInt(MEI_DEV_T *pMeiDev)
{
+ unsigned long flags;
+ spin_lock_irqsave(&MEI_InterruptLock, flags);
+
MEI_MaskInterrupts( &pMeiDev->meiDrvCntrl,
ME_ARC2ME_INTERRUPT_MASK_ALL);

+ spin_unlock_irqrestore(&MEI_InterruptLock, flags);
+
return;
}

0 comments on commit 1700424

Please sign in to comment.