From: Manfred Spraul <manfred@colorfullife.com>
To: Felipe W Damasio <felipewd@terra.com.br>
Cc: linux-kernel@vger.kernel.org, rnp@netlink.co.nz
Subject: Re: [PATCH] Fix SMP support on 3c527 net driver
Date: Sun, 31 Aug 2003 19:30:53 +0200 [thread overview]
Message-ID: <3F5230CD.5030908@colorfullife.com> (raw)
In-Reply-To: <3F522756.9000105@terra.com.br>
[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]
Felipe W Damasio wrote:
> Hi Manfred,
>
> Manfred Spraul wrote:
>
>> Additionally, you must replace the sleep_on calls with wait_event, or
>> an open-coded wait queue: sleep_on is racy, it only works with cli().
>
>
> Oh, I didn't no that..
>
>> IMHO the right way to fix cli() is
>> - add a single spinlock to the driver or the device structure. Do not
>> forget the spin_lock_init().
>> - replace cli/sti with spin_lock_irqsave/spin_unlock_irqsave.
>
>
> Yes.
>
>> - Additionally acquire the spinlock in every interrupt handler (cli()
>> stops all interrupts, spinlocks only stop interrupt on the current cpu).
>> - check if there were recursive cli() calls. Fix them.
>> - replace all sleep_on calls with wait queue calls.
>> - check if there are any kmalloc or schedule calls in the area now
>> under the spinlock, and reorganize the code.
>
>
> But doesn't wait_queue call schedule()?
Yes, it does. You need a larger change to fix that. Something like the
attached patch.
--
Manfred
[-- Attachment #2: patch-3c527 --]
[-- Type: text/plain, Size: 2159 bytes --]
--- 2.6/drivers/net/3c527.c 2003-06-17 06:20:03.000000000 +0200
+++ build-2.6/drivers/net/3c527.c 2003-08-31 19:26:37.000000000 +0200
@@ -100,6 +100,7 @@
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/ethtool.h>
+#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -179,6 +180,7 @@
u16 tx_ring_head; /* index to tx en-queue end */
u16 rx_ring_tail; /* index to rx de-queue end */
+ spinlock_t lock;
};
/* The station (ethernet) address prefix, used for a sanity check. */
@@ -579,6 +581,27 @@
return 0;
}
+/**
+ * wait_exec_pending - sleep until exec_pending reaches a certain value
+ * @lp: m32_local structure describing the target card
+ * @value: value to wait for
+ *
+ * The caller must acquire lp->lock before calling this function, it
+ * temporarily drops the lock when it sleeps.
+ */
+
+static void wait_exec_pending(struct mc32_local *lp, int value)
+{
+ while (lp->exec_pending != value) {
+ DEFINE_WAIT(wait);
+
+ prepare_to_wait(&lp->event, &wait, TASK_UNINTERRUPTIBLE);
+ spin_unlock_irq(&lp->lock);
+ schedule();
+ finish_wait(&lp->event, &wait);
+ spin_lock_irq(&lp->lock);
+ }
+}
/**
* mc32_command - send a command and sleep until completion
@@ -619,14 +642,11 @@
int ret = 0;
/*
- * Wait for a command
+ * Wait until there are no more pending commands
*/
- save_flags(flags);
- cli();
-
- while(lp->exec_pending)
- sleep_on(&lp->event);
+ spin_lock_irqsave(&lp->lock, flags);
+ wait_exec_pending(lp, 0);
/*
* Issue mine
@@ -634,7 +654,7 @@
lp->exec_pending=1;
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
lp->exec_box->mbox=0;
lp->exec_box->mbox=cmd;
@@ -645,13 +665,10 @@
while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
outb(1<<6, ioaddr+HOST_CMD);
- save_flags(flags);
- cli();
-
- while(lp->exec_pending!=2)
- sleep_on(&lp->event);
+ spin_lock_irqsave(&lp->lock, flags);
+ wait_exec_pending(lp, 2);
lp->exec_pending=0;
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
if(lp->exec_box->mbox&(1<<13))
ret = -1;
next prev parent reply other threads:[~2003-08-31 17:31 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-31 8:28 [PATCH] Fix SMP support on 3c527 net driver Manfred Spraul
2003-08-31 16:50 ` Felipe W Damasio
2003-08-31 17:30 ` Manfred Spraul [this message]
-- strict thread matches above, loose matches on Subject: below --
2003-08-31 3:06 Felipe W Damasio
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=3F5230CD.5030908@colorfullife.com \
--to=manfred@colorfullife.com \
--cc=felipewd@terra.com.br \
--cc=linux-kernel@vger.kernel.org \
--cc=rnp@netlink.co.nz \
/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.