Netdev List
 help / color / mirror / Atom feed
* Re: set vlan CFI and TPID
From: Jesse Gross @ 2010-12-13  0:20 UTC (permalink / raw)
  To: hong zhiyi; +Cc: netdev
In-Reply-To: <AANLkTimW35xF4dcr_UO6XX1tBb3VBcp2PWPq8SkMk60=@mail.gmail.com>

On Tue, Dec 7, 2010 at 8:04 PM, hong zhiyi <zhiyi.hong@gmail.com> wrote:
> Hi All,
>
> May I ask how to set the 1 bit CFI and 2 bytesTPID in the VLAN header
> by vconfig?

You can't change them using vconfig.  For 802.1q/Ethernet, the TPID is
0x8100 and the CFI is 0.

> and what is the meaning of the egress map and ingress map?

These convert between the PCP bits found in the vlan header and the
priority field that is used internally for QoS, which you access
through tc.

^ permalink raw reply

* Re: [PATCH 2.6.36] vlan: Avoid hwaccel vlan packets when vid not used
From: Jesse Gross @ 2010-12-13  0:11 UTC (permalink / raw)
  To: Michael Leun, Matt Carlson, Michael Chan
  Cc: Eric Dumazet, David Miller, Ben Greear, linux-kernel, netdev
In-Reply-To: <20101206222703.32fbe852@xenia.leun.net>

On Mon, Dec 6, 2010 at 1:27 PM, Michael Leun
<lkml20101129@newton.leun.net> wrote:
> On Mon, 6 Dec 2010 12:04:48 -0800
> Jesse Gross <jesse@nicira.com> wrote:
>
>> On Mon, Dec 6, 2010 at 11:34 AM, Michael Leun
>> <lkml20101129@newton.leun.net> wrote:
>> > On Mon, 6 Dec 2010 10:14:55 -0800
>> > Jesse Gross <jesse@nicira.com> wrote:
>> >
>> >> On Sun, Dec 5, 2010 at 2:44 AM, Michael Leun
>> >> <lkml20101129@newton.leun.net> wrote:
>> >> > Hi Jesse,
>> >> >
>> >> > On Sun, 5 Dec 2010 10:55:28 +0100
>> >> > Michael Leun <lkml20101129@newton.leun.net> wrote:
>> >> >
>> >> >> On Sun, 05 Dec 2010 09:03:53 +0100
>> >> >> Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> >> >>
>> >> >> > > But on
>> >> >> > >
>> >> >> > > hpdl320g5:/home/ml # lspci | grep Eth
>> >> >> > > 03:04.0 Ethernet controller: Broadcom Corporation NetXtreme
>> >> >> > > BCM5714 Gigabit Ethernet (rev a3) 03:04.1 Ethernet
>> >> >> > > controller: Broadcom Corporation NetXtreme BCM5714 Gigabit
>> >> >> > > Ethernet (rev a3)
>> >> >> > >
>> >> >> > > the good message is that it also does not crash, but with
>> >> >> > > tcpdump I see vlan tags when no vlan devices configured on
>> >> >> > > the respective eth, if so I do not see tags anymore vlan
>> >> >> > > tags on the trunk interface.
>> >> >> > >
>> >> >> >
>> >> >> > For all these very specific needs, you'll have to try 2.6.37
>> >> >> > I am afraid. Jesse did huge changes to exactly make this
>> >> >> > working, we wont backport this to 2.6.36, but only avoid
>> >> >> > crashes.
>> >> >>
>> >> >> OK, I'm perfectly fine with that, of course, actually nice to
>> >> >> hear that the issue already is addressed.
>> >> >>
>> >> >> Likely I'll give some rc an shot on this machine (maybe over
>> >> >> christmas), but it is an production machine (acutally testing
>> >> >> other devices is the "product" produced on this machine), so
>> >> >> unfortunately I'm not that free in when and what I can do (but
>> >> >> the possibility to, for example, bridge the trunk interface
>> >> >> would make testing easier, that justifies something...).
>> >> >>
>> >> >> Thank you all very much for your work.
>> >> >
>> >> > Are these changes already in 2.6.37-rc4? Or, if not are they
>> >> > somewhere publically available already?
>> >> >
>> >> > I looked into various changelogs but have some difficulties to
>> >> > identify them...
>> >> >
>> >> > Maybe I have some time next days to give them an try...
>> >>
>> >> Yes, all of the existing vlan changes are in 2.6.37-rc4.  There
>> >> were a number of patches but the main one was
>> >> 3701e51382a026cba10c60b03efabe534fba4ca4
>> >
>> > Then, I'm afraid, this (seeing vlan tags even if vlan interfaces are
>> > configured) does not work on HP DL320G5 (for exact description and
>> > examples please see my mail a few days ago).
>>
>> What driver are you using?  Is it tg3?
>>
>> The vlan changes that I made unfortunately require updating drivers to
>> get the full benefit.  I've been busy lately so tg3 hasn't yet been
>> updated.
>>
>> I know that tg3 does some things differently depending on whether a
>> vlan group is configured, so that would likely be the cause of what
>> you are seeing.  I'd have to look at it in more detail to be sure
>> though.
>>
>> You said that everything works on the other Broadcom NIC that you
>> tested?  Maybe it uses bnx2 instead?
>>
>
> Both machines use tg3 / 2.6.36.1 - one is opensuse, one ubuntu (but
> this should not matter, I think).
>
> If I can do anything to support your investigations / work (most
> likely testing / providing information) please let me know.

Unfortunately, I probably won't have time to look at this in the near
future.  Given that the test works on one NIC but not another that
strongly suggests that it is a driver problem, even if both NICs use
the same driver.  I see tg3 can do different things with vlans
depending on the model and what features are enabled.  I also ran a
quick test on some of my machines and I didn't experience this issue.
They are running net-next with ixgbe.

One of the main goals of my general vlan changes was to remove as much
logic as possible from the drivers and put it in the networking core,
so we should in theory see consistent behavior.  However, in 2.6.36
and earlier, each driver knows about what vlan devices are configured
and does different things with that information.

Given all of that, the most logical step to me is simply to convert
tg3 to use the new vlan infrastructure.  It should be done regardless
and it will probably solve this problem.  Maybe you can convince the
Broadcom guys to do that?  It would be a lot faster for them to do it
than me.

^ permalink raw reply

* Re: System blocks (hangs) on ifconfig up
From: Stephen Hemminger @ 2010-12-12 23:29 UTC (permalink / raw)
  To: Shmulik Hen; +Cc: netdev
In-Reply-To: <4D04E38A.1040605@trego.co.il>

On Sun, 12 Dec 2010 17:00:26 +0200
Shmulik Hen <shmulik.hen@gmail.com> wrote:

