* Re: PF_RING: Include in main line kernel?
From: Luca Deri @ 2009-10-18 17:37 UTC (permalink / raw)
To: Harald Welte; +Cc: Brad Doctor, netdev
In-Reply-To: <20091018123811.GD27747@prithivi.gnumonks.org>
Harald
many thanks for your support. As I have stated before my wish is to
include into the the mainstream kernel some features that I have
implemented in PF_RING and on which many users rely since very long
time. I understand that there are some overlaps with PF_PACKET and I'm
willing to work with the kernel maintainers to address this issue.
The only thing I want to say is that PF_RING is *not* just for
accelerating packet capture. This was the minimal goal when in 2003 I
have coded the first release. PF_RING is a kernel module that
implements several features (e.g. advanced packet filtering,
extensible architecture by means of plugins, balancing, multicore/
multiqueue, packet modification and retransmission) that ease the
implementation of efficient applications not limited to packet capture
application. So in this view PF_RING has been designed to be a
superset of PF_PACKET, because the needs I (and many other people
have) are not of just having efficient packet capture.
This said I'm already at work to modify PF_RING so that it's a pure
module that does not require any change in the mainstream kernel (i.e.
net/core/dev.c). I'm almost done so I plan to release by tomorrow a
new PF_RING release that implements this. Of course some changes into
the kernel (such as Ben's patch) would ease PF_RING's life and pave
the way to new kernel modules.
Done that I will start working at the RFC that you proposed.
Cheers Luca
PS. Just to clarify, when I say 'packet filtering' I mean the ability
for packet capture applications to specify filters more advanced that
BPF (even if BPF is supported by PF_RING) that prevent those
applications from receiving packets they don't like, but that in any
case will continue their journey into the kernel; this has nothing to
do with netfilter filtering).
On Oct 18, 2009, at 2:38 PM, Harald Welte wrote:
> Hi Brad and Luca,
>
> On Wed, Oct 14, 2009 at 08:33:08AM -0600, Brad Doctor wrote:
>
>> On behalf of the users and developers of the PF_RING project, we
>> would
>> like to ask consideration to include the PF_RING module in the main
>> line kernel.
>
> First of all, let me state that I think the mainline support for
> nProbe/nTop is
> something that I have been hoping for many years. I think the
> performance you
> are achieving is remarkable, and it would be very usable to have this
> capability of high performance zero-copy packet access from
> userspace as a
> stock feature of the Linux kernel.
>
> The actual PF_RING implementation has been criticized a couple of
> times even in
> the past. One general point I remember from past discussions in the
> kernel
> network community was that there is too much overlap with PF_PACKET,
> and that
> this could possibly be extended with a ring buffer rather than
> replaced with a
> fairly similar alternative mechanism.
>
> So let's see what kind of solution the current discussion thread
> will come up
> with... let's hope eventually we'll have the functionality in the
> kernel.
> --
> - Harald Welte <laforge@gnumonks.org> http://laforge.gnumonks.org/
> =
> =
> =
> =
> =
> =
> ======================================================================
> "Privacy in residential applications is a desirable marketing option."
> (ETSI EN 300 175-7
> Ch. A6)
^ permalink raw reply
* Re: [PATCH/RFC] make unregister_netdev() delete more than 4 interfaces per second
From: Eric Dumazet @ 2009-10-18 17:51 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: netdev
In-Reply-To: <20091018161356.GA23395@kvack.org>
Benjamin LaHaise a écrit :
> On Sun, Oct 18, 2009 at 06:26:22AM +0200, Eric Dumazet wrote:
>> Unfortunatly this slow down fast path by an order of magnitude.
>>
>> atomic_dec() is pretty cheap (and eventually could use a per_cpu thing,
>> now we have a new and sexy per_cpu allocator), but atomic_dec_and_test()
>> is not that cheap and more important forbids a per_cpu conversion.
>
> dev_put() is not a fast path by any means. atomic_dec_and_test() costs
> the same as atomic_dec() on any modern CPU -- the cost is in the cacheline
> bouncing and serialisation both require. The case of the device count
> becoming 0 is quite rare -- any device with a route on it will never hit
> a reference count of 0.
You forgot af_packet sendmsg() users, and heavy routers where route cache
is stressed or disabled. I know several of them, they even added mmap TX
support to get better performance. They will be disapointed by your patch.
atomic_dec_and_test() is definitly more expensive, because of strong barrier
semantics and added test after the decrement.
refcnt being close to zero or not has not impact, even on 2 years old cpus.
Machines hardly had to dismantle a netdevice in a normal lifetime, so maybe
we were lazy with this insane msleep(250). This came from old linux times,
when cpus were soooo slow and programers soooo lazy :)
The msleep(250) should be tuned first. Then if this is really necessary
to dismantle 100.000 netdevices per second, we might have to think a bit more.
Just try msleep(1 or 2), it should work quite well.
^ permalink raw reply
* Re: [PATCH/RFC] make unregister_netdev() delete more than 4 interfaces per second
From: Benjamin LaHaise @ 2009-10-18 18:21 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <4ADB55BC.5020107@gmail.com>
On Sun, Oct 18, 2009 at 07:51:56PM +0200, Eric Dumazet wrote:
> You forgot af_packet sendmsg() users, and heavy routers where route cache
> is stressed or disabled. I know several of them, they even added mmap TX
> support to get better performance. They will be disapointed by your patch.
If that's a problem, the cacheline overhead is a more serious issue.
AF_PACKET should really keep the reference on the device between syscalls.
Do you have a benchmark in mind that would show the overhead?
> atomic_dec_and_test() is definitly more expensive, because of strong barrier
> semantics and added test after the decrement.
> refcnt being close to zero or not has not impact, even on 2 years old cpus.
At least on x86, the atomic_dec_and_test() cost is pretty much identical to
atomic_dec(). If this really is a performance bottleneck, people should be
complaining about the cache miss overhead and lock overhead which will dwarf
the atomic_dec_and_test() cost vs atomic_dec(). Granted, I'm not saying
that it isn't an issue on other architectures, but for x86 the lock prefix
is what's expensive, not checking the flags or not after doing the operation.
If your complaint is about uninlining dev_put(), I'm indifferent to keeping
it inline or out of line and can change the patch to suit.
> Machines hardly had to dismantle a netdevice in a normal lifetime, so maybe
> we were lazy with this insane msleep(250). This came from old linux times,
> when cpus were soooo slow and programers soooo lazy :)
It's only now that machines can actually route one or more 10Gbps links
that it really becomes an issue. I've been hacking around it for some
time, but fixing it properly is starting to be a real requirement.
> The msleep(250) should be tuned first. Then if this is really necessary
> to dismantle 100.000 netdevices per second, we might have to think a bit more.
>
> Just try msleep(1 or 2), it should work quite well.
My goal is tearing down 100,000 interfaces in a few seconds, which really is
necessary. Right now we're running about 40,000 interfaces on a not yet
saturated 10Gbps link. Going to dual 10Gbps links means pushing more than
100,000 subscriber interfaces, and it looks like a modern dual socket system
can handle that.
A bigger concern is rtnl_lock(). It is a huge impediment to scaling up
interface creation/deletion on multicore systems. That's going to be a
lot more invasive to fix, though.
-ben
^ permalink raw reply
* [PATCH v2] can: provide library functions for skb allocation
From: Wolfgang Grandegger @ 2009-10-18 18:45 UTC (permalink / raw)
To: Linux Netdev List
Cc: SocketCAN Core Mailing List, Sebastian Haas, Gole, Anant,
Marc Kleine-Budde, David Miller
This patch makes the private functions alloc_can_skb() and
alloc_can_err_skb() of the at91_can driver public and adapts all
drivers to use these. While making the patch I realized, that
the skb's are *not* setup consistently. It's now done as shown
below:
skb->protocol = htons(ETH_P_CAN);
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
*cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
memset(*cf, 0, sizeof(struct can_frame));
The frame is zeroed out to avoid uninitialized data to be passed to
user space. Some drivers or library code did not set "pkt_type" or
"ip_summed". Also, "__constant_htons()" should not be used for
runtime invocations, as pointed out by David Miller.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
drivers/net/can/at91_can.c | 32 ----------------------------
drivers/net/can/dev.c | 42 +++++++++++++++++++++++++++++++-------
drivers/net/can/sja1000/sja1000.c | 12 +---------
drivers/net/can/ti_hecc.c | 17 +++------------
drivers/net/can/usb/ems_usb.c | 16 +-------------
5 files changed, 43 insertions(+), 76 deletions(-)
Index: net-next-2.6/drivers/net/can/dev.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/dev.c
+++ net-next-2.6/drivers/net/can/dev.c
@@ -366,17 +366,12 @@ void can_restart(unsigned long data)
can_flush_echo_skb(dev);
/* send restart message upstream */
- skb = dev_alloc_skb(sizeof(struct can_frame));
+ skb = alloc_can_err_skb(dev, &cf);
if (skb == NULL) {
err = -ENOMEM;
goto restart;
}
- skb->dev = dev;
- skb->protocol = htons(ETH_P_CAN);
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- memset(cf, 0, sizeof(struct can_frame));
- cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
- cf->can_dlc = CAN_ERR_DLC;
+ cf->can_id |= CAN_ERR_RESTARTED;
netif_rx(skb);
@@ -449,6 +444,39 @@ static void can_setup(struct net_device
dev->features = NETIF_F_NO_CSUM;
}
+struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
+{
+ struct sk_buff *skb;
+
+ skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
+ if (unlikely(!skb))
+ return NULL;
+
+ skb->protocol = htons(ETH_P_CAN);
+ skb->pkt_type = PACKET_BROADCAST;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+ memset(*cf, 0, sizeof(struct can_frame));
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_skb);
+
+struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
+{
+ struct sk_buff *skb;
+
+ skb = alloc_can_skb(dev, cf);
+ if (unlikely(!skb))
+ return NULL;
+
+ (*cf)->can_id = CAN_ERR_FLAG;
+ (*cf)->can_dlc = CAN_ERR_DLC;
+
+ return skb;
+}
+EXPORT_SYMBOL_GPL(alloc_can_err_skb);
+
/*
* Allocate and setup space for the CAN network device
*/
Index: net-next-2.6/drivers/net/can/at91_can.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/at91_can.c
+++ net-next-2.6/drivers/net/can/at91_can.c
@@ -221,38 +221,6 @@ static inline void set_mb_mode(const str
set_mb_mode_prio(priv, mb, mode, 0);
}
-static struct sk_buff *alloc_can_skb(struct net_device *dev,
- struct can_frame **cf)
-{
- struct sk_buff *skb;
-
- skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
- if (unlikely(!skb))
- return NULL;
-
- skb->protocol = htons(ETH_P_CAN);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
- return skb;
-}
-
-static struct sk_buff *alloc_can_err_skb(struct net_device *dev,
- struct can_frame **cf)
-{
- struct sk_buff *skb;
-
- skb = alloc_can_skb(dev, cf);
- if (unlikely(!skb))
- return NULL;
-
- memset(*cf, 0, sizeof(struct can_frame));
- (*cf)->can_id = CAN_ERR_FLAG;
- (*cf)->can_dlc = CAN_ERR_DLC;
-
- return skb;
-}
-
/*
* Swtich transceiver on or off
*/
Index: net-next-2.6/drivers/net/can/sja1000/sja1000.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/sja1000/sja1000.c
+++ net-next-2.6/drivers/net/can/sja1000/sja1000.c
@@ -296,11 +296,9 @@ static void sja1000_rx(struct net_device
uint8_t dlc;
int i;
- skb = dev_alloc_skb(sizeof(struct can_frame));
+ skb = alloc_can_skb(dev, &cf);
if (skb == NULL)
return;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_CAN);
fi = priv->read_reg(priv, REG_FI);
dlc = fi & 0x0F;
@@ -351,15 +349,9 @@ static int sja1000_err(struct net_device
enum can_state state = priv->can.state;
uint8_t ecc, alc;
- skb = dev_alloc_skb(sizeof(struct can_frame));
+ skb = alloc_can_err_skb(dev, &cf);
if (skb == NULL)
return -ENOMEM;
- skb->dev = dev;
- skb->protocol = htons(ETH_P_CAN);
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- memset(cf, 0, sizeof(struct can_frame));
- cf->can_id = CAN_ERR_FLAG;
- cf->can_dlc = CAN_ERR_DLC;
if (isrc & IRQ_DOI) {
/* data overrun interrupt */
Index: net-next-2.6/drivers/net/can/usb/ems_usb.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/usb/ems_usb.c
+++ net-next-2.6/drivers/net/can/usb/ems_usb.c
@@ -311,14 +311,10 @@ static void ems_usb_rx_can_msg(struct em
int i;
struct net_device_stats *stats = &dev->netdev->stats;
- skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+ skb = alloc_can_skb(dev->netdev, &cf);
if (skb == NULL)
return;
- skb->protocol = htons(ETH_P_CAN);
-
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
-
cf->can_id = msg->msg.can_msg.id;
cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8);
@@ -346,18 +342,10 @@ static void ems_usb_rx_err(struct ems_us
struct sk_buff *skb;
struct net_device_stats *stats = &dev->netdev->stats;
- skb = netdev_alloc_skb(dev->netdev, sizeof(struct can_frame));
+ skb = alloc_can_err_skb(dev->netdev, &cf);
if (skb == NULL)
return;
- skb->protocol = htons(ETH_P_CAN);
-
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- memset(cf, 0, sizeof(struct can_frame));
-
- cf->can_id = CAN_ERR_FLAG;
- cf->can_dlc = CAN_ERR_DLC;
-
if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
u8 state = msg->msg.can_state;
Index: net-next-2.6/drivers/net/can/ti_hecc.c
===================================================================
--- net-next-2.6.orig/drivers/net/can/ti_hecc.c
+++ net-next-2.6/drivers/net/can/ti_hecc.c
@@ -535,18 +535,15 @@ static int ti_hecc_rx_pkt(struct ti_hecc
u32 data, mbx_mask;
unsigned long flags;
- skb = netdev_alloc_skb(priv->ndev, sizeof(struct can_frame));
+ skb = alloc_can_skb(priv->ndev, &cf);
if (!skb) {
if (printk_ratelimit())
dev_err(priv->ndev->dev.parent,
- "ti_hecc_rx_pkt: netdev_alloc_skb() failed\n");
+ "ti_hecc_rx_pkt: alloc_can_skb() failed\n");
return -ENOMEM;
}
- skb->protocol = __constant_htons(ETH_P_CAN);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
mbx_mask = BIT(mbxno);
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
if (data & HECC_CANMID_IDE)
cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
@@ -656,19 +653,13 @@ static int ti_hecc_error(struct net_devi
struct sk_buff *skb;
/* propogate the error condition to the can stack */
- skb = netdev_alloc_skb(ndev, sizeof(struct can_frame));
+ skb = alloc_can_err_skb(ndev, &cf);
if (!skb) {
if (printk_ratelimit())
dev_err(priv->ndev->dev.parent,
- "ti_hecc_error: netdev_alloc_skb() failed\n");
+ "ti_hecc_error: alloc_can_err_skb() failed\n");
return -ENOMEM;
}
- skb->protocol = __constant_htons(ETH_P_CAN);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
- memset(cf, 0, sizeof(struct can_frame));
- cf->can_id = CAN_ERR_FLAG;
- cf->can_dlc = CAN_ERR_DLC;
if (int_status & HECC_CANGIF_WLIF) { /* warning level int */
if ((int_status & HECC_CANGIF_BOIF) == 0) {
^ permalink raw reply
* Re: [PATCH] can: provide library functions for skb allocation
From: Wolfgang Grandegger @ 2009-10-18 18:46 UTC (permalink / raw)
To: David Miller; +Cc: netdev, socketcan-core, haas, anantgole, mkl
In-Reply-To: <20091017.235520.265660027.davem@davemloft.net>
David Miller wrote:
> From: Wolfgang Grandegger <wg@grandegger.com>
> Date: Thu, 15 Oct 2009 11:22:18 +0200
>
>> + skb->protocol = __constant_htons(ETH_P_CAN);
>
> Please don't use __constant_htonX() for runtime invocatios.
> It's only for situation which must be compile time evaluations
> such as case statements and static initializations.
>
> GCC can figure out that's it's constant if you just use
> plan htonX().
OK, I just dent out v2 of this patch.
Wolfgang.
^ permalink raw reply
* Re: [PATCH/RFC] make unregister_netdev() delete more than 4 interfaces per second
From: Eric Dumazet @ 2009-10-18 19:36 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: netdev
In-Reply-To: <20091018182144.GC23395@kvack.org>
Benjamin LaHaise a écrit :
>
> My goal is tearing down 100,000 interfaces in a few seconds, which really is
> necessary. Right now we're running about 40,000 interfaces on a not yet
> saturated 10Gbps link. Going to dual 10Gbps links means pushing more than
> 100,000 subscriber interfaces, and it looks like a modern dual socket system
> can handle that.
>
> A bigger concern is rtnl_lock(). It is a huge impediment to scaling up
> interface creation/deletion on multicore systems. That's going to be a
> lot more invasive to fix, though.
Dont forget synchronize_net() too (two calls per rollback_registered())
You need something to dismantle XXXXX interfaces at once, instead
of serializing one by one. Because in three years you'll want to dismantle
1.000.000 interfaces in one second.
Maybe defining an asynchronous unregister_netdev() function...
^ permalink raw reply
* Re: Kernel oops when clearing bgp neighbor info with TCP MD5SUM enabled
From: Anirban Sinha @ 2009-10-18 20:19 UTC (permalink / raw)
To: linux-kernel, Oleg Nesterov; +Cc: David Miller, netdev, Anirban Sinha
In-Reply-To: <4ADA7EDC.5010402@anirban.org>
Hi Oleg:
I have a question for you. The queue_work() routine which is called from schedule_work() does a put_cpu() which in turn does a enable_preempt(). Is this an attempt to trigger the scheduler? One of the side affects of this enable_preempt() is the crash that we see below. What is happening is that a timer callback routine, in this case inet_twdr_hangman(), tries a bunch of cleanup until a threshold is reached. If further cleanups needs to be done beyond the threshold, it queues a work function. Now when the timer callback is run in __run_timers(), the routine grabs the value of preempt_count before and after the callback function call. If the two counts do not match, it calls BUG() (line 1037 in kernel/timer.c). Is is it illegal to schedule a work function from within a timer callback? Wha
t would be a good solution? I have already posted in netdev but since workqueues and timers are general kernel infrastructure, I thought I might as well post the question in the main linux m
ailing list and to you.
Here's the output from my instrumented BUG() call:
[02:15:15.941981] Kernel panic - not syncing: <3>huh, entered ffffffff803fbd60
(inet_twdr_hangman+0x0/0xe0)with preempt_count 00000102, exited with 00000101?
I was thinking of a hacky solution, to replace schedule_work() with schedule_delayed_work() just to get around the issue. But I am sure this is just too hacky and probably not the ideal solution ...
Cheers,
Ani
Once upon a time, like on 09-10-17 7:35 PM, Anirban Sinha wrote:
>
>
> Once upon a time, like on 09-10-17 10:57 AM, Anirban Sinha wrote:
>> On Thu, 8 Oct 2009, David Miller wrote:
>>
>>>>>> We are noticing a kernel OOPS on 2.6.26 kernel when we issue the command
>>>>>> "clear ip bgp <bgp-peer-ip>" on Quagga BGP routing software.
>
> and btw, this is the crash (on mips) we are talking about:
>
> # [23:10:35.108808] Kernel bug detected[#1]:
> [23:10:35.112527] Cpu 0
> [23:10:35.114676] $ 0 : 0000000000000000 0000000014001fe0
> 0000000000000066 0000000000000004
> [23:10:35.122845] $ 4 : ffffffff80516c10 0000000014001fe0
> ffffffff8050c010 0000000000000004
> [23:10:35.131015] $ 8 : 0000000000000000 0000000000000041
> ffffffff805142e8 0000000000000001
> [23:10:35.139184] $12 : ffffffff80600000 ffffffff805f0000
> 0000000000000064 0000000000000190
> [23:10:35.147354] $16 : 0000000000000102 ffffffff803afdf0
> ffffffff80539040 ffffffff80600780
> [23:10:35.155526] $20 : ffffffff80540000 0000000000200200
> ffffffff804c0000 000000000000000a
> [23:10:35.163695] $24 : a3d70a3d70a3d70b 8000000000000003
> [23:10:35.171865] $28 : ffffffff8050c000 ffffffff8050fd90
> 9000000010030000 ffffffff801487a8
> [23:10:35.180035] Hi : 0000000000000000
> [23:10:35.183819] Lo : 0000000000000000
> [23:10:35.187603] epc : ffffffff801487a8 run_timer_softirq+0x198/0x258
> Tainted: P
> [23:10:35.196032] ra : ffffffff801487a8 run_timer_softirq+0x198/0x258
> [23:10:35.202395] Status: 14001fe3 KX SX UX KERNEL EXL IE
> [23:10:35.207814] Cause : 00808024
> [23:10:35.210911] PrId : 01041100 (SiByte SB1A)
> [23:10:35.215209] Modules linked in: xt_state ipt_REJECT iptable_filter
> nf_conntrack_ftp ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4
> ip_tables ebtable_filter ebtables bridge llc zeug_ipmcdrv(P) irqdisp(P)
> zvirt(P) zeugmod(P) softdog
> [23:10:35.236024] Process swapper (pid: 0, threadinfo=ffffffff8050c000,
> task=ffffffff805142e8, tls=0000000000000000)
> [23:10:35.246169] Stack : ffffffff8050fd90 ffffffff8050fd90
> 0000000014001fe0 ffffffff805ff3e0
> [23:10:35.254166] ffffffff806003c4 0000000000000001
> ffffffff8053f650 ffffffff805706d0
> [23:10:35.262337] ffffffff80572020 ffffffff80142280
> ffffffff806003c0 0000000000000000
> [23:10:35.270507] 0000000014001fe0 000000000000c5b0
> ffffffff8fefc520 ffffffff8feea52c
> [23:10:35.278676] 0000000000000015 0000000000004460
> 0000000000000940 ffffffff8fe1bf00
> [23:10:35.286846] ffffffff8fffdab0 ffffffff80142410
> 0000000000000000 ffffffff80142778
> [23:10:35.295017] ffffffff80103d20 ffffffff80103d20
> 0000000000000000 0000000014001fe1
> [23:10:35.303187] 0000000000040000 ffffffff8050c010
> 0000000000000000 a80000017f87c138
> [23:10:35.311357] 0000000014001fe0 ffffffffffff00fe
> 0000000000000004 a80000017e7e0680
> [23:10:35.319528] 0000000000000000 000000000000001d
> ffffffff8050ffe0 0000000000001f00
> [23:10:35.327696] ...
> [23:10:35.330536] Call Trace:
> [23:10:35.333201] [<ffffffff801487a8>] run_timer_softirq+0x198/0x258
> [23:10:35.339224] [<ffffffff80142280>] __do_softirq+0x198/0x288
> [23:10:35.344812] [<ffffffff80142410>] do_softirq+0xa0/0xa8
> [23:10:35.350057] [<ffffffff80142778>] irq_exit+0x70/0x88
> [23:10:35.355131] [<ffffffff80103d20>] ret_from_irq+0x0/0x4
> [23:10:35.360377] [<ffffffff801063f4>] cpu_idle+0x1c/0x88
> [23:10:35.365455]
> [23:10:35.367171]
> [23:10:35.367174] Code: 0040382d 0c04ef4c 00000000 <0200000d> 0c10ee9c
> 0260202d dfa60000 17a6ffe5 00000000
> [23:10:35.378822] Kernel panic - not syncing: Fatal exception in
> interrupt
>
^ permalink raw reply
* Re: [PATCH][RFC]: ingress socket filter by mark
From: jamal @ 2009-10-18 20:28 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev, David Miller, Atis Elsts, Maciej Z.enczykowski
In-Reply-To: <4ADB5043.7070707@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 385 bytes --]
On Sun, 2009-10-18 at 19:28 +0200, Eric Dumazet wrote:
> I vote for extending BPF, and not adding the price of a compare
> for each packet. Only users wanting mark filtering should pay the price.
To be honest it nagged me as well;->
So here's a basic patch stolen from a patch i just saw that you
posted;-> I still havent tested. Let me know if it looks reasonable...
cheers,
jamal
[-- Attachment #2: filt-sock-m-2 --]
[-- Type: text/x-patch, Size: 778 bytes --]
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 1354aaf..909193e 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -123,7 +123,8 @@ struct sock_fprog /* Required for SO_ATTACH_FILTER. */
#define SKF_AD_IFINDEX 8
#define SKF_AD_NLATTR 12
#define SKF_AD_NLATTR_NEST 16
-#define SKF_AD_MAX 20
+#define SKF_AD_MARK 20
+#define SKF_AD_MAX 24
#define SKF_NET_OFF (-0x100000)
#define SKF_LL_OFF (-0x200000)
diff --git a/net/core/filter.c b/net/core/filter.c
index d1d779c..e3987e1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -303,6 +303,9 @@ load_b:
case SKF_AD_IFINDEX:
A = skb->dev->ifindex;
continue;
+ case SKF_AD_MARK:
+ A = skb->mark;
+ continue;
case SKF_AD_NLATTR: {
struct nlattr *nla;
^ permalink raw reply related
* kernel panic in latest vanilla stable, while using nameif with "alive" pppoe interfaces
From: Denys Fedoryschenko @ 2009-10-18 21:02 UTC (permalink / raw)
To: netdev, linux-ppp, paulus, mostrows
I have server running as pppoe NAS.
Tried to rename customers without dropping pppd connections first, got panic
after few seconds.
Panic triggerable at 2.6.30.4 and 2.6.31.4
pppoe users running on eth2
pppoe flags:
1457 root /usr/sbin/pppoe-server -I eth2 -k -L 172.16.1.1 -R
172.16.1.2 -N 253 -C gpzone -S gpzone
Commands sequence that i think triggered that:
ip link set eth0 down
ip link set eth1 down
ip link set eth2 down
nameif etherx 00:16:76:8D:83:BA
nameif eth0 00:19:e0:72:4a:37
nameif eth1 00:19:e0:72:4a:4b
ip addr flush dev eth0
ip addr flush dev eth1
ip addr add X.X.X.X/29 dev eth0
ip addr add 192.168.2.177/24 dev eth0
ip addr add 192.168.0.1/32 dev eth1
ip addr add 127.0.0.0/8 dev lo
#ip link set eth0 up
ip link set eth0 up
ip link set eth1 up
ip link set lo up
ip route add 0.0.0.0/0 via X.X.X.X
[ 103.428591] r8169: eth0: link up
[ 103.430360] r8169: eth1: link up
[ 113.361528] BUG: unable to handle kernel
NULL pointer dereference
at 0000018f
[ 113.361717] IP:
[<f8868269>] pppoe_device_event+0x80/0x12c [pppoe]
[ 113.361853] *pdpt = 000000003411a001
*pde = 0000000000000000
Oct 18 23:59:40 194.146.153.93
[ 113.362012] Oops: 0000 [#1]
SMP
Oct 18 23:59:40 194.146.153.93
[ 113.362166] last sysfs file: /sys/devices/virtual/vc/vcs3/dev
[ 113.362246] Modules linked in:
netconsole
configfs
act_skbedit
sch_ingress
sch_prio
cls_flow
cls_u32
em_meta
cls_basic
xt_dscp
xt_DSCP
ipt_REJECT
ts_bm
xt_string
xt_hl
ifb
cls_fw
sch_tbf
sch_htb
act_ipt
act_mirred
xt_MARK
pppoe
pppox
ppp_generic
slhc
xt_TCPMSS
xt_mark
xt_tcpudp
iptable_mangle
iptable_nat
nf_nat
rtc_cmos
nf_conntrack_ipv4
rtc_core
nf_conntrack
rtc_lib
nf_defrag_ipv4
iptable_filter
ip_tables
x_tables
8021q
garp
stp
llc
loop
sata_sil
pata_atiixp
pata_acpi
ata_generic
libata
8139cp
usb_storage
mtdblock
mtd_blkdevs
mtd
sr_mod
cdrom
tulip
r8169
sky2
via_velocity
via_rhine
sis900
ne2k_pci
8390
skge
tg3
libphy
8139too
e1000
e100
usbhid
ohci_hcd
uhci_hcd
ehci_hcd
usbcore
nls_base
Oct 18 23:59:40 194.146.153.93
[ 113.362344]
[ 113.362344] Pid: 2858, comm: pppd Not tainted (2.6.31.4-build-0047 #7)
[ 113.362344] EIP: 0060:[<f8868269>] EFLAGS: 00010286 CPU: 0
[ 113.362344] EIP is at pppoe_device_event+0x80/0x12c [pppoe]
[ 113.362344] EAX: f4fbe000 EBX: ffffffff ECX: f6cea5a0 EDX: f7403680
[ 113.362344] ESI: 0000000f EDI: f6cea5e0 EBP: f4145e34 ESP: f4145e1c
[ 113.362344] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[ 113.362344] Process pppd (pid: 2858, ti=f4145000 task=f4112ff0
task.ti=f4145000)
[ 113.362344] Stack:
[ 113.362344] f4fbe220
f4fbe000
f6cea5a0
f886a430
fffffff5
00000000
f4145e54
c01422b3
Oct 18 23:59:40 194.146.153.93
[ 113.362344] <0>
f4fbe000
00000009
f8a457d8
f4fbe000
f8850190
00001091
f4145e64
c0142361
Oct 18 23:59:40 194.146.153.93
[ 113.362344] <0>
ffffffff
00000000
f4145e74
c029ffbf
f4fbe000
000010d0
f4145e90
c029fa70
Oct 18 23:59:40 194.146.153.93
[ 113.362344] Call Trace:
[ 113.362344] [<c01422b3>] ? notifier_call_chain+0x2b/0x4a
[ 113.362344] [<c0142361>] ? raw_notifier_call_chain+0xc/0xe
[ 113.362344] [<c029ffbf>] ? dev_close+0x4c/0x8c
[ 113.362344] [<c029fa70>] ? dev_change_flags+0xa5/0x158
[ 113.362344] [<c02da633>] ? devinet_ioctl+0x21a/0x503
[ 113.362344] [<c02db693>] ? inet_ioctl+0x8d/0xa6
[ 113.362344] [<c0292b21>] ? sock_ioctl+0x1c8/0x1ec
[ 113.362344] [<c0292959>] ? sock_ioctl+0x0/0x1ec
[ 113.362344] [<c019af2b>] ? vfs_ioctl+0x22/0x69
[ 113.362344] [<c019b435>] ? do_vfs_ioctl+0x41f/0x459
[ 113.362344] [<c02934eb>] ? sys_send+0x18/0x1a
[ 113.362344] [<c011942f>] ? do_page_fault+0x242/0x26f
[ 113.362344] [<c019b49b>] ? sys_ioctl+0x2c/0x45
[ 113.362344] [<c0102975>] ? syscall_call+0x7/0xb
[ 113.362344] Code:
c9
00
00
00
89
c7
31
f6
83
c7
40
89
f8
e8
cc
60
a9
c7
8b
45
ec
05
20
02
00
00
89
45
e8
8b
4d
f0
8b
1c
b1
e9
8c
00
00
00
8b
45
ec
Oct 18 23:59:40 194.146.153.93
83
90
01
00
00
74
08
8b
9b
8c
01
00
00
eb
79
b8
c0
a6
86
f8
Oct 18 23:59:40 194.146.153.93
[ 113.362344] EIP: [<f8868269>]
pppoe_device_event+0x80/0x12c [pppoe]
SS:ESP 0068:f4145e1c
[ 113.362344] CR2: 000000000000018f
[ 113.373124] ---[ end trace f6fe64a307e97f3b ]---
[ 113.373203] Kernel panic - not syncing: Fatal exception in interrupt
[ 113.373286] Pid: 2858, comm: pppd Tainted: G D 2.6.31.4-build-0047
#7
[ 113.373379] Call Trace:
[ 113.373479] [<c02fc496>] ? printk+0xf/0x11
[ 113.373561] [<c02fc3e7>] panic+0x39/0xd9
[ 113.373656] [<c01059b7>] oops_end+0x8b/0x9a
[ 113.373727] [<c0118f6d>] no_context+0x13d/0x147
[ 113.373800] [<c011908a>] __bad_area_nosemaphore+0x113/0x11b
[ 113.373881] [<c02953b3>] ? sock_alloc_send_pskb+0x8b/0x24a
[ 113.373959] [<c0121801>] ? __wake_up_sync_key+0x3b/0x45
[ 113.374030] [<c0131967>] ? irq_exit+0x39/0x5c
[ 113.374107] [<c0104393>] ? do_IRQ+0x80/0x96
[ 113.374183] [<c0102f49>] ? common_interrupt+0x29/0x30
[ 113.374259] [<c011909f>] bad_area_nosemaphore+0xd/0x10
[ 113.374348] [<c0119301>] do_page_fault+0x114/0x26f
[ 113.374526] [<c01191ed>] ? do_page_fault+0x0/0x26f
[ 113.374605] [<c02fe506>] error_code+0x66/0x6c
[ 113.374683] [<c02d007b>] ? tcp_v4_send_ack+0xa3/0x10e
[ 113.374764] [<c01191ed>] ? do_page_fault+0x0/0x26f
[ 113.374850] [<f8868269>] ? pppoe_device_event+0x80/0x12c [pppoe]
[ 113.374928] [<c01422b3>] notifier_call_chain+0x2b/0x4a
[ 113.375012] [<c0142361>] raw_notifier_call_chain+0xc/0xe
[ 113.375097] [<c029ffbf>] dev_close+0x4c/0x8c
[ 113.375169] [<c029fa70>] dev_change_flags+0xa5/0x158
[ 113.375239] [<c02da633>] devinet_ioctl+0x21a/0x503
[ 113.375318] [<c02db693>] inet_ioctl+0x8d/0xa6
[ 113.375411] [<c0292b21>] sock_ioctl+0x1c8/0x1ec
[ 113.375491] [<c0292959>] ? sock_ioctl+0x0/0x1ec
[ 113.375574] [<c019af2b>] vfs_ioctl+0x22/0x69
[ 113.375653] [<c019b435>] do_vfs_ioctl+0x41f/0x459
[ 113.375734] [<c02934eb>] ? sys_send+0x18/0x1a
[ 113.375813] [<c011942f>] ? do_page_fault+0x242/0x26f
[ 113.375884] [<c019b49b>] sys_ioctl+0x2c/0x45
[ 113.375960] [<c0102975>] syscall_call+0x7/0xb
[ 113.376041] Rebooting in 5 seconds..
^ permalink raw reply
* possible circular locking dependency in ISDN PPP
From: Tilman Schmidt @ 2009-10-18 22:16 UTC (permalink / raw)
To: LKML, isdn4linux, Netdev
[-- Attachment #1: Type: text/plain, Size: 4958 bytes --]
A test of PPP over ISDN with ipppd, capidrv and the so far unmerged
CAPI port of the Gigaset driver produced the following lockdep
message:
=======================================================
[ INFO: possible circular locking dependency detected ]
2.6.32-rc4-testing #7
-------------------------------------------------------
ipppd/28379 is trying to acquire lock:
(&netdev->queue_lock){......}, at: [<e62ad0fd>] isdn_net_device_busy+0x2c/0x74 [isdn]
but task is already holding lock:
(&netdev->local->xmit_lock){+.....}, at: [<e62aefc2>] isdn_net_write_super+0x3f/0x6e [isdn]
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&netdev->local->xmit_lock){+.....}:
[<c0157e9c>] __lock_acquire+0xa12/0xb99
[<c01580ac>] lock_acquire+0x89/0xa0
[<c0373249>] _spin_lock+0x1b/0x2a
[<e62b9d1c>] isdn_ppp_xmit+0xf0/0x5b0 [isdn]
[<e62b03f0>] isdn_net_start_xmit+0x4c6/0x66b [isdn]
[<c0307e75>] dev_hard_start_xmit+0x251/0x2e4
[<c0317bcc>] sch_direct_xmit+0x4f/0x122
[<c030829c>] dev_queue_xmit+0x2ae/0x412
[<c030d748>] neigh_resolve_output+0x1f2/0x23c
[<c0329b9c>] ip_finish_output2+0x1b1/0x1db
[<c0329c25>] ip_finish_output+0x5f/0x62
[<c0329cb5>] ip_output+0x8d/0x92
[<c03290c0>] ip_local_out+0x18/0x1b
[<c032932c>] ip_push_pending_frames+0x269/0x2c1
[<c033fd78>] raw_sendmsg+0x618/0x6b0
[<c0347ac9>] inet_sendmsg+0x3b/0x48
[<c02fa5b5>] __sock_sendmsg+0x45/0x4e
[<c02fad4b>] sock_sendmsg+0xb8/0xce
[<c02faea0>] sys_sendmsg+0x13f/0x192
[<c02fbeb2>] sys_socketcall+0x157/0x18e
[<c0102974>] sysenter_do_call+0x12/0x32
-> #0 (&netdev->queue_lock){......}:
[<c0157da9>] __lock_acquire+0x91f/0xb99
[<c01580ac>] lock_acquire+0x89/0xa0
[<c03732db>] _spin_lock_irqsave+0x24/0x34
[<e62ad0fd>] isdn_net_device_busy+0x2c/0x74 [isdn]
[<e62aeee3>] isdn_net_writebuf_skb+0x6e/0xc2 [isdn]
[<e62aefd4>] isdn_net_write_super+0x51/0x6e [isdn]
[<e62bc26f>] isdn_ppp_write+0x3a8/0x3bc [isdn]
[<e62b785a>] isdn_write+0x1d9/0x1f9 [isdn]
[<c01c42c5>] vfs_write+0x84/0xdf
[<c01c43b9>] sys_write+0x3b/0x60
[<c0102974>] sysenter_do_call+0x12/0x32
other info that might help us debug this:
1 lock held by ipppd/28379:
#0: (&netdev->local->xmit_lock){+.....}, at: [<e62aefc2>] isdn_net_write_super+0x3f/0x6e [isdn]
stack backtrace:
Pid: 28379, comm: ipppd Not tainted 2.6.32-rc4-testing #7
Call Trace:
[<c03710dc>] ? printk+0xf/0x13
[<c015714d>] print_circular_bug+0x90/0x9c
[<c0157da9>] __lock_acquire+0x91f/0xb99
[<c01580ac>] lock_acquire+0x89/0xa0
[<e62ad0fd>] ? isdn_net_device_busy+0x2c/0x74 [isdn]
[<c03732db>] _spin_lock_irqsave+0x24/0x34
[<e62ad0fd>] ? isdn_net_device_busy+0x2c/0x74 [isdn]
[<e62ad0fd>] isdn_net_device_busy+0x2c/0x74 [isdn]
[<e62aeee3>] isdn_net_writebuf_skb+0x6e/0xc2 [isdn]
[<e62aefd4>] isdn_net_write_super+0x51/0x6e [isdn]
[<e62bc26f>] isdn_ppp_write+0x3a8/0x3bc [isdn]
[<e62b785a>] isdn_write+0x1d9/0x1f9 [isdn]
[<c01c3b6c>] ? rw_verify_area+0x8a/0xad
[<e62b7681>] ? isdn_write+0x0/0x1f9 [isdn]
[<c01c42c5>] vfs_write+0x84/0xdf
[<c01c43b9>] sys_write+0x3b/0x60
[<c0102974>] sysenter_do_call+0x12/0x32
The message appeared shortly after initiating the connection,
during the PPP negotiation, just when the IP address was assigned.
The system continued to run normally, and the connection was
successfully established. Full log showing the entire connection
(with capidrv and Gigaset driver debugging output enabled, 70 kB),
available at http://www.phoenixsoftware.de/~ts/ppp-lockprob-full.log
in case someone's interested. It shows the messages from ipppd
about the IP address assignment arriving in the middle of the
lockdep message.
I cannot say whether this is a regression. My previous tests of
that scenario were done on a machine with an Nvidia graphics card
where the lockdep machinery would refuse to run because of the
kernel being tainted by the Nvidia driver, so I wouldn't have seen
anything one way or another.
Btw, one of those "NOHZ: local_softirq_pending 08" messages is also
present in the log, but that's 28 seconds later so I'd be surprised
if the two were related.
Any hints about the possible cause and seriousness of that
message would be welcome. I'm particularly interested, of course,
in finding out whether the Gigaset driver might somehow be causing
it, even though it doesn't appear anywhere in the backtraces.
aTdHvAaNnKcSe
Tilman
--
Tilman Schmidt E-Mail: tilman@imap.cc
Bonn, Germany
Diese Nachricht besteht zu 100% aus wiederverwerteten Bits.
Ungeöffnet mindestens haltbar bis: (siehe Rückseite)
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]
^ permalink raw reply
* Re: [PATCH 0/2] Reduce number of GFP_ATOMIC allocation failures
From: Karol Lewandowski @ 2009-10-18 22:18 UTC (permalink / raw)
To: Karol Lewandowski
Cc: Mel Gorman, Andrew Morton, stable, Rafael J. Wysocki,
David Miller, Frans Pop, reinette chatre, Kalle Valo,
John W. Linville, Pekka Enberg, Bartlomiej Zolnierkiewicz, netdev,
linux-kernel, linux-mm@kvack.org
In-Reply-To: <20091017183421.GA3370@bizet.domek.prywatny>
On Sat, Oct 17, 2009 at 08:34:21PM +0200, Karol Lewandowski wrote:
> I'll go now for another round of bisecting... and hopefully this time
> I'll be able to trigger this problem on different/faster computer with
> e100-based card.
No luck with that either.
I've tried merging 'akpm' (517d08699b25) into clean 2.6.30 tree and
got suspend-breakage which makes it untestable for me. (I've tried
reverting drm, suspend, and other commits... all that failed.)
Is there mm-related git tree hidden somewhere? ... or broken out
mm-related patches that were sent to Andrew ... or maybe it's possible
to get "git log -p" from Mel's private repo? Anything?
Thanks.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH] fix section mismatch in fec.c
From: Steven King @ 2009-10-18 22:25 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
fec_enet_init is called by both fec_probe and fec_resume, so it shouldn't
be marked as __init.
Signed-off-by: Steven King <sfking@fdwdc.com>
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2923438..e8218a3 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1654,7 +1654,8 @@ static const struct net_device_ops fec_netdev_ops = {
*
* index is only used in legacy code
*/
-int __init fec_enet_init(struct net_device *dev, int index)
+static int
+fec_enet_init(struct net_device *dev, int index)
{
struct fec_enet_private *fep = netdev_priv(dev);
struct bufdesc *cbd_base;
--
Steven King -- sfking at fdwdc dot com
^ permalink raw reply related
* Re: [PATCH 0/2] Reduce number of GFP_ATOMIC allocation failures
From: Frans Pop @ 2009-10-18 22:31 UTC (permalink / raw)
To: Karol Lewandowski
Cc: Mel Gorman, Andrew Morton, stable, Rafael J. Wysocki,
David Miller, reinette chatre, Kalle Valo, John W. Linville,
Pekka Enberg, Bartlomiej Zolnierkiewicz, netdev, linux-kernel,
linux-mm@kvack.org
In-Reply-To: <20091018221844.GA2061@bizet.domek.prywatny>
Hi Karol,
On Monday 19 October 2009, Karol Lewandowski wrote:
> On Sat, Oct 17, 2009 at 08:34:21PM +0200, Karol Lewandowski wrote:
> > I'll go now for another round of bisecting... and hopefully this time
> > I'll be able to trigger this problem on different/faster computer with
> > e100-based card.
>
> No luck with that either.
>
> I've tried merging 'akpm' (517d08699b25) into clean 2.6.30 tree and
> got suspend-breakage which makes it untestable for me. (I've tried
> reverting drm, suspend, and other commits... all that failed.)
>
> Is there mm-related git tree hidden somewhere? ... or broken out
> mm-related patches that were sent to Andrew ... or maybe it's possible
> to get "git log -p" from Mel's private repo? Anything?
Please try reverting 373c0a7e + 8aa7e847 [1] on top of 2.6.31. I've finally
been able to solidly trace the main regression to that. I'm doing some
final confirmation tests now and will mail detailed results afterwards.
It would be great if you could confirm if that fixes the issue for you too.
Cheers,
FJP
[1] The first commit is a build fix for the second.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] iputils: ping by mark
From: Maciej Żenczykowski @ 2009-10-18 22:57 UTC (permalink / raw)
To: hadi; +Cc: Rob.Townley, YOSHIFUJI Hideaki, netdev
In-Reply-To: <1255865866.4815.21.camel@dogo.mojatatu.com>
> It works fine with tcp and udp and to emphasize: i have never seen it
> broken.
Really? Ok, so we're doing something very differently...
My testing was done on a 2.6.26 kernel (but AFAICT from browsing the
code, the behaviour in question should not have changed till the last
few patches posted in the last 2-3 weeks).
^ permalink raw reply
* [PATCH 3/9] pcmcia: use pcmcia_loop_config in misc pcmcia drivers
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia
Cc: Dominik Brodowski, David S. Miller, John W. Linville, Jiri Kosina,
David Sterba, netdev, linux-wireless
In-Reply-To: <1255907255-28297-2-git-send-email-linux@dominikbrodowski.net>
Use pcmcia_loop_config() in a few drivers missed during the first
round. On fmvj18x_cs.c it -- strangely -- only requries us to set
conf.ConfigIndex, which is done by the core, so include an empty
loop function which returns 0 unconditionally.
CC: David S. Miller <davem@davemloft.net>
CC: John W. Linville <linville@tuxdriver.com>
CC: Jiri Kosina <jkosina@suse.cz>
CC: David Sterba <dsterba@suse.cz>
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/char/pcmcia/ipwireless/main.c | 103 +++++++--------------------------
drivers/char/pcmcia/synclink_cs.c | 64 ++++++++-------------
drivers/net/pcmcia/fmvj18x_cs.c | 22 +++++--
drivers/net/wireless/libertas/if_cs.c | 67 +++++++++-------------
4 files changed, 88 insertions(+), 168 deletions(-)
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 5216fce..263a18f 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -79,14 +79,32 @@ static void signalled_reboot_callback(void *callback_data)
schedule_work(&ipw->work_reboot);
}
+static int ipwireless_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->io.IOAddrLines = 16;
+
+ p_dev->irq.IRQInfo1 = cfg->irq.IRQInfo1;
+
+ /* 0x40 causes it to generate level mode interrupts. */
+ /* 0x04 enables IREQ pin. */
+ p_dev->conf.ConfigIndex = cfg->index | 0x44;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int config_ipwireless(struct ipw_dev *ipw)
{
struct pcmcia_device *link = ipw->link;
- int ret;
+ int ret = 0;
tuple_t tuple;
unsigned short buf[64];
cisparse_t parse;
- unsigned short cor_value;
memreq_t memreq_attr_memory;
memreq_t memreq_common_memory;
@@ -97,103 +115,26 @@ static int config_ipwireless(struct ipw_dev *ipw)
tuple.TupleDataMax = sizeof(buf);
tuple.TupleOffset = 0;
- tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- while (ret == 0) {
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
- ret = pcmcia_get_next_tuple(link, &tuple);
- }
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
-
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, ParseTuple, ret);
- goto exit0;
- }
-
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
- link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
- link->io.IOAddrLines = 16;
-
- link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
-
- /* 0x40 causes it to generate level mode interrupts. */
- /* 0x04 enables IREQ pin. */
- cor_value = parse.cftable_entry.index | 0x44;
- link->conf.ConfigIndex = cor_value;
-
- /* IRQ and I/O settings */
- tuple.DesiredTuple = CISTPL_CONFIG;
-
- ret = pcmcia_get_first_tuple(link, &tuple);
-
+ ret = pcmcia_loop_config(link, ipwireless_ioprobe, NULL);
if (ret != 0) {
- cs_error(link, GetFirstTuple, ret);
- goto exit0;
- }
-
- ret = pcmcia_get_tuple_data(link, &tuple);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
+ cs_error(link, RequestIO, ret);
goto exit0;
}
- ret = pcmcia_parse_tuple(&tuple, &parse);
-
- if (ret != 0) {
- cs_error(link, GetTupleData, ret);
- goto exit0;
- }
link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
link->conf.IntType = INT_MEMORY_AND_IO;
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
link->irq.Handler = ipwireless_interrupt;
link->irq.Instance = ipw->hardware;
- ret = pcmcia_request_io(link, &link->io);
-
- if (ret != 0) {
- cs_error(link, RequestIO, ret);
- goto exit0;
- }
-
request_region(link->io.BasePort1, link->io.NumPorts1,
IPWIRELESS_PCCARD_NAME);
/* memory settings */
-
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
ret = pcmcia_get_first_tuple(link, &tuple);
-
if (ret != 0) {
cs_error(link, GetFirstTuple, ret);
goto exit1;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index caf6e4d..429b731 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -575,55 +575,39 @@ static int mgslpc_probe(struct pcmcia_device *link)
#define CS_CHECK(fn, ret) \
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->io.nwin > 0) {
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(cfg->io.flags & CISTPL_IO_8BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(cfg->io.flags & CISTPL_IO_16BIT))
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ return -ENODEV;
+}
+
static int mgslpc_config(struct pcmcia_device *link)
{
MGSLPC_INFO *info = link->priv;
- tuple_t tuple;
- cisparse_t parse;
- int last_fn, last_ret;
- u_char buf[64];
- cistpl_cftable_entry_t dflt = { 0 };
- cistpl_cftable_entry_t *cfg;
+ int last_fn = RequestIO;
+ int last_ret;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_config(0x%p)\n", link);
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- /* get CIS configuration entry */
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
- cfg = &(parse.cftable_entry);
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
- if (cfg->index == 0)
+ last_ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+ if (last_ret != 0)
goto cs_failed;
- link->conf.ConfigIndex = cfg->index;
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
- }
-
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 8;
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 7e01fbd..c7a2bbf 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -341,14 +341,23 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
return ret; /* RequestIO failed */
}
+static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ return 0; /* strange, but that's what the code did already before... */
+}
+
+
static int fmvj18x_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
tuple_t tuple;
- cisparse_t parse;
u_short buf[32];
- int i, last_fn = 0, last_ret = 0, ret;
+ int i, last_fn = RequestIO, last_ret = 0, ret;
unsigned int ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
@@ -362,12 +371,11 @@ static int fmvj18x_config(struct pcmcia_device *link)
tuple.DesiredTuple = CISTPL_FUNCE;
tuple.TupleOffset = 0;
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+ last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
+ if (last_ret != 0)
+ goto cs_failed;
+
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
- link->conf.ConfigIndex = parse.cftable_entry.index;
switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 6238176..cb40c38 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
* configure the card at this point -- we wait until we receive a card
* insertion event.
*/
+
+static int if_cs_ioprobe(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->io.BasePort1 = cfg->io.win[0].base;
+ p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ if (cfg->io.nwin != 1) {
+ lbs_pr_err("wrong CIS (check number of IO windows)\n");
+ return -ENODEV;
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
static int if_cs_probe(struct pcmcia_device *p_dev)
{
int ret = -ENOMEM;
unsigned int prod_id;
struct lbs_private *priv;
struct if_cs_card *card;
- /* CIS parsing */
- tuple_t tuple;
- cisparse_t parse;
- cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
- cistpl_io_t *io = &cfg->io;
- u_char buf[64];
lbs_deb_enter(LBS_DEB_CS);
@@ -823,43 +842,11 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
p_dev->conf.Attributes = 0;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
- (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
- {
- lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
- goto out1;
- }
-
- p_dev->conf.ConfigIndex = cfg->index;
-
- /* Do we need to allocate an interrupt? */
- if (cfg->irq.IRQInfo1) {
- p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
- }
-
- /* IO window settings */
- if (cfg->io.nwin != 1) {
- lbs_pr_err("wrong CIS (check number of IO windows)\n");
- ret = -ENODEV;
+ if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
+ lbs_pr_err("error in pcmcia_loop_config\n");
goto out1;
}
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
- /* This reserves IO space but doesn't actually enable it */
- ret = pcmcia_request_io(p_dev, &p_dev->io);
- if (ret) {
- lbs_pr_err("error in pcmcia_request_io\n");
- goto out1;
- }
/*
* Allocate an interrupt line. Note that this does not assign
--
1.6.0.4
^ permalink raw reply related
* [PATCH 2/9] pcmcia: use pre-determined values
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia
Cc: Dominik Brodowski, David S. Miller, John W. Linville, netdev,
linux-wireless
In-Reply-To: <1255907255-28297-1-git-send-email-linux@dominikbrodowski.net>
A few PCMCIA network drivers can make use of values provided by the pcmcia
core, instead of tedious, independent CIS parsing.
xirc32ps_cs.c: manf_id
hostap_cs.c: multifunction count
b43/pcmcia.c: ConfigBase address and "Present"
smc91c92_cs.c: By default, mhz_setup() can use VERS_1 as it is stored
in struct pcmcia_device. Only some cards require workarounds, such as
reading out VERS_1 twice.
CC: David S. Miller <davem@davemloft.net>
CC: John W. Linville <linville@tuxdriver.com>
CC: netdev@vger.kernel.org
CC: linux-wireless@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/net/pcmcia/smc91c92_cs.c | 11 +++++++++--
drivers/net/pcmcia/xirc2ps_cs.c | 5 ++---
drivers/net/wireless/b43/pcmcia.c | 20 --------------------
drivers/net/wireless/hostap/hostap_cs.c | 21 +--------------------
4 files changed, 12 insertions(+), 45 deletions(-)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 7bde2cd..af03759 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -545,6 +545,14 @@ static int mhz_setup(struct pcmcia_device *link)
u_char *buf, *station_addr;
int rc;
+ /* Read the station address from the CIS. It is stored as the last
+ (fourth) string in the Version 1 Version/ID tuple. */
+ if ((link->prod_id[3]) &&
+ (cvt_ascii_address(dev, link->prod_id[3]) == 0))
+ return 0;
+
+ /* Workarounds for broken cards start here. */
+
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
if (!cfg_mem)
return -1;
@@ -557,8 +565,7 @@ static int mhz_setup(struct pcmcia_device *link)
tuple->TupleData = (cisdata_t *)buf;
tuple->TupleDataMax = 255;
- /* Read the station address from the CIS. It is stored as the last
- (fourth) string in the Version 1 Version/ID tuple. */
+ /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
tuple->DesiredTuple = CISTPL_VERS_1;
if (first_tuple(link, tuple, parse) != 0) {
rc = -1;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index cf84231..3dd6ba6 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -792,13 +792,12 @@ xirc2ps_config(struct pcmcia_device * link)
tuple.TupleOffset = 0;
/* Is this a valid card */
- tuple.DesiredTuple = CISTPL_MANFID;
- if ((err=first_tuple(link, &tuple, &parse))) {
+ if (link->has_manf_id == 0) {
printk(KNOT_XIRC "manfid not found in CIS\n");
goto failure;
}
- switch(parse.manfid.manf) {
+ switch (link->manf_id) {
case MANFID_XIRCOM:
local->manf_str = "Xircom";
break;
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 6c3a749..cd14b7e 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
struct ssb_bus *ssb;
win_req_t win;
memreq_t mem;
- tuple_t tuple;
- cisparse_t parse;
int err = -ENOMEM;
int res = 0;
- unsigned char buf[64];
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
if (!ssb)
goto out_error;
err = -ENODEV;
- tuple.DesiredTuple = CISTPL_CONFIG;
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- res = pcmcia_get_first_tuple(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_get_tuple_data(dev, &tuple);
- if (res != 0)
- goto err_kfree_ssb;
- res = pcmcia_parse_tuple(&tuple, &parse);
- if (res != 0)
- goto err_kfree_ssb;
-
- dev->conf.ConfigBase = parse.config.base;
- dev->conf.Present = parse.config.rmask[0];
dev->conf.Attributes = CONF_ENABLE_IRQ;
dev->conf.IntType = INT_MEMORY_AND_IO;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index ad8eab4..31b60dd 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
conf_reg_t reg;
struct hostap_interface *iface = netdev_priv(dev);
local_info_t *local = iface->local;
- tuple_t tuple;
- cisparse_t *parse = NULL;
- u_char buf[64];
struct hostap_cs_priv *hw_priv = local->hw_priv;
if (hw_priv->link->io.NumPorts1 < 0x42) {
@@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
goto done;
}
- parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
- if (parse == NULL) {
- ret = -ENOMEM;
- goto done;
- }
-
- tuple.Attributes = TUPLE_RETURN_COMMON;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
-
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
/* No SanDisk manfid found */
ret = -ENODEV;
goto done;
}
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
- pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
- pcmcia_parse_tuple(&tuple, parse) ||
- parse->longlink_mfc.nfn < 2) {
+ if (hw_priv->link->socket->functions < 2) {
/* No multi-function links found */
ret = -ENODEV;
goto done;
@@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
udelay(10);
done:
- kfree(parse);
return ret;
}
--
1.6.0.4
^ permalink raw reply related
* [PATCH 6/9] pcmcia: convert net pcmcia drivers to use new CIS helpers
From: Dominik Brodowski @ 2009-10-18 23:07 UTC (permalink / raw)
To: linux-pcmcia; +Cc: Dominik Brodowski, David S. Miller, netdev
In-Reply-To: <1255907255-28297-5-git-send-email-linux@dominikbrodowski.net>
Use the new CIS helpers in net pcmcia drivers, which allows for
a few code cleanups.
CC: David S. Miller <davem@davemloft.net>
CC: netdev@vger.kernel.org
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
drivers/net/pcmcia/3c574_cs.c | 18 ++--
drivers/net/pcmcia/3c589_cs.c | 24 ++---
drivers/net/pcmcia/fmvj18x_cs.c | 51 ++++-----
drivers/net/pcmcia/nmclan_cs.c | 19 ++--
drivers/net/pcmcia/smc91c92_cs.c | 238 +++++++++++---------------------------
drivers/net/pcmcia/xirc2ps_cs.c | 101 ++++++----------
6 files changed, 154 insertions(+), 297 deletions(-)
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index b58965a..6449290 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -344,13 +344,13 @@ static int tc574_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
int last_fn, last_ret, i, j;
unsigned int ioaddr;
__be16 *phys_addr;
char *cardname;
__u32 config;
+ u8 *buf;
+ size_t len;
phys_addr = (__be16 *)dev->dev_addr;
@@ -378,16 +378,14 @@ static int tc574_config(struct pcmcia_device *link)
/* The 3c574 normally uses an EEPROM for configuration info, including
the hardware address. The future products may include a modem chip
and put the address in the CIS. */
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
+
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
EL3WINDOW(0);
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 569fb06..ea04356 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -256,22 +256,15 @@ static int tc589_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct el3_private *lp = netdev_priv(dev);
- tuple_t tuple;
- __le16 buf[32];
- __be16 *phys_addr;
+ __be16 *phys_addr = NULL;
int last_fn, last_ret, i, j, multi = 0, fifo;
unsigned int ioaddr;
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ u8 *buf;
+ size_t len;
DEBUG(0, "3c589_config(0x%p)\n", link);
- phys_addr = (__be16 *)dev->dev_addr;
- tuple.Attributes = 0;
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.Attributes = TUPLE_RETURN_COMMON;
-
/* Is this a 3c562? */
if (link->manf_id != MANFID_3COM)
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -301,12 +294,13 @@ static int tc589_config(struct pcmcia_device *link)
/* The 3c589 has an extra EEPROM for configuration info, including
the hardware address. The 3c562 puts the address in the CIS. */
- tuple.DesiredTuple = 0x88;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
- pcmcia_get_tuple_data(link, &tuple);
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(le16_to_cpu(buf[i]));
+ len = pcmcia_get_tuple(link, 0x88, &buf);
+ if (buf && len >= 6) {
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+ kfree(buf);
} else {
+ kfree(buf); /* 0 < len < 6 */
for (i = 0; i < 3; i++)
phys_addr[i] = htons(read_eeprom(ioaddr, i));
if (phys_addr[0] == htons(0x6060)) {
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index c7a2bbf..58954a6 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -350,32 +350,30 @@ static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
return 0; /* strange, but that's what the code did already before... */
}
-
static int fmvj18x_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
local_info_t *lp = netdev_priv(dev);
- tuple_t tuple;
- u_short buf[32];
int i, last_fn = RequestIO, last_ret = 0, ret;
unsigned int ioaddr;
cardtype_t cardtype;
char *card_name = "unknown";
- u_char *node_id;
+ u8 *buf;
+ size_t len;
+ u_char buggybuf[32];
DEBUG(0, "fmvj18x_config(0x%p)\n", link);
- tuple.TupleData = (u_char *)buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ if (buf)
+ kfree(buf);
+
+ if (len) {
+ /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
last_ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
if (last_ret != 0)
goto cs_failed;
- /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
switch (link->manf_id) {
case MANFID_TDK:
cardtype = TDK;
@@ -482,21 +480,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
case CONTEC:
case NEC:
case KME:
- tuple.DesiredTuple = CISTPL_FUNCE;
- tuple.TupleOffset = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- tuple.TupleOffset = 0;
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
if (cardtype == MBH10304) {
- /* MBH10304's CIS_FUNCE is corrupted */
- node_id = &(tuple.TupleData[5]);
card_name = "FMV-J182";
- } else {
- while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
- CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+
+ len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+ if (len < 11) {
+ kfree(buf);
+ goto failed;
}
- node_id = &(tuple.TupleData[2]);
+ /* Read MACID from CIS */
+ for (i = 5; i < 11; i++)
+ dev->dev_addr[i] = buf[i];
+ kfree(buf);
+ } else {
+ if (pcmcia_get_mac_from_cis(link, dev))
+ goto failed;
if( cardtype == TDK ) {
card_name = "TDK LAK-CD021";
} else if( cardtype == LA501 ) {
@@ -509,9 +507,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
card_name = "C-NET(PC)C";
}
}
- /* Read MACID from CIS */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id[i];
break;
case UNGERMANN:
/* Read MACID from register */
@@ -521,12 +516,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
break;
case XXX10304:
/* Read MACID from Buggy CIS */
- if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
+ if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
goto failed;
}
for (i = 0 ; i < 6; i++) {
- dev->dev_addr[i] = tuple.TupleData[i];
+ dev->dev_addr[i] = buggybuf[i];
}
card_name = "FMV-J182";
break;
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 5ed6339..4b96b35 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -661,8 +661,8 @@ static int nmclan_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
mace_private *lp = netdev_priv(dev);
- tuple_t tuple;
- u_char buf[64];
+ u8 *buf;
+ size_t len;
int i, last_ret, last_fn;
unsigned int ioaddr;
@@ -677,14 +677,13 @@ static int nmclan_config(struct pcmcia_device *link)
ioaddr = dev->base_addr;
/* Read the ethernet address from the CIS. */
- tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
- tuple.TupleData = buf;
- tuple.TupleDataMax = 64;
- tuple.TupleOffset = 0;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
- memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+ len = pcmcia_get_tuple(link, 0x80, &buf);
+ if (!buf || len < ETHER_ADDR_LEN) {
+ kfree(buf);
+ goto failed;
+ }
+ memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
+ kfree(buf);
/* Verify configuration by reading the MACE ID. */
{
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index af03759..df92bcd 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -126,12 +126,6 @@ struct smc_private {
int rx_ovrn;
};
-struct smc_cfg_mem {
- tuple_t tuple;
- cisparse_t parse;
- u_char buf[255];
-};
-
/* Special definitions for Megahertz multifunction cards */
#define MEGAHERTZ_ISR 0x0380
@@ -408,34 +402,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
return 0;
}
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- i = pcmcia_get_first_tuple(handle, tuple);
- if (i != 0)
- return i;
- i = pcmcia_get_tuple_data(handle, tuple);
- if (i != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
- cisparse_t *parse)
-{
- int i;
-
- if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
- (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
- return i;
- return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
Configuration stuff for Megahertz cards
@@ -490,15 +457,10 @@ static int mhz_mfc_config(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
- struct smc_cfg_mem *cfg_mem;
win_req_t req;
memreq_t mem;
int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
link->irq.Attributes =
@@ -510,7 +472,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
- goto free_cfg_mem;
+ return -ENODEV;
+
dev->base_addr = link->io.BasePort1;
/* Allocate a memory window, for accessing the ISR */
@@ -519,7 +482,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
req.AccessSpeed = 0;
i = pcmcia_request_window(&link, &req, &link->win);
if (i != 0)
- goto free_cfg_mem;
+ return -ENODEV;
+
smc->base = ioremap(req.Base, req.Size);
mem.CardOffset = mem.Page = 0;
if (smc->manfid == MANFID_MOTOROLA)
@@ -531,18 +495,32 @@ static int mhz_mfc_config(struct pcmcia_device *link)
&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
-free_cfg_mem:
- kfree(cfg_mem);
- return -ENODEV;
+ return 0;
}
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ cisparse_t parse;
+
+ if (pcmcia_parse_tuple(tuple, &parse))
+ return -EINVAL;
+
+ if ((parse.version_1.ns > 3) &&
+ (cvt_ascii_address(dev,
+ (parse.version_1.str + parse.version_1.ofs[3]))))
+ return 0;
+
+ return -EINVAL;
+};
+
static int mhz_setup(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- u_char *buf, *station_addr;
+ size_t len;
+ u8 *buf;
int rc;
/* Read the station address from the CIS. It is stored as the last
@@ -552,56 +530,22 @@ static int mhz_setup(struct pcmcia_device *link)
return 0;
/* Workarounds for broken cards start here. */
-
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
-
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- tuple->DesiredTuple = CISTPL_VERS_1;
- if (first_tuple(link, tuple, parse) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
- if (next_tuple(link, tuple, parse) != 0)
- first_tuple(link, tuple, parse);
- if (parse->version_1.ns > 3) {
- station_addr = parse->version_1.str + parse->version_1.ofs[3];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
- }
+ if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+ return 0;
/* Another possibility: for the EM3288, in a special tuple */
- tuple->DesiredTuple = 0x81;
- if (pcmcia_get_first_tuple(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- if (pcmcia_get_tuple_data(link, tuple) != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- buf[12] = '\0';
- if (cvt_ascii_address(dev, buf) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
-}
+ len = pcmcia_get_tuple(link, 0x81, &buf);
+ if (buf && len >= 13) {
+ buf[12] = '\0';
+ if (cvt_ascii_address(dev, buf))
+ rc = 0;
+ }
+ kfree(buf);
+
+ return rc;
+};
/*======================================================================
@@ -691,58 +635,21 @@ static int smc_config(struct pcmcia_device *link)
return i;
}
+
static int smc_setup(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- cisparse_t *parse;
- cistpl_lan_node_id_t *node_id;
- u_char *buf, *station_addr;
- int i, rc;
-
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -ENOMEM;
-
- tuple = &cfg_mem->tuple;
- parse = &cfg_mem->parse;
- buf = cfg_mem->buf;
-
- tuple->Attributes = tuple->TupleOffset = 0;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
/* Check for a LAN function extension tuple */
- tuple->DesiredTuple = CISTPL_FUNCE;
- i = first_tuple(link, tuple, parse);
- while (i == 0) {
- if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
- break;
- i = next_tuple(link, tuple, parse);
- }
- if (i == 0) {
- node_id = (cistpl_lan_node_id_t *)parse->funce.data;
- if (node_id->nb == 6) {
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
- rc = 0;
- goto free_cfg_mem;
- }
- }
+ if (!pcmcia_get_mac_from_cis(link, dev))
+ return 0;
+
/* Try the third string in the Version 1 Version/ID tuple. */
if (link->prod_id[2]) {
- station_addr = link->prod_id[2];
- if (cvt_ascii_address(dev, station_addr) == 0) {
- rc = 0;
- goto free_cfg_mem;
- }
+ if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+ return 0;
}
-
- rc = -1;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return -1;
}
/*====================================================================*/
@@ -801,41 +708,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
return err;
}
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
{
- struct net_device *dev = link->priv;
- struct smc_cfg_mem *cfg_mem;
- tuple_t *tuple;
- u_char *buf;
- int i, rc;
+ struct net_device *dev = priv;
+ int i;
- cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
- if (!cfg_mem)
- return -1;
+ if (tuple->TupleDataLen < 8)
+ return -EINVAL;
+ if (tuple->TupleData[0] != 0x04)
+ return -EINVAL;
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
- tuple = &cfg_mem->tuple;
- buf = cfg_mem->buf;
- tuple->Attributes = TUPLE_RETURN_COMMON;
- tuple->TupleData = (cisdata_t *)buf;
- tuple->TupleDataMax = 255;
- tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+ struct net_device *dev = link->priv;
+ int rc;
/* Read the station address from tuple 0x90, subtuple 0x04 */
- tuple->DesiredTuple = 0x90;
- i = pcmcia_get_first_tuple(link, tuple);
- while (i == 0) {
- i = pcmcia_get_tuple_data(link, tuple);
- if ((i != 0) || (buf[0] == 0x04))
- break;
- i = pcmcia_get_next_tuple(link, tuple);
- }
- if (i != 0) {
- rc = -1;
- goto free_cfg_mem;
- }
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = buf[i+2];
+ if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+ return -1;
if (((manfid == MANFID_OSITECH) &&
(cardid == PRODID_OSITECH_SEVEN)) ||
@@ -843,7 +740,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
(cardid == PRODID_PSION_NET100))) {
rc = osi_load_firmware(link);
if (rc)
- goto free_cfg_mem;
+ return rc;
} else if (manfid == MANFID_OSITECH) {
/* Make sure both functions are powered up */
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
@@ -853,10 +750,7 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
}
- rc = 0;
-free_cfg_mem:
- kfree(cfg_mem);
- return rc;
+ return 0;
}
static int smc91c92_suspend(struct pcmcia_device *link)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 3dd6ba6..8ed8449 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -371,28 +371,6 @@ static void do_powerdown(struct net_device *dev);
static int do_stop(struct net_device *dev);
/*=============== Helper functions =========================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
- int err;
-
- if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
- err = pcmcia_parse_tuple(tuple, parse);
- return err;
-}
-
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
@@ -761,6 +739,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
}
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+ tuple_t *tuple,
+ void *priv)
+{
+ struct net_device *dev = priv;
+ int i;
+
+ if (tuple->TupleDataLen != 13)
+ return -EINVAL;
+ if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+ (tuple->TupleData[2] != 6))
+ return -EINVAL;
+ /* another try (James Lehmer's CE2 version 4.1)*/
+ for (i = 2; i < 6; i++)
+ dev->dev_addr[i] = tuple->TupleData[i+2];
+ return 0;
+};
+
+
/****************
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
* is received, to configure the PCMCIA socket, and to make the
@@ -774,9 +772,9 @@ xirc2ps_config(struct pcmcia_device * link)
unsigned int ioaddr;
tuple_t tuple;
cisparse_t parse;
- int err, i;
- u_char buf[64];
- cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
+ int err;
+ u8 *buf;
+ size_t len;
local->dingo_ccr = NULL;
@@ -827,49 +825,28 @@ xirc2ps_config(struct pcmcia_device * link)
}
/* get the ethernet address from the CIS */
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
- * the first one with a length of zero the second correct -
- * so I skip all entries with length 0 */
- if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
- && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
- break;
- }
- if (err) { /* not found: try to get the node-id from tuple 0x89 */
- tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
- if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
- (err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
- if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
- memcpy(&parse, buf, 8);
- else
- err = -1;
- }
- }
- if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
- tuple.DesiredTuple = CISTPL_FUNCE;
- for (err = first_tuple(link, &tuple, &parse); !err;
- err = next_tuple(link, &tuple, &parse)) {
- if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
- && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
- buf[1] = 4;
- memcpy(&parse, buf+1, 8);
- break;
+ err = pcmcia_get_mac_from_cis(link, dev);
+
+ /* not found: try to get the node-id from tuple 0x89 */
+ if (err) {
+ len = pcmcia_get_tuple(link, 0x89, &buf);
+ /* data layout looks like tuple 0x22 */
+ if (buf && len == 8) {
+ if (*buf == CISTPL_FUNCE_LAN_NODE_ID)
+ memcpy(&parse, buf, 8);
+ else
+ err = -1;
}
- }
+ kfree(buf);
}
+
+ if (err)
+ err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
if (err) {
printk(KNOT_XIRC "node-id not found in CIS\n");
goto failure;
}
- node_id = (cistpl_lan_node_id_t *)parse.funce.data;
- if (node_id->nb != 6) {
- printk(KNOT_XIRC "malformed node-id in CIS\n");
- goto failure;
- }
- for (i=0; i < 6; i++)
- dev->dev_addr[i] = node_id->id[i];
link->io.IOAddrLines =10;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH][RFC]: ingress socket filter by mark
From: Maciej Żenczykowski @ 2009-10-18 23:09 UTC (permalink / raw)
To: hadi; +Cc: Eric Dumazet, netdev, David Miller, Atis Elsts
In-Reply-To: <1255897680.4815.63.camel@dogo.mojatatu.com>
I haven't looked at the patches, but I do not believe requiring
marking to be symmetric to be a good idea.
Example:
- a relatively complex router/load balancer setup
- normal (no mark) packets get routed/load balanced to destinations
which are healthy
- a separate job which health checks the destinations (and updates the
no mark routing table on destination health state transitions) - it
uses socket marking to select a separate routing table which throws
all load at a specific destination host.
ie. the socket marking is used to explicitly direct load at a specific
destination host.
Obviously only the transmit path is affected. There is no marking
happening on the receive path.
Another example would be tunneling. I'd envision something like:
ip tunnel add vtun0 mode gre remote ... local ... tos inherit ttl 64 mark 0x1234
ip rule add fwmark 0x1234 lookup 250
ip route add 192.168.1.0/24 dev eth0 table 250
ip route add default via 192.168.1.1 dev eth0 table 250
ip route add default dev vtun0 table main
(obviously this is just an example and not fully fleshed out,
furthermore ip tunnel doesn't currently support mark, nor do the
tunnel modules themselves)
If you do want to allow explicit incoming mark filtering use another
socket option (SO_MARK_RCV) and a different/new socket field.
>> I vote for extending BPF, and not adding the price of a compare
>> for each packet. Only users wanting mark filtering should pay the price.
I agree that being able to filter on mark in bpf makes a lot of sense.
I wonder if we're not hitting the filters potentially before the mark
is set though (on receive at least)...
I'm nowhere near sure but I think packets get diverted/cloned to
tcpdump before they hit the ip stack (and thus potentially get marked
by ip(6)table mangle rules)
^ permalink raw reply
* Re: [PATCH 0/2] Reduce number of GFP_ATOMIC allocation failures
From: Karol Lewandowski @ 2009-10-19 0:36 UTC (permalink / raw)
To: Frans Pop
Cc: Karol Lewandowski, Mel Gorman, Andrew Morton, stable,
Rafael J. Wysocki, David Miller, reinette chatre, Kalle Valo,
John W. Linville, Pekka Enberg, Bartlomiej Zolnierkiewicz, netdev,
linux-kernel, linux-mm@kvack.org
In-Reply-To: <200910190031.23237.elendil@planet.nl>
On Mon, Oct 19, 2009 at 12:31:15AM +0200, Frans Pop wrote:
> Hi Karol,
Hi,
> > I've tried merging 'akpm' (517d08699b25) into clean 2.6.30 tree and
> > got suspend-breakage which makes it untestable for me. (I've tried
> > reverting drm, suspend, and other commits... all that failed.)
> >
> > Is there mm-related git tree hidden somewhere? ... or broken out
> > mm-related patches that were sent to Andrew ... or maybe it's possible
> > to get "git log -p" from Mel's private repo? Anything?
>
> Please try reverting 373c0a7e + 8aa7e847 [1] on top of 2.6.31. I've finally
> been able to solidly trace the main regression to that. I'm doing some
> final confirmation tests now and will mail detailed results afterwards.
>
> It would be great if you could confirm if that fixes the issue for you too.
Sadly, reverting these patches didn't fix my problem. I've just
tested it -- I still get allocation failures.
Thanks.
e100: Intel(R) PRO/100 Network Driver, 3.5.24-k2-NAPI
e100: Copyright(c) 1999-2006 Intel Corporation
e100 0000:00:03.0: PCI INT A -> Link[LNKC] -> GSI 9 (level, low) -> IRQ 9
e100 0000:00:03.0: PME# disabled
e100: eth0: e100_probe: addr 0xe8120000, irq 9, MAC addr 00:10:a4:89:e8:84
ifconfig: page allocation failure. order:5, mode:0x8020
Pid: 2390, comm: ifconfig Not tainted 2.6.31+frans-00002-g90702f9 #1
Call Trace:
[<c015c4c3>] ? __alloc_pages_nodemask+0x405/0x44a
[<c0104de7>] ? dma_generic_alloc_coherent+0x4a/0xab
[<c0104d9d>] ? dma_generic_alloc_coherent+0x0/0xab
[<d1428b6f>] ? e100_alloc_cbs+0xc7/0x174 [e100]
[<d1429bfe>] ? e100_up+0x1b/0xf5 [e100]
[<d1429cef>] ? e100_open+0x17/0x41 [e100]
[<c02f86ff>] ? dev_open+0x8f/0xc5
[<c02f7eb9>] ? dev_change_flags+0xa2/0x155
[<c032da86>] ? devinet_ioctl+0x22a/0x51c
[<c02eba9e>] ? sock_ioctl+0x0/0x1e4
[<c02ebc5e>] ? sock_ioctl+0x1c0/0x1e4
[<c02eba9e>] ? sock_ioctl+0x0/0x1e4
[<c017f21e>] ? vfs_ioctl+0x16/0x4a
[<c017fae5>] ? do_vfs_ioctl+0x48a/0x4c1
[<c016811b>] ? handle_mm_fault+0x1e0/0x42c
[<c0348c4b>] ? do_page_fault+0x2ce/0x2e4
[<c017fb48>] ? sys_ioctl+0x2c/0x42
[<c0102748>] ? sysenter_do_call+0x12/0x26
Mem-Info:
DMA per-cpu:
CPU 0: hi: 0, btch: 1 usd: 0
Normal per-cpu:
CPU 0: hi: 90, btch: 15 usd: 37
Active_anon:25140 active_file:4336 inactive_anon:26654
inactive_file:3697 unevictable:0 dirty:7 writeback:0 unstable:0
free:981 slab:1766 mapped:4904 pagetables:456 bounce:0
DMA free:1116kB min:124kB low:152kB high:184kB active_anon:4304kB inactive_anon:4944kB active_file:764kB inactive_file:740kB unevictable:0kB present:15868kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 238 238
Normal free:2808kB min:1908kB low:2384kB high:2860kB active_anon:96256kB inactive_anon:101672kB active_file:16580kB inactive_file:14048kB unevictable:0kB present:243776kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0
DMA: 13*4kB 5*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 1*1024kB 0*2048kB 0*4096kB = 1116kB
Normal: 454*4kB 62*8kB 31*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 2808kB
13458 total pagecache pages
5159 pages in swap cache
Swap cache stats: add 34436, delete 29277, find 9023/11337
Free swap = 465460kB
Total swap = 514040kB
65520 pages RAM
1663 pages reserved
12098 pages shared
55983 pages non-shared
e100 0000:00:03.0: firmware: requesting e100/d101s_ucode.bin
ADDRCONF(NETDEV_UP): eth0: link is not ready
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH net-next-2.6] inet: rename some inet_sock fields
From: David Miller @ 2009-10-19 1:54 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <4AD74E35.9080004@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 15 Oct 2009 18:30:45 +0200
> In order to have better cache layouts of struct sock (separate zones
> for rx/tx paths), we need this preliminary patch.
>
> Goal is to transfert fields used at lookup time in the first
> read-mostly cache line (inside struct sock_common) and move sk_refcnt
> to a separate cache line (only written by rx path)
>
> This patch adds inet_ prefix to daddr, rcv_saddr, dport, num, saddr,
> sport and id fields. This allows a future patch to define these
> fields as macros, like sk_refcnt, without name clashes.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] cosa: Kill off the use of the old ioctl path
From: David Miller @ 2009-10-19 1:54 UTC (permalink / raw)
To: alan; +Cc: netdev
In-Reply-To: <20091014152224.30363.72926.stgit@localhost.localdomain>
From: Alan Cox <alan@linux.intel.com>
Date: Wed, 14 Oct 2009 16:22:24 +0100
> Signed-off-by: Alan Cox <alan@linux.intel.com>
Applied.
^ permalink raw reply
* Re: [PATCH net-next-2.6] net: sk_drops consolidation part 2
From: David Miller @ 2009-10-19 1:54 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev
In-Reply-To: <4AD6F598.4080007@gmail.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 15 Oct 2009 12:12:40 +0200
> - skb_kill_datagram() can increment sk->sk_drops itself, not callers.
>
> - UDP on IPV4 & IPV6 dropped frames (because of bad checksum or policy checks) increment sk_drops
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Applied.
^ permalink raw reply
* Re: kernel panic in latest vanilla stable, while using nameif with "alive" pppoe interfaces
From: Michal Ostrowski @ 2009-10-19 3:34 UTC (permalink / raw)
To: Denys Fedoryschenko; +Cc: netdev, linux-ppp, paulus, mostrows
In-Reply-To: <200910190002.39937.denys@visp.net.lb>
Here's my theory on this after an inital look...
Looking at the oops report and disassembly of the actual module binary
that caused the oops, one can deduce that:
Execution was in pppoe_flush_dev(). %ebx contained the pointer "struct
pppox_sock *po", which is what we faulted on, excuting "cmp %eax, 0x190(%ebx)".
%ebx value was 0xffffffff (hence we got "NULL pointer dereference at 0x18f").
At this point "i" (stored in %esi) is 15 (valid), meaning that we got a value
of 0xffffffff in pn->hash_table[i].
From this I'd hypothesize that the combination of dev_put() and release_sock()
may have allowed us to free "pn". At the bottom of the loop we alreayd
recognize that since locks are dropped we're responsible for handling
invalidation of objects, and perhaps that should be extended to "pn" as well.
--
Michal Ostrowski
mostrows@gmail.com
---
drivers/net/pppoe.c | 86 ++++++++++++++++++++++++++----
--------------------
1 files changed, 45 insertions(+), 41 deletions(-)
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 7cbf6f9..720c4ea 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -296,6 +296,7 @@ static void pppoe_flush_dev(struct net_device *dev)
BUG_ON(dev == NULL);
+restart:
pn = pppoe_pernet(dev_net(dev));
if (!pn) /* already freed */
return;
@@ -303,48 +304,51 @@ static void pppoe_flush_dev(struct net_device *dev)
write_lock_bh(&pn->hash_lock);
for (i = 0; i < PPPOE_HASH_SIZE; i++) {
struct pppox_sock *po = pn->hash_table[i];
+ struct sock *sk;
- while (po != NULL) {
- struct sock *sk;
- if (po->pppoe_dev != dev) {
- po = po->next;
- continue;
- }
- sk = sk_pppox(po);
- spin_lock(&flush_lock);
- po->pppoe_dev = NULL;
- spin_unlock(&flush_lock);
- dev_put(dev);
-
- /* We always grab the socket lock, followed by the
- * hash_lock, in that order. Since we should
- * hold the sock lock while doing any unbinding,
- * we need to release the lock we're holding.
- * Hold a reference to the sock so it doesn't disappear
- * as we're jumping between locks.
- */
+ while (po && po->pppoe_dev != dev) {
+ po = po->next;
+ }
- sock_hold(sk);
+ if (po == NULL) {
+ continue;
+ }
- write_unlock_bh(&pn->hash_lock);
- lock_sock(sk);
+ sk = sk_pppox(po);
- if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
- pppox_unbind_sock(sk);
- sk->sk_state = PPPOX_ZOMBIE;
- sk->sk_state_change(sk);
- }
+ spin_lock(&flush_lock);
+ po->pppoe_dev = NULL;
+ spin_unlock(&flush_lock);
- release_sock(sk);
- sock_put(sk);
+ dev_put(dev);
- /* Restart scan at the beginning of this hash chain.
- * While the lock was dropped the chain contents may
- * have changed.
- */
- write_lock_bh(&pn->hash_lock);
- po = pn->hash_table[i];
- }
+ /* We always grab the socket lock, followed by the
+ * hash_lock, in that order. Since we should
+ * hold the sock lock while doing any unbinding,
+ * we need to release the lock we're holding.
+ * Hold a reference to the sock so it doesn't disappear
+ * as we're jumping between locks.
+ */
+
+ sock_hold(sk);
+
+ write_unlock_bh(&pn->hash_lock);
+ lock_sock(sk);
+
+ if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+ pppox_unbind_sock(sk);
+ sk->sk_state = PPPOX_ZOMBIE;
+ sk->sk_state_change(sk);
+ }
+
+ release_sock(sk);
+ sock_put(sk);
+
+ /* Restart the flush process from the beginning. While
+ * the lock was dropped the chain contents may have
+ * changed, and sock_put may have made things go away.
+ */
+ goto restart;
}
write_unlock_bh(&pn->hash_lock);
}
--
1.6.3.3
On Sun, Oct 18, 2009 at 4:02 PM, Denys Fedoryschenko <denys@visp.net.lb> wrote:
>
> I have server running as pppoe NAS.
> Tried to rename customers without dropping pppd connections first, got panic
> after few seconds.
> Panic triggerable at 2.6.30.4 and 2.6.31.4
> pppoe users running on eth2
> pppoe flags:
> 1457 root /usr/sbin/pppoe-server -I eth2 -k -L 172.16.1.1 -R
> 172.16.1.2 -N 253 -C gpzone -S gpzone
>
>
> Commands sequence that i think triggered that:
>
> ip link set eth0 down
> ip link set eth1 down
> ip link set eth2 down
> nameif etherx 00:16:76:8D:83:BA
> nameif eth0 00:19:e0:72:4a:37
> nameif eth1 00:19:e0:72:4a:4b
>
> ip addr flush dev eth0
> ip addr flush dev eth1
> ip addr add X.X.X.X/29 dev eth0
> ip addr add 192.168.2.177/24 dev eth0
> ip addr add 192.168.0.1/32 dev eth1
> ip addr add 127.0.0.0/8 dev lo
> #ip link set eth0 up
> ip link set eth0 up
> ip link set eth1 up
> ip link set lo up
> ip route add 0.0.0.0/0 via X.X.X.X
>
>
> [ 103.428591] r8169: eth0: link up
> [ 103.430360] r8169: eth1: link up
> [ 113.361528] BUG: unable to handle kernel
> NULL pointer dereference
> at 0000018f
> [ 113.361717] IP:
> [<f8868269>] pppoe_device_event+0x80/0x12c [pppoe]
> [ 113.361853] *pdpt = 000000003411a001
> *pde = 0000000000000000
> Oct 18 23:59:40 194.146.153.93
> [ 113.362012] Oops: 0000 [#1]
> SMP
> Oct 18 23:59:40 194.146.153.93
> [ 113.362166] last sysfs file: /sys/devices/virtual/vc/vcs3/dev
> [ 113.362246] Modules linked in:
> netconsole
> configfs
> act_skbedit
> sch_ingress
> sch_prio
> cls_flow
> cls_u32
> em_meta
> cls_basic
> xt_dscp
> xt_DSCP
> ipt_REJECT
> ts_bm
> xt_string
> xt_hl
> ifb
> cls_fw
> sch_tbf
> sch_htb
> act_ipt
> act_mirred
> xt_MARK
> pppoe
> pppox
> ppp_generic
> slhc
> xt_TCPMSS
> xt_mark
> xt_tcpudp
> iptable_mangle
> iptable_nat
> nf_nat
> rtc_cmos
> nf_conntrack_ipv4
> rtc_core
> nf_conntrack
> rtc_lib
> nf_defrag_ipv4
> iptable_filter
> ip_tables
> x_tables
> 8021q
> garp
> stp
> llc
> loop
> sata_sil
> pata_atiixp
> pata_acpi
> ata_generic
> libata
> 8139cp
> usb_storage
> mtdblock
> mtd_blkdevs
> mtd
> sr_mod
> cdrom
> tulip
> r8169
> sky2
> via_velocity
> via_rhine
> sis900
> ne2k_pci
> 8390
> skge
> tg3
> libphy
> 8139too
> e1000
> e100
> usbhid
> ohci_hcd
> uhci_hcd
> ehci_hcd
> usbcore
> nls_base
> Oct 18 23:59:40 194.146.153.93
> [ 113.362344]
> [ 113.362344] Pid: 2858, comm: pppd Not tainted (2.6.31.4-build-0047 #7)
> [ 113.362344] EIP: 0060:[<f8868269>] EFLAGS: 00010286 CPU: 0
> [ 113.362344] EIP is at pppoe_device_event+0x80/0x12c [pppoe]
> [ 113.362344] EAX: f4fbe000 EBX: ffffffff ECX: f6cea5a0 EDX: f7403680
> [ 113.362344] ESI: 0000000f EDI: f6cea5e0 EBP: f4145e34 ESP: f4145e1c
> [ 113.362344] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
> [ 113.362344] Process pppd (pid: 2858, ti=f4145000 task=f4112ff0
> task.ti=f4145000)
> [ 113.362344] Stack:
> [ 113.362344] f4fbe220
> f4fbe000
> f6cea5a0
> f886a430
> fffffff5
> 00000000
> f4145e54
> c01422b3
> Oct 18 23:59:40 194.146.153.93
> [ 113.362344] <0>
> f4fbe000
> 00000009
> f8a457d8
> f4fbe000
> f8850190
> 00001091
> f4145e64
> c0142361
> Oct 18 23:59:40 194.146.153.93
> [ 113.362344] <0>
> ffffffff
> 00000000
> f4145e74
> c029ffbf
> f4fbe000
> 000010d0
> f4145e90
> c029fa70
> Oct 18 23:59:40 194.146.153.93
> [ 113.362344] Call Trace:
> [ 113.362344] [<c01422b3>] ? notifier_call_chain+0x2b/0x4a
> [ 113.362344] [<c0142361>] ? raw_notifier_call_chain+0xc/0xe
> [ 113.362344] [<c029ffbf>] ? dev_close+0x4c/0x8c
> [ 113.362344] [<c029fa70>] ? dev_change_flags+0xa5/0x158
> [ 113.362344] [<c02da633>] ? devinet_ioctl+0x21a/0x503
> [ 113.362344] [<c02db693>] ? inet_ioctl+0x8d/0xa6
> [ 113.362344] [<c0292b21>] ? sock_ioctl+0x1c8/0x1ec
> [ 113.362344] [<c0292959>] ? sock_ioctl+0x0/0x1ec
> [ 113.362344] [<c019af2b>] ? vfs_ioctl+0x22/0x69
> [ 113.362344] [<c019b435>] ? do_vfs_ioctl+0x41f/0x459
> [ 113.362344] [<c02934eb>] ? sys_send+0x18/0x1a
> [ 113.362344] [<c011942f>] ? do_page_fault+0x242/0x26f
> [ 113.362344] [<c019b49b>] ? sys_ioctl+0x2c/0x45
> [ 113.362344] [<c0102975>] ? syscall_call+0x7/0xb
> [ 113.362344] Code:
> c9
> 00
> 00
> 00
> 89
> c7
> 31
> f6
> 83
> c7
> 40
> 89
> f8
> e8
> cc
> 60
> a9
> c7
> 8b
> 45
> ec
> 05
> 20
> 02
> 00
> 00
> 89
> 45
> e8
> 8b
> 4d
> f0
> 8b
> 1c
> b1
> e9
> 8c
> 00
> 00
> 00
> 8b
> 45
> ec
> Oct 18 23:59:40 194.146.153.93
> 83
> 90
> 01
> 00
> 00
> 74
> 08
> 8b
> 9b
> 8c
> 01
> 00
> 00
> eb
> 79
> b8
> c0
> a6
> 86
> f8
> Oct 18 23:59:40 194.146.153.93
> [ 113.362344] EIP: [<f8868269>]
> pppoe_device_event+0x80/0x12c [pppoe]
> SS:ESP 0068:f4145e1c
> [ 113.362344] CR2: 000000000000018f
> [ 113.373124] ---[ end trace f6fe64a307e97f3b ]---
> [ 113.373203] Kernel panic - not syncing: Fatal exception in interrupt
> [ 113.373286] Pid: 2858, comm: pppd Tainted: G D 2.6.31.4-build-0047
> #7
> [ 113.373379] Call Trace:
> [ 113.373479] [<c02fc496>] ? printk+0xf/0x11
> [ 113.373561] [<c02fc3e7>] panic+0x39/0xd9
> [ 113.373656] [<c01059b7>] oops_end+0x8b/0x9a
> [ 113.373727] [<c0118f6d>] no_context+0x13d/0x147
> [ 113.373800] [<c011908a>] __bad_area_nosemaphore+0x113/0x11b
> [ 113.373881] [<c02953b3>] ? sock_alloc_send_pskb+0x8b/0x24a
> [ 113.373959] [<c0121801>] ? __wake_up_sync_key+0x3b/0x45
> [ 113.374030] [<c0131967>] ? irq_exit+0x39/0x5c
> [ 113.374107] [<c0104393>] ? do_IRQ+0x80/0x96
> [ 113.374183] [<c0102f49>] ? common_interrupt+0x29/0x30
> [ 113.374259] [<c011909f>] bad_area_nosemaphore+0xd/0x10
> [ 113.374348] [<c0119301>] do_page_fault+0x114/0x26f
> [ 113.374526] [<c01191ed>] ? do_page_fault+0x0/0x26f
> [ 113.374605] [<c02fe506>] error_code+0x66/0x6c
> [ 113.374683] [<c02d007b>] ? tcp_v4_send_ack+0xa3/0x10e
> [ 113.374764] [<c01191ed>] ? do_page_fault+0x0/0x26f
> [ 113.374850] [<f8868269>] ? pppoe_device_event+0x80/0x12c [pppoe]
> [ 113.374928] [<c01422b3>] notifier_call_chain+0x2b/0x4a
> [ 113.375012] [<c0142361>] raw_notifier_call_chain+0xc/0xe
> [ 113.375097] [<c029ffbf>] dev_close+0x4c/0x8c
> [ 113.375169] [<c029fa70>] dev_change_flags+0xa5/0x158
> [ 113.375239] [<c02da633>] devinet_ioctl+0x21a/0x503
> [ 113.375318] [<c02db693>] inet_ioctl+0x8d/0xa6
> [ 113.375411] [<c0292b21>] sock_ioctl+0x1c8/0x1ec
> [ 113.375491] [<c0292959>] ? sock_ioctl+0x0/0x1ec
> [ 113.375574] [<c019af2b>] vfs_ioctl+0x22/0x69
> [ 113.375653] [<c019b435>] do_vfs_ioctl+0x41f/0x459
> [ 113.375734] [<c02934eb>] ? sys_send+0x18/0x1a
> [ 113.375813] [<c011942f>] ? do_page_fault+0x242/0x26f
> [ 113.375884] [<c019b49b>] sys_ioctl+0x2c/0x45
> [ 113.375960] [<c0102975>] syscall_call+0x7/0xb
> [ 113.376041] Rebooting in 5 seconds..
^ permalink raw reply related
* ARP Table Access
From: Pawel Pastuszak @ 2009-10-19 3:35 UTC (permalink / raw)
To: netdev
Hi All,
Can anybody guide me to how to access ARP Table to lookup an MAC
access for IP address inside an Network Interface driver (net_dev)?
Also how can i insert into the ARP Table.
Thanks,
Pawel
^ permalink raw reply
* Re: [PATCH 4/4 v3] net: Fix for dst_negative_advice
From: Stephen Hemminger @ 2009-10-19 4:12 UTC (permalink / raw)
To: Krishna Kumar; +Cc: davem, netdev, herbert, Krishna Kumar, dada1
In-Reply-To: <20091018130816.3960.87384.sendpatchset@localhost.localdomain>
On Sun, 18 Oct 2009 18:38:16 +0530
Krishna Kumar <krkumar2@in.ibm.com> wrote:
> From: Krishna Kumar <krkumar2@in.ibm.com>
>
> dst_negative_advice() should check for changed dst and reset
> sk_tx_queue_mapping accordingly. Pass sock to the callers of
> dst_negative_advice.
>
> (sk_reset_txq is defined just for use by dst_negative_advice. The
> only way I could find to get around this is to move dst_negative_()
> from dst.h to dst.c, include sock.h in dst.c, etc)
>
> Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
> ---
> include/net/dst.h | 12 ++++++++++--
> net/core/sock.c | 6 ++++++
> net/dccp/timer.c | 4 ++--
> net/decnet/af_decnet.c | 2 +-
> net/ipv4/tcp_timer.c | 4 ++--
> 5 files changed, 21 insertions(+), 7 deletions(-)
>
> diff -ruNp org/include/net/dst.h new/include/net/dst.h
> --- org/include/net/dst.h 2009-10-16 21:30:56.000000000 +0530
> +++ new/include/net/dst.h 2009-10-16 21:31:30.000000000 +0530
> @@ -222,11 +222,19 @@ static inline void dst_confirm(struct ds
> neigh_confirm(dst->neighbour);
> }
>
> -static inline void dst_negative_advice(struct dst_entry **dst_p)
> +static inline void dst_negative_advice(struct dst_entry **dst_p,
> + struct sock *sk)
> {
> struct dst_entry * dst = *dst_p;
> - if (dst && dst->ops->negative_advice)
> + if (dst && dst->ops->negative_advice) {
> *dst_p = dst->ops->negative_advice(dst);
> +
> + if (dst != *dst_p) {
> + extern void sk_reset_txq(struct sock *sk);
> +
> + sk_reset_txq(sk);
> + }
> + }
> }
>
> static inline void dst_link_failure(struct sk_buff *skb)
> diff -ruNp org/net/core/sock.c new/net/core/sock.c
> --- org/net/core/sock.c 2009-10-16 21:30:56.000000000 +0530
> +++ new/net/core/sock.c 2009-10-16 21:32:33.000000000 +0530
> @@ -352,6 +352,12 @@ discard_and_relse:
> }
> EXPORT_SYMBOL(sk_receive_skb);
>
> +void sk_reset_txq(struct sock *sk)
> +{
> + sk_tx_queue_clear(sk);
> +}
> +EXPORT_SYMBOL(sk_reset_txq);
> +
> struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
> {
> struct dst_entry *dst = sk->sk_dst_cache;
> diff -ruNp org/net/dccp/timer.c new/net/dccp/timer.c
> --- org/net/dccp/timer.c 2009-10-16 21:30:56.000000000 +0530
> +++ new/net/dccp/timer.c 2009-10-16 21:31:30.000000000 +0530
> @@ -38,7 +38,7 @@ static int dccp_write_timeout(struct soc
>
> if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
> if (icsk->icsk_retransmits != 0)
> - dst_negative_advice(&sk->sk_dst_cache);
> + dst_negative_advice(&sk->sk_dst_cache, sk);
> retry_until = icsk->icsk_syn_retries ?
> : sysctl_dccp_request_retries;
> } else {
> @@ -63,7 +63,7 @@ static int dccp_write_timeout(struct soc
> Golden words :-).
> */
>
> - dst_negative_advice(&sk->sk_dst_cache);
> + dst_negative_advice(&sk->sk_dst_cache, sk);
> }
>
> retry_until = sysctl_dccp_retries2;
> diff -ruNp org/net/decnet/af_decnet.c new/net/decnet/af_decnet.c
> --- org/net/decnet/af_decnet.c 2009-10-16 21:30:56.000000000 +0530
> +++ new/net/decnet/af_decnet.c 2009-10-16 21:31:30.000000000 +0530
> @@ -1955,7 +1955,7 @@ static int dn_sendmsg(struct kiocb *iocb
> }
>
> if ((flags & MSG_TRYHARD) && sk->sk_dst_cache)
> - dst_negative_advice(&sk->sk_dst_cache);
> + dst_negative_advice(&sk->sk_dst_cache, sk);
>
> mss = scp->segsize_rem;
> fctype = scp->services_rem & NSP_FC_MASK;
> diff -ruNp org/net/ipv4/tcp_timer.c new/net/ipv4/tcp_timer.c
> --- org/net/ipv4/tcp_timer.c 2009-10-16 21:30:56.000000000 +0530
> +++ new/net/ipv4/tcp_timer.c 2009-10-16 21:31:30.000000000 +0530
> @@ -141,14 +141,14 @@ static int tcp_write_timeout(struct sock
>
> if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
> if (icsk->icsk_retransmits)
> - dst_negative_advice(&sk->sk_dst_cache);
> + dst_negative_advice(&sk->sk_dst_cache, sk);
> retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
> } else {
> if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
> /* Black hole detection */
> tcp_mtu_probing(icsk, sk);
>
> - dst_negative_advice(&sk->sk_dst_cache);
> + dst_negative_advice(&sk->sk_dst_cache, sk);
> }
>
> retry_until = sysctl_tcp_retries2;
It is good that your patch is broken in pieces, but will the intermediate patches
still function correctly. I.e are they bisect safe?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox