Messages in this thread | | | Date | Sat, 28 Feb 2015 18:02:33 +0300 | From | Alexey Khoroshilov <> | Subject | drm/gma500: Possible deadlock in gma_power_begin() |
| |
gma_power_begin() starts with locking power_ctrl_lock spinlock and then, if gma_resume_pci(dev->pdev) succeed, it calls psb_irq_preinstall(dev); psb_irq_postinstall(dev);
psb_irq_postinstall() does some pipestat enabling/disabling dance: if (dev->vblank[0].enabled) psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); else psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
where void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { u32 reg = psb_pipestat(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ if (gma_power_begin(dev_priv->dev, false)) { u32 writeVal = PSB_RVDC32(reg); writeVal |= (mask | (mask >> 16)); PSB_WVDC32(writeVal, reg); (void) PSB_RVDC32(reg); gma_power_end(dev_priv->dev); } } }
So, if a flag in dev_priv->pipestat[pipe] is not in agreement with dev->vblank[0].enabled, we will have a call to gma_power_begin() again and got an unavoidable deadlock.
Thus it seems either some code is unneeded at all or we could have a deadlock from time to time. What do you think?
Found by Linux Driver Verification project (linuxtesting.org).
-- Alexey Khoroshilov Linux Verification Center, ISPRAS
| |