> Hello,
> 
> My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
> 
> Whenever I try to bring up a specific ethernet interface for the second 
> time, my
> system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
> screen refresh. etc.
> 
> Looking at the driver's code, I could see that it's dev->open() method calls
> wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
> the delay I'm seeing.
> 
> I have narrowed the code to a bare minimum (see below - loosely based on
> dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
> still, my system blocks for exactly 10 seconds when I run the following
> sequence:
> 
>  > sudo ifconfig shmulik0 up
>  > sudo ifconfig shmulik0 down
>  > sudo ifconfig shmulik0 up
> 
> At this point - the system is stuck for 10 seconds.
> 
> 
> Thanks,
> Shmulik.

What driver is this? Where is the source? It sounds awful

-- 

^ permalink raw reply

* Re: [PATCH] pppoe.c: Fix kernel panic caused by __pppoe_xmit
From: David Miller @ 2010-12-12 23:06 UTC (permalink / raw)
  To: andrej; +Cc: jarkao2, netdev
In-Reply-To: <4D0407E4.1060805@ota.si>

From: Andrej Ota <andrej@ota.si>
Date: Sun, 12 Dec 2010 00:23:16 +0100

>> Thanks Andrej! I've only updated emails a bit.
> 
> Thank you for your help and support in submitting this patch.

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH update] firewire: net: add carrier detection
From: Ben Hutchings @ 2010-12-12 23:05 UTC (permalink / raw)
  To: Stefan Richter; +Cc: Maxim Levitsky, Peter Stuge, linux1394-devel, netdev
In-Reply-To: <20101212180916.71a57a71@stein>

On Sun, 2010-12-12 at 18:09 +0100, Stefan Richter wrote:
> From: Maxim Levitsky <maximlevitsky@gmail.com>
> 
> To make userland, e.g. NetworkManager work with firewire, we need to
> detect whether cable is plugged or not.  Simple and correct way of doing
> that is just counting number of peers.  No peers - no link and vice
> versa.
[...]

NM doesn't use ETHTOOL_GLINK so you don't need to implement
ethtool_ops::get_link.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [net-2.6 PATCH 1/1] qlge: Fix deadlock when cancelling worker.
From: David Miller @ 2010-12-12 23:04 UTC (permalink / raw)
  To: ron.mercer; +Cc: netdev, jarkao2, mingo, Linux-Driver
In-Reply-To: <1292101610-30661-1-git-send-email-ron.mercer@qlogic.com>

From: Ron Mercer <ron.mercer@qlogic.com>
Date: Sat, 11 Dec 2010 13:06:50 -0800

> Removing usage of rtnl_lock() to protect firmware interface registers.
> These registers are accessed in some worker threads and can create a
> deadlock if rtnl_lock is taken by upper layers while the worker is still
> pending.
> We remove rtnl_lock and use a driver mutex just while mailboxes are
> accessed.
> 
> Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-2.6 3/3] bnx2x: Advance a version number to 1.60.01-0
From: David Miller @ 2010-12-12 23:03 UTC (permalink / raw)
  To: vladz; +Cc: netdev, eilong
In-Reply-To: <1292163149.20811.162.camel@lb-tlvb-vladz>

From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 12 Dec 2010 16:12:29 +0200

> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-2.6 2/3] bnx2x: Fixed a compilation warning
From: David Miller @ 2010-12-12 23:03 UTC (permalink / raw)
  To: vladz; +Cc: netdev, eilong
In-Reply-To: <1292163132.20811.161.camel@lb-tlvb-vladz>

From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 12 Dec 2010 16:12:12 +0200

> bnx2x_src_init_t2() is used only when BCM_CNIC is defined.
> So, to avoid a compilation warning, we won't define it unless
> BCM_CNIC is defined.
> 
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-2.6 1/3] bnx2x: LSO code was broken on BE platforms
From: David Miller @ 2010-12-12 23:03 UTC (permalink / raw)
  To: vladz; +Cc: netdev, eilong
In-Reply-To: <1292163105.20811.160.camel@lb-tlvb-vladz>

From: "Vladislav Zolotarov" <vladz@broadcom.com>
Date: Sun, 12 Dec 2010 16:11:45 +0200

> Make the LSO code work on BE platforms: parsing_data field of 
> a parsing BD (PBD) for 57712 was improperly composed which made FW read wrong 
> values for TCP header's length and offset and, as a result, the corresponding 
> PCI device was performing bad DMA reads triggering EEH.
> 
> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
> Signed-off-by: Eilon Greenstein <eilong@broadcom.com>

Applied.

^ permalink raw reply

* Re: [PATCH] WAN: Fix a TX IRQ causing BUG() in PC300 and PCI200SYN drivers.
From: David Miller @ 2010-12-12 23:03 UTC (permalink / raw)
  To: khc; +Cc: netdev
In-Reply-To: <m37hfe7iiw.fsf@intrepid.localdomain>

From: Krzysztof Halasa <khc@pm.waw.pl>
Date: Sun, 12 Dec 2010 23:06:47 +0100

> We must not wake the TX queue without free TX descriptors.
> sca_xmit() expects at least one free descriptor and BUGs otherwise.
> 
> Problem reported and fix tested by Bernie Innocenti and Ward Vandewege.
> 
> Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>

Applied.

^ permalink raw reply

* Re: System blocks (hangs) on ifconfig up
From: Ben Hutchings @ 2010-12-12 23:03 UTC (permalink / raw)
  To: Shmulik Hen; +Cc: netdev
In-Reply-To: <4D04E38A.1040605@trego.co.il>

On Sun, 2010-12-12 at 17:00 +0200, Shmulik Hen wrote:
> Hello,
> 
> My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
> 
> Whenever I try to bring up a specific ethernet interface for the second 
> time, my
> system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
> screen refresh. etc.
> 
> Looking at the driver's code, I could see that it's dev->open() method calls
> wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
> the delay I'm seeing.

That seems like a stupid thing for it to do.

> I have narrowed the code to a bare minimum (see below - loosely based on
> dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
> still, my system blocks for exactly 10 seconds when I run the following
> sequence:
> 
>  > sudo ifconfig shmulik0 up
>  > sudo ifconfig shmulik0 down
>  > sudo ifconfig shmulik0 up
> 
> At this point - the system is stuck for 10 seconds.

Bringing an interface up or down is a synchronous operation and is
serialised with most other network configuration operations.  So this is
the expected behaviour.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: [PATCHSET] net-dev: don't use flush_scheduled_work()
From: David Miller @ 2010-12-12 22:38 UTC (permalink / raw)
  To: tj; +Cc: linux-kernel, netdev
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

From: Tejun Heo <tj@kernel.org>
Date: Sun, 12 Dec 2010 16:52:56 +0100

> This patchset removes the use of flush_scheduled_work(), which is
> being deprecated, from various network drivers.  It contains the
> following nine patches.
> 
>  0001-drivers-net-remove-unnecessary-flush_scheduled_work-.patch
>  0002-drivers-net-don-t-use-flush_scheduled_work.patch
>  0003-ehea-kill-unused-ehea_rereg_mr_task.patch
>  0004-ehea-don-t-use-flush_scheduled_work.patch
>  0005-iseries_veth-don-t-use-flush_scheduled_work.patch
>  0006-igb-v-ixgbe-don-t-use-flush_scheduled_work.patch
>  0007-sungem-update-gp-reset_task-flushing.patch
>  0008-i2400m-drop-i2400m_schedule_work.patch
>  0009-hostap-don-t-use-flush_scheduled_work.patch
> 
> 0001 and 0002 are straight forward conversions across multiple network
> drivers.  The rest are a bit more involved per-driver or driver family
> conversions.
> 
> This patchset is on top of the current net-next-2.6.git#master
> (ad1184c6cf067a13e8cb2a4e7ccc407f947027d0) and available in the
> following git branch.
> 
>  git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git net-dev-kill-flush_scheduled_work
> 
> diffstat follows.  Thanks.

I spent the afternoon going over these and they look good to me.
Pulled, thanks a lot.

If any follow-up bug fixes show up just send me relative patches,
thanks again!

^ permalink raw reply

* Re: [GIT PULL net-2.6] vhost-net: logging fixup
From: David Miller @ 2010-12-12 22:21 UTC (permalink / raw)
  To: mst; +Cc: kvm, virtualization, netdev, linux-kernel, stable
In-Reply-To: <20101212100943.GA12725@redhat.com>

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Sun, 12 Dec 2010 12:09:43 +0200

> Please merge the following fix for 2.6.37.
> It is also applicable to -stable.
> Thanks!
> 
> The following changes since commit a19faf0250e09b16cac169354126404bc8aa342b:
> 
>   net: fix skb_defer_rx_timestamp() (2010-12-10 16:20:56 -0800)

Pulled, thanks.

^ permalink raw reply

* [PATCH] WAN: Fix a TX IRQ causing BUG() in PC300 and PCI200SYN drivers.
From: Krzysztof Halasa @ 2010-12-12 22:06 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

We must not wake the TX queue without free TX descriptors.
sca_xmit() expects at least one free descriptor and BUGs otherwise.

Problem reported and fix tested by Bernie Innocenti and Ward Vandewege.

Signed-off-by: Krzysztof Hałasa <khc@pm.waw.pl>

--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port)
 	struct net_device *dev = port->netdev;
 	card_t* card = port->card;
 	u8 stat;
