* Re: Locking model for NAPI drivers
From: Herbert Xu @ 2005-06-01 8:42 UTC (permalink / raw)
To: Andi Kleen; +Cc: davem, netdev
In-Reply-To: <m1fyw2wpzf.fsf@muc.de>
Andi Kleen <ak@muc.de> wrote:
>
> That is because of the kmap_atomic it does right? At least in the i386
> highmem implementation I don't see any code that would be less safe in
> hard interrupt context compared to BHs. And FRV and mips look like they
> allow it too.
To make it safe we'll have to allocate another precious km_type entry.
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: Locking model for NAPI drivers
From: Greg Banks @ 2005-06-01 8:16 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Network Development list
In-Reply-To: <20050531.154847.63995530.davem@davemloft.net>
On Wed, 2005-06-01 at 08:48, David S. Miller wrote:
> So the idea is, if we can make all of the spinlocks BH locks we'll
> solve a whole bunch of problems:
> [...]
> 2) the driver will actually produce useful profiling data
> via oprofile and friends since timer interrupts will run
> even while holding the locks
That would be really, really nice.
Greg.
--
Greg Banks, R&D Software Engineer, SGI Australian Software Group.
I don't speak for SGI.
^ permalink raw reply
* Re: Locking model for NAPI drivers
From: Andi Kleen @ 2005-06-01 6:28 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050531.154847.63995530.davem@davemloft.net>
"David S. Miller" <davem@davemloft.net> writes:
Stupid question, but...
> I was doing some brainstorming to try and fix a nagging problem in
> the tg3 driver which suggested that doing the SMP locking differently
> might be the best and cleanest solution.
>
> The tg3 problem is that it can do an skb_copy() in HW IRQ disabled
> context which is illegal.
That is because of the kmap_atomic it does right? At least in the i386
highmem implementation I don't see any code that would be less safe in
hard interrupt context compared to BHs. And FRV and mips look like they
allow it too.
> This fixes the skb_copy() we were doing with hw
> IRQs disabled (which is illegal and triggers a
> BUG() with HIGHMEM enabled).
Which BUG did it trigger?
-Andi
^ permalink raw reply
* Re: 2.6.12-rcx networking oops
From: Herbert Xu @ 2005-06-01 5:49 UTC (permalink / raw)
To: Phil Oester; +Cc: netdev, akpm
In-Reply-To: <20050531224012.GA16789@linuxace.com>
On Tue, May 31, 2005 at 03:40:12PM -0700, Phil Oester wrote:
>
> EIP is at fib_validate_source+0xcf/0x1f0
> eax: f7c2c000 ebx: c0337dec ecx: f7c258a0 edx: 00000000
> esi: c0335c2c edi: 00000000 ebp: c0337db0 esp: c0337d40
> ds: 3f1f es: 007b ss: 0068
> Process swapper (pid: 0, threadinfo=c0337000 task=c02b9bc0)
This looks like stack overflow. %esi is meant to be "res" which is
a local variable. As you can see, it's pointing below %esp and
threadinfo.
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] shaper.c: fix locking
From: Christoph Hellwig @ 2005-06-01 5:21 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050531.144114.78710204.davem@davemloft.net>
On Tue, May 31, 2005 at 02:41:14PM -0700, David S. Miller wrote:
> From: Christoph Hellwig <hch@lst.de>
> Subject: [PATCH] shaper.c: fix locking
> Date: Fri, 27 May 2005 13:54:50 +0200
>
> > o use a semaphore instead of an opencoded and racy lock
> > o move locking out of shaper_kick and into the callers - most just
> > released the lock before calling shaper_kick
> > o remove in_interrupt() tests. from ->close we can always block, from
> > ->hard_start_xmit and timer context never
>
> Do you really want to use a semaphore for a lock taken
> %99 of the time in software IRQ context, which obviously
> cannot sleep?
I want to change as little as possible from the previous variant ;-)
^ permalink raw reply
* Driver for MCS7780 USB-IrDA bridge chip
From: Lukasz Stelmach @ 2005-06-01 1:11 UTC (permalink / raw)
To: netdev
In-Reply-To: <42943CB5.50400@poczta.fm>
[-- Attachment #1: Type: text/plain, Size: 1336 bytes --]
Greetings Everyone.
Greg told me that you (the list) might be interested in this so I
should send the announcement to you.
The new, shiny 0.2alpha.3 release is ready to test it, smash it and blow
it off ;-)
The major improvement is support for other SIR speeds: 2400 through
115200 bps. Well I think they will work but frankly speaking I haven't
tested them because my Handspring always negotiates the highest rate.
I am sure there is quite a lot of bugs left so *please* test it as much
as you can. I am realy convinced that performance may be a really big
problem so I will appreciate any comments on the design.
Source tarball is available at:
http://www.ee.pw.edu.pl/~stelmacl/mcs7780-0.2alpha.3.tar.bz2
http://www.ee.pw.edu.pl/~stelmacl/mcs7780-0.2alpha.3.tar.bz2.asc (sig)
or
http://stlman.fm.interia.pl/mcs7780-0.2alpha.3.tar.bz2
http://stlman.fm.interia.pl/mcs7780-0.2alpha.3.tar.bz2.asc (sig)
To answer your question: I will make a patch but let me first be sure it
is usable and at least beta-stable. You can help ;-)
This is the announcement of the 0.1alpha.1 version:
http://lkml.org/lkml/2005/5/25/47
Always yours.
--
Było mi bardzo miło. Trzecia pospolita klęska, [...]
>Łukasz< Już nie katolicka lecz złodziejska. (c)PP
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]
^ permalink raw reply
* Re: ipv4 ipsec
From: David S. Miller @ 2005-06-01 0:08 UTC (permalink / raw)
To: edgar.iglesias; +Cc: netdev
In-Reply-To: <20050601000259.GA4742@edgar.se.axis.com>
From: Edgar E Iglesias <edgar.iglesias@axis.com>
Date: Wed, 1 Jun 2005 02:02:59 +0200
> --- linux-2.6.11-gentoo-r6/net/ipv4/esp4.c 2005-04-14 21:39:32.000000000 +0200
> +++ linux-2.6.11-gentoo-r9/net/ipv4/esp4.c 2005-06-01 00:38:55.000000000 +0200
Patch applied, thank you.
^ permalink raw reply
* Re: ipv4 ipsec
From: Edgar E Iglesias @ 2005-06-01 0:02 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050531.164741.116354448.davem@davemloft.net>
On Tue, May 31, 2005 at 04:47:41PM -0700, David S. Miller wrote:
> From: Edgar E Iglesias <edgar.iglesias@axis.com>
> Date: Wed, 1 Jun 2005 01:23:40 +0200
>
> > oh sorry, I hope I get it right this time :)
>
> Your email client has mangled the tab characters into spaces
> in the patch, so the patch still will not apply correctly.
>
> Please fix this.
One more try.. sorry
Best regards
--
Programmer
Edgar E Iglesias <edgar@axis.com> 46.46.272.1946
Signed-off-by: Edgar E Iglesias <edgar@axis.com>
-----
--- linux-2.6.11-gentoo-r6/net/ipv4/esp4.c 2005-04-14 21:39:32.000000000 +0200
+++ linux-2.6.11-gentoo-r9/net/ipv4/esp4.c 2005-06-01 00:38:55.000000000 +0200
@@ -480,7 +480,7 @@
{
struct xfrm_decap_state decap;
- if (sizeof(struct esp_decap_data) <
+ if (sizeof(struct esp_decap_data) >
sizeof(decap.decap_data)) {
extern void decap_data_too_small(void);
^ permalink raw reply
* Re: ipv4 ipsec
From: David S. Miller @ 2005-05-31 23:47 UTC (permalink / raw)
To: edgar.iglesias; +Cc: netdev
In-Reply-To: <20050531232340.GA4589@edgar.se.axis.com>
From: Edgar E Iglesias <edgar.iglesias@axis.com>
Date: Wed, 1 Jun 2005 01:23:40 +0200
> oh sorry, I hope I get it right this time :)
Your email client has mangled the tab characters into spaces
in the patch, so the patch still will not apply correctly.
Please fix this.
^ permalink raw reply
* Re: r8169 802.1q/MTU bug
From: Francois Romieu @ 2005-05-31 23:44 UTC (permalink / raw)
To: Jon Mason; +Cc: James Harr, netdev
In-Reply-To: <200505311820.41469.jdmason@us.ibm.com>
Jon Mason <jdmason@us.ibm.com> :
[...]
> I wonder if this is related to the adapter breaking large frames into
> multiple descriptors. On normal (non-VLAN) frames, this happens at MTU
> 8169. I wonder if enabling VLAN and jumbo frames (a combination I never
> tried) brings down the threshold to MTU 7200.
Testing suggests that there is at least a size filtering issue (fixed
in netdev-2.6.git but not in 2.6.11.xx nor in 2.6.12-rc). It is unrelated
to hardware vlan support and happens a few bytes above the MTU on the vlan
device (which is set to the same value as the adapter). Of course different
issues could hide in the dark.
--
Ueimor
^ permalink raw reply
* Re: 2.6.12-rcx networking oops
From: Phil Oester @ 2005-05-31 23:34 UTC (permalink / raw)
To: Andrew Morton; +Cc: netdev, herbert
In-Reply-To: <20050531162837.4a110b29.akpm@osdl.org>
On Tue, May 31, 2005 at 04:28:37PM -0700, Andrew Morton wrote:
> hm, OK. So I assume the machine has recently been running 2.6.10. So it's
> unlikely to be a hardware problem.
It's running 2.6.10 as we speak -- I typically reboot it at night into
2.6.12-rc and between 8-10am the next day it panics itself back into
2.6.10.
> > > Have you tried CONFIG_DEBUG_SLAB and/or CONFIG_DEBUG_PAGEALLOC?
> >
> > No - do you think it would reveal anything given the above?
>
> It might catch the failure at an earlier stage.
I'll try it out tomorrow.
Phil
^ permalink raw reply
* Re: RFC: NAPI packet weighting patch
From: Jon Mason @ 2005-05-31 23:28 UTC (permalink / raw)
To: David S. Miller
Cc: mitch.a.williams, hadi, shemminger, netdev, Robert.Olsson,
john.ronciak, ganesh.venkatesan, jesse.brandeburg
In-Reply-To: <20050531.151443.74564699.davem@davemloft.net>
On Tuesday 31 May 2005 05:14 pm, David S. Miller wrote:
> From: Jon Mason <jdmason@us.ibm.com>
> Date: Tue, 31 May 2005 17:07:54 -0500
>
> > Of course some performace analysis would have to be done to determine the
> > optimal numbers for each speed/duplexity setting per driver.
>
> per cpu speed, per memory bus speed, per I/O bus speed, and add in other
> complications such as NUMA
>
> My point is that whatever experimental number you come up with will be
> good for that driver on your systems, not necessarily for others.
>
> Even within a system, whatever number you select will be the wrong
> thing to use if one starts a continuous I/O stream to the SATA
> controller in the next PCI slot, for example.
>
> We keep getting bitten by this, as the Altix perf data continually shows,
> and we need to absolutely stop thinking this way.
>
> The way to go is to make selections based upon observed events and
> mesaurements.
I'm not arguing against a /proc entry to tune dev->weight for those sysadmins
advanced enough to do that. I am arguing that we can make the driver smarter
(at little/no cost) for "out of the box" users.
^ permalink raw reply
* Re: 2.6.12-rcx networking oops
From: Andrew Morton @ 2005-05-31 23:28 UTC (permalink / raw)
To: Phil Oester; +Cc: netdev, herbert
In-Reply-To: <20050531232326.GA17289@linuxace.com>
Phil Oester <kernel@linuxace.com> wrote:
>
> On Tue, May 31, 2005 at 04:12:20PM -0700, Andrew Morton wrote:
> > Are you _sure_ the hardware is good?
>
> Well, it lasts on 2.6.10 indefinitely (since 1/1/5 minus the recent
> upgrade attempts). And the hardware itself has been in service for
> a few years without failure. It will last on 2.6.11 or 12-rc over
> the weekend fine, but as soon as traffic picks up during the workday
> it keels over.
hm, OK. So I assume the machine has recently been running 2.6.10. So it's
unlikely to be a hardware problem.
> > Are you running anything which would cause netdevs to be destroyed?
> > Bringing virtual devices up and down? TUN/TAP driver? Bonding driver?
> > Anything like that?
>
> The box runs keepalived (for VRRP), and quagga (for OSPF). Neither should
> be destroying netdevs during normal operation AFAIK.
OK. It would need more than a very-ex-net person to work out how those
things affect the networking stack ;)
> > Have you tried CONFIG_DEBUG_SLAB and/or CONFIG_DEBUG_PAGEALLOC?
>
> No - do you think it would reveal anything given the above?
It might catch the failure at an earlier stage.
^ permalink raw reply
* Re: ipv4 ipsec
From: Edgar E Iglesias @ 2005-05-31 23:23 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
In-Reply-To: <20050531.155642.38710400.davem@davemloft.net>
On Tue, May 31, 2005 at 03:56:42PM -0700, David S. Miller wrote:
> From: Edgar E Iglesias <edgar.iglesias@axis.com>
> Date: Wed, 1 Jun 2005 00:47:17 +0200
>
> > Im not sure this is the correct list for ipsec issues, but shouldn't
> > the size check at the bottom of net/ipv4/esp4.c be the other way
> > around (2.6.11)?
>
> You are right, good catch. Luckily the size of esp_decap_data
> is exactly 20 bytes, so the incorrect test happens to be harmless.
mostly harmless..
But for gcc ports that create packed structs per default, it is 19
bytes.
>
> > --- /usr/src/linux-2.6.11-gentoo-r8/net/ipv4/esp4.c 2005-05-11 10:05:03.000000000 +0200
> > +++ esp4.c 2005-06-01 00:38:55.000000000 +0200
>
> Please porperly -p1 root your patch so I can apply it, and also
> please provide a "Signed-off-by: " line for yourself as well.
>
> It may seem pointless for a one-line patch, but I want to get you
> and others into the habit of submitting patches properly in the
> future.
oh sorry, I hope I get it right this time :)
Best regards
--
Programmer
Edgar E Iglesias <edgar@axis.com> 46.46.272.1946
Signed-off-by: Edgar E Iglesias <edgar@axis.com>
---------
% diff -Naur linux-2.6.11-gentoo-r6/net/ipv4/esp4.c linux-2.6.11-gentoo-r9/net/ipv4/esp4.c
--- linux-2.6.11-gentoo-r6/net/ipv4/esp4.c 2005-04-14 21:39:32.000000000 +0200
+++ linux-2.6.11-gentoo-r9/net/ipv4/esp4.c 2005-06-01 00:38:55.000000000 +0200
@@ -480,7 +480,7 @@
{
struct xfrm_decap_state decap;
- if (sizeof(struct esp_decap_data) <
+ if (sizeof(struct esp_decap_data) >
sizeof(decap.decap_data)) {
extern void decap_data_too_small(void);
^ permalink raw reply
* Re: 2.6.12-rcx networking oops
From: Phil Oester @ 2005-05-31 23:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: netdev, herbert
In-Reply-To: <20050531161220.4af50a69.akpm@osdl.org>
On Tue, May 31, 2005 at 04:12:20PM -0700, Andrew Morton wrote:
> Are you _sure_ the hardware is good?
Well, it lasts on 2.6.10 indefinitely (since 1/1/5 minus the recent
upgrade attempts). And the hardware itself has been in service for
a few years without failure. It will last on 2.6.11 or 12-rc over
the weekend fine, but as soon as traffic picks up during the workday
it keels over.
> Are you running anything which would cause netdevs to be destroyed?
> Bringing virtual devices up and down? TUN/TAP driver? Bonding driver?
> Anything like that?
The box runs keepalived (for VRRP), and quagga (for OSPF). Neither should
be destroying netdevs during normal operation AFAIK.
> Have you tried CONFIG_DEBUG_SLAB and/or CONFIG_DEBUG_PAGEALLOC?
No - do you think it would reveal anything given the above?
Phil
^ permalink raw reply
* Re: r8169 802.1q/MTU bug
From: Jon Mason @ 2005-05-31 23:20 UTC (permalink / raw)
To: James Harr; +Cc: Francois Romieu, netdev
In-Reply-To: <200505301927.26110.james@grickle.org>
On Monday 30 May 2005 07:27 pm, James Harr wrote:
> Hi,
> The driver you sent gives me an error when I try to compile and load it
> with 2.6.11.11:
>
> # make
> [...]
> CC [M] drivers/net/r8169.o
> drivers/net/r8169.c: In function `rtl8169_down':
> drivers/net/r8169.c:2589: warning: implicit declaration of function
> synchronize_sched
> [...]
>
> # insmod drivers/net/r8169.ko
> insmod: error inserting 'drivers/net/r8169.ko': -1 Unknown symbol in module
>
>
> It does a similar thing when I try to install it:
>
> # make modules_install
> [...]
> if [ -r System.map ]; then /sbin/depmod -ae -F System.map 2.6.11.11; fi
> WARNING: /lib/modules/2.6.11.11/kernel/drivers/net/r8169.ko needs unknown
> symbol synchronize_sched
>
> As I noted in a previous email, it doesn't give me this problem when I have
> jumbo frames enabled on my switch.
>
> Since I found out my switch supported jumbo frames, I started to toy around
> with larger MTUs. When a VLAN's MTU was set to 7200, my system locked up. I
> didn't have this problem at 7196. Also, the crash problem wasn't there on a
> regular interface with no VLANs and the MTU at 7200.
I wonder if this is related to the adapter breaking large frames into multiple
descriptors. On normal (non-VLAN) frames, this happens at MTU 8169. I
wonder if enabling VLAN and jumbo frames (a combination I never tried) brings
down the threshold to MTU 7200.
Thanks,
Jon
^ permalink raw reply
* Re: 2.6.12-rcx networking oops
From: Andrew Morton @ 2005-05-31 23:12 UTC (permalink / raw)
To: Phil Oester; +Cc: netdev, herbert
In-Reply-To: <20050531224012.GA16789@linuxace.com>
Phil Oester <kernel@linuxace.com> wrote:
>
> At Andrew's suggestion, I tested the latest 2.6.12-rc5-gitx, and am still
> hitting an oops on a gateway box under load. From comparing the various
> oops, it seems like a dev is disappearing while one CPU is in the middle
> of processing traffic. At least that's what my naive analysis leads
> me to believe.
Are you _sure_ the hardware is good?
Are you running anything which would cause netdevs to be destroyed?
Bringing virtual devices up and down? TUN/TAP driver? Bonding driver?
Anything like that?
Have you tried CONFIG_DEBUG_SLAB and/or CONFIG_DEBUG_PAGEALLOC?
^ permalink raw reply
* Re: ipv4 ipsec
From: David S. Miller @ 2005-05-31 22:56 UTC (permalink / raw)
To: edgar.iglesias; +Cc: netdev
In-Reply-To: <20050531224717.GE4068@edgar.se.axis.com>
From: Edgar E Iglesias <edgar.iglesias@axis.com>
Date: Wed, 1 Jun 2005 00:47:17 +0200
> Im not sure this is the correct list for ipsec issues, but shouldn't
> the size check at the bottom of net/ipv4/esp4.c be the other way
> around (2.6.11)?
You are right, good catch. Luckily the size of esp_decap_data
is exactly 20 bytes, so the incorrect test happens to be harmless.
> --- /usr/src/linux-2.6.11-gentoo-r8/net/ipv4/esp4.c 2005-05-11 10:05:03.000000000 +0200
> +++ esp4.c 2005-06-01 00:38:55.000000000 +0200
Please porperly -p1 root your patch so I can apply it, and also
please provide a "Signed-off-by: " line for yourself as well.
It may seem pointless for a one-line patch, but I want to get you
and others into the habit of submitting patches properly in the
future.
^ permalink raw reply
* Re: [RFC] textsearch infrastructure et al v2
From: David S. Miller @ 2005-05-31 22:50 UTC (permalink / raw)
To: tgraf; +Cc: netdev, hadi
In-Reply-To: <20050531224439.GL15391@postel.suug.ch>
From: Thomas Graf <tgraf@suug.ch>
Date: Wed, 1 Jun 2005 00:44:39 +0200
> Pablo joined me on the subject, he's currently working
> on converting the fragmentation iteration to use Rusty's
> skb_iter code. we'll present new work with some numbers
> shortly.
Sounds good.
^ permalink raw reply
* Locking model for NAPI drivers
From: David S. Miller @ 2005-05-31 22:48 UTC (permalink / raw)
To: netdev
I was doing some brainstorming to try and fix a nagging problem in
the tg3 driver which suggested that doing the SMP locking differently
might be the best and cleanest solution.
The tg3 problem is that it can do an skb_copy() in HW IRQ disabled
context which is illegal.
But then I noticed that the spinlocks really don't need IRQ disabling.
Only the tinyest sliver of code, the interrupt handler, actually runs
in HW interrupt context. The bulk of the driver runs in SW interrupt
context.
So the idea is, if we can make all of the spinlocks BH locks we'll
solve a whole bunch of problems:
1) skb_copy() will run in BH context, fixing that bug
2) the driver will actually produce useful profiling data
via oprofile and friends since timer interrupts will run
even while holding the locks
3) moving long delays (particually when doing link settings)
into work queues becomes much easier, at least in theory
Once we make this transformation, we need some way to synchronize
with the IRQ handler when shutting down the device or making major
configuration changes to the chip.
The idea I came up with is a two-bit atomic bitmask. When base
level code wants to quiesce interrupt processing, it takes the
necessary driver spinlocks, sets the "SYNC" bit in the bitmask,
forces and IRQ to be asserted by the tg3 card, then waits for the
COMPLETE bit to get set by the interrupt handler.
The total cost of this scheme under normal operation is a single
shared memory location read at hw IRQ time.
If e1000, ixgb, s2io, the infiniband drivers, and friends can force
the chip to signal an interrupt they can do this kind of locking
enhancement as well.
Here is the full implementation I'm testing currently with Michael
Chan for tg3. Note how tg3_tx() can now directly call dev_kfree_skb()
directly (instead of dev_kfree_skb_irq()) and most of tg3_poll() can
now run totally lockless.
[TG3]: Eliminate all hw IRQ handler spinlocks.
Move all driver spinlocks to be taken at sw IRQ
context only.
This fixes the skb_copy() we were doing with hw
IRQs disabled (which is illegal and triggers a
BUG() with HIGHMEM enabled). It also simplifies
the locking all over the driver tremendously.
We accomplish this feat by creating a special
sequence to synchronize with the hw IRQ handler
using a 2-bit atomic state.
Signed-off-by: David S. Miller <davem@davemloft.net>
--- 1/drivers/net/tg3.c.~1~ 2005-05-30 15:29:23.000000000 -0700
+++ 2/drivers/net/tg3.c 2005-05-31 14:20:08.000000000 -0700
@@ -332,12 +332,10 @@ static struct {
static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
{
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
} else {
writel(val, tp->regs + off);
if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
@@ -348,12 +346,10 @@ static void tg3_write_indirect_reg32(str
static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
{
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
} else {
void __iomem *dest = tp->regs + off;
writel(val, dest);
@@ -393,28 +389,24 @@ static inline void _tw32_tx_mbox(struct
static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
{
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
}
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
}
static void tg3_disable_ints(struct tg3 *tp)
@@ -438,7 +430,7 @@ static void tg3_enable_ints(struct tg3 *
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
(tp->last_tag << 24));
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
-
+ tp->irq_state = 0;
tg3_cond_int(tp);
}
@@ -475,6 +467,8 @@ static void tg3_restart_ints(struct tg3
tp->last_tag << 24);
mmiowb();
+ BUG_ON(tp->irq_state);
+
/* When doing tagged status, this work check is unnecessary.
* The last_tag we write above tells the chip which piece of
* work we've completed.
@@ -2573,7 +2567,7 @@ static void tg3_tx(struct tg3 *tp)
sw_idx = NEXT_TX(sw_idx);
}
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb(skb);
}
tp->tx_cons = sw_idx;
@@ -2879,11 +2873,8 @@ static int tg3_poll(struct net_device *n
{
struct tg3 *tp = netdev_priv(netdev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
int done;
- spin_lock_irqsave(&tp->lock, flags);
-
/* handle link change and other phy events */
if (!(tp->tg3_flags &
(TG3_FLAG_USE_LINKCHG_REG |
@@ -2891,7 +2882,9 @@ static int tg3_poll(struct net_device *n
if (sblk->status & SD_STATUS_LINK_CHG) {
sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG);
+ spin_lock(&tp->lock);
tg3_setup_phy(tp, 0);
+ spin_unlock(&tp->lock);
}
}
@@ -2902,8 +2895,6 @@ static int tg3_poll(struct net_device *n
spin_unlock(&tp->tx_lock);
}
- spin_unlock_irqrestore(&tp->lock, flags);
-
/* run RX thread, within the bounds set by NAPI.
* All RX "locking" is done by ensuring outside
* code synchronizes with dev->poll()
@@ -2928,15 +2919,56 @@ static int tg3_poll(struct net_device *n
/* if no more work, tell net stack and NIC we're done */
done = !tg3_has_work(tp);
if (done) {
- spin_lock_irqsave(&tp->lock, flags);
+ spin_lock(&tp->lock);
__netif_rx_complete(netdev);
tg3_restart_ints(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
}
return (done ? 0 : 1);
}
+static void tg3_irq_quiesce(struct tg3 *tp)
+{
+ BUG_ON(test_bit(TG3_IRQSTATE_SYNC, &tp->irq_state));
+
+ set_bit(TG3_IRQSTATE_SYNC, &tp->irq_state);
+ smp_mb();
+ tw32(GRC_LOCAL_CTRL,
+ tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+
+ while (!test_bit(TG3_IRQSTATE_COMPLETE, &tp->irq_state))
+ cpu_relax();
+}
+
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+ if (test_bit(TG3_IRQSTATE_SYNC, &tp->irq_state)) {
+ set_bit(TG3_IRQSTATE_COMPLETE, &tp->irq_state);
+ return 1;
+ }
+ return 0;
+}
+
+/* Fully shutdown all tg3 driver activity elsewhere in the system.
+ * If irq_sync is non-zero, then the IRQ handler must be synchronized
+ * with as well. Most of the time, this is not necessary except when
+ * shutting down the device.
+ */
+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
+{
+ if (irq_sync)
+ tg3_irq_quiesce(tp);
+ spin_lock_bh(&tp->lock);
+ spin_lock(&tp->tx_lock);
+}
+
+static inline void tg3_full_unlock(struct tg3 *tp)
+{
+ spin_unlock(&tp->tx_lock);
+ spin_unlock_bh(&tp->lock);
+}
+
/* MSI ISR - No need to check for interrupt sharing and no need to
* flush status block and interrupt mailbox. PCI ordering rules
* guarantee that MSI will arrive after the status block.
@@ -2946,9 +2978,6 @@ static irqreturn_t tg3_msi(int irq, void
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
@@ -2959,6 +2988,8 @@ static irqreturn_t tg3_msi(int irq, void
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
tp->last_tag = sblk->status_tag;
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -2967,9 +2998,7 @@ static irqreturn_t tg3_msi(int irq, void
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
tp->last_tag << 24);
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(1);
}
@@ -2978,11 +3007,8 @@ static irqreturn_t tg3_interrupt(int irq
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
unsigned int handled = 1;
- spin_lock_irqsave(&tp->lock, flags);
-
/* In INTx mode, it is possible for the interrupt to arrive at
* the CPU before the status block posted prior to the interrupt.
* Reading the PCI State register will confirm whether the
@@ -2999,6 +3025,8 @@ static irqreturn_t tg3_interrupt(int irq
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -3013,9 +3041,7 @@ static irqreturn_t tg3_interrupt(int irq
} else { /* shared interrupt */
handled = 0;
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(handled);
}
@@ -3024,11 +3050,8 @@ static irqreturn_t tg3_interrupt_tagged(
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
unsigned int handled = 1;
- spin_lock_irqsave(&tp->lock, flags);
-
/* In INTx mode, it is possible for the interrupt to arrive at
* the CPU before the status block posted prior to the interrupt.
* Reading the PCI State register will confirm whether the
@@ -3046,6 +3069,8 @@ static irqreturn_t tg3_interrupt_tagged(
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
tp->last_tag = sblk->status_tag;
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -3060,9 +3085,7 @@ static irqreturn_t tg3_interrupt_tagged(
} else { /* shared interrupt */
handled = 0;
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(handled);
}
@@ -3101,8 +3124,7 @@ static void tg3_reset_task(void *_data)
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
@@ -3112,8 +3134,7 @@ static void tg3_reset_task(void *_data)
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (restart_timer)
mod_timer(&tp->timer, jiffies + 1);
@@ -3219,39 +3240,21 @@ static int tg3_start_xmit(struct sk_buff
unsigned int i;
u32 len, entry, base_flags, mss;
int would_hit_hwbug;
- unsigned long flags;
len = skb_headlen(skb);
/* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software
- * interrupt. Rejoice!
- *
- * Actually, things are not so simple. If we are to take a hw
- * IRQ here, we can deadlock, consider:
- *
- * CPU1 CPU2
- * tg3_start_xmit
- * take tp->tx_lock
- * tg3_timer
- * take tp->lock
- * tg3_interrupt
- * spin on tp->lock
- * spin on tp->tx_lock
- *
- * So we really do need to disable interrupts when taking
- * tx_lock here.
+ * interrupt. Furthermore, IRQ processing runs lockless so we have
+ * no IRQ context deadlocks to worry about either. Rejoice!
*/
- local_irq_save(flags);
- if (!spin_trylock(&tp->tx_lock)) {
- local_irq_restore(flags);
+ if (!spin_trylock(&tp->tx_lock))
return NETDEV_TX_LOCKED;
- }
/* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
netif_stop_queue(dev);
- spin_unlock_irqrestore(&tp->tx_lock, flags);
+ spin_unlock(&tp->tx_lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return NETDEV_TX_BUSY;
@@ -3416,7 +3419,7 @@ static int tg3_start_xmit(struct sk_buff
out_unlock:
mmiowb();
- spin_unlock_irqrestore(&tp->tx_lock, flags);
+ spin_unlock(&tp->tx_lock);
dev->trans_start = jiffies;
@@ -3450,8 +3453,8 @@ static int tg3_change_mtu(struct net_dev
}
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+
+ tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -3461,8 +3464,7 @@ static int tg3_change_mtu(struct net_dev
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -5083,9 +5085,9 @@ static int tg3_set_mac_addr(struct net_d
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -5797,10 +5799,8 @@ static void tg3_periodic_fetch_stats(str
static void tg3_timer(unsigned long __opaque)
{
struct tg3 *tp = (struct tg3 *) __opaque;
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
- spin_lock(&tp->tx_lock);
+ spin_lock(&tp->lock);
if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
/* All of this garbage is because when using non-tagged
@@ -5817,8 +5817,7 @@ static void tg3_timer(unsigned long __op
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
schedule_work(&tp->reset_task);
return;
}
@@ -5886,8 +5885,7 @@ static void tg3_timer(unsigned long __op
tp->asf_counter = tp->asf_multiplier;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);
@@ -6002,14 +6000,12 @@ static int tg3_test_msi(struct tg3 *tp)
/* Need to reset the chip because the MSI cycle may have terminated
* with Master Abort.
*/
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
err = tg3_init_hw(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (err)
free_irq(tp->pdev->irq, dev);
@@ -6022,14 +6018,12 @@ static int tg3_open(struct net_device *d
struct tg3 *tp = netdev_priv(dev);
int err;
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
/* The placement of this call is tied
* to the setup and use of Host TX descriptors.
@@ -6076,8 +6070,7 @@ static int tg3_open(struct net_device *d
return err;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
err = tg3_init_hw(tp);
if (err) {
@@ -6101,8 +6094,7 @@ static int tg3_open(struct net_device *d
tp->timer.function = tg3_timer;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (err) {
free_irq(tp->pdev->irq, dev);
@@ -6118,8 +6110,7 @@ static int tg3_open(struct net_device *d
err = tg3_test_msi(tp);
if (err) {
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
pci_disable_msi(tp->pdev);
@@ -6129,22 +6120,19 @@ static int tg3_open(struct net_device *d
tg3_free_rings(tp);
tg3_free_consistent(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return err;
}
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
add_timer(&tp->timer);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_enable_ints(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
netif_start_queue(dev);
@@ -6390,8 +6378,7 @@ static int tg3_close(struct net_device *
del_timer_sync(&tp->timer);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
#if 0
tg3_dump_state(tp);
#endif
@@ -6405,8 +6392,7 @@ static int tg3_close(struct net_device *
TG3_FLAG_GOT_SERDES_FLOWCTL);
netif_carrier_off(tp->dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
free_irq(tp->pdev->irq, dev);
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6443,16 +6429,15 @@ static unsigned long calc_crc_errors(str
if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
- unsigned long flags;
u32 val;
- spin_lock_irqsave(&tp->lock, flags);
+ spin_lock_bh(&tp->lock);
if (!tg3_readphy(tp, 0x1e, &val)) {
tg3_writephy(tp, 0x1e, val | 0x8000);
tg3_readphy(tp, 0x14, &val);
} else
val = 0;
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock_bh(&tp->lock);
tp->phy_crc_errors += val;
@@ -6714,11 +6699,9 @@ static void tg3_set_rx_mode(struct net_d
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
__tg3_set_rx_mode(dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
#define TG3_REGDUMP_LEN (32 * 1024)
@@ -6740,8 +6723,7 @@ static void tg3_get_regs(struct net_devi
memset(p, 0, TG3_REGDUMP_LEN);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
#define __GET_REG32(reg) (*(p)++ = tr32(reg))
#define GET_REG32_LOOP(base,len) \
@@ -6791,8 +6773,7 @@ do { p = (u32 *)(orig_p + (reg)); \
#undef GET_REG32_LOOP
#undef GET_REG32_1
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
static int tg3_get_eeprom_len(struct net_device *dev)
@@ -6968,8 +6949,7 @@ static int tg3_set_settings(struct net_d
return -EINVAL;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tp->link_config.autoneg = cmd->autoneg;
if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -6985,8 +6965,7 @@ static int tg3_set_settings(struct net_d
if (netif_running(dev))
tg3_setup_phy(tp, 1);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -7022,12 +7001,12 @@ static int tg3_set_wol(struct net_device
!(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
return -EINVAL;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
if (wol->wolopts & WAKE_MAGIC)
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
else
tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -7067,7 +7046,7 @@ static int tg3_nway_reset(struct net_dev
if (!netif_running(dev))
return -EAGAIN;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
r = -EINVAL;
tg3_readphy(tp, MII_BMCR, &bmcr);
if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
@@ -7075,7 +7054,7 @@ static int tg3_nway_reset(struct net_dev
tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
r = 0;
}
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return r;
}
@@ -7106,8 +7085,7 @@ static int tg3_set_ringparam(struct net_
if (netif_running(dev))
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tp->rx_pending = ering->rx_pending;
@@ -7123,8 +7101,7 @@ static int tg3_set_ringparam(struct net_
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -7145,8 +7122,8 @@ static int tg3_set_pauseparam(struct net
if (netif_running(dev))
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
+
if (epause->autoneg)
tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
else
@@ -7165,8 +7142,8 @@ static int tg3_set_pauseparam(struct net
tg3_init_hw(tp);
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+
+ tg3_full_unlock(tp);
return 0;
}
@@ -7187,12 +7164,12 @@ static int tg3_set_rx_csum(struct net_de
return 0;
}
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
if (data)
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
else
tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -7714,8 +7691,7 @@ static void tg3_self_test(struct net_dev
if (netif_running(dev))
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
tg3_nvram_lock(tp);
@@ -7737,14 +7713,14 @@ static void tg3_self_test(struct net_dev
data[4] = 1;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
+
if (tg3_test_interrupt(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED;
data[5] = 1;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+
+ tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
@@ -7752,8 +7728,8 @@ static void tg3_self_test(struct net_dev
tg3_init_hw(tp);
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+
+ tg3_full_unlock(tp);
}
}
@@ -7774,9 +7750,9 @@ static int tg3_ioctl(struct net_device *
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
break; /* We have no PHY */
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
data->val_out = mii_regval;
@@ -7790,9 +7766,9 @@ static int tg3_ioctl(struct net_device *
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return err;
@@ -7808,28 +7784,24 @@ static void tg3_vlan_rx_register(struct
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tp->vlgrp = grp;
/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
__tg3_set_rx_mode(dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
if (tp->vlgrp)
tp->vlgrp->vlan_devices[vid] = NULL;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
#endif
@@ -10136,24 +10108,19 @@ static int tg3_suspend(struct pci_dev *p
del_timer_sync(&tp->timer);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
tg3_disable_ints(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
netif_device_detach(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_init_hw(tp);
@@ -10163,8 +10130,7 @@ static int tg3_suspend(struct pci_dev *p
netif_device_attach(dev);
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
return err;
@@ -10187,8 +10153,7 @@ static int tg3_resume(struct pci_dev *pd
netif_device_attach(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_init_hw(tp);
@@ -10199,8 +10164,7 @@ static int tg3_resume(struct pci_dev *pd
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
--- 1/drivers/net/tg3.h.~1~ 2005-05-30 15:29:23.000000000 -0700
+++ 2/drivers/net/tg3.h 2005-05-30 18:55:43.000000000 -0700
@@ -2006,17 +2006,33 @@ struct tg3_ethtool_stats {
struct tg3 {
/* begin "general, frequently-used members" cacheline section */
+ /* If the IRQ handler (which runs lockless) needs to be
+ * quiesced, the following bitmask state is used. The
+ * SYNC bit is set by non-IRQ context code to initiate
+ * the quiescence. The setter of this bit also forces
+ * an interrupt to run via the GRC misc host control
+ * register.
+ *
+ * The IRQ handler notes this, disables interrupts, and
+ * sets the COMPLETE bit. At this point the SYNC bit
+ * setter can be assured that interrupts will no longer
+ * get run.
+ *
+ * In this way all SMP driver locks are never acquired
+ * in hw IRQ context, only sw IRQ context or lower.
+ */
+ unsigned long irq_state;
+#define TG3_IRQSTATE_SYNC 0
+#define TG3_IRQSTATE_COMPLETE 1
+
/* SMP locking strategy:
*
* lock: Held during all operations except TX packet
* processing.
*
- * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+ * tx_lock: Held during tg3_start_xmit and tg3_tx
*
- * If you want to shut up all asynchronous processing you must
- * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must
- * be disabled to take 'lock' but only softirq disabling is
- * necessary for acquisition of 'tx_lock'.
+ * Both of these locks are to be held with BH safety.
*/
spinlock_t lock;
spinlock_t indirect_lock;
^ permalink raw reply
* ipv4 ipsec
From: Edgar E Iglesias @ 2005-05-31 22:47 UTC (permalink / raw)
To: netdev
Hi,
Im not sure this is the correct list for ipsec issues, but shouldn't
the size check at the bottom of net/ipv4/esp4.c be the other way
around (2.6.11)?
static int __init esp4_init(void)
{
struct xfrm_decap_state decap;
if (sizeof(struct esp_decap_data) <
sizeof(decap.decap_data)) {
extern void decap_data_too_small(void);
decap_data_too_small();
}
decap.decap_data should hold an opaque type for the implementation
specific decap state, so I guess it should be the bigger of the
two.
Best regards
--
Programmer
Edgar E Iglesias <edgar@axis.com> 46.46.272.1946
% diff -bu /usr/src/linux-2.6.11-gentoo-r8/net/ipv4/esp4.c esp4.c
--- /usr/src/linux-2.6.11-gentoo-r8/net/ipv4/esp4.c 2005-05-11 10:05:03.000000000 +0200
+++ esp4.c 2005-06-01 00:38:55.000000000 +0200
@@ -480,7 +480,7 @@
{
struct xfrm_decap_state decap;
- if (sizeof(struct esp_decap_data) <
+ if (sizeof(struct esp_decap_data) >
sizeof(decap.decap_data)) {
extern void decap_data_too_small(void);
^ permalink raw reply
* Re: [RFC] textsearch infrastructure et al v2
From: Thomas Graf @ 2005-05-31 22:44 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, hadi
In-Reply-To: <20050531.145627.85412348.davem@davemloft.net>
* David S. Miller <20050531.145627.85412348.davem@davemloft.net> 2005-05-31 14:56
> From: Thomas Graf <tgraf@suug.ch>
> Date: Sat, 28 May 2005 00:47:25 +0200
>
> > Any other ideas around?
>
> You could just fetch "windows" of data.
>
> You can define this window to be 32 bytes, or whatever.
Heh, I had something like this in mind. Well, basically the
current behaviour is not different except that the window
is variable and uses the page data directly rather than
copying.
Back on the static window subject, it would definitely
be helpful for right-to-left scan algorithms such as
boyer-moore. However, I think that the overhead due to
the massive map/unmap and copying is bigger than the
costs of naive searches around the fragment borders.
Pablo joined me on the subject, he's currently working
on converting the fragmentation iteration to use Rusty's
skb_iter code. we'll present new work with some numbers
shortly.
^ permalink raw reply
* 2.6.12-rcx networking oops
From: Phil Oester @ 2005-05-31 22:40 UTC (permalink / raw)
To: netdev; +Cc: herbert, akpm
At Andrew's suggestion, I tested the latest 2.6.12-rc5-gitx, and am still
hitting an oops on a gateway box under load. From comparing the various
oops, it seems like a dev is disappearing while one CPU is in the middle
of processing traffic. At least that's what my naive analysis leads
me to believe.
The latest oops is the first shown below (2.6.12-rc5-git5), and seems to be
here:
0xc0270d3f is in fib_validate_source (net/ipv4/fib_frontend.c:195).
195 if (FIB_RES_DEV(res) == dev)
The second oops below was against 2.6.12-rc4, hitting here:
0xc026a59a is in inet_select_addr (inetdevice.h:159).
159 return (struct in_device*)dev->ip_ptr;
The third oops below is also against 2.6.12-rc4, hitting here:
0xc026dbba is in ip_check_mc (net/ipv4/igmp.c:2101).
2101 for (im=in_dev->mc_list; im; im=im->next) {
Since I'm trying to update a 2.6.10 box, Herbert Xu asked me to test each
2.6.11-rc to see where the problem begins, but it appears around 2.6.11-rc2
some LLTX changes were made which caused lockups (they were later
reverted before 2.6.11-final). So, I can't really tell when this started.
Any further suggestions?
Phil
Unable to handle kernel NULL pointer dereference at virtual address 00000060
printing eip:
c0270d3f
*pde = 00000000
Oops: 0000 [#1]
SMP
CPU: 0
EIP: 0060:[<c0270d3f>] Not tainted VLI
EFLAGS: 00010206 (2.6.12-rc5-git5)
EIP is at fib_validate_source+0xcf/0x1f0
eax: f7c2c000 ebx: c0337dec ecx: f7c258a0 edx: 00000000
esi: c0335c2c edi: 00000000 ebp: c0337db0 esp: c0337d40
ds: 3f1f es: 007b ss: 0068
Process swapper (pid: 0, threadinfo=c0337000 task=c02b9bc0)
Stack: 00000000 3b6014aa 00000000 00010000 f7b7a460 00000000 00000002 3b6014aa
4f7514aa 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 c0337e00
Call Trace:
[<c010389a>] show_stack+0x7a/0x90
[<c0103a1d>] show_registers+0x14d/0x1b0
[<c0103c1d>] die+0xed/0x170
[<c010f05a>] do_page_fault+0x30a/0x65a
[<c01034e3>] error_code+0x4f/0x54
[<c0244795>] ip_route_input_slow+0x445/0x840
[<c0244c2a>] ip_route_input+0x9a/0x160
[<c0246d00>] ip_rcv+0x3b0/0x4d0
[<c02342ea>] netif_receive_skb+0x13a/0x1a0
[<c01f8d10>] e1000_clean_rx_irq+0x180/0x4d0
[<c01f8550>] e1000_clean+0x40/0xe0
[<c0234500>] net_rx_action+0x90/0x130
[<c011a804>] __do_softirq+0xd4/0xf0
[<c0104f82>] do_softirq+0x52/0x70
=======================
[<c011a8ea>] irq_exit+0x3a/0x40
[<c0104e70>] do_IRQ+0x50/0x70
[<c010338a>] common_interrupt+0x1a/0x20
[<c0100a8b>] cpu_idle+0x7b/0x80
[<c01002be>] rest_init+0x1e/0x20
[<c02fc96c>] start_kernel+0x14c/0x170
[<c010020e>] 0xc010020e
Code: ff 83 c4 64 5b 5e 5f 5d c3 89 d0 e8 4c 09 00 00 eb ea 8b 46 04 8b 40 24 85 c0 0f 84 00 01 00
00 8b 5d 10 89 03 8b 56 04 8b 45 0c <39> 42 60 0f 84 dd 00 00 00 85 d2 74 0f f0 ff 4a 14 0f 94 c0 84
Unable to handle kernel NULL pointer dereference at virtual address 000000ec
printing eip:
c026a59a
*pde = 00000000
Oops: 0000 [#1]
SMP
CPU: 1
EIP: 0060:[<c026a59a>] Not tainted VLI
EFLAGS: 00010246 (2.6.12-rc4)
EIP is at inet_select_addr+0xa/0xf0
eax: 00000000 ebx: c1bb4720 ecx: 00000000 edx: 00000000
esi: 00000000 edi: 00000000 ebp: c0333d60 esp: c0333d54
ds: 007b es: 007b ss: 0068
Process swapper (pid: 0, threadinfo=c0333000 task=c191b520)
Stack: c1bb4720 c0333d74 00000000 c0333dd8 c026eb0b 00000000 3e6014aa 00000000
0001001d f78d169f 00000000 00000001 3e6014aa 25e65e42 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Call Trace:
[<c01038ba>] show_stack+0x7a/0x90
[<c0103a3d>] show_registers+0x14d/0x1b0
[<c0103c3d>] die+0xed/0x170
[<c010f05a>] do_page_fault+0x30a/0x65a
[<c0103503>] error_code+0x4f/0x54
[<c026eb0b>] fib_validate_source+0x1cb/0x1f0
[<c0242305>] ip_route_input_slow+0x445/0x840
[<c0244890>] ip_rcv+0x3b0/0x4d0
[<c0231e3a>] netif_receive_skb+0x13a/0x1a0
[<c01f87e6>] e1000_clean_rx_irq+0x156/0x480
[<c01f822f>] e1000_clean+0x3f/0xe0
[<c0232050>] net_rx_action+0x90/0x130
[<c011a884>] __do_softirq+0xd4/0xf0
[<c0104fc2>] do_softirq+0x52/0x70
=======================
[<c0104eb0>] do_IRQ+0x50/0x70
[<c01033aa>] common_interrupt+0x1a/0x20
[<c0100a82>] cpu_idle+0x72/0x80
[<00000000>] stext+0x3feffd6c/0xc
[<c191ffb4>] 0xc191ffb4
Code: 30 5b 5e 5f 5d c3 c7 45 c4 f2 <7> ff ff ff eb ec 89 f6 8b 75 d0 eb ae 8d 74 26 00 8d bc 27 00 00 00 00 55 89 e5 57 31 ff 56 89 ce 53 <8b> 80 ec 00 00 00 85 c0 74 38 8b 48 0c 85 c9 74 2d f6 41 25 01
Unable to handle kernel NULL pointer dereference at virtual address 00000060
printing eip: c026b44a
*pde = 00000000
Oops: 0000 [#1]
SMP
CPU: 1
EIP: 0060:[<c026b44a>] Not tainted VLI
EFLAGS: 00010206 (2.6.12-rc4)
EIP is at ip_check_mc+0x2a/0xb0
eax: 026014aa ebx: c1bb4720 ecx: f7a51e60 edx: 00000000
esi: c033bbe6 edi: 0000b9e6 ebp: f7c29000 esp: c0331d88
ds: 007b es: 007b ss: 0068
Process swapper (pid: 0, threadinfo=c0331000 task=c191b520)
Stack: 00000000 3e6014aa 00000000 0001001d f7044f60 00000000 00000001 3e6014aa
7525bece 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 c0331e44
Call Trace:
[<c024051a>] ip_route_input_slow+0x3da/0x760
[<c0242939>] ip_rcv+0x3b9/0x4d0
[<c0242bb0>] ip_rcv_finish+0x0/0x240
[<c0111f48>] __wake_up+0x38/0x50
[<c02304ea>] netif_receive_skb+0x13a/0x1a0
[<c01f748e>] e1000_clean_rx_irq+0x16e/0x4c0
[<c01f711f>] e1000_clean_tx_irq+0x1af/0x3b0
[<c01f6ecc>] e1000_clean+0x3c/0xe0
[<c02306ef>] net_rx_action+0x7f/0x110
[<c011a414>] __do_softirq+0xd4/0xf0
[<c010507f>] do_softirq+0x4f/0x60
=======================
[<c0104f6d>] do_IRQ+0x4d/0x70
[<c0103406>] common_interrupt+0x1a/0x20
[<c0100990>] default_idle+0x0/0x30
[<c01009b3>] default_idle+0x23/0x30
[<c0100a70>] cpu_idle+0x70/0x80
Code: 90 55 31 ed 57 56 89 d6 53 83 ec 08 89 c3 89 4c 24 04 8d 40 10 89 04 24 0f b7 7c 24 1c e8 3f be 01 00 8b 43 14 85 c0 74 14 90 8d <b4> 26 00 00 00 00 39 70 04 74 19 8b 40 1c 85 c0 75 f4 8b 04 24
^ permalink raw reply
* Re: [PATCH] [DECNET] Remove unnecessary initilization of unused variable entries
From: David S. Miller @ 2005-05-31 22:38 UTC (permalink / raw)
To: tgraf; +Cc: netdev
In-Reply-To: <20050528162624.GU15391@postel.suug.ch>
From: Thomas Graf <tgraf@suug.ch>
Date: Sat, 28 May 2005 18:26:24 +0200
> This patch was supposed to be part of the neighbour tables related
> patchset but apparently got lost.
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
Applied to net-2.6.13
^ permalink raw reply
* Re: [IPSEC] Add XFRMA_SA/XFRMA_POLICY for delete notification
From: David S. Miller @ 2005-05-31 22:37 UTC (permalink / raw)
To: herbert; +Cc: hadi, kaber, netdev
In-Reply-To: <20050527233741.GA9157@gondor.apana.org.au>
Applied to net-2.6.13, so you have some time to make some changes
to the API before they get cast in stone.
Thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox