All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Bottomley <jbottomley@parallels.com>
To: "hare@suse.de" <hare@suse.de>
Cc: "hch@lst.de" <hch@lst.de>,
	"linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>,
	"g.liakhovetski@gmx.de" <g.liakhovetski@gmx.de>
Subject: Re: [PATCH] tmscsim: fix spinlock usage in isr
Date: Fri, 7 Nov 2014 13:09:03 +0000	[thread overview]
Message-ID: <1415365740.27625.14.camel@jarvis.quadriga.com> (raw)
In-Reply-To: <1415364584-28951-1-git-send-email-hare@suse.de>

On Fri, 2014-11-07 at 13:49 +0100, Hannes Reinecke wrote:
> Loading the tmscsim driver would result in kernel splat as
> the interrupt service routine would only use spin_lock_irq,
> not spin_lock_irqsave.

I don't understand the reasoning ... what kernel splat?

Linux runs interrupt routines with interrupts enabled, so you know the
irq state on entry; that's why you can do spin_lock_irq ... because you
know it was enabled before and now it's disabled.  It only saves a
couple of instructions, so there's no real point using a different
pattern, but there's no reason to change it either, because it's
harmless when done correctly.

> And while we're at it there is not need to release the
> spin lock when calling udelay; it's implemented via a
> processor counter, not via interrupts.

That looks a bit incorrect:  The potential timeout is jiffies + HZ, i.e.
up to 1 second of udelay.  If it didn't drop and retake the lock (and
enable interrupts), it would spin with interrupts disabled for up to a
second ... with all the badness that would result from that.

James

> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>  drivers/scsi/tmscsim.c | 15 +++++----------
>  1 file changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
> index 7645757..2aecd2c 100644
> --- a/drivers/scsi/tmscsim.c
> +++ b/drivers/scsi/tmscsim.c
> @@ -654,6 +654,7 @@ DC390_Interrupt(void *dev_id)
>      u8  phase;
>      void   (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *);
>      u8  istate, istatus;
> +    unsigned long flags;
>  
>      sstatus = DC390_read8 (Scsi_Status);
>      if( !(sstatus & INTERRUPT) )
> @@ -665,7 +666,7 @@ DC390_Interrupt(void *dev_id)
>      //dstatus = DC390_read8 (DMA_Status);
>      //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
>  
> -    spin_lock_irq(pACB->pScsiHost->host_lock);
> +    spin_lock_irqsave(pACB->pScsiHost->host_lock, flags);
>  
>      istate = DC390_read8 (Intern_State);
>      istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
> @@ -736,7 +737,7 @@ DC390_Interrupt(void *dev_id)
>      }
>  
>   unlock:
> -    spin_unlock_irq(pACB->pScsiHost->host_lock);
> +    spin_unlock_irqrestore(pACB->pScsiHost->host_lock, flags);
>      return IRQ_HANDLED;
>  }
>  
> @@ -770,11 +771,8 @@ dc390_DataOut_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
>  
>  	    /* Function called from the ISR with the host_lock held and interrupts disabled */
>  	    if (pSRB->SGToBeXferLen)
> -		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
> -		    spin_unlock_irq(pACB->pScsiHost->host_lock);
> +		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE))
>  		    udelay(50);
> -		    spin_lock_irq(pACB->pScsiHost->host_lock);
> -		}
>  	    if (!time_before(jiffies, timeout))
>  		printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n",
>  			DC390_read32 (DMA_Wk_ByteCntr));
> @@ -829,11 +827,8 @@ dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
>  
>  	    /* Function called from the ISR with the host_lock held and interrupts disabled */
>  	    if (pSRB->SGToBeXferLen)
> -		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
> -		    spin_unlock_irq(pACB->pScsiHost->host_lock);
> +		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE))
>  		    udelay(50);
> -		    spin_lock_irq(pACB->pScsiHost->host_lock);
> -		}
>  	    if (!time_before(jiffies, timeout)) {
>  		printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
>  			DC390_read32 (DMA_Wk_ByteCntr));


  reply	other threads:[~2014-11-07 13:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-07 12:49 [PATCH] tmscsim: fix spinlock usage in isr Hannes Reinecke
2014-11-07 13:09 ` James Bottomley [this message]
2014-11-07 13:16   ` Hannes Reinecke
2014-11-07 14:11     ` James Bottomley

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=1415365740.27625.14.camel@jarvis.quadriga.com \
    --to=jbottomley@parallels.com \
    --cc=g.liakhovetski@gmx.de \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=linux-scsi@vger.kernel.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.