+	unsigned count = 0;
 
 	spin_lock(&port->lock);
 
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port)
 			dev->stats.tx_bytes += readw(&desc->len);
 		}
 		writeb(0, &desc->stat);	/* Free descriptor */
+		count++;
 		port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
 	}
 
-	netif_wake_queue(dev);
+	if (count)
+		netif_wake_queue(dev);
 	spin_unlock(&port->lock);
 }
 

^ permalink raw reply

* Re: [PATCH] pppoe.c: Fix kernel panic caused by __pppoe_xmit
From: Denys Fedoryshchenko @ 2010-12-12 21:02 UTC (permalink / raw)
  To: Jarek Poplawski
  Cc: Andrej Ota, Paweł Staszewski, Andrew Morton, netdev,
	Paul Mackerras, bugzilla-daemon, bugme-daemon, pstaszewski,
	Eric Dumazet, David Miller, Gorik Van Steenberge,
	Daniel Kenzelmann
In-Reply-To: <20101211200823.GA1917@del.dom.local>

On Saturday 11 December 2010 22:08:23 Jarek Poplawski wrote:
> On Sat, Dec 11, 2010 at 01:44:38PM +0100, Andrej Ota wrote:
> > __pppoe_xmit function return value was invalid resulting in
> > additional call to kfree_skb on already freed skb. This resulted in
> > memory corruption and consequent kernel panic after PPPoE peer
> > terminated the link.
> > 
> > This fixes commit 55c95e738da85373965cb03b4f975d0fd559865b.
> > 
> > Signed-off-by: Jarek Poplawski [jarkao2@gmail.com]
> > Signed-off-by: Andrej Ota [andrej@ota.si]
> > Reported-by: Pawel Staszewski [pstaszewski@artcom.pl]
> 
> Thanks Andrej! I've only updated emails a bit.
> Jarek P.
> 
> Reported-by: Gorik Van Steenberge <gvs@zemos.net>
> Reported-by: Daniel Kenzelmann <kernel.bugzilla@kenzelmann.dyndns.info>
> Reported-by: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
> Reported-by: Pawel Staszewski <pstaszewski@artcom.pl>
> Diagnosed-by: Andrej Ota <andrej@ota.si>
> Diagnosed-by: Eric Dumazet <eric.dumazet@gmail.com>
> Tested-by: Denys Fedoryshchenko <nuclearcat@nuclearcat.com>
> Tested-by: Pawel Staszewski <pstaszewski@artcom.pl>
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
> Signed-off-by: Andrej Ota <andrej@ota.si>
Thanks a lot!

^ permalink raw reply

* Re: System blocks (hangs) on ifconfig up
From: Eric Dumazet @ 2010-12-12 20:53 UTC (permalink / raw)
  To: Shmulik Hen; +Cc: netdev
In-Reply-To: <1292185786.18698.5.camel@edumazet-laptop>

