[3547] in linux-scsi channel archive
Re: spinlocks in SCSI code
daemon@ATHENA.MIT.EDU (Kurt Garloff)
Tue Mar 17 07:33:20 1998
Date: Tue, 17 Mar 1998 13:29:50 +0100
From: Kurt Garloff <garloff@kg1.ping.de>
To: Doug Ledford <dledford@dialnet.net>, linux-scsi@vger.rutgers.edu,
"Leonard N. Zubkoff" <lnz@dandelion.com>,
Gerard Roudier <groudier@club-internet.fr>
Mail-Followup-To: Doug Ledford <dledford@dialnet.net>,
linux-scsi@vger.rutgers.edu,
"Leonard N. Zubkoff" <lnz@dandelion.com>,
Gerard Roudier <groudier@club-internet.fr>
In-Reply-To: <19980317121818.A1000@kg1.ping.de>; from Kurt Garloff on Tue, Mar 17, 1998 at 12:18:18PM +0100
--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
On Tue, Mar 17, 1998 at 12:18:18PM +0100, Kurt Garloff wrote:
> If I correctly understand the locking mechanism, it should be possible to
> create a driver specific spinlock: spinlock_t rmscsim_lock =
> SPIN_LOCK_UNLOCKED; and replace every save_flags(flags); cli(); within the
> driver by spin_lock_irqsave (&tmscsim_lock, flags); and every
> restore_flags(flags); by spin_unlock_irqrestore(&tmscsim_lock, flags);
> [I assume, that all necessary locking is done by the driver at the moment
> using the cli() mechanism, here.]
> This would be somehow suboptimal, but very safe and still much better for
> SMP machines than the current approach.
Well, as a first test, I implemented this for the ncr53c8xx driver, as I'm
able to test it directly. Of course it works very well, as I have a UP
machine and the spin_lock_irqsave (); does exactly the same as save_flags();
cli();
Too bad I don't have a SMP machine to test.
Gerard, I append the diff. (Against 2.1.89, i.e. ncr53c8xx-2.5f)
--
Kurt Garloff, Dortmund
<K.Garloff@ping.de>
PGP key on http://student.physik.uni-dortmund.de/homepages/garloff
--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ncr53c8xx.spinlocks.diff"
--- linux/drivers/scsi/ncr53c8xx.c.2189 Sun Jan 18 14:06:04 1998
+++ linux/drivers/scsi/ncr53c8xx.c Tue Mar 17 12:40:17 1998
@@ -538,6 +538,16 @@
** Other Linux definitions
*/
+/* Locking */
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)
+static spinlock_t ncr53c8xx_lock = SPIN_LOCK_UNLOCKED;
+# define NCRLOCK(f) spin_lock_irqsave(&ncr53c8xx_lock, f)
+# define NCRUNLOCK(f) spin_unlock_irqrestore(&ncr53c8xx_lock, f)
+#else
+# define NCRLOCK(f) save_flags(f); cli()
+# define NCRUNLOCK(f) restore_flags(f)
+#endif
+
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f))
#if LINUX_VERSION_CODE >= LinuxVersionCode(2,0,0)
@@ -4617,14 +4627,14 @@
** if interrupts are not enabled yet.
** Then enable disconnects.
*/
- save_flags(flags); cli();
+ NCRLOCK(flags);
if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) {
printf("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np));
restore_flags(flags);
goto attach_error;
}
ncr_exception (np);
- restore_flags(flags);
+ NCRUNLOCK(flags);
np->disc = 1;
@@ -4777,7 +4787,7 @@
**
**----------------------------------------------------
*/
- save_flags(flags); cli();
+ NCRLOCK(flags);
if (np->settle_time && cmd->timeout_per_command >= HZ &&
np->settle_time > jiffies + cmd->timeout_per_command - HZ) {
@@ -4786,7 +4796,7 @@
if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->target, cmd->lun))) {
insert_into_waiting_list(np, cmd);
- restore_flags(flags);
+ NCRUNLOCK(flags);
return(DID_OK);
}
cp->cmd = cmd;
@@ -5013,7 +5023,7 @@
if (segments < 0) {
ncr_free_ccb(np, cp, cmd->target, cmd->lun);
- restore_flags(flags);
+ NCRUNLOCK(flags);
return(DID_ERROR);
}
@@ -5193,7 +5203,7 @@
/*
** and reenable interrupts
*/
- restore_flags(flags);
+ NCRUNLOCK(flags);
/*
** Command is successfully queued.
@@ -5218,12 +5228,12 @@
{
u_long flags;
- save_flags(flags); cli();
+ NCRLOCK(flags);
if (!np->settle_time) {
(void) ncr_reset_scsi_bus(np, 1, settle_delay);
}
- restore_flags(flags);
+ NCRUNLOCK(flags);
}
static int ncr_reset_scsi_bus(ncb_p np, int enab_int, int settle_delay)
@@ -5303,12 +5313,12 @@
np->stalling = 0;
#endif
- save_flags(flags); cli();
+ NCRLOCK(flags);
/*
* Return immediately if reset is in progress.
*/
if (np->settle_time) {
- restore_flags(flags);
+ NCRUNLOCK(flags);
return SCSI_RESET_PUNT;
}
/*
@@ -5355,7 +5365,7 @@
cmd->scsi_done(cmd);
}
- restore_flags(flags);
+ NCRUNLOCK(flags);
return SCSI_RESET_SUCCESS;
}
@@ -5385,14 +5395,14 @@
np->stalling = 0;
#endif
- save_flags(flags); cli();
+ NCRLOCK(flags);
/*
* First, look for the scsi command in the waiting list
*/
if (remove_from_waiting_list(np, cmd)) {
cmd->result = ScsiResult(DID_ABORT, 0);
cmd->scsi_done(cmd);
- restore_flags(flags);
+ NCRUNLOCK(flags);
return SCSI_ABORT_SUCCESS;
}
@@ -5411,12 +5421,12 @@
}
if (!found) {
- restore_flags(flags);
+ NCRUNLOCK(flags);
return SCSI_ABORT_NOT_RUNNING;
}
if (np->settle_time) {
- restore_flags(flags);
+ NCRUNLOCK(flags);
return SCSI_ABORT_SNOOZE;
}
@@ -5448,7 +5458,7 @@
#endif
OUTB (nc_istat, SIGP);
- restore_flags(flags);
+ NCRUNLOCK(flags);
return retv;
}
@@ -6697,11 +6707,11 @@
if (np->settle_time <= thistime) {
if (bootverbose > 1)
printf("%s: command processing resumed\n", ncr_name(np));
- save_flags(flags); cli();
+ NCRLOCK(flags);
np->settle_time = 0;
np->disc = 1;
requeue_waiting_list(np);
- restore_flags(flags);
+ NCRUNLOCK(flags);
}
return;
}
@@ -6715,7 +6725,7 @@
/*
** block ncr interrupts
*/
- save_flags(flags); cli();
+ NCRLOCK(flags);
np->lasttime = thistime;
@@ -6803,7 +6813,7 @@
#endif
OUTB (nc_istat, SIGP);
}
- restore_flags(flags);
+ NCRUNLOCK(flags);
}
#ifdef SCSI_NCR_BROKEN_INTR
@@ -6812,11 +6822,11 @@
/*
** Process pending interrupts.
*/
- save_flags(flags); cli();
+ NCRLOCK(flags);
if (DEBUG_FLAGS & DEBUG_TINY) printf ("{");
ncr_exception (np);
if (DEBUG_FLAGS & DEBUG_TINY) printf ("}");
- restore_flags(flags);
+ NCRUNLOCK(flags);
}
#endif /* SCSI_NCR_BROKEN_INTR */
}
@@ -9708,7 +9718,7 @@
printk("ncr53c8xx_reset: pid=%lu reset_flags=%x serial_number=%ld serial_number_at_timeout=%ld\n",
cmd->pid, reset_flags, cmd->serial_number, cmd->serial_number_at_timeout);
- save_flags(flags); cli();
+ NCRLOCK(flags);
/*
* We have to just ignore reset requests in some situations.
@@ -9738,7 +9748,7 @@
#endif
out:
- restore_flags(flags);
+ NCRUNLOCK(flags);
return sts;
}
#else
@@ -9763,7 +9773,7 @@
printk("ncr53c8xx_abort: pid=%lu serial_number=%ld serial_number_at_timeout=%ld\n",
cmd->pid, cmd->serial_number, cmd->serial_number_at_timeout);
- save_flags(flags); cli();
+ NCRLOCK(flags);
/*
* We have to just ignore abort requests in some situations.
@@ -9775,7 +9785,7 @@
sts = ncr_abort_command(cmd);
out:
- restore_flags(flags);
+ NCRUNLOCK(flags);
return sts;
}
#else
@@ -10148,9 +10158,9 @@
else {
long flags;
- save_flags(flags); cli();
+ NCRLOCK(flags);
ncr_usercmd (np);
- restore_flags(flags);
+ NCRUNLOCK(flags);
}
return length;
}
--ZGiS0Q5IWpPtfppv--
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu