* [PATCH] move am79c961's probe function to .devinit.text
From: Uwe Kleine-König @ 2009-07-11 20:52 UTC (permalink / raw)
To: Greg KH, linux-kernel; +Cc: Roel Kluin, Russell King, netdev, Andrew Morton
In-Reply-To: <1247345591-22643-1-git-send-email-u.kleine-koenig@pengutronix.de>
A pointer to am79c961_probe is passed to the core via
platform_driver_register and so the function must not disappear when the
.init sections are discarded. Otherwise (if also having HOTPLUG=y)
unbinding and binding a device to the driver via sysfs will result in an
oops as does a device being registered late.
An alternative to this patch is using platform_driver_probe instead of
platform_driver_register plus removing the pointer to the probe function
from the struct platform_driver.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Cc: Roel Kluin <12o3l@tiscali.nl>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: netdev@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>
---
drivers/net/arm/am79c961a.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 627bc75..51b19f2 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -680,7 +680,7 @@ static const struct net_device_ops am79c961_netdev_ops = {
#endif
};
-static int __init am79c961_probe(struct platform_device *pdev)
+static int __devinit am79c961_probe(struct platform_device *pdev)
{
struct resource *res;
struct net_device *dev;
--
1.6.3.1
^ permalink raw reply related
* Re: [PATCH] pcnet_cs: add odd location support for write_asic function
From: Ken Kawasaki @ 2009-07-11 22:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20090710.202609.57274545.davem@davemloft.net>
On Fri, 10 Jul 2009 20:26:09 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:
>
> > Currently, no one passes odd location to the write_asic function.
> > But this patch add odd location support for future usage of this
> > feature.
> >
> >
> > Signed-off-by: Ken Kawasaki <ken_kawasaki@spring.nifty.jp>
>
> "Who" in the future will use this feature and why do they
> need it?
>
> Ideally, you should submit this patch at the same time as
> the other patch which adds a need for it.
OK.
Thanks.
^ permalink raw reply
* Re: [PATCH] net: ip_push_pending_frames() fix
From: David Miller @ 2009-07-12 3:27 UTC (permalink / raw)
To: eric.dumazet
Cc: emil.s.tantilov, emils.tantilov, netdev, jesse.brandeburg,
jeffrey.t.kirsher, jolsa
In-Reply-To: <4A5537DA.1060200@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 09 Jul 2009 02:20:42 +0200
> [PATCH] net: ip_push_pending_frames() fix
>
> After commit 2b85a34e911bf483c27cfdd124aeb1605145dc80
> (net: No more expensive sock_hold()/sock_put() on each tx)
> we do not take any more references on sk->sk_refcnt on outgoing packets.
>
> I forgot to delete two __sock_put() from ip_push_pending_frames()
> and ip6_push_pending_frames().
>
> Reported-by: Emil S Tantilov <emils.tantilov@gmail.com>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, with the Tested-by marker added.
^ permalink raw reply
* Re: [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
From: David Miller @ 2009-07-12 3:27 UTC (permalink / raw)
To: eric.dumazet
Cc: emil.s.tantilov, emils.tantilov, netdev, jesse.brandeburg,
jeffrey.t.kirsher, jolsa, kaber, paulmck
In-Reply-To: <4A5581C5.5070409@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 09 Jul 2009 07:36:05 +0200
> [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
>
> Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code correctness
> depends on sk->sk_nulls_node.next being always valid. A NULL
> value is not allowed as it might fault a lockless reader.
>
> Current sk_prot_alloc() implementation doesnt respect this hypothesis,
> calling kmem_cache_alloc() with __GFP_ZERO. Just call memset() around
> the forbidden field.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
APplied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH] sit: fix regression: do not release skb->dst before xmit
From: David Miller @ 2009-07-12 3:31 UTC (permalink / raw)
To: eric.dumazet; +Cc: contact, netdev, berni
In-Reply-To: <4A58927F.7040405@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sat, 11 Jul 2009 15:24:15 +0200
> Sascha Hlusiak a écrit :
>> The sit module makes use of skb->dst in it's xmit function,
>> so since 93f154b594fe47 sit tunnels are broken, because the
>> flag IFF_XMIT_DST_RELEASE is not unset.
>>
>> This patch unsets that flag for sit devices to fix this
>> regression.
>>
>> Signed-off-by: Sascha Hlusiak <contact@saschahlusiak.de>
>
> Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks.
^ permalink raw reply
* multiqueue talk in NYC on July 15th
From: David Miller @ 2009-07-12 3:33 UTC (permalink / raw)
To: netdev
If you're in the New York area on July 15th (a Wednesday)
I'll be giving a presentation on multiqueue networking at
the monthly NYLUG meeting held at the IBM building in
midtown.
Details are at http://www.nylug.org/
Note that you must RSVP in order to attend or you won't
be allowed into the building.
^ permalink raw reply
* [PATCH] sky2: Avoid races in sky2_down
From: Mike McCormack @ 2009-07-12 5:28 UTC (permalink / raw)
To: netdev, shemminger
In-Reply-To: <392fb48f0907072016i14cd650fv3524b345c79e498d@mail.gmail.com>
Hi Stephen,
Resending with sign off. (You may have this in your tree already, but
just in case...)
I ran some overnight tests with this patch in, and my machine manages
to stay up all night, where it crashed within minutes before.
Mike
---
Reset rx chain before trying to drain it.
Shut interrupts off last, incase there's something to report.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index daf961a..23a26d6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1825,12 +1825,6 @@ static int sky2_down(struct net_device *dev)
if (netif_msg_ifdown(sky2))
printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
- /* Disable port IRQ */
- imask = sky2_read32(hw, B0_IMSK);
- imask &= ~portirq_msk[port];
- sky2_write32(hw, B0_IMSK, imask);
- sky2_read32(hw, B0_IMSK);
-
/* Force flow control off */
sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
@@ -1870,8 +1864,6 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
- sky2_rx_stop(sky2);
-
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
@@ -1881,6 +1873,14 @@ static int sky2_down(struct net_device *dev)
sky2_write32(hw, STAT_ISR_TIMER_CNT, 0);
sky2_read8(hw, STAT_ISR_TIMER_CTRL);
+ sky2_rx_stop(sky2);
+
+ /* Disable port IRQ */
+ imask = sky2_read32(hw, B0_IMSK);
+ imask &= ~portirq_msk[port];
+ sky2_write32(hw, B0_IMSK, imask);
+ sky2_read32(hw, B0_IMSK);
+
synchronize_irq(hw->pdev->irq);
napi_synchronize(&hw->napi);
--
1.5.6.5
^ permalink raw reply related
* [PATCH] sky2: endianness fix
From: Mike McCormack @ 2009-07-12 5:31 UTC (permalink / raw)
To: netdev, Stephen Hemminger
Hi Stephen,
This patch was prompted by code review.
Mike
---
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 23a26d6..21ec0ca 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4068,7 +4068,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
idx = RING_NEXT(idx, STATUS_RING_SIZE)) {
const struct sky2_status_le *le = hw->st_le + idx;
seq_printf(seq, "[%d] %#x %d %#x\n",
- idx, le->opcode, le->length, le->status);
+ idx, le->opcode, le16_to_cpu(le->length), le32_to_cpu(le->status));
}
seq_puts(seq, "\n");
}
--
1.5.6.5
^ permalink raw reply related
* [PATCH] sky2: Avoid transmitting during sky2_restart()
From: Mike McCormack @ 2009-07-12 5:39 UTC (permalink / raw)
To: netdev, Stephen Hemminger
Hi Stephen,
"ifconfig eth1 up; pktget eth1" will crashed my machine within 10
seconds. (eth1 is sky2)
It appears that sky2_tx_timeout causes a restart, and packets in the
tx queue are free'd twice (once in sky2_status_intr and once in
sky2_down).
Furthermore, if sky2_xmit_frame is called during sky2_restart, bad
things will happen.
This patch fixes both problems and was tested on top of my previous
sky2_down fix.
thanks,
Mike
---
Block the transmit queue during sky2_restart().
Don't free transmit packets in sky2_status_intr() during restart,
as they'll be free'd in sky2_tx_clean()
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 9 ++++++++-
drivers/net/sky2.h | 1 +
2 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 21ec0ca..77fd1b9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1540,6 +1540,8 @@ static inline int tx_dist(unsigned tail, unsigned head)
/* Number of list elements available for next tx */
static inline int tx_avail(const struct sky2_port *sky2)
{
+ if (unlikely(sky2->hw->flags & SKY2_HW_RESTARTING))
+ return 0;
return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
}
@@ -2366,7 +2368,8 @@ static inline void sky2_tx_done(struct
net_device *dev, u16 last)
{
struct sky2_port *sky2 = netdev_priv(dev);
- if (netif_running(dev)) {
+ if (netif_running(dev) &&
+ !(sky2->hw->flags & SKY2_HW_RESTARTING)) {
netif_tx_lock(dev);
sky2_tx_complete(sky2, last);
netif_tx_unlock(dev);
@@ -3081,6 +3084,7 @@ static void sky2_restart(struct work_struct *work)
int i, err;
rtnl_lock();
+ hw->flags |= SKY2_HW_RESTARTING;
for (i = 0; i < hw->ports; i++) {
dev = hw->dev[i];
if (netif_running(dev))
@@ -3092,6 +3096,7 @@ static void sky2_restart(struct work_struct *work)
sky2_reset(hw);
sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
napi_enable(&hw->napi);
+ hw->flags &= ~SKY2_HW_RESTARTING;
for (i = 0; i < hw->ports; i++) {
dev = hw->dev[i];
@@ -3102,6 +3107,8 @@ static void sky2_restart(struct work_struct *work)
dev->name, err);
dev_close(dev);
}
+ else
+ netif_wake_queue(dev);
}
}
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index b5549c9..e71c161 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2073,6 +2073,7 @@ struct sky2_hw {
#define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */
#define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */
#define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */
+#define SKY2_HW_RESTARTING 0x00000100 /* true while restarting */
u8 chip_id;
u8 chip_rev;
--
1.5.6.5
^ permalink raw reply related
* Re: [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
From: Eric Dumazet @ 2009-07-12 7:07 UTC (permalink / raw)
To: David Miller
Cc: emil.s.tantilov, emils.tantilov, netdev, jesse.brandeburg,
jeffrey.t.kirsher, jolsa, kaber, paulmck
In-Reply-To: <20090711.202727.18146102.davem@davemloft.net>
David Miller a écrit :
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Thu, 09 Jul 2009 07:36:05 +0200
>
>> [PATCH] net: sk_prot_alloc() should not blindly overwrite memory
>>
>> Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code correctness
>> depends on sk->sk_nulls_node.next being always valid. A NULL
>> value is not allowed as it might fault a lockless reader.
>>
>> Current sk_prot_alloc() implementation doesnt respect this hypothesis,
>> calling kmem_cache_alloc() with __GFP_ZERO. Just call memset() around
>> the forbidden field.
>>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>
> APplied and queued up for -stable.
I'll try to find some time to fix netfilter conntrack as well.
Thanks
^ permalink raw reply
* [PATCH] sky2: Kick the transmit watchdog timer on transmit
From: Mike McCormack @ 2009-07-12 9:42 UTC (permalink / raw)
To: netdev, Stephen Hemminger
Hi Stephen,
I was curious as to why sky2_tx_timeout() was being called once when
the driver started, and never again (which originally caused the crash
resolved by the previous patch).
I might be missing something, but it looks like we the transmit
watchdog needs to be kicked whenever a packet is transmitted.
This patch has had a small amount of testing, but reviewing other
drivers (e.g. net/atm/lec.c), this appears to be what is done.
thanks,
Mike
---
If we don't kick the watchdog, it always triggers.
Signed-off-by: Mike McCormack <mikem@ring3k.org>
---
drivers/net/sky2.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 77fd1b9..48d58ec 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1708,6 +1708,8 @@ static int sky2_xmit_frame(struct sk_buff *skb,
struct net_device *dev)
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
+ dev->trans_start = jiffies; /* restart tx timeout */
+
return NETDEV_TX_OK;
mapping_unwind:
--
1.5.6.5
^ permalink raw reply related
* Re: [PATCH] sky2: Kick the transmit watchdog timer on transmit
From: Mike McCormack @ 2009-07-12 12:09 UTC (permalink / raw)
To: netdev, Stephen Hemminger
In-Reply-To: <392fb48f0907120242r438411ccm5507998c3fcad877@mail.gmail.com>
Hi Stephen,
Ignore this. I was using 2.6.30 with the sky2 code from net-next-2.6,
and the core network core code changed (in cdd0db058d64f). I'll move
over to using net-next-2.6 and deal with the instability...
thanks,
Mike
2009/7/12 Mike McCormack <mikem@ring3k.org>:
> Hi Stephen,
>
> I was curious as to why sky2_tx_timeout() was being called once when
> the driver started, and never again (which originally caused the crash
> resolved by the previous patch).
>
> I might be missing something, but it looks like we the transmit
> watchdog needs to be kicked whenever a packet is transmitted.
>
> This patch has had a small amount of testing, but reviewing other
> drivers (e.g. net/atm/lec.c), this appears to be what is done.
>
> thanks,
>
> Mike
>
> ---
>
> If we don't kick the watchdog, it always triggers.
>
> Signed-off-by: Mike McCormack <mikem@ring3k.org>
> ---
> drivers/net/sky2.c | 2 ++
> 1 files changed, 2 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
> index 77fd1b9..48d58ec 100644
> --- a/drivers/net/sky2.c
> +++ b/drivers/net/sky2.c
> @@ -1708,6 +1708,8 @@ static int sky2_xmit_frame(struct sk_buff *skb,
> struct net_device *dev)
>
> sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
>
> + dev->trans_start = jiffies; /* restart tx timeout */
> +
> return NETDEV_TX_OK;
>
> mapping_unwind:
> --
> 1.5.6.5
>
^ permalink raw reply
* Re: [PATCH] sky2: Avoid transmitting during sky2_restart()
From: Stephen Hemminger @ 2009-07-12 17:18 UTC (permalink / raw)
To: Mike McCormack; +Cc: netdev
In-Reply-To: <392fb48f0907112239j4c85932cj3f5f180bb8507143@mail.gmail.com>
On Sun, 12 Jul 2009 14:39:29 +0900
Mike McCormack <mikem@ring3k.org> wrote:
> Hi Stephen,
>
> "ifconfig eth1 up; pktget eth1" will crashed my machine within 10
> seconds. (eth1 is sky2)
> It appears that sky2_tx_timeout causes a restart, and packets in the
> tx queue are free'd twice (once in sky2_status_intr and once in
> sky2_down).
> Furthermore, if sky2_xmit_frame is called during sky2_restart, bad
> things will happen.
>
> This patch fixes both problems and was tested on top of my previous
> sky2_down fix.
>
> thanks,
>
> Mike
This should be fixed by managing the queue properly, not
by using a state flag. I will correct the problem.
^ permalink raw reply
* NET: Fix locking issues in PPP, 6pack, mkiss and strip line disciplines.
From: Ralf Baechle @ 2009-07-12 17:27 UTC (permalink / raw)
To: David S. Miller, netdev
Cc: Guido Trentalancia, Paul Mackerras, Alan Cox, Andreas Koensgen,
linux-hams, Hans Albas PE1AYX
Guido Trentalancia reports:
I am trying to use the kiss driver in the Linux kernel that is being
shipped with Fedora 10 but unfortunately I get the following oops:
mkiss: AX.25 Multikiss, Hans Albas PE1AYX
mkiss: ax0: crc mode is auto.
ADDRCONF(NETDEV_CHANGE): ax0: link becomes ready
------------[ cut here ]------------
WARNING: at kernel/softirq.c:77 __local_bh_disable+0x2f/0x83() (Not
tainted)
[...]
unloaded: microcode]
Pid: 0, comm: swapper Not tainted 2.6.27.25-170.2.72.fc10.i686 #1
[<c042ddfb>] warn_on_slowpath+0x65/0x8b
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c04228b4>] ? __enqueue_entity+0xe3/0xeb
[<c042431e>] ? enqueue_entity+0x203/0x20b
[<c0424361>] ? enqueue_task_fair+0x3b/0x3f
[<c041f88c>] ? resched_task+0x3a/0x6e
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c06ab4e2>] ? _spin_lock_bh+0xb/0x16
[<c043255b>] __local_bh_disable+0x2f/0x83
[<c04325ba>] local_bh_disable+0xb/0xd
[<c06ab4e2>] _spin_lock_bh+0xb/0x16
[<f8b6f600>] mkiss_receive_buf+0x2fb/0x3a6 [mkiss]
[<c0572a30>] flush_to_ldisc+0xf7/0x198
[<c0572b12>] tty_flip_buffer_push+0x41/0x51
[<f89477f2>] ftdi_process_read+0x375/0x4ad [ftdi_sio]
[<f8947a5a>] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio]
[<c05d4bec>] usb_hcd_giveback_urb+0x63/0x93
[<c05ea290>] uhci_giveback_urb+0xe5/0x15f
[<c05eaabf>] uhci_scan_schedule+0x52e/0x767
[<c05f6288>] ? psmouse_handle_byte+0xc/0xe5
[<c054df78>] ? acpi_ev_gpe_detect+0xd6/0xe1
[<c05ec5b0>] uhci_irq+0x110/0x125
[<c05d4834>] usb_hcd_irq+0x40/0xa3
[<c0465313>] handle_IRQ_event+0x2f/0x64
[<c046642b>] handle_level_irq+0x74/0xbe
[<c04663b7>] ? handle_level_irq+0x0/0xbe
[<c0406e6e>] do_IRQ+0xc7/0xfe
[<c0405668>] common_interrupt+0x28/0x30
[<c056821a>] ? acpi_idle_enter_simple+0x162/0x19d
[<c0617f52>] cpuidle_idle_call+0x60/0x92
[<c0403c61>] cpu_idle+0x101/0x134
[<c069b1ba>] rest_init+0x4e/0x50
=======================
---[ end trace b7cc8076093467ad ]---
------------[ cut here ]------------
WARNING: at kernel/softirq.c:136 _local_bh_enable_ip+0x3d/0xc4()
[...]
Pid: 0, comm: swapper Tainted: G W 2.6.27.25-170.2.72.fc10.i686
[<c042ddfb>] warn_on_slowpath+0x65/0x8b
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c04228b4>] ? __enqueue_entity+0xe3/0xeb
[<c042431e>] ? enqueue_entity+0x203/0x20b
[<c0424361>] ? enqueue_task_fair+0x3b/0x3f
[<c041f88c>] ? resched_task+0x3a/0x6e
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c06ab4e2>] ? _spin_lock_bh+0xb/0x16
[<f8b6f642>] ? mkiss_receive_buf+0x33d/0x3a6 [mkiss]
[<c04325f9>] _local_bh_enable_ip+0x3d/0xc4
[<c0432688>] local_bh_enable_ip+0x8/0xa
[<c06ab54d>] _spin_unlock_bh+0x11/0x13
[<f8b6f642>] mkiss_receive_buf+0x33d/0x3a6 [mkiss]
[<c0572a30>] flush_to_ldisc+0xf7/0x198
[<c0572b12>] tty_flip_buffer_push+0x41/0x51
[<f89477f2>] ftdi_process_read+0x375/0x4ad [ftdi_sio]
[<f8947a5a>] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio]
[<c05d4bec>] usb_hcd_giveback_urb+0x63/0x93
[<c05ea290>] uhci_giveback_urb+0xe5/0x15f
[<c05eaabf>] uhci_scan_schedule+0x52e/0x767
[<c05f6288>] ? psmouse_handle_byte+0xc/0xe5
[<c054df78>] ? acpi_ev_gpe_detect+0xd6/0xe1
[<c05ec5b0>] uhci_irq+0x110/0x125
[<c05d4834>] usb_hcd_irq+0x40/0xa3
[<c0465313>] handle_IRQ_event+0x2f/0x64
[<c046642b>] handle_level_irq+0x74/0xbe
[<c04663b7>] ? handle_level_irq+0x0/0xbe
[<c0406e6e>] do_IRQ+0xc7/0xfe
[<c0405668>] common_interrupt+0x28/0x30
[<c056821a>] ? acpi_idle_enter_simple+0x162/0x19d
[<c0617f52>] cpuidle_idle_call+0x60/0x92
[<c0403c61>] cpu_idle+0x101/0x134
[<c069b1ba>] rest_init+0x4e/0x50
=======================
---[ end trace b7cc8076093467ad ]---
mkiss: ax0: Trying crc-smack
mkiss: ax0: Trying crc-flexnet
The issue was, that the locking code in mkiss was assuming it was only
ever being called in process or bh context but some tty drivers such as
the USB serial driver may call it in interrupt context. Fixed by
converting the involved locking code to use irq-safe locks.
Review of similar networking line disciplines shows that 6pack, both sync
and async PPP and STRIP have similar issues. The PPP ones are the most
interesting ones as half of the issue was sorted out as far back as 2004
in commit http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=2996d8deaeddd01820691a872550dc0cfba0c37d
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Reported-by: Guido Trentalancia <guido@trentalancia.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Andreas Koensgen <ajk@iehk.rwth-aachen.de>
Cc: Hans Albas PE1AYX <hans@esrac.ele.tue.nl>
---
drivers/net/hamradio/6pack.c | 10 ++++++----
drivers/net/hamradio/mkiss.c | 15 +++++++++------
drivers/net/ppp_async.c | 11 +++++++----
drivers/net/ppp_synctty.c | 11 +++++++----
drivers/net/wireless/strip.c | 39 ++++++++++++++++++++++++---------------
5 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 1551600..913a564 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -398,13 +398,14 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct sixpack *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
if (sp)
atomic_inc(&sp->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
return sp;
}
@@ -688,12 +689,13 @@ out:
*/
static void sixpack_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;
- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!sp)
return;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index fda2fc8..671257a 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -367,6 +367,7 @@ static void ax_changedmtu(struct mkiss *ax)
{
struct net_device *dev = ax->dev;
unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
+ unsigned long flags;
int len;
len = dev->mtu * 2;
@@ -392,7 +393,7 @@ static void ax_changedmtu(struct mkiss *ax)
return;
}
- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
oxbuff = ax->xbuff;
ax->xbuff = xbuff;
@@ -423,7 +424,7 @@ static void ax_changedmtu(struct mkiss *ax)
ax->mtu = dev->mtu + 73;
ax->buffsize = len;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
kfree(oxbuff);
kfree(orbuff);
@@ -704,13 +705,14 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct mkiss *mkiss_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
if (ax)
atomic_inc(&ax->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
return ax;
}
@@ -809,12 +811,13 @@ out:
static void mkiss_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;
- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ax)
return;
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 17c116b..1fd319b 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -132,13 +132,15 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct asyncppp *ap_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}
@@ -215,12 +217,13 @@ ppp_asynctty_open(struct tty_struct *tty)
static void
ppp_asynctty_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;
- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index aa3d39f..1b3f75f 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -182,13 +182,15 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct syncppp *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}
@@ -262,12 +264,13 @@ ppp_sync_open(struct tty_struct *tty)
static void
ppp_sync_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;
- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 38366a5..3d39f65 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -856,6 +856,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
unsigned char *orbuff = strip_info->rx_buff;
unsigned char *osbuff = strip_info->sx_buff;
unsigned char *otbuff = strip_info->tx_buff;
+ unsigned long flags;
if (new_mtu > MAX_SEND_MTU) {
printk(KERN_ERR
@@ -864,11 +865,11 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
if (!allocate_buffers(strip_info, new_mtu)) {
printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
strip_info->dev->name);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
return -ENOMEM;
}
@@ -892,7 +893,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
}
}
strip_info->tx_head = strip_info->tx_buff;
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
@@ -983,10 +984,13 @@ static void strip_seq_neighbours(struct seq_file *seq,
const MetricomNodeTable * table,
const char *title)
{
- /* We wrap this in a do/while loop, so if the table changes */
- /* while we're reading it, we just go around and try again. */
+ unsigned long flags;
struct timeval t;
+ /*
+ * We wrap this in a do/while loop, so if the table changes
+ * while we're reading it, we just go around and try again.
+ */
do {
int i;
t = table->timestamp;
@@ -995,9 +999,9 @@ static void strip_seq_neighbours(struct seq_file *seq,
for (i = 0; i < table->num_nodes; i++) {
MetricomNode node;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
node = table->node[i];
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
seq_printf(seq, " %s\n", node.c);
}
} while (table->timestamp.tv_sec != t.tv_sec
@@ -1536,6 +1540,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct strip *strip_info = netdev_priv(dev);
+ unsigned long flags;
if (!netif_running(dev)) {
printk(KERN_ERR "%s: xmit call when iface is down\n",
@@ -1574,11 +1579,11 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
strip_info->dev->name, sx_pps_count / 8);
}
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
strip_send(strip_info, skb);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
if (skb)
dev_kfree_skb(skb);
@@ -2263,12 +2268,13 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
{
struct strip *strip_info = tty->disc_data;
const unsigned char *end = cp + count;
+ unsigned long flags;
if (!strip_info || strip_info->magic != STRIP_MAGIC
|| !netif_running(strip_info->dev))
return;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
#if 0
{
struct timeval tv;
@@ -2335,7 +2341,7 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
cp++;
}
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
}
@@ -2523,9 +2529,11 @@ static void strip_dev_setup(struct net_device *dev)
static void strip_free(struct strip *strip_info)
{
- spin_lock_bh(&strip_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&strip_lock, flags);
list_del_rcu(&strip_info->list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
strip_info->magic = 0;
@@ -2539,6 +2547,7 @@ static void strip_free(struct strip *strip_info)
static struct strip *strip_alloc(void)
{
struct list_head *n;
+ unsigned long flags;
struct net_device *dev;
struct strip *strip_info;
@@ -2562,7 +2571,7 @@ static struct strip *strip_alloc(void)
strip_info->idle_timer.function = strip_IdleTask;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
rescan:
/*
* Search the list to find where to put our new entry
@@ -2581,7 +2590,7 @@ static struct strip *strip_alloc(void)
sprintf(dev->name, "st%ld", dev->base_addr);
list_add_tail_rcu(&strip_info->list, &strip_list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
return strip_info;
}
^ permalink raw reply related
* [PATCH 11/13] drivers/isdn: Drop unnecessary NULL test
From: Karsten Keil @ 2009-07-12 20:05 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev, David Miller, i4ldeveloper
In-Reply-To: <cover.1248546896.git.keil@b1-systems.de>
From: Julia Lawall <julia@diku.dk>
The result of container_of should not be NULL. In particular, in this case
the argument to the enclosing function has passed though INIT_WORK, which
dereferences it, implying that its container cannot be NULL.
A simplified version of the semantic patch that makes this change is as
follows:
(http://www.emn.fr/x-info/coccinelle/)
// <smpl>
@@
identifier fn,work,x,fld;
type T;
expression E1,E2;
statement S;
@@
static fn(struct work_struct *work) {
... when != work = E1
x = container_of(work,T,fld)
... when != x = E2
- if (x == NULL) S
...
}
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
---
drivers/isdn/hisax/amd7930_fn.c | 2 --
drivers/isdn/hisax/hfc_pci.c | 2 --
drivers/isdn/hisax/hfc_sx.c | 2 --
drivers/isdn/hisax/icc.c | 2 --
drivers/isdn/hisax/isac.c | 2 --
drivers/isdn/hisax/w6692.c | 2 --
6 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 341faf5..bf526a7 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -238,8 +238,6 @@ Amd7930_bh(struct work_struct *work)
container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
- if (!cs)
- return;
if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
if (cs->debug)
debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 3d337d9..d110a77 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1506,8 +1506,6 @@ hfcpci_bh(struct work_struct *work)
u_long flags;
// struct PStack *stptr;
- if (!cs)
- return;
if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
if (!cs->hw.hfcpci.nt_mode)
switch (cs->dc.hfcpci.ph_state) {
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index d92e8d6..419f87c 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -1255,8 +1255,6 @@ hfcsx_bh(struct work_struct *work)
container_of(work, struct IsdnCardState, tqueue);
u_long flags;
- if (!cs)
- return;
if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
if (!cs->hw.hfcsx.nt_mode)
switch (cs->dc.hfcsx.ph_state) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 682cac3..9aba646 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -83,8 +83,6 @@ icc_bh(struct work_struct *work)
container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
- if (!cs)
- return;
if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
if (cs->debug)
debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 07b1673..a19354d 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -86,8 +86,6 @@ isac_bh(struct work_struct *work)
container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
- if (!cs)
- return;
if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
if (cs->debug)
debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index bb1c8dd..c4d862c 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -105,8 +105,6 @@ W6692_bh(struct work_struct *work)
container_of(work, struct IsdnCardState, tqueue);
struct PStack *stptr;
- if (!cs)
- return;
if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
if (cs->debug)
debugl1(cs, "D-Channel Busy cleared");
--
1.6.0.2
^ permalink raw reply related
* Re: [patch 1/3] net: serialize hrtimer callback in sched_cbq
From: David Miller @ 2009-07-12 20:55 UTC (permalink / raw)
To: tglx; +Cc: netdev, linux-kernel, kaber, peterz
In-Reply-To: <20090709215606.526259917@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 09 Jul 2009 21:59:22 -0000
> The hrtimer callback cbq_undelay() is not serialized against
> cbq_ovl_delay(). That affects at least q->pmask and q->delay_timer.
>
> Lock it proper.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
The problems here are even much deeper than it appears.
First of all, I am to understand that hrtimers run from hardware
interrupt context, right? If so, all of these datastructures are
softirq safe only.
And it is not merely the immediate things you see being modified in
this hrtimer, such as ->pmask etc., it is also the q->active[]
pointers, the list state for the classes, just about everything in the
qdisc state is referenced in this hrtimer code path.
I wonder how many queer unexplainable bugs we see because of this.
What should probably happen is that the hrtimer merely fires off work
at software interrupt context (perhaps a tasklet or similar), and that
software interrupt code take the qdisc's root lock throughout it's
execution.
^ permalink raw reply
* Re: [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c
From: David Miller @ 2009-07-12 20:57 UTC (permalink / raw)
To: tglx; +Cc: netdev, linux-kernel, kaber, peterz
In-Reply-To: <20090709215455.703939259@linutronix.de>
From: Thomas Gleixner <tglx@linutronix.de>
Date: Thu, 09 Jul 2009 21:59:18 -0000
> While looking at the "Soft-Lockup/Race in networking in 2.6.31-rc1+195
> ( possibly caused by netem)" issue (http://lkml.org/lkml/2009/7/2/519)
> I noticed some serious problems in the hrtimer related code of
> net/sched/sched/sch_cbq.c.
>
> The following patch series addresses these.
>
> I'm not entirely sure whether patch [1/3] covers all possible
> concurrent modifications, but it fixes the most obvious ones. The
> remaining details are left to the networking experts.
>
> Patches [1/3] and [2/3] might be stable material as well.
I'm holding off on this entire set until we figure out what
to really do with the CBQ hrtimer situation. See my reply
to patch #1, thanks.
^ permalink raw reply
* Re: [PATCH] netlink: remove unused exports
From: David Miller @ 2009-07-12 21:17 UTC (permalink / raw)
To: johannes; +Cc: netdev, tgraf
In-Reply-To: <1247250726.29747.15.camel@johannes.local>
From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 10 Jul 2009 20:32:06 +0200
> I added those myself in commits b4ff4f04 and 84659eb5,
> but I see no reason now why they should be exported,
> only generic netlink uses them which cannot be modular.
>
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Applied.
^ permalink raw reply
* Re: [PATCH 0/4] generic netlink namespace awareness
From: David Miller @ 2009-07-12 21:17 UTC (permalink / raw)
To: johannes-cdvu00un1VgdHxzADdlk8Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, tgraf-G/eBtMaohhA,
ebiederm-aS9lmoZGLiVWk0Htik3J/w
In-Reply-To: <20090710195131.504091075-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
From: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
Date: Fri, 10 Jul 2009 21:51:31 +0200
> This patch series makes generic netlink network namespace
> aware, in some way, paving the way for making wireless
> completely netns aware (which I will submit to John's tree).
>
> The required changes are basically some preparations in
> core netlink, a change to make it possible to iterate net
> namespaces under just RCU (which may be useful elsewhere in
> the future), the actual genetlink patch and finally also
> exporting get_net_ns_by_pid() which wireless will need.
>
> The last patch (for get_net_ns_by_pid) could go through
> the wireless tree as well, but I've put it in here since
> it touches core code. The others probably shouldn't go
> through the wireless tree since they touch more than that.
>
> The first patch in this series fixes the last remaining
> problem I had with the generic netlink one, the patches
> are actually unchanged from the previous submission other
> than adding patch 1 in front.
Looks good, all applied, thanks!
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] netdev: restore MAC address set and validate operations
From: David Miller @ 2009-07-12 21:21 UTC (permalink / raw)
To: ben; +Cc: shemminger, stable, 536455, netdev
In-Reply-To: <1247198075.21924.129.camel@deadeye>
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 10 Jul 2009 04:54:35 +0100
> alloc_etherdev() used to install default implementations of these
> operations, but they must now be explicitly installed in struct
> net_device_ops.
>
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Applied.
^ permalink raw reply
* Re: [PATCH 2/2] netdev: restore MTU change operation
From: David Miller @ 2009-07-12 21:21 UTC (permalink / raw)
To: ben; +Cc: shemminger, stable, netdev
In-Reply-To: <1247198254.21924.132.camel@deadeye>
From: Ben Hutchings <ben@decadent.org.uk>
Date: Fri, 10 Jul 2009 04:57:34 +0100
> alloc_etherdev() used to install a default implementation of this
> operation, but it must now be explicitly installed in struct
> net_device_ops.
Applied, thanks Ben!
^ permalink raw reply
* [PATCH] atl1c: add missing parentheses
From: Roel Kluin @ 2009-07-12 21:40 UTC (permalink / raw)
To: jcliburn; +Cc: atl1-devel, Andrew Morton, netdev
Parentheses are required or the comparison occurs before the bitand.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
#include <stdio.h>
int main()
{
printf("0 & 1 == 0: %u\n", 0 & 1 == 0);
printf("1 & 1 == 0: %u\n", 1 & 1 == 0);
printf("(0 & 1) == 0: %u\n", (0 & 1) == 0);
printf("(1 & 1) == 0: %u\n", (1 & 1) == 0);
return 0;
}
output:
0 & 1 == 0: 0
1 & 1 == 0: 0
(0 & 1) == 0: 1
(1 & 1) == 0: 0
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h
index e1658ef..2a1120a 100644
--- a/drivers/net/atl1c/atl1c.h
+++ b/drivers/net/atl1c/atl1c.h
@@ -188,14 +188,14 @@ struct atl1c_tpd_ext_desc {
#define RRS_HDS_TYPE_DATA 2
#define RRS_IS_NO_HDS_TYPE(flag) \
- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0)
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
#define RRS_IS_HDS_HEAD(flag) \
- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_HEAD)
#define RRS_IS_HDS_DATA(flag) \
- (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+ ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_DATA)
/* rrs word 3 bit 0:31 */
@@ -245,7 +245,7 @@ struct atl1c_tpd_ext_desc {
#define RRS_PACKET_TYPE_802_3 1
#define RRS_PACKET_TYPE_ETH 0
#define RRS_PACKET_IS_ETH(word) \
- (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \
+ ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
RRS_PACKET_TYPE_ETH)
#define RRS_RXD_IS_VALID(word) \
((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
^ permalink raw reply related
* Re: [PATCH net-next-2.6 0/5] Add support for software UDP fragmentation offload(UFO)
From: David Miller @ 2009-07-12 21:39 UTC (permalink / raw)
To: herbert; +Cc: sri, netdev
In-Reply-To: <20090710010405.GA32639@gondor.apana.org.au>
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 10 Jul 2009 09:04:05 +0800
> On Thu, Jul 09, 2009 at 11:09:41AM -0700, Sridhar Samudrala wrote:
>> The following set of patches fixes support for UDP fragmentation offload
>> in the core networking stack to send/receive large UDP packets over UFO
>> enabled devices and fallback to software UFO when the outgoing device
>> doesn't support UFO.
>> These patches enable setting UFO on virtio-net and tap devices and allow
>> large UDP packets to be sent between guest to host and inter guest under
>> KVM.
>>
>> [PATCH net-next-2.6 1/5] udpv4: Handle large incoming UDP/IPv4 packets and support software UFO.
>> [PATCH net-next-2.6 2/5] udpv6: Fix HW checksum support for outgoing UFO packets
>> [PATCH net-next-2.6 3/5] udpv6: Fix gso_size setting in ip6_ufo_append_data
>> [PATCH net-next-2.6 4/5] udpv6: Remove unused skb argument of ipv6_select_ident()
>> [PATCH net-next-2.6 5/5] udpv6: Handle large incoming UDP/IPv6 packets and support software UFO
>
> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Looks good to me, all applied, thanks!
^ permalink raw reply
* Re: [PATCH] atl1c: add missing parentheses
From: David Miller @ 2009-07-12 21:40 UTC (permalink / raw)
To: roel.kluin; +Cc: jcliburn, atl1-devel, akpm, netdev
In-Reply-To: <4A5A5852.4010901@gmail.com>
From: Roel Kluin <roel.kluin@gmail.com>
Date: Sun, 12 Jul 2009 23:40:34 +0200
> Parentheses are required or the comparison occurs before the bitand.
>
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Scary... can someone test this before I apply it please?
Thanks.
^ permalink raw reply
* [PATCH] NET: Fix locking issues in PPP, 6pack, mkiss and strip line disciplines.
From: Ralf Baechle DL5RB @ 2009-07-12 22:26 UTC (permalink / raw)
To: David S. Miller, netdev
Cc: Guido Trentalancia, Paul Mackerras, Alan Cox, linux-hams,
Hans Albas PE1AYX
In-Reply-To: <20090712172720.GA7313@linux-mips.org>
Guido Trentalancia reports:
I am trying to use the kiss driver in the Linux kernel that is being
shipped with Fedora 10 but unfortunately I get the following oops:
mkiss: AX.25 Multikiss, Hans Albas PE1AYX
mkiss: ax0: crc mode is auto.
ADDRCONF(NETDEV_CHANGE): ax0: link becomes ready
------------[ cut here ]------------
WARNING: at kernel/softirq.c:77 __local_bh_disable+0x2f/0x83() (Not
tainted)
[...]
unloaded: microcode]
Pid: 0, comm: swapper Not tainted 2.6.27.25-170.2.72.fc10.i686 #1
[<c042ddfb>] warn_on_slowpath+0x65/0x8b
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c04228b4>] ? __enqueue_entity+0xe3/0xeb
[<c042431e>] ? enqueue_entity+0x203/0x20b
[<c0424361>] ? enqueue_task_fair+0x3b/0x3f
[<c041f88c>] ? resched_task+0x3a/0x6e
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c06ab4e2>] ? _spin_lock_bh+0xb/0x16
[<c043255b>] __local_bh_disable+0x2f/0x83
[<c04325ba>] local_bh_disable+0xb/0xd
[<c06ab4e2>] _spin_lock_bh+0xb/0x16
[<f8b6f600>] mkiss_receive_buf+0x2fb/0x3a6 [mkiss]
[<c0572a30>] flush_to_ldisc+0xf7/0x198
[<c0572b12>] tty_flip_buffer_push+0x41/0x51
[<f89477f2>] ftdi_process_read+0x375/0x4ad [ftdi_sio]
[<f8947a5a>] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio]
[<c05d4bec>] usb_hcd_giveback_urb+0x63/0x93
[<c05ea290>] uhci_giveback_urb+0xe5/0x15f
[<c05eaabf>] uhci_scan_schedule+0x52e/0x767
[<c05f6288>] ? psmouse_handle_byte+0xc/0xe5
[<c054df78>] ? acpi_ev_gpe_detect+0xd6/0xe1
[<c05ec5b0>] uhci_irq+0x110/0x125
[<c05d4834>] usb_hcd_irq+0x40/0xa3
[<c0465313>] handle_IRQ_event+0x2f/0x64
[<c046642b>] handle_level_irq+0x74/0xbe
[<c04663b7>] ? handle_level_irq+0x0/0xbe
[<c0406e6e>] do_IRQ+0xc7/0xfe
[<c0405668>] common_interrupt+0x28/0x30
[<c056821a>] ? acpi_idle_enter_simple+0x162/0x19d
[<c0617f52>] cpuidle_idle_call+0x60/0x92
[<c0403c61>] cpu_idle+0x101/0x134
[<c069b1ba>] rest_init+0x4e/0x50
=======================
---[ end trace b7cc8076093467ad ]---
------------[ cut here ]------------
WARNING: at kernel/softirq.c:136 _local_bh_enable_ip+0x3d/0xc4()
[...]
Pid: 0, comm: swapper Tainted: G W 2.6.27.25-170.2.72.fc10.i686
[<c042ddfb>] warn_on_slowpath+0x65/0x8b
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c04228b4>] ? __enqueue_entity+0xe3/0xeb
[<c042431e>] ? enqueue_entity+0x203/0x20b
[<c0424361>] ? enqueue_task_fair+0x3b/0x3f
[<c041f88c>] ? resched_task+0x3a/0x6e
[<c06ab62b>] ? _spin_unlock_irqrestore+0x22/0x38
[<c06ab4e2>] ? _spin_lock_bh+0xb/0x16
[<f8b6f642>] ? mkiss_receive_buf+0x33d/0x3a6 [mkiss]
[<c04325f9>] _local_bh_enable_ip+0x3d/0xc4
[<c0432688>] local_bh_enable_ip+0x8/0xa
[<c06ab54d>] _spin_unlock_bh+0x11/0x13
[<f8b6f642>] mkiss_receive_buf+0x33d/0x3a6 [mkiss]
[<c0572a30>] flush_to_ldisc+0xf7/0x198
[<c0572b12>] tty_flip_buffer_push+0x41/0x51
[<f89477f2>] ftdi_process_read+0x375/0x4ad [ftdi_sio]
[<f8947a5a>] ftdi_read_bulk_callback+0x130/0x138 [ftdi_sio]
[<c05d4bec>] usb_hcd_giveback_urb+0x63/0x93
[<c05ea290>] uhci_giveback_urb+0xe5/0x15f
[<c05eaabf>] uhci_scan_schedule+0x52e/0x767
[<c05f6288>] ? psmouse_handle_byte+0xc/0xe5
[<c054df78>] ? acpi_ev_gpe_detect+0xd6/0xe1
[<c05ec5b0>] uhci_irq+0x110/0x125
[<c05d4834>] usb_hcd_irq+0x40/0xa3
[<c0465313>] handle_IRQ_event+0x2f/0x64
[<c046642b>] handle_level_irq+0x74/0xbe
[<c04663b7>] ? handle_level_irq+0x0/0xbe
[<c0406e6e>] do_IRQ+0xc7/0xfe
[<c0405668>] common_interrupt+0x28/0x30
[<c056821a>] ? acpi_idle_enter_simple+0x162/0x19d
[<c0617f52>] cpuidle_idle_call+0x60/0x92
[<c0403c61>] cpu_idle+0x101/0x134
[<c069b1ba>] rest_init+0x4e/0x50
=======================
---[ end trace b7cc8076093467ad ]---
mkiss: ax0: Trying crc-smack
mkiss: ax0: Trying crc-flexnet
The issue was, that the locking code in mkiss was assuming it was only
ever being called in process or bh context. Fixed by converting the
involved locking code to use irq-safe locks.
Review of other networking line disciplines shows that 6pack, both sync
and async PPP and STRIP have similar issues. The ppp_async one is the
most interesting one as it sorts out half of the issue as far back as
2004 in commit http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=2996d8deaeddd01820691a872550dc0cfba0c37d
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Reported-by: Guido Trentalancia <guido@trentalancia.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Alan Cox <alan@linux.intel.com>
Cc: linux-hams@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: Hans Albas PE1AYX <hans@esrac.ele.tue.nl>
---
v2 - convert some more mkiss.c _bh locks to irq-save locks.
drivers/net/hamradio/6pack.c | 10 ++++++----
drivers/net/hamradio/mkiss.c | 41 ++++++++++++++++++++++++-----------------
drivers/net/ppp_async.c | 11 +++++++----
drivers/net/ppp_synctty.c | 11 +++++++----
drivers/net/wireless/strip.c | 39 ++++++++++++++++++++++++---------------
5 files changed, 68 insertions(+), 44 deletions(-)
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 1551600..913a564 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -398,13 +398,14 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct sixpack *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
if (sp)
atomic_inc(&sp->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
return sp;
}
@@ -688,12 +689,13 @@ out:
*/
static void sixpack_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct sixpack *sp;
- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
sp = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!sp)
return;
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index fda2fc8..a728650 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -244,15 +244,16 @@ static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
static void ax_bump(struct mkiss *ax)
{
+ unsigned long flags;
struct sk_buff *skb;
int count;
- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if (ax->rbuff[0] > 0x0f) {
if (ax->rbuff[0] & 0x80) {
if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
ax->dev->stats.rx_errors++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}
@@ -267,7 +268,7 @@ static void ax_bump(struct mkiss *ax)
} else if (ax->rbuff[0] & 0x20) {
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
ax->dev->stats.rx_errors++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}
if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
@@ -294,7 +295,7 @@ static void ax_bump(struct mkiss *ax)
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
ax->dev->name);
ax->dev->stats.rx_dropped++;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}
@@ -303,11 +304,13 @@ static void ax_bump(struct mkiss *ax)
netif_rx(skb);
ax->dev->stats.rx_packets++;
ax->dev->stats.rx_bytes += count;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
}
static void kiss_unesc(struct mkiss *ax, unsigned char s)
{
+ unsigned long flags;
+
switch (s) {
case END:
/* drop keeptest bit = VSV */
@@ -334,18 +337,18 @@ static void kiss_unesc(struct mkiss *ax, unsigned char s)
break;
}
- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if (!test_bit(AXF_ERROR, &ax->flags)) {
if (ax->rcount < ax->buffsize) {
ax->rbuff[ax->rcount++] = s;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
return;
}
ax->dev->stats.rx_over_errors++;
set_bit(AXF_ERROR, &ax->flags);
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
}
static int ax_set_mac_address(struct net_device *dev, void *addr)
@@ -367,6 +370,7 @@ static void ax_changedmtu(struct mkiss *ax)
{
struct net_device *dev = ax->dev;
unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
+ unsigned long flags;
int len;
len = dev->mtu * 2;
@@ -392,7 +396,7 @@ static void ax_changedmtu(struct mkiss *ax)
return;
}
- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
oxbuff = ax->xbuff;
ax->xbuff = xbuff;
@@ -423,7 +427,7 @@ static void ax_changedmtu(struct mkiss *ax)
ax->mtu = dev->mtu + 73;
ax->buffsize = len;
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
kfree(oxbuff);
kfree(orbuff);
@@ -433,6 +437,7 @@ static void ax_changedmtu(struct mkiss *ax)
static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
{
struct mkiss *ax = netdev_priv(dev);
+ unsigned long flags;
unsigned char *p;
int actual, count;
@@ -449,7 +454,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
p = icp;
- spin_lock_bh(&ax->buflock);
+ spin_lock_irqsave(&ax->buflock, flags);
if ((*p & 0x0f) != 0) {
/* Configuration Command (kissparms(1).
* Protocol spec says: never append CRC.
@@ -479,7 +484,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
ax->crcauto = (cmd ? 0 : 1);
printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
netif_start_queue(dev);
return;
@@ -512,7 +517,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
}
}
- spin_unlock_bh(&ax->buflock);
+ spin_unlock_irqrestore(&ax->buflock, flags);
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
@@ -704,13 +709,14 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct mkiss *mkiss_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
if (ax)
atomic_inc(&ax->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
return ax;
}
@@ -809,12 +815,13 @@ out:
static void mkiss_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct mkiss *ax;
- write_lock(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ax = tty->disc_data;
tty->disc_data = NULL;
- write_unlock(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ax)
return;
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 17c116b..1fd319b 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -132,13 +132,15 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct asyncppp *ap_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}
@@ -215,12 +217,13 @@ ppp_asynctty_open(struct tty_struct *tty)
static void
ppp_asynctty_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct asyncppp *ap;
- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index aa3d39f..1b3f75f 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -182,13 +182,15 @@ static DEFINE_RWLOCK(disc_data_lock);
static struct syncppp *sp_get(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;
- read_lock(&disc_data_lock);
+ read_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
if (ap != NULL)
atomic_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
+ read_unlock_irqrestore(&disc_data_lock, flags);
+
return ap;
}
@@ -262,12 +264,13 @@ ppp_sync_open(struct tty_struct *tty)
static void
ppp_sync_close(struct tty_struct *tty)
{
+ unsigned long flags;
struct syncppp *ap;
- write_lock_irq(&disc_data_lock);
+ write_lock_irqsave(&disc_data_lock, flags);
ap = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
+ write_unlock_irqrestore(&disc_data_lock, flags);
if (!ap)
return;
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 38366a5..3d39f65 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -856,6 +856,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
unsigned char *orbuff = strip_info->rx_buff;
unsigned char *osbuff = strip_info->sx_buff;
unsigned char *otbuff = strip_info->tx_buff;
+ unsigned long flags;
if (new_mtu > MAX_SEND_MTU) {
printk(KERN_ERR
@@ -864,11 +865,11 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL;
}
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
if (!allocate_buffers(strip_info, new_mtu)) {
printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
strip_info->dev->name);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
return -ENOMEM;
}
@@ -892,7 +893,7 @@ static int strip_change_mtu(struct net_device *dev, int new_mtu)
}
}
strip_info->tx_head = strip_info->tx_buff;
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
strip_info->dev->name, old_mtu, strip_info->mtu);
@@ -983,10 +984,13 @@ static void strip_seq_neighbours(struct seq_file *seq,
const MetricomNodeTable * table,
const char *title)
{
- /* We wrap this in a do/while loop, so if the table changes */
- /* while we're reading it, we just go around and try again. */
+ unsigned long flags;
struct timeval t;
+ /*
+ * We wrap this in a do/while loop, so if the table changes
+ * while we're reading it, we just go around and try again.
+ */
do {
int i;
t = table->timestamp;
@@ -995,9 +999,9 @@ static void strip_seq_neighbours(struct seq_file *seq,
for (i = 0; i < table->num_nodes; i++) {
MetricomNode node;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
node = table->node[i];
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
seq_printf(seq, " %s\n", node.c);
}
} while (table->timestamp.tv_sec != t.tv_sec
@@ -1536,6 +1540,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct strip *strip_info = netdev_priv(dev);
+ unsigned long flags;
if (!netif_running(dev)) {
printk(KERN_ERR "%s: xmit call when iface is down\n",
@@ -1574,11 +1579,11 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
strip_info->dev->name, sx_pps_count / 8);
}
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
strip_send(strip_info, skb);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
if (skb)
dev_kfree_skb(skb);
@@ -2263,12 +2268,13 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
{
struct strip *strip_info = tty->disc_data;
const unsigned char *end = cp + count;
+ unsigned long flags;
if (!strip_info || strip_info->magic != STRIP_MAGIC
|| !netif_running(strip_info->dev))
return;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
#if 0
{
struct timeval tv;
@@ -2335,7 +2341,7 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
}
cp++;
}
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
}
@@ -2523,9 +2529,11 @@ static void strip_dev_setup(struct net_device *dev)
static void strip_free(struct strip *strip_info)
{
- spin_lock_bh(&strip_lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&strip_lock, flags);
list_del_rcu(&strip_info->list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
strip_info->magic = 0;
@@ -2539,6 +2547,7 @@ static void strip_free(struct strip *strip_info)
static struct strip *strip_alloc(void)
{
struct list_head *n;
+ unsigned long flags;
struct net_device *dev;
struct strip *strip_info;
@@ -2562,7 +2571,7 @@ static struct strip *strip_alloc(void)
strip_info->idle_timer.function = strip_IdleTask;
- spin_lock_bh(&strip_lock);
+ spin_lock_irqsave(&strip_lock, flags);
rescan:
/*
* Search the list to find where to put our new entry
@@ -2581,7 +2590,7 @@ static struct strip *strip_alloc(void)
sprintf(dev->name, "st%ld", dev->base_addr);
list_add_tail_rcu(&strip_info->list, &strip_list);
- spin_unlock_bh(&strip_lock);
+ spin_unlock_irqrestore(&strip_lock, flags);
return strip_info;
}
^ permalink raw reply related
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