Le dimanche 12 décembre 2010 à 21:29 +0100, Eric Dumazet a écrit :
> Le dimanche 12 décembre 2010 à 17:08 +0200, Shmulik Hen a écrit :
> > Hello,
> > 
> > My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
> > 
> > Whenever I try to bring up a specific ethernet interface for the second 
> > time, my
> > system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
> > screen refresh. etc.
> > 
> > Looking at the driver's code, I could see that it's dev->open() method 
> > calls
> > wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
> > the delay I'm seeing.
> > 
> 
> What is this driver ?
> 
> > I have narrowed the code to a bare minimum (see below - loosely based on
> > dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
> > still, my system blocks for exactly 10 seconds when I run the following
> > sequence:
> > 
> >  > sudo ifconfig shmulik0 up
> >  > sudo ifconfig shmulik0 down
> >  > sudo ifconfig shmulik0 up
> > 
> > At this point - the system is stuck for 10 seconds.
> > 
> 
> Certainly not "stuck for 10 seconds"
> 
> mdelay(10000) suspends this task for 10 seconds, but other tasks can
> certainly run.
> 
> However, your shell waits that "ifconfig ... up" finishes.
> 
> 

Oops, I forgot mdelay() was a spin primitive, but was misleading by your
wait_event_interruptible_timeout() previous reference.

Doing mdelay(10000) is certainly very lazy, I hope no driver does
that ...




^ permalink raw reply

* Re: System blocks (hangs) on ifconfig up
From: Eric Dumazet @ 2010-12-12 20:29 UTC (permalink / raw)
  To: Shmulik Hen; +Cc: netdev
In-Reply-To: <4D04E57C.7020509@trego.co.il>

Le dimanche 12 décembre 2010 à 17:08 +0200, Shmulik Hen a écrit :
> Hello,
> 
> My system is Ubuntu 10.04, running kernel 2.6.32-26-generic.
> 
> Whenever I try to bring up a specific ethernet interface for the second 
> time, my
> system becomes unresponsive for 60 seconds - i.e. no mouse, no keyboard, no
> screen refresh. etc.
> 
> Looking at the driver's code, I could see that it's dev->open() method 
> calls
> wait_event_interruptible_timeout() with a timeout of 60 seconds - exactly
> the delay I'm seeing.
> 

What is this driver ?

> I have narrowed the code to a bare minimum (see below - loosely based on
> dummy.c), which only calls mdelay(10000) in it's dev->open() method, and
> still, my system blocks for exactly 10 seconds when I run the following
> sequence:
> 
>  > sudo ifconfig shmulik0 up
>  > sudo ifconfig shmulik0 down
>  > sudo ifconfig shmulik0 up
> 
> At this point - the system is stuck for 10 seconds.
> 

Certainly not "stuck for 10 seconds"

mdelay(10000) suspends this task for 10 seconds, but other tasks can
certainly run.

However, your shell waits that "ifconfig ... up" finishes.




^ permalink raw reply

* [PATCH update] firewire: net: add carrier detection
From: Stefan Richter @ 2010-12-12 17:09 UTC (permalink / raw)
  To: Maxim Levitsky; +Cc: Peter Stuge, linux1394-devel, netdev
In-Reply-To: <1291809485.5421.0.camel@maxim-laptop>

From: Maxim Levitsky <maximlevitsky@gmail.com>

To make userland, e.g. NetworkManager work with firewire, we need to
detect whether cable is plugged or not.  Simple and correct way of doing
that is just counting number of peers.  No peers - no link and vice
versa.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
Update:  Moved netif_carrier_on/off calls into lock-protected sections.

 drivers/firewire/net.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

Index: b/drivers/firewire/net.c
===================================================================
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -179,6 +179,7 @@ struct fwnet_device {
 	/* Number of tx datagrams that have been queued but not yet acked */
 	int queued_datagrams;
 
+	int peer_count;
 	struct list_head peer_list;
 	struct fw_card *card;
 	struct net_device *netdev;
@@ -1405,6 +1406,10 @@ static int fwnet_change_mtu(struct net_d
 	return 0;
 }
 
+static const struct ethtool_ops fwnet_ethtool_ops = {
+	.get_link	= ethtool_op_get_link,
+};
+
 static const struct net_device_ops fwnet_netdev_ops = {
 	.ndo_open       = fwnet_open,
 	.ndo_stop	= fwnet_stop,
@@ -1423,6 +1428,7 @@ static void fwnet_init_dev(struct net_de
 	net->hard_header_len	= FWNET_HLEN;
 	net->type		= ARPHRD_IEEE1394;
 	net->tx_queue_len	= FWNET_TX_QUEUE_LEN;
+	net->ethtool_ops	= &fwnet_ethtool_ops;
 }
 
 /* caller must hold fwnet_device_mutex */
@@ -1463,6 +1469,8 @@ static int fwnet_add_peer(struct fwnet_d
 
 	spin_lock_irq(&dev->lock);
 	list_add_tail(&peer->peer_link, &dev->peer_list);
+	if (++dev->peer_count > 1)
+		netif_carrier_on(dev->netdev);
 	spin_unlock_irq(&dev->lock);
 
 	return 0;
@@ -1549,6 +1557,8 @@ static void fwnet_remove_peer(struct fwn
 
 	spin_lock_irq(&peer->dev->lock);
 	list_del(&peer->peer_link);
+	if (--peer->dev->peer_count == 1)
+		netif_carrier_off(peer->dev->netdev);
 	spin_unlock_irq(&peer->dev->lock);
 
 	list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link)


-- 
Stefan Richter
-=====-==-=- ==-- -==--
http://arcgraph.de/sr/

^ permalink raw reply

* [PATCH 2/9] drivers/net: don't use flush_scheduled_work()
From: Tejun Heo @ 2010-12-12 15:52 UTC (permalink / raw)
  To: linux-kernel, netdev, davem
  Cc: Tejun Heo, Jay Cliburn, Michael Chan, Divy Le Ray, e1000-devel,
	Vasanthy Kolluri, Samuel Ortiz, Lennert Buytenhek,
	Andrew Gallatin, Francois Romieu, Ramkrishna Vepa, Matt Carlson,
	David Brownell, Shreyas Bhatewara
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

flush_scheduled_work() is on its way out.  This patch contains simple
conversions to replace flush_scheduled_work() usage with direct
cancels and flushes.

Directly cancel the used works on driver detach and flush them in
other cases.

The conversions are mostly straight forward and the only dangers are,

* Forgetting to cancel/flush one or more used works.

* Cancelling when a work should be flushed (ie. the work must be
  executed once scheduled whether the driver is detaching or not).

I've gone over the changes multiple times but it would be much
appreciated if you can review with the above points in mind.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jay Cliburn <jcliburn@gmail.com>
Cc: Michael Chan <mchan@broadcom.com>
Cc: Divy Le Ray <divy@chelsio.com>
Cc: e1000-devel@lists.sourceforge.net
Cc: Vasanthy Kolluri <vkolluri@cisco.com>
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Cc: Andrew Gallatin <gallatin@myri.com>
Cc: Francois Romieu <romieu@fr.zoreil.com>
Cc: Ramkrishna Vepa <ramkrishna.vepa@exar.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Shreyas Bhatewara <sbhatewara@vmware.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/8139too.c              |    3 ++-
 drivers/net/atlx/atl2.c            |    4 ++--
 drivers/net/bcm63xx_enet.c         |    2 +-
 drivers/net/bnx2.c                 |    4 ++--
 drivers/net/cassini.c              |    4 ++--
 drivers/net/cxgb3/cxgb3_main.c     |    3 ++-
 drivers/net/e1000e/netdev.c        |    6 +++---
 drivers/net/enic/enic_main.c       |    2 +-
 drivers/net/ibm_newemac/core.c     |    2 +-
 drivers/net/irda/mcs7780.c         |    2 +-
 drivers/net/ixgb/ixgb_main.c       |    2 +-
 drivers/net/ixgbevf/ixgbevf_main.c |    3 +--
 drivers/net/mv643xx_eth.c          |    2 +-
 drivers/net/myri10ge/myri10ge.c    |    2 +-
 drivers/net/niu.c                  |    2 +-
 drivers/net/pxa168_eth.c           |    2 +-
 drivers/net/r8169.c                |    2 +-
 drivers/net/s2io.c                 |    6 ++++--
 drivers/net/sis190.c               |    3 ++-
 drivers/net/tg3.c                  |    4 ++--
 drivers/net/usb/sierra_net.c       |    5 ++---
 drivers/net/usb/usbnet.c           |    3 +--
 drivers/net/vmxnet3/vmxnet3_drv.c  |    2 +-
 23 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index f5166dc..98517a3 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1092,10 +1092,11 @@ err_out:
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	assert (dev != NULL);
 
-	flush_scheduled_work();
+	cancel_delayed_work_sync(&tp->thread);
 
 	unregister_netdev (dev);
 
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 35b14be..4e6f4e9 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1504,8 +1504,8 @@ static void __devexit atl2_remove(struct pci_dev *pdev)
 
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_config_timer);
-
-	flush_scheduled_work();
+	cancel_work_sync(&adapter->reset_task);
+	cancel_work_sync(&adapter->link_chg_task);
 
 	unregister_netdev(netdev);
 
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index ecfef24..e94a966 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -1097,7 +1097,7 @@ static int bcm_enet_stop(struct net_device *dev)
 	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
 
 	/* make sure no mib update is scheduled */
-	flush_scheduled_work();
+	cancel_work_sync(&priv->mib_update_task);
 
 	/* disable dma & mac */
 	bcm_enet_disable_dma(priv, priv->tx_chan);
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 03209a3..5c811f3 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -8393,7 +8393,7 @@ bnx2_remove_one(struct pci_dev *pdev)
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct bnx2 *bp = netdev_priv(dev);
 
-	flush_scheduled_work();
+	cancel_work_sync(&bp->reset_task);
 
 	unregister_netdev(dev);
 
@@ -8431,7 +8431,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (!netif_running(dev))
 		return 0;
 
-	flush_scheduled_work();
+	cancel_work_sync(&bp->reset_task);
 	bnx2_netif_stop(bp, true);
 	netif_device_detach(dev);
 	del_timer_sync(&bp->timer);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index d6b6d6a..a8a32bc 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -3880,7 +3880,7 @@ static int cas_change_mtu(struct net_device *dev, int new_mtu)
 	schedule_work(&cp->reset_task);
 #endif
 
-	flush_scheduled_work();
+	flush_work_sync(&cp->reset_task);
 	return 0;
 }
 
@@ -5177,7 +5177,7 @@ static void __devexit cas_remove_one(struct pci_dev *pdev)
 		vfree(cp->fw_data);
 
 	mutex_lock(&cp->pm_mutex);
-	flush_scheduled_work();
+	cancel_work_sync(&cp->reset_task);
 	if (cp->hw_running)
 		cas_shutdown(cp);
 	mutex_unlock(&cp->pm_mutex);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 3864617..4d538a4 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1359,6 +1359,7 @@ out:
 static int offload_close(struct t3cdev *tdev)
 {
 	struct adapter *adapter = tdev2adap(tdev);
+	struct t3c_data *td = T3C_DATA(tdev);
 
 	if (!test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
 		return 0;
@@ -1369,7 +1370,7 @@ static int offload_close(struct t3cdev *tdev)
 	sysfs_remove_group(&tdev->lldev->dev.kobj, &offload_attr_group);
 
 	/* Flush work scheduled while releasing TIDs */
-	flush_scheduled_work();
+	flush_work_sync(&td->tid_release_task);
 
 	tdev->lldev = NULL;
 	cxgb3_set_dummy_ops(tdev);
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 5530d0b..02d093d 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -6028,8 +6028,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	bool down = test_bit(__E1000_DOWN, &adapter->state);
 
 	/*
-	 * flush_scheduled work may reschedule our watchdog task, so
-	 * explicitly disable watchdog tasks from being rescheduled
+	 * The timers may be rescheduled, so explicitly disable them
+	 * from being rescheduled.
 	 */
 	if (!down)
 		set_bit(__E1000_DOWN, &adapter->state);
@@ -6040,8 +6040,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->downshift_task);
 	cancel_work_sync(&adapter->update_phy_task);
+	cancel_work_sync(&adapter->led_blink_task);
 	cancel_work_sync(&adapter->print_hang_task);
-	flush_scheduled_work();
 
 	if (!(netdev->flags & IFF_UP))
 		e1000_power_down_phy(adapter);
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9befd54..77d9138 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -2834,7 +2834,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 	if (netdev) {
 		struct enic *enic = netdev_priv(netdev);
 
-		flush_scheduled_work();
+		cancel_work_sync(&enic->reset);
 		unregister_netdev(netdev);
 		enic_dev_deinit(enic);
 		vnic_dev_close(enic->vdev);
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 06bb9b7..8f11d29 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2950,7 +2950,7 @@ static int __devexit emac_remove(struct platform_device *ofdev)
 
 	unregister_netdev(dev->ndev);
 
-	flush_scheduled_work();
+	cancel_work_sync(&dev->reset_work);
 
 	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
 		tah_detach(dev->tah_dev, dev->tah_port);
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 74b20f1..cc821de 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -959,7 +959,7 @@ static void mcs_disconnect(struct usb_interface *intf)
 	if (!mcs)
 		return;
 
-	flush_scheduled_work();
+	cancel_work_sync(&mcs->work);
 
 	unregister_netdev(mcs->netdev);
 	free_netdev(mcs->netdev);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 2e98506..b021798 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -527,7 +527,7 @@ ixgb_remove(struct pci_dev *pdev)
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
-	flush_scheduled_work();
+	cancel_work_sync(&adapter->tx_timeout_task);
 
 	unregister_netdev(netdev);
 
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 2216a3c..809e38c 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -3484,10 +3484,9 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
 
 	del_timer_sync(&adapter->watchdog_timer);
 
+	cancel_work_sync(&adapter->reset_task);
 	cancel_work_sync(&adapter->watchdog_task);
 
-	flush_scheduled_work();
-
 	if (adapter->netdev_registered) {
 		unregister_netdev(netdev);
 		adapter->netdev_registered = false;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index ce31e74..02076e1 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2978,7 +2978,7 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
 	unregister_netdev(mp->dev);
 	if (mp->phy != NULL)
 		phy_detach(mp->phy);
-	flush_scheduled_work();
+	cancel_work_sync(&mp->tx_timeout_task);
 	free_netdev(mp->dev);
 
 	platform_set_drvdata(pdev, NULL);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 8524cc4..1ce0207 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -4067,7 +4067,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
 	if (mgp == NULL)
 		return;
 
-	flush_scheduled_work();
+	cancel_work_sync(&mgp->watchdog_work);
 	netdev = mgp->dev;
 	unregister_netdev(netdev);
 
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 781e368..f64c424 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -9917,7 +9917,7 @@ static int niu_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (!netif_running(dev))
 		return 0;
 
-	flush_scheduled_work();
+	flush_work_sync(&np->reset_task);
 	niu_netif_stop(np);
 
 	del_timer_sync(&np->timer);
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
index 04ed27d..1b63c8a 100644
--- a/drivers/net/pxa168_eth.c
+++ b/drivers/net/pxa168_eth.c
@@ -1602,7 +1602,7 @@ static int pxa168_eth_remove(struct platform_device *pdev)
 	mdiobus_unregister(pep->smi_bus);
 	mdiobus_free(pep->smi_bus);
 	unregister_netdev(dev);
-	flush_scheduled_work();
+	cancel_work_sync(&pep->tx_timeout_task);
 	free_netdev(dev);
 	platform_set_drvdata(pdev, NULL);
 	return 0;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7d33ef4..98d792c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3240,7 +3240,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	flush_scheduled_work();
+	cancel_delayed_work_sync(&tp->task);
 
 	unregister_netdev(dev);
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9a1e32f..39c17ce 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -8341,9 +8341,11 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 		return;
 	}
 
-	flush_scheduled_work();
-
 	sp = netdev_priv(dev);
+
+	cancel_work_sync(&sp->rst_timer_task);
+	cancel_work_sync(&sp->set_link_task);
+
 	unregister_netdev(dev);
 
 	free_shared_mem(sp);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index a5d6a6b..3406ed8 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1915,9 +1915,10 @@ err_release_board:
 static void __devexit sis190_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+	struct sis190_private *tp = netdev_priv(dev);
 
 	sis190_mii_remove(dev);
-	flush_scheduled_work();
+	cancel_work_sync(&tp->phy_task);
 	unregister_netdev(dev);
 	sis190_release_board(pdev);
 	pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 5faa87d..57e19fb 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -15034,7 +15034,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
 		if (tp->fw)
 			release_firmware(tp->fw);
 
-		flush_scheduled_work();
+		cancel_work_sync(&tp->reset_task);
 
 		if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 			tg3_phy_fini(tp);
@@ -15073,7 +15073,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (!netif_running(dev))
 		return 0;
 
-	flush_scheduled_work();
+	flush_work_sync(&tp->reset_task);
 	tg3_phy_stop(tp);
 	tg3_netif_stop(tp);
 
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index d1ac15c..ed1b432 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -802,10 +802,9 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
 
 	dev_dbg(&dev->udev->dev, "%s", __func__);
 
-	/* Kill the timer then flush the work queue */
+	/* kill the timer and work */
 	del_timer_sync(&priv->sync_timer);
-
-	flush_scheduled_work();
+	cancel_work_sync(&priv->sierra_net_kevent);
 
 	/* tell modem we are going away */
 	status = sierra_net_send_cmd(dev, priv->shdwn_msg,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index cff74b8..ed9a416 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1248,8 +1248,7 @@ void usbnet_disconnect (struct usb_interface *intf)
 	net = dev->net;
 	unregister_netdev (net);
 
-	/* we don't hold rtnl here ... */
-	flush_scheduled_work ();
+	cancel_work_sync(&dev->kevent);
 
 	if (dev->driver_info->unbind)
 		dev->driver_info->unbind (dev, intf);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index 65860a9..0169be7 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -3069,7 +3069,7 @@ vmxnet3_remove_device(struct pci_dev *pdev)
 #endif
 		num_rx_queues = 1;
 
-	flush_scheduled_work();
+	cancel_work_sync(&adapter->work);
 
 	unregister_netdev(netdev);
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 5/9] iseries_veth: don't use flush_scheduled_work()
From: Tejun Heo @ 2010-12-12 15:53 UTC (permalink / raw)
  To: linux-kernel, netdev, davem; +Cc: Tejun Heo, Santiago Leon
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

flush_scheduled_work() is on its way out.  Remove its usage from
iseries_veth.

* Cancelling a delayed work, queueing it for immediate execution if
  cancelled and then waiting for completion can be done by simply
  calling flush_delayed_work_sync().

* Explicitly cancel cnx->statemachine_wq on module unload.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Santiago Leon <santil@linux.vnet.ibm.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/iseries_veth.c |   18 ++++--------------
 1 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 63ac531..9ece1fd 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -885,17 +885,8 @@ static void veth_stop_connection(struct veth_lpar_connection *cnx)
 	veth_kick_statemachine(cnx);
 	spin_unlock_irq(&cnx->lock);
 
-	/* There's a slim chance the reset code has just queued the
-	 * statemachine to run in five seconds. If so we need to cancel
-	 * that and requeue the work to run now. */
-	if (cancel_delayed_work(&cnx->statemachine_wq)) {
-		spin_lock_irq(&cnx->lock);
-		veth_kick_statemachine(cnx);
-		spin_unlock_irq(&cnx->lock);
-	}
-
-	/* Wait for the state machine to run. */
-	flush_scheduled_work();
+	/* ensure the statemachine runs now and waits for its completion */
+	flush_delayed_work_sync(&cnx->statemachine_wq);
 }
 
 static void veth_destroy_connection(struct veth_lpar_connection *cnx)
@@ -1653,15 +1644,14 @@ static void __exit veth_module_cleanup(void)
 	/* Disconnect our "irq" to stop events coming from the Hypervisor. */
 	HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
 
-	/* Make sure any work queued from Hypervisor callbacks is finished. */
-	flush_scheduled_work();
-
 	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
 		cnx = veth_cnx[i];
 
 		if (!cnx)
 			continue;
 
+		/* Cancel work queued from Hypervisor callbacks */
+		cancel_delayed_work_sync(&cnx->statemachine_wq);
 		/* Remove the connection from sysfs */
 		kobject_del(&cnx->kobject);
 		/* Drop the driver's reference to the connection */
-- 
1.7.1


^ permalink raw reply related

* [PATCH 6/9] igb[v],ixgbe: don't use flush_scheduled_work()
From: Tejun Heo @ 2010-12-12 15:53 UTC (permalink / raw)
  To: linux-kernel, netdev, davem; +Cc: Tejun Heo, e1000-devel
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

All three drivers use flush_scheduled_work() similarly during driver
detach.  Replace it with explicit cancels.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: e1000-devel@lists.sourceforge.net
Cc: netdev@vger.kernel.org
---
 drivers/net/igb/igb_main.c     |    9 ++++++---
 drivers/net/igbvf/netdev.c     |    7 ++++---
 drivers/net/ixgbe/ixgbe_main.c |   11 +++++++----
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 041f8e6..62348fc 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2050,13 +2050,16 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	/* flush_scheduled work may reschedule our watchdog task, so
-	 * explicitly disable watchdog tasks from being rescheduled  */
+	/*
+	 * The watchdog timer may be rescheduled, so explicitly
+	 * disable watchdog from being rescheduled.
+	 */
 	set_bit(__IGB_DOWN, &adapter->state);
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
-	flush_scheduled_work();
+	cancel_work_sync(&adapter->reset_task);
+	cancel_work_sync(&adapter->watchdog_task);
 
 #ifdef CONFIG_IGB_DCA
 	if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 8dbde23..4fb023b 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -2825,13 +2825,14 @@ static void __devexit igbvf_remove(struct pci_dev *pdev)
 	struct e1000_hw *hw = &adapter->hw;
 
 	/*
-	 * flush_scheduled work may reschedule our watchdog task, so
-	 * explicitly disable watchdog tasks from being rescheduled
+	 * The watchdog timer may be rescheduled, so explicitly
+	 * disable it from being rescheduled.
 	 */
 	set_bit(__IGBVF_DOWN, &adapter->state);
 	del_timer_sync(&adapter->watchdog_timer);
 
-	flush_scheduled_work();
+	cancel_work_sync(&adapter->reset_task);
+	cancel_work_sync(&adapter->watchdog_task);
 
 	unregister_netdev(netdev);
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 8af0fc0..ca9036d 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -7373,13 +7373,15 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 	struct net_device *netdev = adapter->netdev;
 
 	set_bit(__IXGBE_DOWN, &adapter->state);
-	/* clear the module not found bit to make sure the worker won't
-	 * reschedule
+
+	/*
+	 * The timers may be rescheduled, so explicitly disable them
+	 * from being rescheduled.
 	 */
 	clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
 	del_timer_sync(&adapter->watchdog_timer);
-
 	del_timer_sync(&adapter->sfp_timer);
+
 	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->sfp_task);
 	cancel_work_sync(&adapter->multispeed_fiber_task);
@@ -7387,7 +7389,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
 	    adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
 		cancel_work_sync(&adapter->fdir_reinit_task);
-	flush_scheduled_work();
+	if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
+		cancel_work_sync(&adapter->check_overtemp_task);
 
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
-- 
1.7.1


^ permalink raw reply related

* [PATCH 8/9] i2400m: drop i2400m_schedule_work()
From: Tejun Heo @ 2010-12-12 15:53 UTC (permalink / raw)
  To: linux-kernel, netdev, davem; +Cc: Tejun Heo, Inaky Perez-Gonzalez, linux-wimax
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

i2400m implements dynamic work allocation and queueing mechanism in
i2400_schedule_work(); however, this is only used for reset and
recovery which can be served equally well with preallocated per device
works.

Replace i2400m_schedule_work() with two work structs in struct i2400m.
These works are explicitly canceled when the device is released making
calls to flush_scheduled_work(), which is being deprecated,
unnecessary.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
Cc: linux-wimax@intel.com
Cc: netdev@vger.kernel.org
---
 drivers/net/wimax/i2400m/driver.c |   96 ++++++------------------------------
 drivers/net/wimax/i2400m/i2400m.h |   19 ++-----
 drivers/net/wimax/i2400m/sdio.c   |    1 -
 drivers/net/wimax/i2400m/usb.c    |    1 -
 4 files changed, 21 insertions(+), 96 deletions(-)

diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index cdedab4..f060332 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -92,54 +92,6 @@ MODULE_PARM_DESC(barkers,
 		 "signal; values are appended to a list--setting one value "
 		 "as zero cleans the existing list and starts a new one.");
 
-static
-struct i2400m_work *__i2400m_work_setup(
-	struct i2400m *i2400m, void (*fn)(struct work_struct *),
-	gfp_t gfp_flags, const void *pl, size_t pl_size)
-{
-	struct i2400m_work *iw;
-
-	iw = kzalloc(sizeof(*iw) + pl_size, gfp_flags);
-	if (iw == NULL)
-		return NULL;
-	iw->i2400m = i2400m_get(i2400m);
-	iw->pl_size = pl_size;
-	memcpy(iw->pl, pl, pl_size);
-	INIT_WORK(&iw->ws, fn);
-	return iw;
-}
-
-
-/*
- * Schedule i2400m's specific work on the system's queue.
- *
- * Used for a few cases where we really need it; otherwise, identical
- * to i2400m_queue_work().
- *
- * Returns < 0 errno code on error, 1 if ok.
- *
- * If it returns zero, something really bad happened, as it means the
- * works struct was already queued, but we have just allocated it, so
- * it should not happen.
- */
-static int i2400m_schedule_work(struct i2400m *i2400m,
-			 void (*fn)(struct work_struct *), gfp_t gfp_flags,
-			 const void *pl, size_t pl_size)
-{
-	int result;
-	struct i2400m_work *iw;
-
-	result = -ENOMEM;
-	iw = __i2400m_work_setup(i2400m, fn, gfp_flags, pl, pl_size);
-	if (iw != NULL) {
-		result = schedule_work(&iw->ws);
-		if (WARN_ON(result == 0))
-			result = -ENXIO;
-	}
-	return result;
-}
-
-
 /*
  * WiMAX stack operation: relay a message from user space
  *
@@ -648,17 +600,11 @@ EXPORT_SYMBOL_GPL(i2400m_post_reset);
 static
 void __i2400m_dev_reset_handle(struct work_struct *ws)
 {
-	int result;
-	struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
-	const char *reason;
-	struct i2400m *i2400m = iw->i2400m;
+	struct i2400m *i2400m = container_of(ws, struct i2400m, reset_ws);
+	const char *reason = i2400m->reset_reason;
 	struct device *dev = i2400m_dev(i2400m);
 	struct i2400m_reset_ctx *ctx = i2400m->reset_ctx;
-
-	if (WARN_ON(iw->pl_size != sizeof(reason)))
-		reason = "SW BUG: reason n/a";
-	else
-		memcpy(&reason, iw->pl, sizeof(reason));
+	int result;
 
 	d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason);
 
@@ -733,8 +679,6 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
 		}
 	}
 out:
-	i2400m_put(i2400m);
-	kfree(iw);
 	d_fnend(3, dev, "(ws %p i2400m %p reason %s) = void\n",
 		ws, i2400m, reason);
 }
@@ -754,8 +698,8 @@ out:
  */
 int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason)
 {
-	return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
-				    GFP_ATOMIC, &reason, sizeof(reason));
+	i2400m->reset_reason = reason;
+	return schedule_work(&i2400m->reset_ws);
 }
 EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
 
