* Re: [net-next-2.6 V7 PATCH 1/2] Add netlink support for virtual port management (was iovnl)
From: Patrick McHardy @ 2010-05-14 18:46 UTC (permalink / raw)
To: Chris Wright; +Cc: Scott Feldman, Arnd Bergmann, davem, netdev
In-Reply-To: <20100514182526.GO5798@x200.localdomain>
Chris Wright wrote:
> * Patrick McHardy (kaber@trash.net) wrote:
>> Scott Feldman wrote:
>>> On 5/14/10 10:29 AM, "Arnd Bergmann" <arnd@arndb.de> wrote:
>>>
>>>>> I think we should redo the other IFLA_VF_xxx msgs in the same style. I'm
>>>>> not going to tackle that for IFLA_VF_PORTS patch, but it would be a good
>>>>> followup patch.
>>>> I fear it's too late for that now. While we have not yet released 2.6.34
>>>> and 2.6.33 does not contain the broken message, it's extremely late in the
>>>> stabilization phase of v2.6.34, so I doubt that there is still a chance for
>>>> that at this point.
>>> That's too bad. I wish Patrick's objections were honored and then we
>>> wouldn't have followed that broken model! Can the broken msgs be disabled
>>> somehow for 2.6.34? Keep the definitions in if_link.h but fail the SET/GET
>>> actions in rtnetlink.c?
>> That would be a possibility. Unfortunately I don't think we can fix
>> this in a backwards compatible way.
>
> $ git describe --contains ebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659
> v2.6.34-rc1~233^2~336
>
> It's not released yet?
Correct, it was added in 2.6.34-rc.
^ permalink raw reply
* Re: [net-next-2.6 V7 PATCH 1/2] Add netlink support for virtual port management (was iovnl)
From: Chris Wright @ 2010-05-14 18:48 UTC (permalink / raw)
To: Patrick McHardy
Cc: Chris Wright, Scott Feldman, Arnd Bergmann, davem, shemminger,
netdev
In-Reply-To: <4BED9A85.4080507@trash.net>
* Patrick McHardy (kaber@trash.net) wrote:
> Chris Wright wrote:
> > * Patrick McHardy (kaber@trash.net) wrote:
> >> Scott Feldman wrote:
> >>> On 5/14/10 10:29 AM, "Arnd Bergmann" <arnd@arndb.de> wrote:
> >>>
> >>>>> I think we should redo the other IFLA_VF_xxx msgs in the same style. I'm
> >>>>> not going to tackle that for IFLA_VF_PORTS patch, but it would be a good
> >>>>> followup patch.
> >>>> I fear it's too late for that now. While we have not yet released 2.6.34
> >>>> and 2.6.33 does not contain the broken message, it's extremely late in the
> >>>> stabilization phase of v2.6.34, so I doubt that there is still a chance for
> >>>> that at this point.
> >>> That's too bad. I wish Patrick's objections were honored and then we
> >>> wouldn't have followed that broken model! Can the broken msgs be disabled
> >>> somehow for 2.6.34? Keep the definitions in if_link.h but fail the SET/GET
> >>> actions in rtnetlink.c?
> >> That would be a possibility. Unfortunately I don't think we can fix
> >> this in a backwards compatible way.
> >
> > $ git describe --contains ebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659
> > v2.6.34-rc1~233^2~336
> >
> > It's not released yet?
>
> Correct, it was added in 2.6.34-rc.
AFAICT iproute2 hasn't been released either w/ that support.
So, I'll prepare patches to fix it (or disable as Scott mentioned).
What do you think?
thanks,
-chris
^ permalink raw reply
* Re: [net-next-2.6 V7 PATCH 1/2] Add netlink support for virtual port management (was iovnl)
From: Patrick McHardy @ 2010-05-14 18:50 UTC (permalink / raw)
To: Chris Wright; +Cc: Scott Feldman, Arnd Bergmann, davem, shemminger, netdev
In-Reply-To: <20100514184803.GP5798@x200.localdomain>
Chris Wright wrote:
> * Patrick McHardy (kaber@trash.net) wrote:
>> Chris Wright wrote:
>>> * Patrick McHardy (kaber@trash.net) wrote:
>>>> Scott Feldman wrote:
>>>>> On 5/14/10 10:29 AM, "Arnd Bergmann" <arnd@arndb.de> wrote:
>>>>>
>>>>>>> I think we should redo the other IFLA_VF_xxx msgs in the same style. I'm
>>>>>>> not going to tackle that for IFLA_VF_PORTS patch, but it would be a good
>>>>>>> followup patch.
>>>>>> I fear it's too late for that now. While we have not yet released 2.6.34
>>>>>> and 2.6.33 does not contain the broken message, it's extremely late in the
>>>>>> stabilization phase of v2.6.34, so I doubt that there is still a chance for
>>>>>> that at this point.
>>>>> That's too bad. I wish Patrick's objections were honored and then we
>>>>> wouldn't have followed that broken model! Can the broken msgs be disabled
>>>>> somehow for 2.6.34? Keep the definitions in if_link.h but fail the SET/GET
>>>>> actions in rtnetlink.c?
>>>> That would be a possibility. Unfortunately I don't think we can fix
>>>> this in a backwards compatible way.
>>> $ git describe --contains ebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659
>>> v2.6.34-rc1~233^2~336
>>>
>>> It's not released yet?
>> Correct, it was added in 2.6.34-rc.
>
> AFAICT iproute2 hasn't been released either w/ that support.
> So, I'll prepare patches to fix it (or disable as Scott mentioned).
> What do you think?
That would be great, otherwise we'll probably have to support it
forever.
^ permalink raw reply
* Re: [PATCHv2] netfilter: Remove skb_is_nonlinear check from nf_conntrack_sip
From: Patrick McHardy @ 2010-05-14 19:26 UTC (permalink / raw)
To: Jason Gunthorpe; +Cc: netfilter-devel, netdev
In-Reply-To: <4BED99A3.2050404@trash.net>
[-- Attachment #1: Type: text/plain, Size: 1184 bytes --]
Patrick McHardy wrote:
> Jason Gunthorpe wrote:
>> On Fri, May 14, 2010 at 08:13:03PM +0200, Patrick McHardy wrote:
>>> Your patch is based on an old version, the current version also
>>> supports TCP. I'll commit this patch to my tree after some testing.
>> Thanks!
>>
>>> diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
>>> index b20f427..45750cc 100644
>>> +++ b/net/netfilter/nf_conntrack_sip.c
>>> @@ -1393,10 +1393,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
>>>
>>> nf_ct_refresh(ct, skb, sip_timeout * HZ);
>>>
>>> - if (skb_is_nonlinear(skb)) {
>>> - pr_debug("Copy of skbuff not supported yet.\n");
>>> + if (unlikely(skb_linearize(skb)))
>>> return NF_ACCEPT;
>>> - }
>> Should this be NF_DROP? As I understand it skb_linearize only failes
>> if it runs out of memory, which probably means dropping is OK. But
>> passing a packet that might need rewriting could be harmful..
>
> We so far also didn't rewrite the packet. But agreed, its
> a corner case and dropping it is the safer choice.
This is what I've added to my tree. Tested with asterisk and TSO
enabled NIC, which fails without this patch.
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 1462 bytes --]
commit a1d7c1b4b8dfbc5ecadcff9284d64bb6ad4c0196
Author: Patrick McHardy <kaber@trash.net>
Date: Fri May 14 21:18:17 2010 +0200
netfilter: nf_ct_sip: handle non-linear skbs
Handle non-linear skbs by linearizing them instead of silently failing.
Long term the helper should be fixed to either work with non-linear skbs
directly by using the string search API or work on a copy of the data.
Based on patch by Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index b20f427..53d8922 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -1393,10 +1393,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff,
nf_ct_refresh(ct, skb, sip_timeout * HZ);
- if (skb_is_nonlinear(skb)) {
- pr_debug("Copy of skbuff not supported yet.\n");
- return NF_ACCEPT;
- }
+ if (unlikely(skb_linearize(skb)))
+ return NF_DROP;
dptr = skb->data + dataoff;
datalen = skb->len - dataoff;
@@ -1455,10 +1453,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
nf_ct_refresh(ct, skb, sip_timeout * HZ);
- if (skb_is_nonlinear(skb)) {
- pr_debug("Copy of skbuff not supported yet.\n");
- return NF_ACCEPT;
- }
+ if (unlikely(skb_linearize(skb)))
+ return NF_DROP;
dptr = skb->data + dataoff;
datalen = skb->len - dataoff;
^ permalink raw reply related
* Re: [PATCHv2] netfilter: Remove skb_is_nonlinear check from nf_conntrack_sip
From: Jan Engelhardt @ 2010-05-14 19:33 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Jason Gunthorpe, netfilter-devel, netdev
In-Reply-To: <4BEDA3CA.4030407@trash.net>
On Friday 2010-05-14 21:26, Patrick McHardy wrote:
>>> Should this be NF_DROP? As I understand it skb_linearize only failes
>>> if it runs out of memory, which probably means dropping is OK. But
>>> passing a packet that might need rewriting could be harmful..
>>
>> We so far also didn't rewrite the packet. But agreed, its
>> a corner case and dropping it is the safer choice.
>
>This is what I've added to my tree. Tested with asterisk and TSO
>enabled NIC, which fails without this patch.
>
[..patch..]
Shouldn't we do this for the other nf_conntrack_xyz too?
That would mean getting rid of the size-limited locked packet
buffer.
^ permalink raw reply
* Re: [PATCHv2] netfilter: Remove skb_is_nonlinear check from nf_conntrack_sip
From: Patrick McHardy @ 2010-05-14 19:41 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Jason Gunthorpe, netfilter-devel, netdev
In-Reply-To: <alpine.LSU.2.01.1005142133001.16437@obet.zrqbmnf.qr>
Jan Engelhardt wrote:
> On Friday 2010-05-14 21:26, Patrick McHardy wrote:
>>>> Should this be NF_DROP? As I understand it skb_linearize only failes
>>>> if it runs out of memory, which probably means dropping is OK. But
>>>> passing a packet that might need rewriting could be harmful..
>>> We so far also didn't rewrite the packet. But agreed, its
>>> a corner case and dropping it is the safer choice.
>> This is what I've added to my tree. Tested with asterisk and TSO
>> enabled NIC, which fails without this patch.
>>
>
> [..patch..]
>
> Shouldn't we do this for the other nf_conntrack_xyz too?
> That would mean getting rid of the size-limited locked packet
> buffer.
Those got introduced to avoid the linearization. SIP is kind of special
because its the only helper mangling packets multiple times with
variable sizes and is currently unable to use the data copying scheme.
Amanda does this as well, but uses the string search API, which works
fine.
The best fix to get rid of the copying in other helpers would be to
convert them to the string search API. I started doing that a few
years ago, but never finished it. One related improvement we could
add would be to make only those parts of the skb writable that are
actually written to when mangling packets, at least for non-linear
non-paged skbs (using frag_list).
^ permalink raw reply
* Re: [PATCHv2] netfilter: Remove skb_is_nonlinear check from nf_conntrack_sip
From: Jason Gunthorpe @ 2010-05-14 19:56 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, netdev
In-Reply-To: <4BED99A3.2050404@trash.net>
On Fri, May 14, 2010 at 08:42:43PM +0200, Patrick McHardy wrote:
> > Should this be NF_DROP? As I understand it skb_linearize only failes
> > if it runs out of memory, which probably means dropping is OK. But
> > passing a packet that might need rewriting could be harmful..
>
> We so far also didn't rewrite the packet. But agreed, its
> a corner case and dropping it is the safer choice.
I was just thinking that, say, a request goes out, gets rewritten but
the reply comes back and does not get rewritten = bad. Better to drop.
Looks OK to me..
Jason
^ permalink raw reply
* RE: why get different number of MSI-X vector for broadcom bnx2x every time
From: Dmitry Kravkov @ 2010-05-14 20:02 UTC (permalink / raw)
To: Jon Zhou, netdev
In-Reply-To: <4A6A2125329CFD4D8CC40C9E8ABCAB9F2497DED2BE@MILEXCH2.ds.jdsu.net>
Hi
Your system (from the log below) allowed bnx2x to use only 4 MSI-X vectors instead of 16 required by the driver.
Regards,
Dmitry
-----Original Message-----
From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On Behalf Of Jon Zhou
Sent: Friday, May 14, 2010 11:02 AM
To: netdev
Subject: why get different number of MSI-X vector for broadcom bnx2x every time
hi there:
bnx2x_enable_msix :
...
rc = pci_enable_msix(bp->pdev, &bp->msix_table[0],
BNX2X_NUM_QUEUES(bp) + offset);
/*
* reconfigure number of tx/rx queues according to available
* MSI-X vectors
*/
if (rc >= BNX2X_MIN_MSIX_VEC_CNT) {
/* vectors available for FP */
int fp_vec = rc - BNX2X_MSIX_VEC_FP_START;
sometimes I can run up the driver with 4 queues but most of time I can only get 2 queues
why?
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_set_num_queues:8053(eth5)]set number of queues to 15
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7544(eth5)]msix_table[0].entry = 0 (slowpath)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7549(eth5)]msix_table[1].entry = 1 (CNIC)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[2].entry = 2 (fastpath #0)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[3].entry = 3 (fastpath #1)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[4].entry = 4 (fastpath #2)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[5].entry = 5 (fastpath #3)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[6].entry = 6 (fastpath #4)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[7].entry = 7 (fastpath #5)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[8].entry = 8 (fastpath #6)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[9].entry = 9 (fastpath #7)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[10].entry = 10 (fastpath #8)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[11].entry = 11 (fastpath #9)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[12].entry = 12 (fastpath #10)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[13].entry = 13 (fastpath #11)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[14].entry = 14 (fastpath #12)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[15].entry = 15 (fastpath #13)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7556(eth5)]msix_table[16].entry = 16 (fastpath #14)
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7571(eth5)]Trying to use less MSI-X vectors: 4
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_enable_msix:7584(eth5)]New queue configuration set: 2
May 14 01:40:16 ibm-bc-54 kernel: bnx2x: eth5: using MSI-X IRQs: sp 4321 fp[0] 4319 ... fp[1] 4318
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_nic_init:6067(eth5)]queue[0]: bnx2x_init_sb(ffff8803e6810780,ffff8803f9c4f000) cl_id 0 sb 1 cos 0
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_nic_init:6067(eth5)]queue[1]: bnx2x_init_sb(ffff8803e6810780,ffff8803fb006000) cl_id 1 sb 2 cos 0
May 14 01:40:16 ibm-bc-54 kernel: [bnx2x_init_rx_rings:5305(eth5)]mtu 1500 rx_buf_size 1650
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* TSC unstable due to TSC halts in idle?
From: Jesper Dangaard Brouer @ 2010-05-14 20:13 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: linux-kernel, netdev, Len Brown, Shaohua Li, hawk
Hi Thomas,
I want to know, if its safe to enable the TSC clocksource, when the
kernel reports:
"Marking TSC unstable due to TSC halts in idle"
The system selects HPET (in current_clocksource), but I can still see
TSC as an available clocksource (in
/sys/devices/system/clocksource/clocksource0/available_clocksource).
Is it safe to enable TSC manually (by changing current_clocksource)?
(my workload is 10Git/s routing, cannot survive with a slow clock)
Any trick to avoid this? (e.g. kernel config setting, or a /sys/ setting
which changes the minimum P-state?)
The system is a new HP370-G6 server, with two Xeon X5550 CPUs. Its
(currently) running a Debian compiled kernel 2.6.26-2-amd64.
Kernel log:
checking TSC synchronization [CPU#0 -> CPU#1]: passed.
checking TSC synchronization [CPU#0 -> CPU#2]: passed.
...
checking TSC synchronization [CPU#0 -> CPU#14]: passed.
checking TSC synchronization [CPU#0 -> CPU#15]: passed.
Marking TSC unstable due to TSC halts in idle
Cheers,
Jesper Brouer
--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------
^ permalink raw reply
* Re: [PATCH -next] netfilter: xt_TEE depends on NF_CONNTRACK
From: David Miller @ 2010-05-14 20:52 UTC (permalink / raw)
To: kaber
Cc: randy.dunlap, sfr, netdev, jengelh, netfilter-devel, linux-next,
linux-kernel
In-Reply-To: <4BED8650.5040808@trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Fri, 14 May 2010 19:20:16 +0200
> Randy Dunlap wrote:
>> From: Randy Dunlap <randy.dunlap@oracle.com>
>>
>> Fix xt_TEE build for the case of NF_CONNTRACK=m and
>> NETFILTER_XT_TARGET_TEE=y:
>>
>> xt_TEE.c:(.text+0x6df5c): undefined reference to `nf_conntrack_untracked'
>> 4x
>>
>> Built with all 4 m/y combinations.
>>
>> Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
>> Cc: Patrick McHardy <kaber@trash.net>
>> Cc: Jan Engelhardt <jengelh@medozas.de>
>
> Acked-by: Patrick McHardy <kaber@trash.net>
>
> Dave, please apply directly. Thanks!
Done, thanks everyone.
^ permalink raw reply
* RE: [net-next-2.6 V7 PATCH 1/2] Add netlink support for virtual port management (was iovnl)
From: Williams, Mitch A @ 2010-05-14 20:56 UTC (permalink / raw)
To: Patrick McHardy, Chris Wright
Cc: Scott Feldman, Arnd Bergmann, davem@davemloft.net,
shemminger@vyatta.com, netdev@vger.kernel.org
In-Reply-To: <4BED9B5B.6010001@trash.net>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>On Behalf Of Patrick McHardy
>Sent: Friday, May 14, 2010 11:50 AM
>To: Chris Wright
>Cc: Scott Feldman; Arnd Bergmann; davem@davemloft.net;
>shemminger@vyatta.com; netdev@vger.kernel.org
>Subject: Re: [net-next-2.6 V7 PATCH 1/2] Add netlink support for virtual
>port management (was iovnl)
>
>Chris Wright wrote:
>> * Patrick McHardy (kaber@trash.net) wrote:
>>> Chris Wright wrote:
>>>> * Patrick McHardy (kaber@trash.net) wrote:
>>>>> Scott Feldman wrote:
>>>>>> On 5/14/10 10:29 AM, "Arnd Bergmann" <arnd@arndb.de> wrote:
>>>>>>
>>>>>>>> I think we should redo the other IFLA_VF_xxx msgs in the same
>style. I'm
>>>>>>>> not going to tackle that for IFLA_VF_PORTS patch, but it would be
>a good
>>>>>>>> followup patch.
>>>>>>> I fear it's too late for that now. While we have not yet released
>2.6.34
>>>>>>> and 2.6.33 does not contain the broken message, it's extremely
>late in the
>>>>>>> stabilization phase of v2.6.34, so I doubt that there is still a
>chance for
>>>>>>> that at this point.
>>>>>> That's too bad. I wish Patrick's objections were honored and then
>we
>>>>>> wouldn't have followed that broken model! Can the broken msgs be
>disabled
>>>>>> somehow for 2.6.34? Keep the definitions in if_link.h but fail the
>SET/GET
>>>>>> actions in rtnetlink.c?
>>>>> That would be a possibility. Unfortunately I don't think we can fix
>>>>> this in a backwards compatible way.
>>>> $ git describe --contains ebc08a6f47ee76ecad8e9f26c26e6ec9b46ca659
>>>> v2.6.34-rc1~233^2~336
>>>>
>>>> It's not released yet?
>>> Correct, it was added in 2.6.34-rc.
>>
>> AFAICT iproute2 hasn't been released either w/ that support.
>> So, I'll prepare patches to fix it (or disable as Scott mentioned).
>> What do you think?
>
>That would be great, otherwise we'll probably have to support it
>forever.
I'd really like to find a way to fix this, instead of having the functionality disabled.
I know Patrick had objections to how the data structures were set up, but I figured that was something we'd tackle later, especially since the series got merged after Patrick's email, and with no further objection. At that point, things got quiet, I got shuffled onto another project, and we all thought things were OK.
At this point, Scott's work depends on what I did, so it's probably more work to unwind my stuff and respin his, than to just fix mine.
Can we quickly respin the kernel side to take care of Patrick's objections, and work the userspace side over the next week or so? The userspace side is where the real fiddly bits will be. I'll drop what I'm working on and get this taken care of as quickly as I can.
Sorry for the confusion - I thought we were OK, until yesterday.
-Mitch
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next] net: Remove unnecessary semicolons after switch statements
From: Joe Perches @ 2010-05-14 20:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Also added an explicit break; to avoid
a fallthrough in net/ipv4/tcp_input.c
Signed-off-by: Joe Perches <joe@perches.com>
---
net/8021q/vlan_core.c | 2 +-
net/core/ethtool.c | 4 ++--
net/ipv4/tcp.c | 2 +-
net/ipv4/tcp_input.c | 5 +++--
net/rds/tcp_connect.c | 2 +-
net/socket.c | 2 +-
net/xfrm/xfrm_hash.h | 6 +++---
7 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index c584a0a..bd537fc 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -61,7 +61,7 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb)
dev->dev_addr))
skb->pkt_type = PACKET_HOST;
break;
- };
+ }
return 0;
}
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 1a7db92..a0f4964 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -522,7 +522,7 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
p += ETH_GSTRING_LEN;
num_strings++;
goto unknown_filter;
- };
+ }
/* now the rest of the filters */
switch (fsc->fs.flow_type) {
@@ -646,7 +646,7 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
p += ETH_GSTRING_LEN;
num_strings++;
break;
- };
+ }
sprintf(p, "\tVLAN: %d, mask: 0x%x\n",
fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask);
p += ETH_GSTRING_LEN;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 8ce2974..9d4c8fc 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2215,7 +2215,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
default:
/* fallthru */
break;
- };
+ }
if (optlen < sizeof(int))
return -EINVAL;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e82162c..3e6dafc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3845,12 +3845,13 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
/* 16-bit multiple */
opt_rx->cookie_plus = opsize;
*hvpp = ptr;
+ break;
default:
/* ignore option */
break;
- };
+ }
break;
- };
+ }
ptr += opsize-2;
length -= opsize;
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index 0562562..c397524 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -141,7 +141,7 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn)
release_sock(sock->sk);
sock_release(sock);
- };
+ }
if (tc->t_tinc) {
rds_inc_put(&tc->t_tinc->ti_inc);
diff --git a/net/socket.c b/net/socket.c
index dae8c6b..f9f7d08 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2615,7 +2615,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
return dev_ioctl(net, cmd, uifr);
default:
return -EINVAL;
- };
+ }
}
static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
diff --git a/net/xfrm/xfrm_hash.h b/net/xfrm/xfrm_hash.h
index 1396572..8e69533 100644
--- a/net/xfrm/xfrm_hash.h
+++ b/net/xfrm/xfrm_hash.h
@@ -55,7 +55,7 @@ static inline unsigned __xfrm_src_hash(xfrm_address_t *daddr,
case AF_INET6:
h ^= __xfrm6_daddr_saddr_hash(daddr, saddr);
break;
- };
+ }
return (h ^ (h >> 16)) & hmask;
}
@@ -102,7 +102,7 @@ static inline unsigned int __sel_hash(struct xfrm_selector *sel, unsigned short
h = __xfrm6_daddr_saddr_hash(daddr, saddr);
break;
- };
+ }
h ^= (h >> 16);
return h & hmask;
}
@@ -119,7 +119,7 @@ static inline unsigned int __addr_hash(xfrm_address_t *daddr, xfrm_address_t *sa
case AF_INET6:
h = __xfrm6_daddr_saddr_hash(daddr, saddr);
break;
- };
+ }
h ^= (h >> 16);
return h & hmask;
}
^ permalink raw reply related
* Implementation of the LISP protocol (GSOC 2010)
From: Alex Lorca @ 2010-05-14 21:26 UTC (permalink / raw)
To: netdev; +Cc: Johannes Berg
Hi
My name is Alex Lorca and I'm working in the implementation of LISP
[0] in Linux for the Google Summer of Code 2010 program, so I'll be
bothering the list with silly questions for the next months. Any
feedback is much appreciated.
Basically, LISP is somewhat of a tunneling protocol that creates
tunnels on demand between routers called Ingress Tunnel Router (ITR)
and Egress Tunnel Router (ETR). ITRs encapsulate normal traffic
appending a special header and send it to ETRs where it gets
decapsulated. The purpose of this is to forward packets from hosts
behind then ITR to hosts behind the ETR because they can't reach
each other directly using their public IPs (more info in [0]). The
encapsulation is done like this:
IP | UDP | LISP | IP | ...
The idea is to implement something like ipip or ip_gre: a virtual
interface that takes care of the LISP packets, creating and
maintaining tunnels, decapsulating/encapsulating and forwarding
packets. This includes also the userspace tools for administration.
Ideally, for the implementation to be useful, the process has to have
as lowest latency as possible since almost all the traffic directed to
the LISP interface is to be forwarded.
I've come across the first problem: since the IP protocol number field
in the LISP packets is UDP (17) I can't send the packet to a layer 4
handler function via the registered protocols table. The only thing
that comes to my mind is just replace the l4 handler for UDP (udp_rcv)
in the protocol table. Is there a cleaner way to do this?
Also, is there others tunnel like implementations in linux, aside from
ipip, gre and sit?
Regards
[0] http://www.lisp4.net/
--
Alex Lorca
^ permalink raw reply
* Re: Implementation of the LISP protocol (GSOC 2010)
From: Patrick McHardy @ 2010-05-14 21:34 UTC (permalink / raw)
To: Alex Lorca; +Cc: netdev, Johannes Berg
In-Reply-To: <87ocgijhtz.wl%alex.lorca@gmail.com>
Alex Lorca wrote:
> Hi
>
> My name is Alex Lorca and I'm working in the implementation of LISP
> [0] in Linux for the Google Summer of Code 2010 program, so I'll be
> bothering the list with silly questions for the next months. Any
> feedback is much appreciated.
>
> Basically, LISP is somewhat of a tunneling protocol that creates
> tunnels on demand between routers called Ingress Tunnel Router (ITR)
> and Egress Tunnel Router (ETR). ITRs encapsulate normal traffic
> appending a special header and send it to ETRs where it gets
> decapsulated. The purpose of this is to forward packets from hosts
> behind then ITR to hosts behind the ETR because they can't reach
> each other directly using their public IPs (more info in [0]). The
> encapsulation is done like this:
>
> IP | UDP | LISP | IP | ...
>
> The idea is to implement something like ipip or ip_gre: a virtual
> interface that takes care of the LISP packets, creating and
> maintaining tunnels, decapsulating/encapsulating and forwarding
> packets. This includes also the userspace tools for administration.
> Ideally, for the implementation to be useful, the process has to have
> as lowest latency as possible since almost all the traffic directed to
> the LISP interface is to be forwarded.
>
> I've come across the first problem: since the IP protocol number field
> in the LISP packets is UDP (17) I can't send the packet to a layer 4
> handler function via the registered protocols table. The only thing
> that comes to my mind is just replace the l4 handler for UDP (udp_rcv)
> in the protocol table. Is there a cleaner way to do this?
You can use an encapsulation socket - check out udp_queue_rcv_skb().
> Also, is there others tunnel like implementations in linux, aside from
> ipip, gre and sit?
L2TP.
^ permalink raw reply
* [patch 2.6.35 00/25] WiMAX pull request
From: Inaky Perez-Gonzalez @ 2010-05-14 21:44 UTC (permalink / raw)
To: netdev, wimax
From: Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
There are no new features driver wise -- this is all a set of bug
fixes, mostly small ones, some bigger:
- TX FIFO handling had a few more corner cases Q&A found
fix incorrect return -ESHUTDOWN when there is no Tx buffer available
fix the race condition for accessing TX queue
add the error recovery mechanism on TX path
Reset the TX FIFO indices when allocating the TX FIFO in tx_setup()
increase the maximum number of payloads per message to 60 [v1]
limit the message size upto 16KiB [v1]
modify i2400m_tx_fifo_push() to check for head room space in the TX FIFO [v1]
fix system freeze caused by an infinite loop [v1]
reserve additional space in the TX queue's buffer while allocating space for a new message header
- RX chain
fix incorrect handling of type 2 and 3 RX messages
fix race condition while accessing rx_roq by using kref count
- SDIO reset handling: work out quirks
- Small rearrangements to reduce forward declarations
NOTE: the WiMAX tree in
git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git has been
rebased, so if you were tracking it, you will need to do a hard
pull. Sorry for that.
The reason this has been done is that wimax.git/master will now
stable, no cherry picking and always chasing net-next-2.6 /
net-2.6. The old wimax/master tree was thus unfeasible for upstream
pull as it was quite contaminated with extraenous commits.
When net-2.6 opens, wimax/2.6.X opens chasing net-2.6, later it will
chase linux-allstable-2.6/linux-2.6.X.y if need be when the kernel
release happens.
The following changes since commit 2b0b05ddc04b6d45e71cd36405df512075786f1e:
Marcel Holtmann (1):
Bluetooth: Fix issues where sk_sleep() helper is needed now
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git master
Patches follow for reviewing convenience.
Cindy H Kao (6):
wimax/i2400m: fix the race condition for accessing TX queue
wimax/i2400m: correct the error path handlers in dev_start()
wimax/i2400m: fix for missed reset events if triggered by dev_reset_handle()
wimax/i2400m: add the error recovery mechanism on TX path
wimax/i2400m: Correct the error path handlers order in i2400m_post_reset()
wimax/i2400m: Reset the TX FIFO indices when allocating the TX FIFO in tx_setup()
Dan Carpenter (2):
wimax: checking ERR_PTR vs null
wimax: wimax_msg_alloc() returns ERR_PTR not null
Inaky Perez-Gonzalez (2):
wimax/i2400m: driver defaults to firmware v1.5 for i5x50 devices
wimax/i2400m: driver defaults to firmware v1.5 for i6x60 devices
Prasanna S Panchamukhi (1):
wimax/i2400m: Move module params to other file so they can be static
Prasanna S. Panchamukhi (13):
wimax/i2400m: move I2400M_MAX_MTU enum from netdev.c to i2400m.h
wimax/i2400m: fix insufficient size of Tx buffer for 12 payload of 1400 MTU.
wimax/i2400m: increase the maximum number of payloads per message to 60 [v1]
wimax/i2400m: limit the message size upto 16KiB [v1]
wimax/i2400m: fix BUILD_BUG_ON() to use the maximum message size constant [v1]
wimax/i2400m: modify i2400m_tx_fifo_push() to check for head room space in the TX FIFO [v1]
wimax/i2400m: fix system freeze caused by an infinite loop [v1]
wimax/i2400m: increase tx queue length from 5 to 20 [v1]
wimax i2400m: fix race condition while accessing rx_roq by using kref count
wimax/i2400m: fix incorrect handling of type 2 and 3 RX messages
wimax/i2400m: reserve additional space in the TX queue's buffer while allocating space for a new message header
wimax/i2400m: SDIO specific TX queue's minimum buffer room for new message
wimax/i2400m: USB specific TX queue's minimum buffer room required for new message
Prasanna S.Panchamukhi (1):
wimax/i2400m: fix incorrect return -ESHUTDOWN when there is no Tx buffer available
drivers/net/wimax/i2400m/control.c | 15 +++
drivers/net/wimax/i2400m/driver.c | 165 +++++++++++++++++++++++++-------
drivers/net/wimax/i2400m/i2400m-sdio.h | 5 +-
drivers/net/wimax/i2400m/i2400m.h | 82 ++++++++++++++--
drivers/net/wimax/i2400m/netdev.c | 12 +--
drivers/net/wimax/i2400m/rx.c | 109 ++++++++++++++-------
drivers/net/wimax/i2400m/sdio-tx.c | 35 ++++++--
drivers/net/wimax/i2400m/sdio.c | 7 ++
drivers/net/wimax/i2400m/tx.c | 153 ++++++++++++++++++++++++++----
drivers/net/wimax/i2400m/usb.c | 12 ++-
net/wimax/stack.c | 2 +-
11 files changed, 480 insertions(+), 117 deletions(-)
^ permalink raw reply
* [patch 2.6.35 01/25] wimax/i2400m: fix incorrect return -ESHUTDOWN when there is no Tx buffer available
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Prasanna S.Panchamukhi
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Prasanna S.Panchamukhi <prasannax.s.panchamukhi@intel.com>
i2400m_tx() routine was returning -ESHUTDOWN even when there was no Tx buffer
available. This patch fixes the i2400m_tx() to return -ESHUTDOWN only when
the device is down(i2400m->tx_buf is NULL) and also to return -ENOSPC
when there is no Tx buffer. Error seen in the kernel log.
kernel: i2400m_sdio mmc0:0001:1: can't send message 0x5606: -108
kernel: i2400m_sdio mmc0:0001:1: Failed to issue 'Enter power save'command: -108
Signed-off-by: Prasanna S.Panchamukhi <prasannax.s.panchamukhi@intel.com>
---
drivers/net/wimax/i2400m/tx.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 6db909e..fab27e4 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -643,9 +643,11 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
* current one is out of payload slots or we have a singleton,
* close it and start a new one */
spin_lock_irqsave(&i2400m->tx_lock, flags);
- result = -ESHUTDOWN;
- if (i2400m->tx_buf == NULL)
+ /* If tx_buf is NULL, device is shutdown */
+ if (i2400m->tx_buf == NULL) {
+ result = -ESHUTDOWN;
goto error_tx_new;
+ }
try_new:
if (unlikely(i2400m->tx_msg == NULL))
i2400m_tx_new(i2400m);
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 02/25] wimax/i2400m: move I2400M_MAX_MTU enum from netdev.c to i2400m.h
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Prasanna S. Panchamukhi
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
This patch moves I2400M_MAX_MTU enum defined in netdev.c to i2400m.h.
Follow up changes will make use of this value in other location,
thus requiring it to be moved to a global header file i2400m.h.
Signed-off-by: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
---
drivers/net/wimax/i2400m/i2400m.h | 10 ++++++++++
drivers/net/wimax/i2400m/netdev.c | 6 ------
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 820b128..da218b9 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -160,6 +160,16 @@
#include <linux/wimax/i2400m.h>
#include <asm/byteorder.h>
+enum {
+/* netdev interface */
+ /*
+ * Out of NWG spec (R1_v1.2.2), 3.3.3 ASN Bearer Plane MTU Size
+ *
+ * The MTU is 1400 or less
+ */
+ I2400M_MAX_MTU = 1400,
+};
+
/* Misc constants */
enum {
/* Size of the Boot Mode Command buffer */
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index b811c2f..fc3754a 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -84,12 +84,6 @@
enum {
/* netdev interface */
- /*
- * Out of NWG spec (R1_v1.2.2), 3.3.3 ASN Bearer Plane MTU Size
- *
- * The MTU is 1400 or less
- */
- I2400M_MAX_MTU = 1400,
/* 20 secs? yep, this is the maximum timeout that the device
* might take to get out of IDLE / negotiate it with the base
* station. We add 1sec for good measure. */
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 03/25] wimax/i2400m: fix insufficient size of Tx buffer for 12 payload of 1400 MTU.
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Prasanna S. Panchamukhi
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
This patch increases the Tx buffer size so as to accommodate 12 payloads
of 1408 (1400 MTU 16 bytes aligned). Currently Tx buffer is 32 KiB which
is insufficient to accommodate 12 payloads of 1408 size.
This patch
- increases I2400M_TX_BUF_SIZE from 32KiB to 64KiB
- Adds a BUILD_BUG_ON if the calculated buffer size based
on the given MTU exceeds the I2400M_TX_BUF_SIZE.
Below is how we calculate the size of the Tx buffer.
Payload + 4 bytes prefix for each payload (1400 MTU 16 bytes boundary aligned)
= (1408 + sizeof(struct i2400m_pl_data_hdr)) * I2400M_TX_PLD_MAX
Adding 16 byte message header = + sizeof(struct i2400m_msg_hdr)
Aligning to 256 byte boundary
Total Tx buffer = (((((1408 + sizeof(struct i2400m_pl_data_hdr))
* I2400M_TX_PLD_MAX )+ sizeof(struct i2400m_msg_hdr))
/ 256) + 1) * 256 * 2
Signed-off-by: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
---
drivers/net/wimax/i2400m/tx.c | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index fab27e4..8561c07 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -258,8 +258,10 @@ enum {
* Doc says maximum transaction is 16KiB. If we had 16KiB en
* route and 16KiB being queued, it boils down to needing
* 32KiB.
+ * 32KiB is insufficient for 1400 MTU, hence increasing
+ * tx buffer size to 64KiB.
*/
- I2400M_TX_BUF_SIZE = 32768,
+ I2400M_TX_BUF_SIZE = 65536,
/**
* Message header and payload descriptors have to be 16
* aligned (16 + 4 * N = 16 * M). If we take that average sent
@@ -274,6 +276,19 @@ enum {
I2400M_TX_PLD_SIZE = sizeof(struct i2400m_msg_hdr)
+ I2400M_TX_PLD_MAX * sizeof(struct i2400m_pld),
I2400M_TX_SKIP = 0x80000000,
+ /*
+ * 16 byte aligned MAX_MTU + 4 byte payload prefix.
+ */
+ I2400M_MAX_MTU_ALIGN = 16,
+ I2400M_TX_PDU_SIZE = I2400M_MAX_MTU % I2400M_MAX_MTU_ALIGN
+ + I2400M_MAX_MTU + sizeof(struct i2400m_pl_data_hdr),
+ /*
+ * 256 byte aligned toal size of 12 PDUs including msg header,
+ */
+ I2400M_TX_PDU_ALIGN = 256,
+ I2400M_TX_PDU_TOTAL_SIZE = ((I2400M_TX_PDU_SIZE * I2400M_TX_PLD_MAX
+ + sizeof(struct i2400m_msg_hdr))/I2400M_TX_PDU_ALIGN + 1)
+ * I2400M_TX_PDU_ALIGN * 2,
};
#define TAIL_FULL ((void *)~(unsigned long)NULL)
@@ -874,6 +889,8 @@ int i2400m_tx_setup(struct i2400m *i2400m)
INIT_WORK(&i2400m->wake_tx_ws, i2400m_wake_tx_work);
i2400m->tx_sequence = 0;
+ /* Warn if the calculated buffer size exceeds I2400M_TX_BUF_SIZE. */
+ BUILD_BUG_ON(I2400M_TX_PDU_TOTAL_SIZE > I2400M_TX_BUF_SIZE);
i2400m->tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_KERNEL);
if (i2400m->tx_buf == NULL)
result = -ENOMEM;
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 04/25] wimax/i2400m: fix the race condition for accessing TX queue
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
The race condition happens when the TX queue is accessed by
the TX work while the same TX queue is being destroyed because
a bus reset is triggered either by debugfs entry or simply
by failing waking up the device from WiMAX IDLE mode.
This fix is to prevent the TX queue from being accessed by
multiple threads
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/i2400m-sdio.h | 5 ++++-
drivers/net/wimax/i2400m/sdio-tx.c | 31 ++++++++++++++++++++++++-------
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h
index b9c4bed..360d4fb 100644
--- a/drivers/net/wimax/i2400m/i2400m-sdio.h
+++ b/drivers/net/wimax/i2400m/i2400m-sdio.h
@@ -99,7 +99,10 @@ enum {
*
* @tx_workqueue: workqeueue used for data TX; we don't use the
* system's workqueue as that might cause deadlocks with code in
- * the bus-generic driver.
+ * the bus-generic driver. The read/write operation to the queue
+ * is protected with spinlock (tx_lock in struct i2400m) to avoid
+ * the queue being destroyed in the middle of a the queue read/write
+ * operation.
*
* @debugfs_dentry: dentry for the SDIO specific debugfs files
*
diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c
index de66d06..412b6a8 100644
--- a/drivers/net/wimax/i2400m/sdio-tx.c
+++ b/drivers/net/wimax/i2400m/sdio-tx.c
@@ -114,13 +114,17 @@ void i2400ms_bus_tx_kick(struct i2400m *i2400m)
{
struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
struct device *dev = &i2400ms->func->dev;
+ unsigned long flags;
d_fnstart(3, dev, "(i2400m %p) = void\n", i2400m);
/* schedule tx work, this is because tx may block, therefore
* it has to run in a thread context.
*/
- queue_work(i2400ms->tx_workqueue, &i2400ms->tx_worker);
+ spin_lock_irqsave(&i2400m->tx_lock, flags);
+ if (i2400ms->tx_workqueue != NULL)
+ queue_work(i2400ms->tx_workqueue, &i2400ms->tx_worker);
+ spin_unlock_irqrestore(&i2400m->tx_lock, flags);
d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
}
@@ -130,27 +134,40 @@ int i2400ms_tx_setup(struct i2400ms *i2400ms)
int result;
struct device *dev = &i2400ms->func->dev;
struct i2400m *i2400m = &i2400ms->i2400m;
+ struct workqueue_struct *tx_workqueue;
+ unsigned long flags;
d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
INIT_WORK(&i2400ms->tx_worker, i2400ms_tx_submit);
snprintf(i2400ms->tx_wq_name, sizeof(i2400ms->tx_wq_name),
"%s-tx", i2400m->wimax_dev.name);
- i2400ms->tx_workqueue =
+ tx_workqueue =
create_singlethread_workqueue(i2400ms->tx_wq_name);
- if (NULL == i2400ms->tx_workqueue) {
+ if (tx_workqueue == NULL) {
dev_err(dev, "TX: failed to create workqueue\n");
result = -ENOMEM;
} else
result = 0;
+ spin_lock_irqsave(&i2400m->tx_lock, flags);
+ i2400ms->tx_workqueue = tx_workqueue;
+ spin_unlock_irqrestore(&i2400m->tx_lock, flags);
d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result);
return result;
}
void i2400ms_tx_release(struct i2400ms *i2400ms)
{
- if (i2400ms->tx_workqueue) {
- destroy_workqueue(i2400ms->tx_workqueue);
- i2400ms->tx_workqueue = NULL;
- }
+ struct i2400m *i2400m = &i2400ms->i2400m;
+ struct workqueue_struct *tx_workqueue;
+ unsigned long flags;
+
+ tx_workqueue = i2400ms->tx_workqueue;
+
+ spin_lock_irqsave(&i2400m->tx_lock, flags);
+ i2400ms->tx_workqueue = NULL;
+ spin_unlock_irqrestore(&i2400m->tx_lock, flags);
+
+ if (tx_workqueue)
+ destroy_workqueue(tx_workqueue);
}
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 05/25] wimax/i2400m: correct the error path handlers in dev_start()
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
This fix is to correct order of the handlers in the error path
of dev_start(). When i2400m_firmware_check fails, all the works done
before it should be released or cleared.
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 94dc83c..3a6c8dd 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -403,10 +403,10 @@ retry:
error_dev_initialize:
error_check_mac_addr:
+error_fw_check:
i2400m->ready = 0;
wmb(); /* see i2400m->ready's documentation */
flush_workqueue(i2400m->work_queue);
-error_fw_check:
if (i2400m->bus_dev_stop)
i2400m->bus_dev_stop(i2400m);
error_bus_dev_start:
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 07/25] wimax/i2400m: add the error recovery mechanism on TX path
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
This patch adds an error recovery mechanism on TX path.
The intention is to bring back the device to some known state
whenever TX sees -110 (-ETIMEOUT) on copying the data to the HW FIFO.
The TX failure could mean a device bus stuck or function stuck, so
the current error recovery implementation is to trigger a bus reset
and expect this can bring back the device.
Since the TX work is done in a thread context, there may be a queue of TX works
already that all hit the -ETIMEOUT error condition because the device has
somewhat stuck already. We don't want any consecutive bus resets simply because
multiple TX works in the queue all hit the same device erratum, the flag
"error_recovery" is introduced to denote if we are ready for taking any
error recovery. See @error_recovery doc in i2400m.h.
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/driver.c | 74 ++++++++++++++++++++++++++++++++++++
drivers/net/wimax/i2400m/i2400m.h | 14 +++++++
drivers/net/wimax/i2400m/sdio-tx.c | 4 ++
3 files changed, 92 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 1674dba..d83fe84 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -395,6 +395,16 @@ retry:
result = i2400m_dev_initialize(i2400m);
if (result < 0)
goto error_dev_initialize;
+
+ /* We don't want any additional unwanted error recovery triggered
+ * from any other context so if anything went wrong before we come
+ * here, let's keep i2400m->error_recovery untouched and leave it to
+ * dev_reset_handle(). See dev_reset_handle(). */
+
+ atomic_dec(&i2400m->error_recovery);
+ /* Every thing works so far, ok, now we are ready to
+ * take error recovery if it's required. */
+
/* At this point, reports will come for the device and set it
* to the right state if it is different than UNINITIALIZED */
d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
@@ -770,6 +780,66 @@ int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason)
EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
+ /*
+ * The actual work of error recovery.
+ *
+ * The current implementation of error recovery is to trigger a bus reset.
+ */
+static
+void __i2400m_error_recovery(struct work_struct *ws)
+{
+ struct i2400m_work *iw = container_of(ws, struct i2400m_work, ws);
+ struct i2400m *i2400m = iw->i2400m;
+
+ i2400m_reset(i2400m, I2400M_RT_BUS);
+
+ i2400m_put(i2400m);
+ kfree(iw);
+ return;
+}
+
+/*
+ * Schedule a work struct for error recovery.
+ *
+ * The intention of error recovery is to bring back the device to some
+ * known state whenever TX sees -110 (-ETIMEOUT) on copying the data to
+ * the device. The TX failure could mean a device bus stuck, so the current
+ * error recovery implementation is to trigger a bus reset to the device
+ * and hopefully it can bring back the device.
+ *
+ * The actual work of error recovery has to be in a thread context because
+ * it is kicked off in the TX thread (i2400ms->tx_workqueue) which is to be
+ * destroyed by the error recovery mechanism (currently a bus reset).
+ *
+ * Also, there may be already a queue of TX works that all hit
+ * the -ETIMEOUT error condition because the device is stuck already.
+ * Since bus reset is used as the error recovery mechanism and we don't
+ * want consecutive bus resets simply because the multiple TX works
+ * in the queue all hit the same device erratum, the flag "error_recovery"
+ * is introduced for preventing unwanted consecutive bus resets.
+ *
+ * Error recovery shall only be invoked again if previous one was completed.
+ * The flag error_recovery is set when error recovery mechanism is scheduled,
+ * and is checked when we need to schedule another error recovery. If it is
+ * in place already, then we shouldn't schedule another one.
+ */
+void i2400m_error_recovery(struct i2400m *i2400m)
+{
+ struct device *dev = i2400m_dev(i2400m);
+
+ if (atomic_add_return(1, &i2400m->error_recovery) == 1) {
+ if (i2400m_schedule_work(i2400m, __i2400m_error_recovery,
+ GFP_ATOMIC, NULL, 0) < 0) {
+ dev_err(dev, "run out of memory for "
+ "scheduling an error recovery ?\n");
+ atomic_dec(&i2400m->error_recovery);
+ }
+ } else
+ atomic_dec(&i2400m->error_recovery);
+ return;
+}
+EXPORT_SYMBOL_GPL(i2400m_error_recovery);
+
/*
* Alloc the command and ack buffers for boot mode
*
@@ -839,6 +909,10 @@ void i2400m_init(struct i2400m *i2400m)
atomic_set(&i2400m->bus_reset_retries, 0);
i2400m->alive = 0;
+
+ /* initialize error_recovery to 1 for denoting we
+ * are not yet ready to take any error recovery */
+ atomic_set(&i2400m->error_recovery, 1);
}
EXPORT_SYMBOL_GPL(i2400m_init);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index ad8e6a3..7a9c2c5 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -545,6 +545,15 @@ struct i2400m_barker_db;
* all the device reboot events detected can be still handled properly
* by either dev_reset_handle() or .pre_reset/.post_reset as long as
* the driver presents. It is set 0 along with @updown in dev_stop().
+ *
+ * @error_recovery: flag to denote if we are ready to take an error recovery.
+ * 0 for ready to take an error recovery; 1 for not ready. It is
+ * initialized to 1 while probe() since we don't tend to take any error
+ * recovery during probe(). It is decremented by 1 whenever dev_start()
+ * succeeds to indicate we are ready to take error recovery from now on.
+ * It is checked every time we wanna schedule an error recovery. If an
+ * error recovery is already in place (error_recovery was set 1), we
+ * should not schedule another one until the last one is done.
*/
struct i2400m {
struct wimax_dev wimax_dev; /* FIRST! See doc */
@@ -625,6 +634,10 @@ struct i2400m {
/* if the device is expected to be alive */
unsigned alive;
+
+ /* 0 if we are ready for error recovery; 1 if not ready */
+ atomic_t error_recovery;
+
};
@@ -847,6 +860,7 @@ void i2400m_put(struct i2400m *i2400m)
extern int i2400m_dev_reset_handle(struct i2400m *, const char *);
extern int i2400m_pre_reset(struct i2400m *);
extern int i2400m_post_reset(struct i2400m *);
+extern void i2400m_error_recovery(struct i2400m *);
/*
* _setup()/_release() are called by the probe/disconnect functions of
diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c
index 412b6a8..b53cd1c 100644
--- a/drivers/net/wimax/i2400m/sdio-tx.c
+++ b/drivers/net/wimax/i2400m/sdio-tx.c
@@ -98,6 +98,10 @@ void i2400ms_tx_submit(struct work_struct *ws)
tx_msg_size, result);
}
+ if (result == -ETIMEDOUT) {
+ i2400m_error_recovery(i2400m);
+ break;
+ }
d_printf(2, dev, "TX: %zub submitted\n", tx_msg_size);
}
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 06/25] wimax/i2400m: fix for missed reset events if triggered by dev_reset_handle()
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
The problem is only seen on SDIO interface since on USB, a bus reset would
really re-probe the driver, but on SDIO interface, a bus reset will not
re-enumerate the SDIO bus, so no driver re-probe is happening. Therefore,
on SDIO interface, the reset event should be still detected and handled by
dev_reset_handle().
Problem description:
Whenever a reboot barker is received during operational mode (i2400m->boot_mode == 0),
dev_reset_handle() is invoked to handle that function reset event.
dev_reset_handle() then sets the flag i2400m->boot_mode to 1 indicating the device is
back to bootmode before proceeding to dev_stop() and dev_start().
If dev_start() returns failure, a bus reset is triggered by dev_reset_handle().
The flag i2400m->boot_mode then remains 1 when the second reboot barker arrives.
However the interrupt service routine i2400ms_rx() instead of invoking dev_reset_handle()
to handle that reset event, it filters out that boot event to bootmode because it sees
the flag i2400m->boot_mode equal to 1.
The fix:
Maintain the flag i2400m->boot_mode within dev_reset_handle() and set the flag
i2400m->boot_mode to 1 when entering dev_reset_handle(). It remains 1
until the dev_reset_handle() issues a bus reset. ie: the bus reset is
taking place just like it happens for the first time during operational mode.
To denote the actual device state and the state we expect, a flag i2400m->alive
is introduced in addition to the existing flag i2400m->updown.
It's maintained with the same way for i2400m->updown but instead of reflecting
the actual state like i2400m->updown does, i2400m->alive maintains the state
we expect. i2400m->alive is set 1 just like whenever i2400m->updown is set 1.
Yet i2400m->alive remains 1 since we expect the device to be up all the time
until the driver is removed. See the doc for @alive in i2400m.h.
An enumeration I2400M_BUS_RESET_RETRIES is added to define the maximum number of
bus resets that a device reboot can retry.
A counter i2400m->bus_reset_retries is added to track how many bus resets
have been retried in one device reboot. If I2400M_BUS_RESET_RETRIES bus resets
were retried in this boot, we give up any further retrying so the device would enter
low power state. The counter i2400m->bus_reset_retries is incremented whenever
dev_reset_handle() is issuing a bus reset and is cleared to 0 when dev_start() is
successfully done, ie: a successful reboot.
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/driver.c | 68 ++++++++++++++++++++++++++++---------
drivers/net/wimax/i2400m/i2400m.h | 34 ++++++++++++++++++
2 files changed, 86 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 3a6c8dd..1674dba 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -436,7 +436,8 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
result = __i2400m_dev_start(i2400m, bm_flags);
if (result >= 0) {
i2400m->updown = 1;
- wmb(); /* see i2400m->updown's documentation */
+ i2400m->alive = 1;
+ wmb();/* see i2400m->updown and i2400m->alive's doc */
}
}
mutex_unlock(&i2400m->init_mutex);
@@ -497,7 +498,8 @@ void i2400m_dev_stop(struct i2400m *i2400m)
if (i2400m->updown) {
__i2400m_dev_stop(i2400m);
i2400m->updown = 0;
- wmb(); /* see i2400m->updown's documentation */
+ i2400m->alive = 0;
+ wmb(); /* see i2400m->updown and i2400m->alive's doc */
}
mutex_unlock(&i2400m->init_mutex);
}
@@ -669,6 +671,9 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
d_fnstart(3, dev, "(ws %p i2400m %p reason %s)\n", ws, i2400m, reason);
+ i2400m->boot_mode = 1;
+ wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
+
result = 0;
if (mutex_trylock(&i2400m->init_mutex) == 0) {
/* We are still in i2400m_dev_start() [let it fail] or
@@ -679,32 +684,62 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
complete(&i2400m->msg_completion);
goto out;
}
- if (i2400m->updown == 0) {
- dev_info(dev, "%s: device is down, doing nothing\n", reason);
- goto out_unlock;
- }
+
dev_err(dev, "%s: reinitializing driver\n", reason);
- __i2400m_dev_stop(i2400m);
- result = __i2400m_dev_start(i2400m,
- I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT);
- if (result < 0) {
+ rmb();
+ if (i2400m->updown) {
+ __i2400m_dev_stop(i2400m);
i2400m->updown = 0;
wmb(); /* see i2400m->updown's documentation */
- dev_err(dev, "%s: cannot start the device: %d\n",
- reason, result);
- result = -EUCLEAN;
}
-out_unlock:
+
+ if (i2400m->alive) {
+ result = __i2400m_dev_start(i2400m,
+ I2400M_BRI_SOFT | I2400M_BRI_MAC_REINIT);
+ if (result < 0) {
+ dev_err(dev, "%s: cannot start the device: %d\n",
+ reason, result);
+ result = -EUCLEAN;
+ if (atomic_read(&i2400m->bus_reset_retries)
+ >= I2400M_BUS_RESET_RETRIES) {
+ result = -ENODEV;
+ dev_err(dev, "tried too many times to "
+ "reset the device, giving up\n");
+ }
+ }
+ }
+
if (i2400m->reset_ctx) {
ctx->result = result;
complete(&ctx->completion);
}
mutex_unlock(&i2400m->init_mutex);
if (result == -EUCLEAN) {
+ /*
+ * We come here because the reset during operational mode
+ * wasn't successully done and need to proceed to a bus
+ * reset. For the dev_reset_handle() to be able to handle
+ * the reset event later properly, we restore boot_mode back
+ * to the state before previous reset. ie: just like we are
+ * issuing the bus reset for the first time
+ */
+ i2400m->boot_mode = 0;
+ wmb();
+
+ atomic_inc(&i2400m->bus_reset_retries);
/* ops, need to clean up [w/ init_mutex not held] */
result = i2400m_reset(i2400m, I2400M_RT_BUS);
if (result >= 0)
result = -ENODEV;
+ } else {
+ rmb();
+ if (i2400m->alive) {
+ /* great, we expect the device state up and
+ * dev_start() actually brings the device state up */
+ i2400m->updown = 1;
+ wmb();
+ atomic_set(&i2400m->bus_reset_retries, 0);
+ }
}
out:
i2400m_put(i2400m);
@@ -729,8 +764,6 @@ out:
*/
int i2400m_dev_reset_handle(struct i2400m *i2400m, const char *reason)
{
- i2400m->boot_mode = 1;
- wmb(); /* Make sure i2400m_msg_to_dev() sees boot_mode */
return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
GFP_ATOMIC, &reason, sizeof(reason));
}
@@ -803,6 +836,9 @@ void i2400m_init(struct i2400m *i2400m)
mutex_init(&i2400m->init_mutex);
/* wake_tx_ws is initialized in i2400m_tx_setup() */
+ atomic_set(&i2400m->bus_reset_retries, 0);
+
+ i2400m->alive = 0;
}
EXPORT_SYMBOL_GPL(i2400m_init);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index da218b9..ad8e6a3 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -177,6 +177,11 @@ enum {
I2400M_BM_ACK_BUF_SIZE = 256,
};
+enum {
+ /* Maximum number of bus reset can be retried */
+ I2400M_BUS_RESET_RETRIES = 3,
+};
+
/**
* struct i2400m_poke_table - Hardware poke table for the Intel 2400m
*
@@ -517,6 +522,29 @@ struct i2400m_barker_db;
* same.
*
* @pm_notifier: used to register for PM events
+ *
+ * @bus_reset_retries: counter for the number of bus resets attempted for
+ * this boot. It's not for tracking the number of bus resets during
+ * the whole driver life cycle (from insmod to rmmod) but for the
+ * number of dev_start() executed until dev_start() returns a success
+ * (ie: a good boot means a dev_stop() followed by a successful
+ * dev_start()). dev_reset_handler() increments this counter whenever
+ * it is triggering a bus reset. It checks this counter to decide if a
+ * subsequent bus reset should be retried. dev_reset_handler() retries
+ * the bus reset until dev_start() succeeds or the counter reaches
+ * I2400M_BUS_RESET_RETRIES. The counter is cleared to 0 in
+ * dev_reset_handle() when dev_start() returns a success,
+ * ie: a successul boot is completed.
+ *
+ * @alive: flag to denote if the device *should* be alive. This flag is
+ * everything like @updown (see doc for @updown) except reflecting
+ * the device state *we expect* rather than the actual state as denoted
+ * by @updown. It is set 1 whenever @updown is set 1 in dev_start().
+ * Then the device is expected to be alive all the time
+ * (i2400m->alive remains 1) until the driver is removed. Therefore
+ * all the device reboot events detected can be still handled properly
+ * by either dev_reset_handle() or .pre_reset/.post_reset as long as
+ * the driver presents. It is set 0 along with @updown in dev_stop().
*/
struct i2400m {
struct wimax_dev wimax_dev; /* FIRST! See doc */
@@ -591,6 +619,12 @@ struct i2400m {
struct i2400m_barker_db *barker;
struct notifier_block pm_notifier;
+
+ /* counting bus reset retries in this boot */
+ atomic_t bus_reset_retries;
+
+ /* if the device is expected to be alive */
+ unsigned alive;
};
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 08/25] wimax/i2400m: Correct the error path handlers order in i2400m_post_reset()
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
When bus_setup fails in i2400m_post_reset(), it falls to the error path handler
"error_bus_setup:" which includes unlock the mutext. However, we didn't ever
try to the obtain the lock when running bus_setup.
The patch is to fix the misplaced error path handler "error_bus_setup:".
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index d83fe84..39cf96a 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -629,12 +629,12 @@ int i2400m_post_reset(struct i2400m *i2400m)
error_dev_start:
if (i2400m->bus_release)
i2400m->bus_release(i2400m);
-error_bus_setup:
/* even if the device was up, it could not be recovered, so we
* mark it as down. */
i2400m->updown = 0;
wmb(); /* see i2400m->updown's documentation */
mutex_unlock(&i2400m->init_mutex);
+error_bus_setup:
d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
return result;
}
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 10/25] wimax/i2400m: increase the maximum number of payloads per message to 60 [v1]
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Prasanna S. Panchamukhi
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
According to Intel Wimax i3200, i5x50 and i6x50 device specification
documents, the maximum number of payloads per message can be up to 60.
Increasing the number of payloads to 60 per message helps to
accommodate smaller payloads in a single transaction. This patch
increases the maximum number of payloads from 12 to 60 per message.
Signed-off-by: Prasanna S. Panchamukhi <prasannax.s.panchamukhi@intel.com>
---
drivers/net/wimax/i2400m/tx.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 21909e5..b10c3b7 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -272,7 +272,13 @@ enum {
* at the end there are less, we pad up to the nearest
* multiple of 16.
*/
- I2400M_TX_PLD_MAX = 12,
+ /*
+ * According to Intel Wimax i3200, i5x50 and i6x50 specification
+ * documents, the maximum number of payloads per message can be
+ * up to 60. Increasing the number of payloads to 60 per message
+ * helps to accommodate smaller payloads in a single transaction.
+ */
+ I2400M_TX_PLD_MAX = 60,
I2400M_TX_PLD_SIZE = sizeof(struct i2400m_msg_hdr)
+ I2400M_TX_PLD_MAX * sizeof(struct i2400m_pld),
I2400M_TX_SKIP = 0x80000000,
--
1.6.6.1
^ permalink raw reply related
* [patch 2.6.35 09/25] wimax/i2400m: Reset the TX FIFO indices when allocating the TX FIFO in tx_setup()
From: Inaky Perez-Gonzalez @ 2010-05-14 21:45 UTC (permalink / raw)
To: netdev, wimax; +Cc: Cindy H Kao
In-Reply-To: <cover.1273708027.git.inaky.perez-gonzalez@intel.com>
From: Cindy H Kao <cindy.h.kao@intel.com>
This patch makes sure whenever tx_setup() is invoked during driver
initialization or device reset where TX FIFO is released and re-allocated,
the indices tx_in, tx_out, tx_msg_size, tx_sequence, tx_msg are properly
initialized.
When a device reset happens and the TX FIFO is released/re-allocated,
a new block of memory may be allocated for the TX FIFO, therefore tx_msg
should be cleared so that no any TX threads (tx_worker, tx) would access
to the out-of-date addresses.
Also, the TX threads use tx_in and tx_out to decide where to put the new
host-to-device messages and from where to copy them to the device HW FIFO,
these indices have to be cleared so after the TX FIFO is re-allocated during
the reset, the indices both refer to the head of the FIFO, ie. a new start.
The same rational applies to tx_msg_size and tx_sequence.
To protect the indices from being accessed by multiple threads simultaneously,
the lock tx_lock has to be obtained before the initializations and released
afterwards.
Signed-off-by: Cindy H Kao <cindy.h.kao@intel.com>
---
drivers/net/wimax/i2400m/tx.c | 29 +++++++++++++++++++++--------
1 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wimax/i2400m/tx.c b/drivers/net/wimax/i2400m/tx.c
index 8561c07..21909e5 100644
--- a/drivers/net/wimax/i2400m/tx.c
+++ b/drivers/net/wimax/i2400m/tx.c
@@ -877,27 +877,40 @@ EXPORT_SYMBOL_GPL(i2400m_tx_msg_sent);
* i2400m_tx_setup - Initialize the TX queue and infrastructure
*
* Make sure we reset the TX sequence to zero, as when this function
- * is called, the firmware has been just restarted.
+ * is called, the firmware has been just restarted. Same rational
+ * for tx_in, tx_out, tx_msg_size and tx_msg. We reset them since
+ * the memory for TX queue is reallocated.
*/
int i2400m_tx_setup(struct i2400m *i2400m)
{
- int result;
+ int result = 0;
+ void *tx_buf;
+ unsigned long flags;
/* Do this here only once -- can't do on
* i2400m_hard_start_xmit() as we'll cause race conditions if
* the WS was scheduled on another CPU */
INIT_WORK(&i2400m->wake_tx_ws, i2400m_wake_tx_work);
- i2400m->tx_sequence = 0;
+ tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_ATOMIC);
+ if (tx_buf == NULL) {
+ result = -ENOMEM;
+ goto error_kmalloc;
+ }
+
/* Warn if the calculated buffer size exceeds I2400M_TX_BUF_SIZE. */
BUILD_BUG_ON(I2400M_TX_PDU_TOTAL_SIZE > I2400M_TX_BUF_SIZE);
- i2400m->tx_buf = kmalloc(I2400M_TX_BUF_SIZE, GFP_KERNEL);
- if (i2400m->tx_buf == NULL)
- result = -ENOMEM;
- else
- result = 0;
+ spin_lock_irqsave(&i2400m->tx_lock, flags);
+ i2400m->tx_sequence = 0;
+ i2400m->tx_in = 0;
+ i2400m->tx_out = 0;
+ i2400m->tx_msg_size = 0;
+ i2400m->tx_msg = NULL;
+ i2400m->tx_buf = tx_buf;
+ spin_unlock_irqrestore(&i2400m->tx_lock, flags);
/* Huh? the bus layer has to define this... */
BUG_ON(i2400m->bus_tx_block_size == 0);
+error_kmalloc:
return result;
}
--
1.6.6.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox