From: Anton Blanchard <anton@samba.org>
To: Brian King <brking@us.ibm.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [RFC] IBM Power RAID driver (ipr)
Date: Mon, 19 Jan 2004 01:10:03 +1100 [thread overview]
Message-ID: <20040118141003.GA6293@krispykreme> (raw)
In-Reply-To: <40085EDA.4010802@us.ibm.com>
Hi Brian,
> I have just written a LLD for the IBM Power RAID family of adapters.
> This includes several IBM iSeries and pSeries SCSI adapters. Please
> review for 2.6 inclusion.
Nice work! It does a good job of using all the recent PCI and SCSI
infrastructure. I had a quick look through it and can only offer some
minor suggestions.
- Since ipr_sleep_no_lock/ipr_sleep is used once, we can open code
a schedule_timeout there instead.
- Add a comment to explain why the wakeup strategy isnt racy. I
automatically thought it was (just like the kernel version of
sleep_on) until I could verify all wake ups are done under the scsi
host lock. I also have a trivial change to make the two sleep
functions alike.
- Im a bit worried about memory barriers wrt the allow_* things. As an
example I added some mb()s wherever ->allow_interrupts is set.
Actually, do we need this flag at all? Cant we just set the bits on the
card to disable interrupts, then do a synchronize_irq()? Similarly it
would be nice to get rid of some of the other allow_ flags if we can
get around them.
- The forcing of the pci cacheline size worries me, could we have problems
with enabling MWI etc after doing this?
- Do we need the extra ipr_set_pcix_cmd_reg during init? We are going to
do it after a reset arent we?
- It looks like the kmalloc in ipr_sdt_copy is called from process
context without any locks held, so we dont need an atomic allocation.
Anton
diff -urp t.orig/drivers/scsi/ipr.c t/drivers/scsi/ipr.c
--- t.orig/drivers/scsi/ipr.c 2004-01-01 00:01:37.000000000 +1100
+++ t/drivers/scsi/ipr.c 2004-01-19 01:08:38.958959407 +1100
@@ -670,46 +670,12 @@ static const struct ipr_ses_table_entry
};
/**
- * ipr_sleep_no_lock - Sleep for the specified amount of time
- * @delay: time to sleep
- *
- * Sleep for the specified amount of time
- *
- * Return value:
- * none
- **/
-static void ipr_sleep_no_lock(signed long delay)
-{
- DECLARE_WAIT_QUEUE_HEAD(internal_wait);
-
- sleep_on_timeout(&internal_wait, (delay * HZ) / 1000);
- return;
-}
-
-/**
- * ipr_sleep - Sleep for the specified amount of time
- * @ioa_cfg: ioa config struct
- * @delay: time to sleep in msecs
- *
- * Release the host lock and sleep for the specified amount of time
- *
- * Return value:
- * none
- **/
-static void ipr_sleep(struct ipr_ioa_cfg *ioa_cfg, signed long delay)
-{
- spin_unlock_irq(ioa_cfg->host->host_lock);
- ipr_sleep_no_lock(delay);
- spin_lock_irq(ioa_cfg->host->host_lock);
- return;
-}
-
-/**
* ipr_interruptible_sleep_on - Sleep on the wait queue
* @ioa_cfg: ioa config struct
* @wait_head: wait queue to sleep on
*
- * Sleep interruptibly on the wait queue.
+ * Sleep interruptibly on the wait queue. We avoid wakeup races by
+ * having the scsi host lock held on both sleep and wakeup.
*
* Return value:
* 0 on success / -EINTR if woken due to a signal
@@ -717,7 +683,9 @@ static void ipr_sleep(struct ipr_ioa_cfg
static int ipr_interruptible_sleep_on(struct ipr_ioa_cfg *ioa_cfg,
wait_queue_head_t *wait_head)
{
- DECLARE_WAITQUEUE(wait_q_entry, current);
+ wait_queue_t wait_q_entry;
+
+ init_waitqueue_entry(&wait_q_entry);
set_current_state(TASK_INTERRUPTIBLE);
@@ -742,7 +710,8 @@ static int ipr_interruptible_sleep_on(st
* @ioa_cfg: ioa config struct
* @wait_head: wait queue to sleep on
*
- * Sleep uninterruptibly on the wait queue.
+ * Sleep uninterruptibly on the wait queue. We avoid wakeup races by
+ * having the scsi host lock held on both sleep and wakeup.
*
* Return value:
* none
@@ -1076,6 +1045,7 @@ static void ipr_mask_and_clear_all_inter
/* Stop new interrupts */
ioa_cfg->allow_interrupts = 0;
+ mb();
/* Set interrupt mask to stop all new interrupts */
writel(~0, ioa_cfg->regs.set_interrupt_mask_reg);
@@ -1395,7 +1365,7 @@ static int __devinit ipr_probe_ioa(struc
ioa_cfg->chip_cfg->cache_line_size);
if (rc != PCIBIOS_SUCCESSFUL) {
- dev_err(&pdev->dev, "Read of config space failed\n");
+ dev_err(&pdev->dev, "Write of config space failed\n");
rc = -EIO;
goto cleanup_nomem;
}
@@ -1412,9 +1382,6 @@ static int __devinit ipr_probe_ioa(struc
if ((rc = ipr_save_pcix_cmd_reg(ioa_cfg)))
goto cleanup_nomem;
- if ((rc = ipr_set_pcix_cmd_reg(ioa_cfg)))
- goto cleanup_nomem;
-
if ((rc = ipr_alloc_mem(ioa_cfg)))
goto cleanup;
@@ -2276,6 +2243,7 @@ static int ipr_reset_enable_ioa(struct i
/* Enable interrupts */
ioa_cfg->allow_interrupts = 1;
+ mb();
writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg);
temp_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
@@ -6249,13 +6217,12 @@ static int ipr_diagnostic_ioctl(struct i
ipr_unblock_requests(ioa_cfg);
/* Wait for a second for any errors to be logged */
- ipr_sleep(ioa_cfg, 1000);
+ spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+ schedule_timeout(HZ);
if (ioa_cfg->errors_logged)
rc = -EIO;
- spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-
return rc;
}
@@ -7490,7 +7457,7 @@ static int ipr_sdt_copy(struct ipr_ioa_c
((ioa_cfg->ioa_dump->hdr.length + bytes_copied) < IPR_MAX_IOA_DUMP_SIZE)) {
if ((ioa_cfg->ioa_dump->page_offset >= PAGE_SIZE) ||
(ioa_cfg->ioa_dump->page_offset == 0)) {
- page = (u32 *)__get_free_page(GFP_ATOMIC);
+ page = (u32 *)__get_free_page(GFP_KERNEL);
if (!page) {
ipr_trace;
next prev parent reply other threads:[~2004-01-18 14:11 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-01-16 21:59 [RFC] IBM Power RAID driver (ipr) Brian King
2004-01-16 23:01 ` Muli Ben-Yehuda
2004-01-16 23:46 ` Brian King
2004-01-18 14:10 ` Anton Blanchard [this message]
2004-01-19 16:16 ` Brian King
2004-01-19 18:34 ` Christoph Hellwig
2004-01-19 19:33 ` Mike Anderson
2004-01-19 19:35 ` Christoph Hellwig
2004-01-20 5:57 ` Douglas Gilbert
2004-01-20 13:21 ` Christoph Hellwig
2004-01-19 20:30 ` Brian King
2004-01-20 13:38 ` Christoph Hellwig
2004-01-20 16:41 ` Brian King
2004-01-20 17:18 ` Mike Anderson
2004-01-20 18:01 ` Christoph Hellwig
2004-01-20 19:13 ` Brian King
2004-01-20 19:28 ` Christoph Hellwig
2004-01-20 20:13 ` Brian King
2004-01-21 20:49 ` Brian King
2004-01-22 14:02 ` Christoph Hellwig
2004-01-22 16:39 ` Patrick Mansfield
2004-01-22 16:56 ` Patrick Mansfield
2004-01-22 17:09 ` Brian King
2004-01-22 17:27 ` Patrick Mansfield
2004-01-22 17:33 ` Brian King
2004-01-20 20:35 ` Patrick Mansfield
2004-01-20 22:37 ` Brian King
2004-01-20 22:39 ` Christoph Hellwig
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=20040118141003.GA6293@krispykreme \
--to=anton@samba.org \
--cc=brking@us.ibm.com \
--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.