@@ -768,14 +712,9 @@ EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
 static
 void __i2400m_error_recovery(struct work_struct *ws)
 {
-	struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
-	struct i2400m *i2400m = iw->i2400m;
+	struct i2400m *i2400m = container_of(ws, struct i2400m, recovery_ws);
 
 	i2400m_reset(i2400m, I2400M_RT_BUS);
-
-	i2400m_put(i2400m);
-	kfree(iw);
-	return;
 }
 
 /*
@@ -805,18 +744,10 @@ void __i2400m_error_recovery(struct work_struct *ws)
  */
 void i2400m_error_recovery(struct i2400m *i2400m)
 {
-	struct device *dev = i2400m_dev(i2400m);
-
-	if (atomic_add_return(1, &i2400m->error_recovery) == 1) {
-		if (i2400m_schedule_work(i2400m, __i2400m_error_recovery,
-			GFP_ATOMIC, NULL, 0) < 0) {
-			dev_err(dev, "run out of memory for "
-				"scheduling an error recovery ?\n");
-			atomic_dec(&i2400m->error_recovery);
-		}
-	} else
+	if (atomic_add_return(1, &i2400m->error_recovery) == 1)
+		schedule_work(&i2400m->recovery_ws);
+	else
 		atomic_dec(&i2400m->error_recovery);
-	return;
 }
 EXPORT_SYMBOL_GPL(i2400m_error_recovery);
 
@@ -886,6 +817,10 @@ void i2400m_init(struct i2400m *i2400m)
 
 	mutex_init(&i2400m->init_mutex);
 	/* wake_tx_ws is initialized in i2400m_tx_setup() */
+
+	INIT_WORK(&i2400m->reset_ws, __i2400m_dev_reset_handle);
+	INIT_WORK(&i2400m->recovery_ws, __i2400m_error_recovery);
+
 	atomic_set(&i2400m->bus_reset_retries, 0);
 
 	i2400m->alive = 0;
@@ -1040,6 +975,9 @@ void i2400m_release(struct i2400m *i2400m)
 
 	i2400m_dev_stop(i2400m);
 
+	cancel_work_sync(&i2400m->reset_ws);
+	cancel_work_sync(&i2400m->recovery_ws);
+
 	i2400m_debugfs_rm(i2400m);
 	sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
 			   &i2400m_dev_attr_group);
@@ -1083,8 +1021,6 @@ module_init(i2400m_driver_init);
 static
 void __exit i2400m_driver_exit(void)
 {
-	/* for scheds i2400m_dev_reset_handle() */
-	flush_scheduled_work();
 	i2400m_barker_db_exit();
 }
 module_exit(i2400m_driver_exit);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 59ac770..17ecaa4 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -632,6 +632,11 @@ struct i2400m {
 	struct work_struct wake_tx_ws;
 	struct sk_buff *wake_tx_skb;
 
+	struct work_struct reset_ws;
+	const char *reset_reason;
+
+	struct work_struct recovery_ws;
+
 	struct dentry *debugfs_dentry;
 	const char *fw_name;		/* name of the current firmware image */
 	unsigned long fw_version;	/* version of the firmware interface */
@@ -896,20 +901,6 @@ struct device *i2400m_dev(struct i2400m *i2400m)
 	return i2400m->wimax_dev.net_dev->dev.parent;
 }
 
-/*
- * Helper for scheduling simple work functions
- *
- * This struct can get any kind of payload attached (normally in the
- * form of a struct where you pack the stuff you want to pass to the
- * _work function).
- */
-struct i2400m_work {
-	struct work_struct ws;
-	struct i2400m *i2400m;
-	size_t pl_size;
-	u8 pl[0];
-};
-
 extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *,
 				   char *, size_t);
 extern int i2400m_msg_size_check(struct i2400m *,
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 9bfc26e..be428ca 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -590,7 +590,6 @@ module_init(i2400ms_driver_init);
 static
 void __exit i2400ms_driver_exit(void)
 {
-	flush_scheduled_work();	/* for the stuff we schedule */
 	sdio_unregister_driver(&i2400m_sdio_driver);
 }
 module_exit(i2400ms_driver_exit);
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index d3365ac..10e3ab3 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -780,7 +780,6 @@ module_init(i2400mu_driver_init);
 static
 void __exit i2400mu_driver_exit(void)
 {
-	flush_scheduled_work();	/* for the stuff we schedule from sysfs.c */
 	usb_deregister(&i2400mu_driver);
 }
 module_exit(i2400mu_driver_exit);
-- 
1.7.1


^ permalink raw reply related

* [PATCHSET] net-dev: don't use flush_scheduled_work()
From: Tejun Heo @ 2010-12-12 15:52 UTC (permalink / raw)
  To: linux-kernel, netdev, davem

Hello,

This patchset removes the use of flush_scheduled_work(), which is
being deprecated, from various network drivers.  It contains the
following nine patches.

 0001-drivers-net-remove-unnecessary-flush_scheduled_work-.patch
 0002-drivers-net-don-t-use-flush_scheduled_work.patch
 0003-ehea-kill-unused-ehea_rereg_mr_task.patch
 0004-ehea-don-t-use-flush_scheduled_work.patch
 0005-iseries_veth-don-t-use-flush_scheduled_work.patch
 0006-igb-v-ixgbe-don-t-use-flush_scheduled_work.patch
 0007-sungem-update-gp-reset_task-flushing.patch
 0008-i2400m-drop-i2400m_schedule_work.patch
 0009-hostap-don-t-use-flush_scheduled_work.patch

0001 and 0002 are straight forward conversions across multiple network
drivers.  The rest are a bit more involved per-driver or driver family
conversions.

This patchset is on top of the current net-next-2.6.git#master
(ad1184c6cf067a13e8cb2a4e7ccc407f947027d0) and available in the
following git branch.

 git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git net-dev-kill-flush_scheduled_work

diffstat follows.  Thanks.

 drivers/net/8139too.c                   |    3 -
 drivers/net/atlx/atl2.c                 |    4 -
 drivers/net/bcm63xx_enet.c              |    2 
 drivers/net/bnx2.c                      |    4 -
 drivers/net/can/janz-ican3.c            |    9 ---
 drivers/net/cassini.c                   |    4 -
 drivers/net/cxgb3/cxgb3_main.c          |    3 -
 drivers/net/e1000e/netdev.c             |    6 +-
 drivers/net/ehea/ehea.h                 |    2 
 drivers/net/ehea/ehea_main.c            |   14 +---
 drivers/net/enic/enic_main.c            |    2 
 drivers/net/ibm_newemac/core.c          |    2 
 drivers/net/igb/igb_main.c              |    9 ++-
 drivers/net/igbvf/netdev.c              |    7 +-
 drivers/net/irda/mcs7780.c              |    2 
 drivers/net/iseries_veth.c              |   18 +-----
 drivers/net/ixgb/ixgb_main.c            |    2 
 drivers/net/ixgbe/ixgbe_main.c          |   11 ++-
 drivers/net/ixgbevf/ixgbevf_main.c      |    3 -
 drivers/net/mv643xx_eth.c               |    2 
 drivers/net/myri10ge/myri10ge.c         |    2 
 drivers/net/niu.c                       |    2 
 drivers/net/pxa168_eth.c                |    2 
 drivers/net/r8169.c                     |    2 
 drivers/net/s2io.c                      |    6 +-
 drivers/net/sh_eth.c                    |    1 
 drivers/net/sh_eth.h                    |    1 
 drivers/net/sis190.c                    |    3 -
 drivers/net/skge.c                      |    2 
 drivers/net/sungem.c                    |   12 +---
 drivers/net/tg3.c                       |    4 -
 drivers/net/usb/sierra_net.c            |    5 -
 drivers/net/usb/usbnet.c                |    3 -
 drivers/net/vmxnet3/vmxnet3_drv.c       |    2 
 drivers/net/vxge/vxge-main.c            |    2 
 drivers/net/wimax/i2400m/driver.c       |   96 +++++---------------------------
 drivers/net/wimax/i2400m/i2400m.h       |   19 +-----
 drivers/net/wimax/i2400m/sdio.c         |    1 
 drivers/net/wimax/i2400m/usb.c          |    1 
 drivers/net/wireless/hostap/hostap_ap.c |    3 +
 drivers/net/wireless/hostap/hostap_hw.c |    8 ++
 41 files changed, 97 insertions(+), 189 deletions(-)

--
tejun

^ permalink raw reply

* [PATCH 9/9] hostap: don't use flush_scheduled_work()
From: Tejun Heo @ 2010-12-12 15:53 UTC (permalink / raw)
  To: linux-kernel, netdev, davem; +Cc: Tejun Heo, Jes Sorensen
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

flush_scheduled_work() is on its way out.  Drop flush_scheduled_work()
from prism2_free_local_data() and replace it with explicit flushing of
work items on the respective free functions.  Work items in ap_data
are flushed from hostap_free_data() and the ones in local_info from
prism2_free_local_data().

Flush is used instead of cancel as some process and free items from
queue.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jes Sorensen <jes@trained-monkey.org>
Cc: netdev@vger.kernel.org
---
 drivers/net/wireless/hostap/hostap_ap.c |    3 +++
 drivers/net/wireless/hostap/hostap_hw.c |    8 +++++++-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index dbb9869..18d63f5 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -858,7 +858,10 @@ void hostap_free_data(struct ap_data *ap)
 		return;
 	}
 
+	flush_work_sync(&ap->add_sta_proc_queue);
+
 #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
+	flush_work_sync(&ap->wds_oper_queue);
 	if (ap->crypt)
 		ap->crypt->deinit(ap->crypt_priv);
 	ap->crypt = ap->crypt_priv = NULL;
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index b7cb165..a8bddd8 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3317,7 +3317,13 @@ static void prism2_free_local_data(struct net_device *dev)
 
 	unregister_netdev(local->dev);
 
-	flush_scheduled_work();
+	flush_work_sync(&local->reset_queue);
+	flush_work_sync(&local->set_multicast_list_queue);
+	flush_work_sync(&local->set_tim_queue);
+#ifndef PRISM2_NO_STATION_MODES
+	flush_work_sync(&local->info_queue);
+#endif
+	flush_work_sync(&local->comms_qual_update);
 
 	lib80211_crypt_info_free(&local->crypt_info);
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 7/9] sungem: update gp->reset_task flushing
From: Tejun Heo @ 2010-12-12 15:53 UTC (permalink / raw)
  To: linux-kernel, netdev, davem; +Cc: Tejun Heo
In-Reply-To: <1292169185-10579-1-git-send-email-tj@kernel.org>

gp->reset_task_pending is always set right before reset_task is
scheduled and as there is no synchronization between the setting and
scheduling, busy looping on reset_task_pending before flushing
reset_task doesn't really buy anything.

Directly flush gp->reset_task on suspend and cancel on detach.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
---
 drivers/net/sungem.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 4ceb3cf..9e992ca 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2380,10 +2380,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 	 */
 	mutex_unlock(&gp->pm_mutex);
 
-	/* Wait for a pending reset task to complete */
-	while (gp->reset_task_pending)
-		yield();
-	flush_scheduled_work();
+	/* Wait for the pending reset task to complete */
+	flush_work_sync(&gp->reset_task);
 
 	/* Shut the PHY down eventually and setup WOL */
 	gem_stop_phy(gp, gp->asleep_wol);
@@ -2928,10 +2926,8 @@ static void gem_remove_one(struct pci_dev *pdev)
 		/* We shouldn't need any locking here */
 		gem_get_cell(gp);
 
-		/* Wait for a pending reset task to complete */
-		while (gp->reset_task_pending)
-			yield();
-		flush_scheduled_work();
+		/* Cancel reset task */
+		cancel_work_sync(&gp->reset_task);
 
 		/* Shut the PHY down */
 		gem_stop_phy(gp, 0);
-- 
1.7.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox