* Re: [PATCH v4 1/3] make jump_labels wait while updates are in place
From: Jason Baron @ 2012-04-27 13:53 UTC (permalink / raw)
To: Steven Rostedt
Cc: Glauber Costa, cgroups, netdev, linux-kernel, Li Zefan, Tejun Heo,
kamezawa.hiroyu, linux-mm, devel, Johannes Weiner, Michal Hocko,
Ingo Molnar
In-Reply-To: <20120427004305.GC23877@home.goodmis.org>
On Thu, Apr 26, 2012 at 08:43:06PM -0400, Steven Rostedt wrote:
> On Thu, Apr 26, 2012 at 07:51:05PM -0300, Glauber Costa wrote:
> > In mem cgroup, we need to guarantee that two concurrent updates
> > of the jump_label interface wait for each other. IOW, we can't have
> > other updates returning while the first one is still patching the
> > kernel around, otherwise we'll race.
>
> But it shouldn't. The code as is should prevent that.
>
> >
> > I believe this is something that can fit well in the static branch
> > API, without noticeable disadvantages:
> >
> > * in the common case, it will be a quite simple lock/unlock operation
> > * Every context that calls static_branch_slow* already expects to be
> > in sleeping context because it will mutex_lock the unlikely case.
> > * static_key_slow_inc is not expected to be called in any fast path,
> > otherwise it would be expected to have quite a different name. Therefore
> > the mutex + atomic combination instead of just an atomic should not kill
> > us.
> >
> > Signed-off-by: Glauber Costa <glommer@parallels.com>
> > CC: Tejun Heo <tj@kernel.org>
> > CC: Li Zefan <lizefan@huawei.com>
> > CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> > CC: Johannes Weiner <hannes@cmpxchg.org>
> > CC: Michal Hocko <mhocko@suse.cz>
> > CC: Ingo Molnar <mingo@elte.hu>
> > CC: Jason Baron <jbaron@redhat.com>
> > ---
> > kernel/jump_label.c | 21 +++++++++++----------
> > 1 files changed, 11 insertions(+), 10 deletions(-)
> >
> > diff --git a/kernel/jump_label.c b/kernel/jump_label.c
> > index 4304919..5d09cb4 100644
> > --- a/kernel/jump_label.c
> > +++ b/kernel/jump_label.c
> > @@ -57,17 +57,16 @@ static void jump_label_update(struct static_key *key, int enable);
> >
> > void static_key_slow_inc(struct static_key *key)
> > {
> > + jump_label_lock();
> > if (atomic_inc_not_zero(&key->enabled))
> > - return;
>
> If key->enabled is not zero, there's nothing to be done. As the jump
> label has already been enabled. Note, the key->enabled doesn't get set
> until after the jump label is updated. Thus, if two tasks were to come
> in, they both would be locked on the jump_label_lock().
>
Right, for x86 which uses stop_machine currently, we guarantee that all
cpus are going to see the updated code, before the inc of key->enabled.
However, other arches (sparc, mips, powerpc, for example), seem to be
using much lighter weight updates, which I hope are ok :)
Thanks,
-Jason
--
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/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-27 13:29 UTC (permalink / raw)
To: Lennert Buytenhek
Cc: John W. Linville, linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, lautriv, Jim Cromie
In-Reply-To: <CA+icZUUnJPeDmL9xXfvj62an40bXwwaOnrJmxmLN_cBt9PyCZA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 5077 bytes --]
On Fri, Apr 27, 2012 at 12:57 PM, Sedat Dilek
<sedat.dilek-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
> On Fri, Apr 27, 2012 at 12:17 PM, Lennert Buytenhek
> <buytenh-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org> wrote:
>> On Fri, Apr 27, 2012 at 12:12:13PM +0200, Sedat Dilek wrote:
>>
>>> >> >> >> Are you planning to or even working on support (for) 8361 devices?
>>> >> >> >
>>> >> >> > I don't have any such plans, and I don't know of anyone who does.
>>> >> >>
>>> >> >> Does 8361 require firmware support?
>>> >> >
>>> >> > What do you mean by that?
>>> >>
>>> >> IIRC ath5k for example needs no external firmware file.
>>> >
>>> > The 8361 requires firmware to be loaded into it before it'll do
>>> > anything useful.
>>> >
>>> >
>>> >> >> Does a firmware file exist (name?)?
>>> >> >
>>> >> > There's firmware for the 8361 out there, however, that version of
>>> >> > the firmware implements a firmware API that is different from the
>>> >> > one that mwl8k currently implements.
>>> >> >
>>> >> > You could add 8361 support to mwl8k, but then you'd have to go over
>>> >> > all the firmware command invocations in mwl8k and make sure that they
>>> >> > will work on the 8361 firmware that you're trying to support as well.
>>> >>
>>> >> Without having a 8361 this will be even harder to walk through.
>>> >>
>>> >> Anyway, thanks for your detailed explanations.
>>> >>
>>> >> What's the alternative for such affected users?
>>> >> Use ndis-wrapper?
>>> >
>>> > I'm not sure. I've never tried to get a 8361 work under Linux.
>>>
>>> Just found on [1] this same wrong patch in [2] :-).
>>> Dunno if [3] worked and from where they have stolen fw-files.
>>>
>>> - Sedat -
>>>
>>> [1] https://dev.openwrt.org/ticket/7209
>>> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
>>> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
>>
>> I doubt that [3] is really all that's needed to make it work. But if
>> there's someone for whom it works, I'd like them to run some tests on
>> mwl8k + [3] on 88w8361p.
>
> Just asked lautriv to do so (he will do against linux-3.3.3), lets' see.
> Also, I refreshed and adapted a bit the instructions (see attachment).
>
> - Sedat -
[ CC Jim Cromie ]
Now, with extracted firmware files renamed & copied to
/lib/firmware/mwl8k/ and applied patch (see attachment) against
Linux-3.4-rc4+ I am seeing with modinfo:
$ sudo modinfo mwl8k
filename:
/lib/modules/3.4.0-rc4-5-generic/kernel/drivers/net/wireless/mwl8k.ko
license: GPL
author: Lennert Buytenhek <buytenh-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
version: 0.13
description: Marvell TOPDOG(R) 802.11 Wireless Network Driver
firmware: mwl8k/fmimage_8366_ap-2.fw
firmware: mwl8k/fmimage_8366.fw
firmware: mwl8k/helper_8366.fw
firmware: mwl8k/fmimage_8687.fw
firmware: mwl8k/helper_8687.fw
firmware: mwl8k/fmimage_8363.fw
firmware: mwl8k/helper_8363.fw
firmware: mwl8k/fmimage_8361p.fw
firmware: mwl8k/helper_8361p.fw
srcversion: 9E1479A05C8D67E6AE90746
alias: pci:v000011ABd00002A43sv*sd*bc*sc*i*
alias: pci:v000011ABd00002A40sv*sd*bc*sc*i*
alias: pci:v000011ABd00002A30sv*sd*bc*sc*i*
alias: pci:v000011ABd00002A2Bsv*sd*bc*sc*i*
alias: pci:v000011ABd00002A24sv*sd*bc*sc*i*
alias: pci:v000011ABd00002A0Csv*sd*bc*sc*i*
alias: pci:v000011ABd00002A0Asv*sd*bc*sc*i*
alias: pci:v000011ABd00002A02sv*sd*bc*sc*i* <--- 8361P:
0x2a02 PCI device-id
depends: mac80211,cfg80211
vermagic: 3.4.0-rc4-5-generic SMP mod_unload modversions
parm: ap_mode_default:Set to 1 to make ap mode the default
instead of sta mode (bool)
$ ls -l /lib/firmware/mwl8k/
insgesamt 456
-rw-r--r-- 1 root root 75848 Apr 27 13:49 fmimage_8361p.fw <---
8361P: Firmware image
-rw-r--r-- 1 root root 101780 Mär 19 19:32 fmimage_8366_ap-1.fw
-rw-r--r-- 1 root root 101976 Mär 19 19:32 fmimage_8366_ap-2.fw
-rw-r--r-- 1 root root 96664 Mär 19 19:32 fmimage_8366.fw
-rw-r--r-- 1 root root 73252 Feb 23 20:07 fmimage_8687.fw
-rw-r--r-- 1 root root 2476 Apr 27 13:49 helper_8361p.fw <--- 8361P:
Helper image
-rw-r--r-- 1 root root 2476 Mär 19 19:32 helper_8366.fw
-rw-r--r-- 1 root root 2476 Feb 23 20:07 helper_8687.fw
As said... ***compile-tested*** only here.
I had a short query with lautriv on #linux-wireless this afternoon:
* mwl8k kernel-module was autoloaded
* wlan0 interface got fired up
* ESSID was accepted
* logs reported 802.11bgn support is active
* (he tested on Linux-3.3.3)
With WPA/WPA2 lautriv had some problems as his installation was
missing wpasupplicant.
He setup a classic /etc/network/interfaces.
After resetting his router mwl8k worked nicely.
Unfortunately, he was on the run and promised me to send logs and do
more testing this evening.
So, Lennert if you want more testing - What? How? etc.
Thanks in advance.
- Sedat -
[-- Attachment #2: 0001-mwl8k-Add-support-for-MWL8361P.patch --]
[-- Type: application/octet-stream, Size: 2171 bytes --]
From 1a586a1f21f820de0ea06c5382a69191d93d80fe Mon Sep 17 00:00:00 2001
From: Sedat Dilek <sedat.dilek@gmail.com>
Date: Fri, 27 Apr 2012 13:46:02 +0200
Subject: [PATCH] mwl8k: Add support for MWL8361P
Follow discussion in [1] for more details about adding driver
support and howto extract firmware files.
$ sudo modinfo mwl8k | egrep -i '8361p|2a02'
firmware: mwl8k/fmimage_8361p.fw
firmware: mwl8k/helper_8361p.fw
alias: pci:v000011ABd00002A02sv*sd*bc*sc*i*
Compile-tested against Linux-3.4-rc4+.
[1] http://marc.info/?t=133551792600004&r=1&w=2
Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
drivers/net/wireless/mwl8k.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b48674b..3ea9b8e 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -5225,6 +5225,7 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
}
enum {
+ MWL8361P = 0,
MWL8363 = 0,
MWL8687,
MWL8366,
@@ -5235,6 +5236,11 @@ enum {
#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
+ [MWL8361P] = {
+ .part_name = "88w8361p",
+ .helper_image = "mwl8k/helper_8361p.fw",
+ .fw_image_sta = "mwl8k/fmimage_8361p.fw",
+ },
[MWL8363] = {
.part_name = "88w8363",
.helper_image = "mwl8k/helper_8363.fw",
@@ -5255,6 +5261,8 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
},
};
+MODULE_FIRMWARE("mwl8k/helper_8361p.fw");
+MODULE_FIRMWARE("mwl8k/fmimage_8361p.fw");
MODULE_FIRMWARE("mwl8k/helper_8363.fw");
MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
MODULE_FIRMWARE("mwl8k/helper_8687.fw");
@@ -5264,6 +5272,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
+ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8361P, },
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH 00/14 v2] usb/net: rndis: first step toward consolidation
From: Haiyang Zhang @ 2012-04-27 12:56 UTC (permalink / raw)
To: Linus Walleij
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Greg Kroah-Hartman, David S. Miller, Felipe Balbi,
Jussi Kivilinna, Wei Yongjun, Ben Hutchings, KY Srinivasan
In-Reply-To: <CACRpkdYmeRweAe3YJmZztAJ9A5C_qvVwCmG3M-qwmrsv9Sq79A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
> -----Original Message-----
> From: Linus Walleij [mailto:linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org]
> Sent: Friday, April 27, 2012 8:29 AM
> To: Haiyang Zhang
> Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Greg Kroah-
> Hartman; David S. Miller; Felipe Balbi; Jussi Kivilinna; Wei Yongjun; Ben
> Hutchings; KY Srinivasan
> Subject: Re: [PATCH 00/14 v2] usb/net: rndis: first step toward consolidation
>
> On Wed, Apr 25, 2012 at 10:36 PM, Haiyang Zhang
> <haiyangz-0li6OtcxBFHby3iVrkZq2A@public.gmane.org> wrote:
>
> > I tested Hyper-V netvsc driver, it works fine with the patches.
>
> Thanks! Can I add yout Tested-by: on them?
Yes, you can, after I test the version 3.
Thanks,
- Haiyang
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 03/15] batman-adv: add biggest_unsigned_int(x) macro
From: Antonio Quartulli @ 2012-04-27 12:51 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
david.laight-JxhZ9S5GRejQT0dZR+AlfA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <20120425.140904.935584797119761625.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Il 25.04.2012 20:09 David Miller ha scritto:
> From: "David Laight" <David.Laight-ZS65k/vG3HxXrIkS9f7CXA@public.gmane.org>
> Date: Wed, 25 Apr 2012 15:57:39 +0100
>
>>
>>> > +/* Returns the biggest unsigned integer with the sizeof x */
>>> > +#define biggest_unsigned_int(x) (~(x)0)
>>>
>>> Nope - biggest_unsigned_int(unsigned char) is probably 0xffffffff
>>
>> To correct myself, it is actually ((int)(-1)) (ie a signed value).
>
> In any event this is just a terrible macro, and too stupid to live.
Hello David,
ok. So the suggestion is to directly use the ~ operator in the code
without creating a macro.
If the rest of the patchset is ok, I will eliminate this macro and
resend the pull request again.
Cheers,
--
Antonio Quartulli
^ permalink raw reply
* Re: [PATCH 00/14 v2] usb/net: rndis: first step toward consolidation
From: Linus Walleij @ 2012-04-27 12:28 UTC (permalink / raw)
To: Haiyang Zhang
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Greg Kroah-Hartman, David S. Miller, Felipe Balbi,
Jussi Kivilinna, Wei Yongjun, Ben Hutchings, KY Srinivasan
In-Reply-To: <A1F3067C9B68744AA19F6802BAB8FFDC0DD36C9E-Jfd81uAzPQthtgIzimG1dFir+X/St4rqwBk/1ggFUS45P9zcU8sUGwC/G2K4zDHf@public.gmane.org>
On Wed, Apr 25, 2012 at 10:36 PM, Haiyang Zhang <haiyangz-0li6OtcxBFHby3iVrkZq2A@public.gmane.org> wrote:
> I tested Hyper-V netvsc driver, it works fine with the patches.
Thanks! Can I add yout Tested-by: on them?
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 5/5 net-next] net: makes skb_splice_bits() aware of skb->head_frag
From: Eric Dumazet @ 2012-04-27 12:10 UTC (permalink / raw)
To: David Miller
Cc: netdev, Neal Cardwell, Jeff Kirsher, Tom Herbert, Herbert Xu,
Ben Hutchings, Matt Carlson, Michael Chan,
Maciej Żenczykowski, Ilpo Järvinen
From: Eric Dumazet <edumazet@google.com>
__skb_splice_bits() can check if skb to be spliced has its skb->head
mapped to a page fragment, instead of a kmalloc() area.
If so we can avoid a copy of the skb head and get a reference on
underlying page.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
net/core/skbuff.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2ad1ee7..e5bd086 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1699,14 +1699,18 @@ static bool __skb_splice_bits(struct sk_buff *skb, struct pipe_inode_info *pipe,
struct splice_pipe_desc *spd, struct sock *sk)
{
int seg;
+ bool head_is_linear = !skb->head_frag;
- /*
- * map the linear part
+ /* map the linear part :
+ * If skb->head_frag is set, this 'linear' part is backed
+ * by a fragment, and we can avoid a copy.
*/
if (__splice_segment(virt_to_page(skb->data),
(unsigned long) skb->data & (PAGE_SIZE - 1),
skb_headlen(skb),
- offset, len, skb, spd, true, sk, pipe))
+ offset, len, skb, spd,
+ head_is_linear,
+ sk, pipe))
return true;
/*
^ permalink raw reply related
* Re: [PATCH 02/14 v2] usb/net: rndis: break out <linux/rndis.h> defines
From: Linus Walleij @ 2012-04-27 11:24 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, linux-usb-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, balbi-l0cyMroinI0,
jussi.kivilinna-E01nCVcF24I, haiyangz-0li6OtcxBFHby3iVrkZq2A,
yongjun_wei-zrsr2BFq86L20UzCJQGyNP8+0UxHXcjY,
ben-/+tVBieCtBitmTQ+vhA3Yw
In-Reply-To: <20120425.194447.1519804940735129000.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
On Thu, Apr 26, 2012 at 1:44 AM, David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:
> After this patch the build emits tons of warnings because you've
> left a situation where there will be duplicate definitions:
Sure, that was on purpose, doing it step-wise so we could find
bisect if something broke in the step of ironing out the duplicate
defines. So actually it was being cautious (maybe in a bad way.)
But I'll just squash the duplication-removal patches now that
we know it works, and we end on warning-free patches.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-27 10:57 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120427101732.GX3157@wantstofly.org>
[-- Attachment #1: Type: text/plain, Size: 2084 bytes --]
On Fri, Apr 27, 2012 at 12:17 PM, Lennert Buytenhek
<buytenh@wantstofly.org> wrote:
> On Fri, Apr 27, 2012 at 12:12:13PM +0200, Sedat Dilek wrote:
>
>> >> >> >> Are you planning to or even working on support (for) 8361 devices?
>> >> >> >
>> >> >> > I don't have any such plans, and I don't know of anyone who does.
>> >> >>
>> >> >> Does 8361 require firmware support?
>> >> >
>> >> > What do you mean by that?
>> >>
>> >> IIRC ath5k for example needs no external firmware file.
>> >
>> > The 8361 requires firmware to be loaded into it before it'll do
>> > anything useful.
>> >
>> >
>> >> >> Does a firmware file exist (name?)?
>> >> >
>> >> > There's firmware for the 8361 out there, however, that version of
>> >> > the firmware implements a firmware API that is different from the
>> >> > one that mwl8k currently implements.
>> >> >
>> >> > You could add 8361 support to mwl8k, but then you'd have to go over
>> >> > all the firmware command invocations in mwl8k and make sure that they
>> >> > will work on the 8361 firmware that you're trying to support as well.
>> >>
>> >> Without having a 8361 this will be even harder to walk through.
>> >>
>> >> Anyway, thanks for your detailed explanations.
>> >>
>> >> What's the alternative for such affected users?
>> >> Use ndis-wrapper?
>> >
>> > I'm not sure. I've never tried to get a 8361 work under Linux.
>>
>> Just found on [1] this same wrong patch in [2] :-).
>> Dunno if [3] worked and from where they have stolen fw-files.
>>
>> - Sedat -
>>
>> [1] https://dev.openwrt.org/ticket/7209
>> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
>> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
>
> I doubt that [3] is really all that's needed to make it work. But if
> there's someone for whom it works, I'd like them to run some tests on
> mwl8k + [3] on 88w8361p.
Just asked lautriv to do so (he will do against linux-3.3.3), lets' see.
Also, I refreshed and adapted a bit the instructions (see attachment).
- Sedat -
[-- Attachment #2: mwl8k_extract_firmware.txt --]
[-- Type: text/plain, Size: 1159 bytes --]
### HELP-1: https://forum.openwrt.org/viewtopic.php?pid=103243#p103243
### HELP-2: https://forum.openwrt.org/viewtopic.php?pid=110004#p110004
### From HELP-1:
To extract the firmware for the mwl8k driver, open your Ubuntu terminal:
sudo apt-get install cabextract unshield
mkdir mwl8k
cd mwl8k
wget -O mrv8k_extract_fw.c 'http://marc.info/?l=linux-wireless&m=126540674419330&q=p3'
wget ftp://downloads.netgear.com/files/wn311t_4_2_setup.exe
mkdir mess
cabextract -F Disk1/data*.* -d mess wn311t_4_2_setup.exe
unshield -g Driver -d mess x mess/Disk1/data1.cab
gcc -o mrv8k_extract_fw mrv8k_extract_fw.c
./mrv8k_extract_fw mess/Driver/netmw145.sys
rm -r mess
md5sum -b *.fw
mv fmimage_8XX1.fw fmimage_8363.fw
mv helper_8XX1.fw helper_8363.fw
### From HELP-2: For Marwell 8361P
md5sum -b *.fw | egrep '48c79b085f7f5a590d3dbc15647e519f|0fe11f415adbbd5e8ca03641705c4a6c'
[ OUTPUT ]
48c79b085f7f5a590d3dbc15647e519f *fmimage_8XX0.fw
0fe11f415adbbd5e8ca03641705c4a6c *helper_8XX0.fw
mv fmimage_8XX0.fw fmimage_8361p.fw
mv helper_8XX0.fw helper_8361p.fw
### PATCH: https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
-dileks // 27-Apr-2012
^ permalink raw reply
* [PATCH 4/4 net-next] tcp: makes tcp_try_coalesce aware of skb->head_frag
From: Eric Dumazet @ 2012-04-27 10:38 UTC (permalink / raw)
To: David Miller
Cc: netdev, Neal Cardwell, Jeff Kirsher, Tom Herbert, Herbert Xu,
Ben Hutchings, Matt Carlson, Michael Chan,
Maciej Żenczykowski, Ilpo Järvinen
From: Eric Dumazet <edumazet@google.com>
TCP coalesce can check if skb to be merged has its skb->head mapped to a
page fragment, instead of a kmalloc() area.
We had to disable coalescing in this case, for performance reasons.
We 'upgrade' skb->head as a fragment in itself.
This reduces number of cache misses when user makes its copies, since a
less sk_buff are fetched.
This makes receive and ofo queues shorter and thus reduce cache line
misses in TCP stack.
This is a followup of patch "net: allow skb->head to be a page fragment"
Tested with tg3 nic, with GRO on or off. We can see "TCPRcvCoalesce"
counter being incremented.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
net/ipv4/tcp_input.c | 55 ++++++++++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c93b0cb..96a631d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4464,10 +4464,12 @@ static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
*/
static bool tcp_try_coalesce(struct sock *sk,
struct sk_buff *to,
- struct sk_buff *from)
+ struct sk_buff *from,
+ bool *fragstolen)
{
- int len = from->len;
+ int delta, len = from->len;
+ *fragstolen = false;
if (tcp_hdr(from)->fin)
return false;
if (len <= skb_tailroom(to)) {
@@ -4478,15 +4480,19 @@ merge:
TCP_SKB_CB(to)->ack_seq = TCP_SKB_CB(from)->ack_seq;
return true;
}
+
+ if (skb_has_frag_list(to) || skb_has_frag_list(from))
+ return false;
+
if (skb_headlen(from) == 0 &&
- !skb_has_frag_list(to) &&
- !skb_has_frag_list(from) &&
(skb_shinfo(to)->nr_frags +
skb_shinfo(from)->nr_frags <= MAX_SKB_FRAGS)) {
- int delta = from->truesize - ksize(from->head) -
- SKB_DATA_ALIGN(sizeof(struct sk_buff));
+ WARN_ON_ONCE(from->head_frag);
+ delta = from->truesize - ksize(from->head) -
+ SKB_DATA_ALIGN(sizeof(struct sk_buff));
WARN_ON_ONCE(delta < len);
+copyfrags:
memcpy(skb_shinfo(to)->frags + skb_shinfo(to)->nr_frags,
skb_shinfo(from)->frags,
skb_shinfo(from)->nr_frags * sizeof(skb_frag_t));
@@ -4499,6 +4505,20 @@ merge:
to->data_len += len;
goto merge;
}
+ if (from->head_frag) {
+ struct page *page;
+ unsigned int offset;
+
+ if (skb_shinfo(to)->nr_frags + skb_shinfo(from)->nr_frags >= MAX_SKB_FRAGS)
+ return false;
+ page = virt_to_head_page(from->head);
+ offset = from->data - (unsigned char *)page_address(page);
+ skb_fill_page_desc(to, skb_shinfo(to)->nr_frags,
+ page, offset, skb_headlen(from));
+ *fragstolen = true;
+ delta = len; /* we dont know real truesize... */
+ goto copyfrags;
+ }
return false;
}
@@ -4540,10 +4560,15 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
end_seq = TCP_SKB_CB(skb)->end_seq;
if (seq == TCP_SKB_CB(skb1)->end_seq) {
- if (!tcp_try_coalesce(sk, skb1, skb)) {
+ bool fragstolen;
+
+ if (!tcp_try_coalesce(sk, skb1, skb, &fragstolen)) {
__skb_queue_after(&tp->out_of_order_queue, skb1, skb);
} else {
- __kfree_skb(skb);
+ if (fragstolen)
+ kmem_cache_free(skbuff_head_cache, skb);
+ else
+ __kfree_skb(skb);
skb = NULL;
}
@@ -4626,6 +4651,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
const struct tcphdr *th = tcp_hdr(skb);
struct tcp_sock *tp = tcp_sk(sk);
int eaten = -1;
+ bool fragstolen = false;
if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
goto drop;
@@ -4672,7 +4698,9 @@ queue_and_out:
goto drop;
tail = skb_peek_tail(&sk->sk_receive_queue);
- eaten = (tail && tcp_try_coalesce(sk, tail, skb)) ? 1 : 0;
+ eaten = (tail &&
+ tcp_try_coalesce(sk, tail, skb,
+ &fragstolen)) ? 1 : 0;
if (eaten <= 0) {
skb_set_owner_r(skb, sk);
__skb_queue_tail(&sk->sk_receive_queue, skb);
@@ -4699,9 +4727,12 @@ queue_and_out:
tcp_fast_path_check(sk);
- if (eaten > 0)
- __kfree_skb(skb);
- else if (!sock_flag(sk, SOCK_DEAD))
+ if (eaten > 0) {
+ if (fragstolen)
+ kmem_cache_free(skbuff_head_cache, skb);
+ else
+ __kfree_skb(skb);
+ } else if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk, 0);
return;
}
^ permalink raw reply related
* [PATCH 3/4 net-next] net: make GRO aware of skb->head_frag
From: Eric Dumazet @ 2012-04-27 10:37 UTC (permalink / raw)
To: David Miller
Cc: netdev, Neal Cardwell, Tom Herbert, Jeff Kirsher, Michael Chan,
Matt Carlson, Herbert Xu, Ben Hutchings, Ilpo Järvinen,
Maciej Żenczykowski
From: Eric Dumazet <edumazet@google.com>
GRO can check if skb to be merged has its skb->head mapped to a page
fragment, instead of a kmalloc() area.
We 'upgrade' skb->head as a fragment in itself
This avoids the frag_list fallback, and permits to build true GRO skb
(one sk_buff and up to 16 fragments), using less memory.
This reduces number of cache misses when user makes its copy, since a
single sk_buff is fetched.
This is a followup of patch "net: allow skb->head to be a page fragment"
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
include/linux/netdevice.h | 2 ++
include/linux/skbuff.h | 1 +
net/core/dev.c | 5 ++++-
net/core/skbuff.c | 27 ++++++++++++++++++++++++++-
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e0b70e9..7f377fb 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1509,6 +1509,8 @@ struct napi_gro_cb {
/* Free the skb? */
int free;
+#define NAPI_GRO_FREE 1
+#define NAPI_GRO_FREE_STOLEN_HEAD 2
};
#define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9d28a22..2c75e98 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -561,6 +561,7 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
extern void kfree_skb(struct sk_buff *skb);
extern void consume_skb(struct sk_buff *skb);
extern void __kfree_skb(struct sk_buff *skb);
+extern struct kmem_cache *skbuff_head_cache;
extern struct sk_buff *__alloc_skb(unsigned int size,
gfp_t priority, int fclone, int node);
extern struct sk_buff *build_skb(void *data, unsigned int frag_size);
diff --git a/net/core/dev.c b/net/core/dev.c
index 501f3cc..a2be59f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3546,7 +3546,10 @@ gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
break;
case GRO_MERGED_FREE:
- consume_skb(skb);
+ if (NAPI_GRO_CB(skb)->free == NAPI_GRO_FREE_STOLEN_HEAD)
+ kmem_cache_free(skbuff_head_cache, skb);
+ else
+ __kfree_skb(skb);
break;
case GRO_HELD:
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index effa75d..2ad1ee7 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -69,7 +69,7 @@
#include <trace/events/skb.h>
#include <linux/highmem.h>
-static struct kmem_cache *skbuff_head_cache __read_mostly;
+struct kmem_cache *skbuff_head_cache __read_mostly;
static struct kmem_cache *skbuff_fclone_cache __read_mostly;
static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
@@ -2901,6 +2901,31 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
NAPI_GRO_CB(skb)->free = 1;
goto done;
+ } else if (skb->head_frag) {
+ int nr_frags = pinfo->nr_frags;
+ skb_frag_t *frag = pinfo->frags + nr_frags;
+ struct page *page = virt_to_head_page(skb->head);
+ unsigned int first_size = headlen - offset;
+ unsigned int first_offset;
+
+ if (nr_frags + 1 + skbinfo->nr_frags > MAX_SKB_FRAGS)
+ return -E2BIG;
+
+ first_offset = skb->head -
+ (unsigned char *)page_address(page) +
+ offset;
+
+ pinfo->nr_frags = nr_frags + 1 + skbinfo->nr_frags;
+
+ frag->page.p = page;
+ frag->page_offset = first_offset;
+ skb_frag_size_set(frag, first_size);
+
+ memcpy(frag + 1, skbinfo->frags, sizeof(*frag) * skbinfo->nr_frags);
+ /* We dont need to clear skbinfo->nr_frags here */
+
+ NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD;
+ goto done;
} else if (skb_gro_len(p) != pinfo->gso_size)
return -E2BIG;
^ permalink raw reply related
* [PATCH 2/4 net-next] tg3: provide frags as skb head
From: Eric Dumazet @ 2012-04-27 10:34 UTC (permalink / raw)
To: David Miller
Cc: netdev, Ilpo Järvinen, Tom Herbert, Neal Cardwell,
Ben Hutchings, Matt Carlson, Jeff Kirsher, Michael Chan,
Herbert Xu, Maciej Żenczykowski
From: Eric Dumazet <edumazet@google.com>
This patch converts tg3 driver, one of our reference drivers, to use new
build_skb() api in frag mode.
Instead of using kmalloc() to allocate the memory block that will be
used by build_skb() as skb->head, we use a page fragment.
This is a followup of patch "net: allow skb->head to be a page fragment"
This allows GRO, TCP coalescing, and splice() to be more efficient.
Incidentally, this also removes SLUB slow path contention in kfree()
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 74 ++++++++++++++++++++++----
drivers/net/ethernet/broadcom/tg3.h | 2
2 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index d481b0a..c1a580e 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -195,6 +195,15 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define TG3_RX_OFFSET(tp) (NET_SKB_PAD)
#endif
+/* This driver uses the new build_skb() API providing a frag as skb->head
+ * This strategy permits better GRO aggregation, better TCP coalescing, and
+ * better splice() implementation (avoids a copy from head to a page), at
+ * minimal memory cost.
+ * In this 2048 bytes block, we have enough room to store the MTU=1500 frame
+ * and the struct skb_shared_info.
+ */
+#define TG3_FRAGSIZE 2048
+
/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
#define TG3_TX_BD_DMA_MAX_2K 2048
@@ -5617,17 +5626,48 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}
+static void *tg3_frag_alloc(struct tg3_rx_prodring_set *tpr)
+{
+ void *data;
+
+ if (tpr->rx_page_size < TG3_FRAGSIZE) {
+ struct page *page = alloc_page(GFP_ATOMIC);
+
+ if (!page)
+ return NULL;
+ atomic_add((PAGE_SIZE / TG3_FRAGSIZE) - 1, &page->_count);
+ tpr->rx_page_addr = page_address(page);
+ tpr->rx_page_size = PAGE_SIZE;
+ }
+ data = tpr->rx_page_addr;
+ tpr->rx_page_addr += TG3_FRAGSIZE;
+ tpr->rx_page_size -= TG3_FRAGSIZE;
+ return data;
+}
+
+static void tg3_frag_free(bool is_frag, void *data)
+{
+ if (is_frag)
+ put_page(virt_to_head_page(data));
+ else
+ kfree(data);
+}
+
static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
{
+ unsigned int skb_size = SKB_DATA_ALIGN(map_sz + TG3_RX_OFFSET(tp)) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
if (!ri->data)
return;
pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping),
map_sz, PCI_DMA_FROMDEVICE);
- kfree(ri->data);
+ tg3_frag_free(skb_size <= TG3_FRAGSIZE, ri->data);
ri->data = NULL;
}
+
/* Returns size of skb allocated or < 0 on error.
*
* We only need to fill in the address because the other members
@@ -5640,7 +5680,8 @@ static void tg3_rx_data_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
* (to fetch the error flags, vlan tag, checksum, and opaque cookie).
*/
static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
- u32 opaque_key, u32 dest_idx_unmasked)
+ u32 opaque_key, u32 dest_idx_unmasked,
+ unsigned int *frag_size)
{
struct tg3_rx_buffer_desc *desc;
struct ring_info *map;
@@ -5675,7 +5716,13 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
*/
skb_size = SKB_DATA_ALIGN(data_size + TG3_RX_OFFSET(tp)) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- data = kmalloc(skb_size, GFP_ATOMIC);
+ if (skb_size <= TG3_FRAGSIZE) {
+ data = tg3_frag_alloc(tpr);
+ *frag_size = TG3_FRAGSIZE;
+ } else {
+ data = kmalloc(skb_size, GFP_ATOMIC);
+ *frag_size = 0;
+ }
if (!data)
return -ENOMEM;
@@ -5683,8 +5730,8 @@ static int tg3_alloc_rx_data(struct tg3 *tp, struct tg3_rx_prodring_set *tpr,
data + TG3_RX_OFFSET(tp),
data_size,
PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(tp->pdev, mapping)) {
- kfree(data);
+ if (unlikely(pci_dma_mapping_error(tp->pdev, mapping))) {
+ tg3_frag_free(skb_size <= TG3_FRAGSIZE, data);
return -EIO;
}
@@ -5835,18 +5882,19 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
if (len > TG3_RX_COPY_THRESH(tp)) {
int skb_size;
+ unsigned int frag_size;
skb_size = tg3_alloc_rx_data(tp, tpr, opaque_key,
- *post_ptr);
+ *post_ptr, &frag_size);
if (skb_size < 0)
goto drop_it;
pci_unmap_single(tp->pdev, dma_addr, skb_size,
PCI_DMA_FROMDEVICE);
- skb = build_skb(data, 0);
+ skb = build_skb(data, frag_size);
if (!skb) {
- kfree(data);
+ tg3_frag_free(frag_size != 0, data);
goto drop_it_no_recycle;
}
skb_reserve(skb, TG3_RX_OFFSET(tp));
@@ -7279,7 +7327,10 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
/* Now allocate fresh SKBs for each rx ring. */
for (i = 0; i < tp->rx_pending; i++) {
- if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i) < 0) {
+ unsigned int frag_size;
+
+ if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_STD, i,
+ &frag_size) < 0) {
netdev_warn(tp->dev,
"Using a smaller RX standard ring. Only "
"%d out of %d buffers were allocated "
@@ -7311,7 +7362,10 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
}
for (i = 0; i < tp->rx_jumbo_pending; i++) {
- if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i) < 0) {
+ unsigned int frag_size;
+
+ if (tg3_alloc_rx_data(tp, tpr, RXD_OPAQUE_RING_JUMBO, i,
+ &frag_size) < 0) {
netdev_warn(tp->dev,
"Using a smaller RX jumbo ring. Only %d "
"out of %d buffers were allocated "
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 93865f8..7c85545 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2815,6 +2815,8 @@ struct tg3_rx_prodring_set {
struct ring_info *rx_jmb_buffers;
dma_addr_t rx_std_mapping;
dma_addr_t rx_jmb_mapping;
+ void *rx_page_addr;
+ unsigned int rx_page_size;
};
#define TG3_IRQ_MAX_VECS_RSS 5
^ permalink raw reply related
* [PATCH 1/4 net-next] net: allow skb->head to be a page fragment
From: Eric Dumazet @ 2012-04-27 10:33 UTC (permalink / raw)
To: David Miller
Cc: netdev, Ilpo Järvinen, Neal Cardwell, Tom Herbert,
Maciej Żenczykowski, Jeff Kirsher, Ben Hutchings,
Matt Carlson, Michael Chan, Herbert Xu
From: Eric Dumazet <edumazet@google.com>
skb->head is currently allocated from kmalloc(). This is convenient but
has the drawback the data cannot be converted to a page fragment if
needed.
We have three spots were it hurts :
1) GRO aggregation
When a linear skb must be appended to another skb, GRO uses the
frag_list fallback, very inefficient since we keep all struct sk_buff
around. So drivers enabling GRO but delivering linear skbs to network
stack aren't enabling full GRO power.
2) splice(socket -> pipe).
We must copy the linear part to a page fragment.
This kind of defeats splice() purpose (zero copy claim)
3) TCP coalescing.
Recently introduced, this permits to group several contiguous segments
into a single skb. This shortens queue lengths and save kernel memory,
and greatly reduce probabilities of TCP collapses. This coalescing
doesnt work on linear skbs (or we would need to copy data, this would be
too slow)
Given all these issues, the following patch introduces the possibility
of having skb->head be a fragment in itself. We use a new skb flag,
skb->head_frag to carry this information.
build_skb() is changed to accept a frag_size argument. Drivers willing
to provide a page fragment instead of kmalloc() data will set a non zero
value, set to the fragment size.
Then, on situations we need to convert the skb head to a frag in itself,
we can check if skb->head_frag is set and avoid the copies or various
fallbacks we have.
This means drivers currently using frags could be updated to avoid the
current skb->head allocation and reduce their memory footprint (aka skb
truesize). (thats 512 or 1024 bytes saved per skb). This also makes
bpf/netfilter faster since the 'first frag' will be part of skb linear
part, no need to copy data.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Cc: Matt Carlson <mcarlson@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/bnx2.c | 2 -
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 4 +-
drivers/net/ethernet/broadcom/tg3.c | 2 -
include/linux/skbuff.h | 5 +-
net/core/skbuff.c | 24 ++++++++++----
5 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index ab55979..ac7b744 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -3006,7 +3006,7 @@ error:
dma_unmap_single(&bp->pdev->dev, dma_addr, bp->rx_buf_use_size,
PCI_DMA_FROMDEVICE);
- skb = build_skb(data);
+ skb = build_skb(data, 0);
if (!skb) {
kfree(data);
goto error;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index 60d5b54..9c5bc5d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -513,7 +513,7 @@ static inline void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp,
dma_unmap_single(&bp->pdev->dev, dma_unmap_addr(rx_buf, mapping),
fp->rx_buf_size, DMA_FROM_DEVICE);
if (likely(new_data))
- skb = build_skb(data);
+ skb = build_skb(data, 0);
if (likely(skb)) {
#ifdef BNX2X_STOP_ON_ERROR
@@ -721,7 +721,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
dma_unmap_addr(rx_buf, mapping),
fp->rx_buf_size,
DMA_FROM_DEVICE);
- skb = build_skb(data);
+ skb = build_skb(data, 0);
if (unlikely(!skb)) {
kfree(data);
fp->eth_q_stats.rx_skb_alloc_failed++;
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 0c3e7c7..d481b0a 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -5844,7 +5844,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
pci_unmap_single(tp->pdev, dma_addr, skb_size,
PCI_DMA_FROMDEVICE);
- skb = build_skb(data);
+ skb = build_skb(data, 0);
if (!skb) {
kfree(data);
goto drop_it_no_recycle;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4a656b5..9d28a22 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -470,7 +470,8 @@ struct sk_buff {
__u8 wifi_acked_valid:1;
__u8 wifi_acked:1;
__u8 no_fcs:1;
- /* 9/11 bit hole (depending on ndisc_nodetype presence) */
+ __u8 head_frag:1;
+ /* 8/10 bit hole (depending on ndisc_nodetype presence) */
kmemcheck_bitfield_end(flags2);
#ifdef CONFIG_NET_DMA
@@ -562,7 +563,7 @@ extern void consume_skb(struct sk_buff *skb);
extern void __kfree_skb(struct sk_buff *skb);
extern struct sk_buff *__alloc_skb(unsigned int size,
gfp_t priority, int fclone, int node);
-extern struct sk_buff *build_skb(void *data);
+extern struct sk_buff *build_skb(void *data, unsigned int frag_size);
static inline struct sk_buff *alloc_skb(unsigned int size,
gfp_t priority)
{
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2342a72..effa75d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -245,6 +245,7 @@ EXPORT_SYMBOL(__alloc_skb);
/**
* build_skb - build a network buffer
* @data: data buffer provided by caller
+ * @frag_size: size of fragment, or 0 if head was kmalloced
*
* Allocate a new &sk_buff. Caller provides space holding head and
* skb_shared_info. @data must have been allocated by kmalloc()
@@ -258,20 +259,21 @@ EXPORT_SYMBOL(__alloc_skb);
* before giving packet to stack.
* RX rings only contains data buffers, not full skbs.
*/
-struct sk_buff *build_skb(void *data)
+struct sk_buff *build_skb(void *data, unsigned int frag_size)
{
struct skb_shared_info *shinfo;
struct sk_buff *skb;
- unsigned int size;
+ unsigned int size = frag_size ? : ksize(data);
skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC);
if (!skb)
return NULL;
- size = ksize(data) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ size -= SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
memset(skb, 0, offsetof(struct sk_buff, tail));
skb->truesize = SKB_TRUESIZE(size);
+ skb->head_frag = frag_size != 0;
atomic_set(&skb->users, 1);
skb->head = data;
skb->data = data;
@@ -376,6 +378,14 @@ static void skb_clone_fraglist(struct sk_buff *skb)
skb_get(list);
}
+static void skb_free_head(struct sk_buff *skb)
+{
+ if (skb->head_frag)
+ put_page(virt_to_head_page(skb->head));
+ else
+ kfree(skb->head);
+}
+
static void skb_release_data(struct sk_buff *skb)
{
if (!skb->cloned ||
@@ -402,7 +412,7 @@ static void skb_release_data(struct sk_buff *skb)
if (skb_has_frag_list(skb))
skb_drop_fraglist(skb);
- kfree(skb->head);
+ skb_free_head(skb);
}
}
@@ -644,6 +654,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
C(tail);
C(end);
C(head);
+ C(head_frag);
C(data);
C(truesize);
atomic_set(&n->users, 1);
@@ -940,7 +951,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta;
}
- if (fastpath &&
+ if (fastpath && !skb->head_frag &&
size + sizeof(struct skb_shared_info) <= ksize(skb->head)) {
memmove(skb->head + size, skb_shinfo(skb),
offsetof(struct skb_shared_info,
@@ -967,7 +978,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags]));
if (fastpath) {
- kfree(skb->head);
+ skb_free_head(skb);
} else {
/* copy this zero copy skb frags */
if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
@@ -985,6 +996,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
off = (data + nhead) - skb->head;
skb->head = data;
+ skb->head_frag = 0;
adjust_others:
skb->data += off;
#ifdef NET_SKBUFF_DATA_USES_OFFSET
^ permalink raw reply related
* Re: [PATCH 1/8] isdn/gigaset: ratelimit CAPI message dumps
From: Tilman Schmidt @ 2012-04-27 10:29 UTC (permalink / raw)
To: Karsten Keil
Cc: Karsten Keil, David Miller, Hansjoerg Lipp, i4ldeveloper, netdev,
linux-kernel
In-Reply-To: <4F98EDB1.5090702@b1-systems.de>
[-- Attachment #1: Type: text/plain, Size: 2320 bytes --]
Am 26.04.2012 08:39, schrieb Karsten Keil:
> Am 26.04.2012 01:02, schrieb Tilman Schmidt:
>> Introduce a global ratelimit for CAPI message dumps to protect
>> against possible log flood.
>> Drop the ratelimit for ignored messages which is now covered by the
>> global one.
>
> Hmm, I think the only CAPI messages which would need a ratelimit are
> related to the DATA_B3 messages. If you need CAPI debug messages in most
> cases you do not need all of the DATA_B3, but you do not want to miss
> any other message related to the call control. With a general rate limit
> you do not have the control, which messages are logged and which are not.
The ratelimit introduced by this patch only applies to messages
other than DATA_B3. Logging DATA_B3 messages is not done via
dump_cmsg().
I'd like to ratelimit specifically non-DATA_B3 messages because I
saw a (possibly buggy) CAPI application flooding the log with
FACILITY messages. Equally important, I'd like to make the
ratelimit in do_nothing() / do_unsupported() bursty because I had
a case where I needed to see several ignored/unhandled CAPI
messages in quick succession. So this patch is killing two birds
with one stone for me.
The burst limit of 20 messages in 20 seconds is chosen to allow a
complete call setup sequence to be logged, while limiting to one
message per second in the long run.
> And here maybe some cases, when even the DATA_B3 are important (e.g.
> searching bugs in flow control), so I would make it still conditional
> to allow to print all messages.
DATA_B3 dumps produce an enormous amount of log data and are
therefore controlled separately by the DEBUG_MCMD flag.
Someone who enables that should know what she or he does.
But if you need them, you need them all. A ratelimit doesn't
make sense there in my experience.
> And I'm not sure, if this is really something for stable.
It's pretty simple and localized, a net simplification, and only
affects generation of debugging messages, so I think it's safe.
But if you see a problem there I can drop the "CC: stable" line.
Thanks,
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: 262 bytes --]
^ permalink raw reply
* [PATCH] usbnet: fix skb traversing races during unlink
From: Ming Lei @ 2012-04-27 10:21 UTC (permalink / raw)
To: David S. Miller, Greg Kroah-Hartman
Cc: netdev, linux-usb, Ming Lei, Huajun Li, Oliver Neukum, stable
Commit 4231d47e6fe69f061f96c98c30eaf9fb4c14b96d(net/usbnet: avoid
recursive locking in usbnet_stop()) fixes the recursive locking
problem by releasing the skb queue lock before unlink, but may
cause skb traversing races:
- after URB is unlinked and the queue lock is released,
the refered skb and skb->next may be moved to done queue,
even be released
- in skb_queue_walk_safe, the next skb is still obtained
by next pointer of the last skb
- so maybe trigger oops or other problems
This patch extends the usage of entry->state to describe 'start_unlink'
state, so always holding the queue(rx/tx) lock to change the state if
the referd skb is in rx or tx queue because we need to know if the
refered urb has been started unlinking in unlink_urbs.
Also the patch uses usb_block_urb introduced by Oliver to block
URB resubmit in complete handler if the URB will be unlinked.
The other part of this patch is based on Huajun's patch:
always traverse from head of the tx/rx queue to get skb which is
to be unlinked but not been started unlinking.
Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Cc: Oliver Neukum <oneukum@suse.de>
Cc: stable@kernel.org
---
This patch depends on the usb_block_urb patch from Oliver.
drivers/net/usb/usbnet.c | 54 ++++++++++++++++++++++++++++++++------------
include/linux/usb/usbnet.h | 3 ++-
2 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index db99536..dff5e1b 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -281,17 +281,30 @@ int usbnet_change_mtu (struct net_device *net, int new_mtu)
}
EXPORT_SYMBOL_GPL(usbnet_change_mtu);
+/*The caller must hold list->lock*/
+static void __usbnet_queue_skb(struct sk_buff_head *list,
+ struct sk_buff *newsk, enum skb_state state)
+{
+ struct skb_data *entry = (struct skb_data *) newsk->cb;
+
+ __skb_queue_tail(list, newsk);
+ entry->state = state;
+}
+
/*-------------------------------------------------------------------------*/
/* some LK 2.4 HCDs oopsed if we freed or resubmitted urbs from
* completion callbacks. 2.5 should have fixed those bugs...
*/
-static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
+static void defer_bh(struct usbnet *dev, struct sk_buff *skb,
+ struct sk_buff_head *list, enum skb_state state)
{
unsigned long flags;
+ struct skb_data *entry = (struct skb_data *) skb->cb;
spin_lock_irqsave(&list->lock, flags);
+ entry->state = state;
__skb_unlink(skb, list);
spin_unlock(&list->lock);
spin_lock(&dev->done.lock);
@@ -339,7 +352,6 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
entry = (struct skb_data *) skb->cb;
entry->urb = urb;
entry->dev = dev;
- entry->state = rx_start;
entry->length = 0;
usb_fill_bulk_urb (urb, dev->udev, dev->in,
@@ -371,7 +383,7 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
tasklet_schedule (&dev->bh);
break;
case 0:
- __skb_queue_tail (&dev->rxq, skb);
+ __usbnet_queue_skb(&dev->rxq, skb, rx_start);
}
} else {
netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -422,16 +434,17 @@ static void rx_complete (struct urb *urb)
struct skb_data *entry = (struct skb_data *) skb->cb;
struct usbnet *dev = entry->dev;
int urb_status = urb->status;
+ enum skb_state state;
skb_put (skb, urb->actual_length);
- entry->state = rx_done;
+ state = rx_done;
entry->urb = NULL;
switch (urb_status) {
/* success */
case 0:
if (skb->len < dev->net->hard_header_len) {
- entry->state = rx_cleanup;
+ state = rx_cleanup;
dev->net->stats.rx_errors++;
dev->net->stats.rx_length_errors++;
netif_dbg(dev, rx_err, dev->net,
@@ -470,7 +483,7 @@ static void rx_complete (struct urb *urb)
"rx throttle %d\n", urb_status);
}
block:
- entry->state = rx_cleanup;
+ state = rx_cleanup;
entry->urb = urb;
urb = NULL;
break;
@@ -481,13 +494,13 @@ block:
// FALLTHROUGH
default:
- entry->state = rx_cleanup;
+ state = rx_cleanup;
dev->net->stats.rx_errors++;
netif_dbg(dev, rx_err, dev->net, "rx status %d\n", urb_status);
break;
}
- defer_bh(dev, skb, &dev->rxq);
+ defer_bh(dev, skb, &dev->rxq, state);
if (urb) {
if (netif_running (dev->net) &&
@@ -578,16 +591,24 @@ EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
{
unsigned long flags;
- struct sk_buff *skb, *skbnext;
+ struct sk_buff *skb;
int count = 0;
spin_lock_irqsave (&q->lock, flags);
- skb_queue_walk_safe(q, skb, skbnext) {
+ while (!skb_queue_empty(q)) {
struct skb_data *entry;
struct urb *urb;
int retval;
- entry = (struct skb_data *) skb->cb;
+ skb_queue_walk(q, skb) {
+ entry = (struct skb_data *) skb->cb;
+ if (entry->state != unlink_start)
+ break;
+ }
+ if (skb == (struct sk_buff *)q)
+ break;
+
+ entry->state = unlink_start;
urb = entry->urb;
/*
@@ -598,6 +619,10 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
* handler(include defer_bh).
*/
usb_get_urb(urb);
+
+ /*speedup unlink by blocking resubmit*/
+ usb_block_urb(urb);
+
spin_unlock_irqrestore(&q->lock, flags);
// during some PM-driven resume scenarios,
// these (async) unlinks complete immediately
@@ -606,6 +631,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
netdev_dbg(dev->net, "unlink urb err, %d\n", retval);
else
count++;
+ usb_unblock_urb(urb);
usb_put_urb(urb);
spin_lock_irqsave(&q->lock, flags);
}
@@ -1039,8 +1065,7 @@ static void tx_complete (struct urb *urb)
}
usb_autopm_put_interface_async(dev->intf);
- entry->state = tx_done;
- defer_bh(dev, skb, &dev->txq);
+ defer_bh(dev, skb, &dev->txq, tx_done);
}
/*-------------------------------------------------------------------------*/
@@ -1096,7 +1121,6 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
entry = (struct skb_data *) skb->cb;
entry->urb = urb;
entry->dev = dev;
- entry->state = tx_start;
entry->length = length;
usb_fill_bulk_urb (urb, dev->udev, dev->out,
@@ -1155,7 +1179,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
break;
case 0:
net->trans_start = jiffies;
- __skb_queue_tail (&dev->txq, skb);
+ __usbnet_queue_skb(&dev->txq, skb, tx_start);
if (dev->txq.qlen >= TX_QLEN (dev))
netif_stop_queue (net);
}
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 605b0aa..76f4396 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -191,7 +191,8 @@ extern void usbnet_cdc_status(struct usbnet *, struct urb *);
enum skb_state {
illegal = 0,
tx_start, tx_done,
- rx_start, rx_done, rx_cleanup
+ rx_start, rx_done, rx_cleanup,
+ unlink_start
};
struct skb_data { /* skb->cb is one of these */
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Lennert Buytenhek @ 2012-04-27 10:17 UTC (permalink / raw)
To: sedat.dilek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <CA+icZUWuynSaPE4pdxzoP783pw7r=5x27ewXN_pkR5VS=0kKUg@mail.gmail.com>
On Fri, Apr 27, 2012 at 12:12:13PM +0200, Sedat Dilek wrote:
> >> >> >> Are you planning to or even working on support (for) 8361 devices?
> >> >> >
> >> >> > I don't have any such plans, and I don't know of anyone who does.
> >> >>
> >> >> Does 8361 require firmware support?
> >> >
> >> > What do you mean by that?
> >>
> >> IIRC ath5k for example needs no external firmware file.
> >
> > The 8361 requires firmware to be loaded into it before it'll do
> > anything useful.
> >
> >
> >> >> Does a firmware file exist (name?)?
> >> >
> >> > There's firmware for the 8361 out there, however, that version of
> >> > the firmware implements a firmware API that is different from the
> >> > one that mwl8k currently implements.
> >> >
> >> > You could add 8361 support to mwl8k, but then you'd have to go over
> >> > all the firmware command invocations in mwl8k and make sure that they
> >> > will work on the 8361 firmware that you're trying to support as well.
> >>
> >> Without having a 8361 this will be even harder to walk through.
> >>
> >> Anyway, thanks for your detailed explanations.
> >>
> >> What's the alternative for such affected users?
> >> Use ndis-wrapper?
> >
> > I'm not sure. I've never tried to get a 8361 work under Linux.
>
> Just found on [1] this same wrong patch in [2] :-).
> Dunno if [3] worked and from where they have stolen fw-files.
>
> - Sedat -
>
> [1] https://dev.openwrt.org/ticket/7209
> [2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
> [3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
I doubt that [3] is really all that's needed to make it work. But if
there's someone for whom it works, I'd like them to run some tests on
mwl8k + [3] on 88w8361p.
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-27 10:12 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120427095842.GW3157@wantstofly.org>
On Fri, Apr 27, 2012 at 11:58 AM, Lennert Buytenhek
<buytenh@wantstofly.org> wrote:
> On Fri, Apr 27, 2012 at 11:56:00AM +0200, Sedat Dilek wrote:
>
>> >> >> Are you planning to or even working on support (for) 8361 devices?
>> >> >
>> >> > I don't have any such plans, and I don't know of anyone who does.
>> >>
>> >> Does 8361 require firmware support?
>> >
>> > What do you mean by that?
>>
>> IIRC ath5k for example needs no external firmware file.
>
> The 8361 requires firmware to be loaded into it before it'll do
> anything useful.
>
>
>> >> Does a firmware file exist (name?)?
>> >
>> > There's firmware for the 8361 out there, however, that version of
>> > the firmware implements a firmware API that is different from the
>> > one that mwl8k currently implements.
>> >
>> > You could add 8361 support to mwl8k, but then you'd have to go over
>> > all the firmware command invocations in mwl8k and make sure that they
>> > will work on the 8361 firmware that you're trying to support as well.
>>
>> Without having a 8361 this will be even harder to walk through.
>>
>> Anyway, thanks for your detailed explanations.
>>
>> What's the alternative for such affected users?
>> Use ndis-wrapper?
>
> I'm not sure. I've never tried to get a 8361 work under Linux.
Just found on [1] this same wrong patch in [2] :-).
Dunno if [3] worked and from where they have stolen fw-files.
- Sedat -
[1] https://dev.openwrt.org/ticket/7209
[2] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_fix_pci_id.patch
[3] https://dev.openwrt.org/attachment/ticket/7209/mwl8k_8361p.patch
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Lennert Buytenhek @ 2012-04-27 9:58 UTC (permalink / raw)
To: sedat.dilek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <CA+icZUXNZ=exTnR=OgD_9bpt_0s-KnR+v-K6u+XzQr4HBoTQHQ@mail.gmail.com>
On Fri, Apr 27, 2012 at 11:56:00AM +0200, Sedat Dilek wrote:
> >> >> Are you planning to or even working on support (for) 8361 devices?
> >> >
> >> > I don't have any such plans, and I don't know of anyone who does.
> >>
> >> Does 8361 require firmware support?
> >
> > What do you mean by that?
>
> IIRC ath5k for example needs no external firmware file.
The 8361 requires firmware to be loaded into it before it'll do
anything useful.
> >> Does a firmware file exist (name?)?
> >
> > There's firmware for the 8361 out there, however, that version of
> > the firmware implements a firmware API that is different from the
> > one that mwl8k currently implements.
> >
> > You could add 8361 support to mwl8k, but then you'd have to go over
> > all the firmware command invocations in mwl8k and make sure that they
> > will work on the 8361 firmware that you're trying to support as well.
>
> Without having a 8361 this will be even harder to walk through.
>
> Anyway, thanks for your detailed explanations.
>
> What's the alternative for such affected users?
> Use ndis-wrapper?
I'm not sure. I've never tried to get a 8361 work under Linux.
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-27 9:56 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120427094637.GV3157@wantstofly.org>
On Fri, Apr 27, 2012 at 11:46 AM, Lennert Buytenhek
<buytenh@wantstofly.org> wrote:
> On Fri, Apr 27, 2012 at 11:42:54AM +0200, Sedat Dilek wrote:
>
>> >> Are you planning to or even working on support (for) 8361 devices?
>> >
>> > I don't have any such plans, and I don't know of anyone who does.
>>
>> Does 8361 require firmware support?
>
> What do you mean by that?
>
IIRC ath5k for example needs no external firmware file.
>
>> Does a firmware file exist (name?)?
>
> There's firmware for the 8361 out there, however, that version of
> the firmware implements a firmware API that is different from the
> one that mwl8k currently implements.
>
> You could add 8361 support to mwl8k, but then you'd have to go over
> all the firmware command invocations in mwl8k and make sure that they
> will work on the 8361 firmware that you're trying to support as well.
Without having a 8361 this will be even harder to walk through.
Anyway, thanks for your detailed explanations.
What's the alternative for such affected users?
Use ndis-wrapper?
- Sedat -
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Lennert Buytenhek @ 2012-04-27 9:46 UTC (permalink / raw)
To: sedat.dilek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <CA+icZUUiYwpHpqe5_kz1rLzTT13qQMwpNpDH7EOaRrVi_c8Z2Q@mail.gmail.com>
On Fri, Apr 27, 2012 at 11:42:54AM +0200, Sedat Dilek wrote:
> >> Are you planning to or even working on support (for) 8361 devices?
> >
> > I don't have any such plans, and I don't know of anyone who does.
>
> Does 8361 require firmware support?
What do you mean by that?
> Does a firmware file exist (name?)?
There's firmware for the 8361 out there, however, that version of
the firmware implements a firmware API that is different from the
one that mwl8k currently implements.
You could add 8361 support to mwl8k, but then you'd have to go over
all the firmware command invocations in mwl8k and make sure that they
will work on the 8361 firmware that you're trying to support as well.
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Sedat Dilek @ 2012-04-27 9:42 UTC (permalink / raw)
To: Lennert Buytenhek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <20120427094007.GU3157@wantstofly.org>
On Fri, Apr 27, 2012 at 11:40 AM, Lennert Buytenhek
<buytenh@wantstofly.org> wrote:
> On Fri, Apr 27, 2012 at 11:22:49AM +0200, Sedat Dilek wrote:
>
>> Are you planning to or even working on support (for) 8361 devices?
>
> I don't have any such plans, and I don't know of anyone who does.
Does 8361 require firmware support? Does a firmware file exist (name?)?
Asking just out of curiosity?
- Sedat -
^ permalink raw reply
* Re: [PATCH] mwl8k: Add 0x2a02 PCI device-id (Marvell 88W8361)
From: Lennert Buytenhek @ 2012-04-27 9:40 UTC (permalink / raw)
To: sedat.dilek; +Cc: John W. Linville, linux-wireless, netdev, linux-kernel
In-Reply-To: <CA+icZUVAK3NHmbG5kR1KhqGe9mAimWWzLz-MfXOXbyry3Sz73w@mail.gmail.com>
On Fri, Apr 27, 2012 at 11:22:49AM +0200, Sedat Dilek wrote:
> Are you planning to or even working on support (for) 8361 devices?
I don't have any such plans, and I don't know of anyone who does.
^ permalink raw reply
* [PATCH 14/17] netfilter: adjust l4proto_gre4 to the nf_conntrack_l4proto_register
From: Gao feng @ 2012-04-27 9:38 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev, serge.hallyn, ebiederm, dlezcano,
Gao feng
In-Reply-To: <1335519484-6089-1-git-send-email-gaofeng@cn.fujitsu.com>
move the nf_conntrack_l4proto_register from module_init to
proto_gre_net_ops.init.
and use gre_pernet to replace net_generic.
because gre proto has no sysctl,so only need to initial pernet data
for gre proto.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
net/netfilter/nf_conntrack_proto_gre.c | 56 ++++++++++++++++++++------------
1 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 4bf6b4e..8d70452 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -54,13 +54,20 @@ static unsigned int gre_timeouts[GRE_CT_MAX] = {
static int proto_gre_net_id __read_mostly;
struct netns_proto_gre {
+ struct nf_proto_net nf;
rwlock_t keymap_lock;
struct list_head keymap_list;
+ unsigned int gre_timeouts[GRE_CT_MAX];
};
+static inline struct netns_proto_gre *gre_pernet(struct net *net)
+{
+ return net_generic(net, proto_gre_net_id);
+}
+
void nf_ct_gre_keymap_flush(struct net *net)
{
- struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
+ struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km, *tmp;
write_lock_bh(&net_gre->keymap_lock);
@@ -85,7 +92,7 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
/* look up the source key for a given tuple */
static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
{
- struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
+ struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km;
__be16 key = 0;
@@ -109,7 +116,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
struct nf_conntrack_tuple *t)
{
struct net *net = nf_ct_net(ct);
- struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
+ struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_conn_help *help = nfct_help(ct);
struct nf_ct_gre_keymap **kmp, *km;
@@ -150,7 +157,7 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
- struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
+ struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_conn_help *help = nfct_help(ct);
enum ip_conntrack_dir dir;
@@ -237,7 +244,7 @@ static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)
static unsigned int *gre_get_timeouts(struct net *net)
{
- return gre_timeouts;
+ return gre_pernet(net)->gre_timeouts;
}
/* Returns verdict for packet, and may modify conntrack */
@@ -339,6 +346,18 @@ gre_timeout_nla_policy[CTA_TIMEOUT_GRE_MAX+1] = {
};
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+static int gre_init_net(struct net *net, u_int8_t compat)
+{
+ int i;
+ struct netns_proto_gre *net_gre = gre_pernet(net);
+
+ rwlock_init(&net_gre->keymap_lock);
+ INIT_LIST_HEAD(&net_gre->keymap_list);
+ for (i = 0; i < GRE_CT_MAX; i++)
+ net_gre->gre_timeouts[i] = gre_timeouts[i];
+ return 0;
+}
+
/* protocol helper struct */
static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
.l3proto = AF_INET,
@@ -368,20 +387,24 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
.nla_policy = gre_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
+ .net_id = &proto_gre_net_id,
+ .init_net = gre_init_net,
};
static int proto_gre_net_init(struct net *net)
{
- struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
-
- rwlock_init(&net_gre->keymap_lock);
- INIT_LIST_HEAD(&net_gre->keymap_list);
-
- return 0;
+ int ret = 0;
+ ret = nf_conntrack_l4proto_register(net,
+ &nf_conntrack_l4proto_gre4);
+ if (ret < 0)
+ pr_err("nf_conntrack_l4proto_gre4 :protocol register failed.\n");
+ return ret;
}
static void proto_gre_net_exit(struct net *net)
{
+ nf_conntrack_l4proto_unregister(net,
+ &nf_conntrack_l4proto_gre4);
nf_ct_gre_keymap_flush(net);
}
@@ -394,20 +417,11 @@ static struct pernet_operations proto_gre_net_ops = {
static int __init nf_ct_proto_gre_init(void)
{
- int rv;
-
- rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
- if (rv < 0)
- return rv;
- rv = register_pernet_subsys(&proto_gre_net_ops);
- if (rv < 0)
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
- return rv;
+ return register_pernet_subsys(&proto_gre_net_ops);
}
static void __exit nf_ct_proto_gre_fini(void)
{
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
unregister_pernet_subsys(&proto_gre_net_ops);
}
--
1.7.7.6
^ permalink raw reply related
* [PATCH 12/17] netfilter: add namespace support for l4proto_udplite
From: Gao feng @ 2012-04-27 9:37 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev, serge.hallyn, ebiederm, dlezcano,
Gao feng
In-Reply-To: <1335519484-6089-1-git-send-email-gaofeng@cn.fujitsu.com>
add pernet_operations udplite_net_ops and register it when
module nf_conntrack_proto_udplite is loaded.
move the l4proto_register from module_init function to
udplite_net_ops.init.
and implement udplite_init_net to initial the pernet sysctl
table for udplite[4,6] protos.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
net/netfilter/nf_conntrack_proto_udplite.c | 103 +++++++++++++++++++++++-----
1 files changed, 85 insertions(+), 18 deletions(-)
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 4d60a53..1e90cf5 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -35,6 +35,17 @@ static unsigned int udplite_timeouts[UDPLITE_CT_MAX] = {
[UDPLITE_CT_REPLIED] = 180*HZ,
};
+static int udplite_net_id __read_mostly;
+struct udplite_net {
+ struct nf_proto_net pn;
+ unsigned int timeouts[UDPLITE_CT_MAX];
+};
+
+static inline struct udplite_net *udplite_pernet(struct net *net)
+{
+ return net_generic(net, udplite_net_id);
+}
+
static bool udplite_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
@@ -70,7 +81,7 @@ static int udplite_print_tuple(struct seq_file *s,
static unsigned int *udplite_get_timeouts(struct net *net)
{
- return udplite_timeouts;
+ return udplite_pernet(net)->timeouts;
}
/* Returns verdict for packet, and may modify conntracktype */
@@ -209,14 +220,12 @@ static struct ctl_table_header *udplite_sysctl_header;
static struct ctl_table udplite_sysctl_table[] = {
{
.procname = "nf_conntrack_udplite_timeout",
- .data = &udplite_timeouts[UDPLITE_CT_UNREPLIED],
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "nf_conntrack_udplite_timeout_stream",
- .data = &udplite_timeouts[UDPLITE_CT_REPLIED],
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
@@ -225,10 +234,36 @@ static struct ctl_table udplite_sysctl_table[] = {
};
#endif /* CONFIG_SYSCTL */
+static int udplite_init_net(struct net *net, u_int8_t compat)
+{
+ int i;
+ struct udplite_net *un = udplite_pernet(net);
+ struct nf_proto_net *pn = (struct nf_proto_net *)un;
+#ifdef CONFIG_SYSCTL
+ if (!pn->ctl_table) {
+#else
+ if (!pn->users++) {
+#endif
+ for (i = 0 ; i < UDPLITE_CT_MAX; i++)
+ un->timeouts[i] = udplite_timeouts[i];
+#ifdef CONFIG_SYSCTL
+ pn->ctl_table = kmemdup(udplite_sysctl_table,
+ sizeof(udplite_sysctl_table),
+ GFP_KERNEL);
+ if (!pn->ctl_table)
+ return -ENOMEM;
+ pn->ctl_table[0].data = &un->timeouts[UDPLITE_CT_UNREPLIED];
+ pn->ctl_table[1].data = &un->timeouts[UDPLITE_CT_REPLIED];
+#endif
+ }
+ return 0;
+}
+
static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
{
.l3proto = PF_INET,
.l4proto = IPPROTO_UDPLITE,
+ .compat = 0,
.name = "udplite",
.pkt_to_tuple = udplite_pkt_to_tuple,
.invert_tuple = udplite_invert_tuple,
@@ -258,12 +293,15 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
.ctl_table_header = &udplite_sysctl_header,
.ctl_table = udplite_sysctl_table,
#endif
+ .net_id = &udplite_net_id,
+ .init_net = udplite_init_net,
};
static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
{
.l3proto = PF_INET6,
.l4proto = IPPROTO_UDPLITE,
+ .compat = 0,
.name = "udplite",
.pkt_to_tuple = udplite_pkt_to_tuple,
.invert_tuple = udplite_invert_tuple,
@@ -293,29 +331,58 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
.ctl_table_header = &udplite_sysctl_header,
.ctl_table = udplite_sysctl_table,
#endif
+ .net_id = &udplite_net_id,
+ .init_net = udplite_init_net,
};
-static int __init nf_conntrack_proto_udplite_init(void)
+static int udplite_net_init(struct net *net)
{
- int err;
-
- err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite4);
- if (err < 0)
- goto err1;
- err = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udplite6);
- if (err < 0)
- goto err2;
+ int ret = 0;
+
+ ret = nf_conntrack_l4proto_register(net,
+ &nf_conntrack_l4proto_udplite4);
+ if (ret < 0) {
+ pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
+ goto out;
+ }
+ ret = nf_conntrack_l4proto_register(net,
+ &nf_conntrack_l4proto_udplite6);
+ if (ret < 0) {
+ pr_err("nf_conntrack_l4proto_udplite4 :protocol register failed.\n");
+ goto cleanup_udplite4;
+ }
return 0;
-err2:
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
-err1:
- return err;
+
+cleanup_udplite4:
+ nf_conntrack_l4proto_unregister(net,
+ &nf_conntrack_l4proto_udplite4);
+out:
+ return ret;
+}
+
+static void udplite_net_exit(struct net *net)
+{
+ nf_conntrack_l4proto_unregister(net,
+ &nf_conntrack_l4proto_udplite6);
+ nf_conntrack_l4proto_unregister(net,
+ &nf_conntrack_l4proto_udplite4);
+}
+
+static struct pernet_operations udplite_net_ops = {
+ .init = udplite_net_init,
+ .exit = udplite_net_exit,
+ .id = &udplite_net_id,
+ .size = sizeof(struct udplite_net),
+};
+
+static int __init nf_conntrack_proto_udplite_init(void)
+{
+ return register_pernet_subsys(&udplite_net_ops);
}
static void __exit nf_conntrack_proto_udplite_exit(void)
{
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
- nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
+ unregister_pernet_subsys(&udplite_net_ops);
}
module_init(nf_conntrack_proto_udplite_init);
--
1.7.7.6
^ permalink raw reply related
* [PATCH 17/17] netfilter: cttimeout use pernet data of l4proto
From: Gao feng @ 2012-04-27 9:38 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev, serge.hallyn, ebiederm, dlezcano,
Gao feng
In-Reply-To: <1335519484-6089-1-git-send-email-gaofeng@cn.fujitsu.com>
replace global data with pernet data of l4proto
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 8 +++++---
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 7 +++++--
net/netfilter/nf_conntrack_proto_dccp.c | 6 ++++--
net/netfilter/nf_conntrack_proto_generic.c | 6 ++++--
net/netfilter/nf_conntrack_proto_gre.c | 10 ++++++----
net/netfilter/nf_conntrack_proto_sctp.c | 7 +++++--
net/netfilter/nf_conntrack_proto_tcp.c | 8 +++++---
net/netfilter/nf_conntrack_proto_udp.c | 10 ++++++----
net/netfilter/nf_conntrack_proto_udplite.c | 10 ++++++----
9 files changed, 46 insertions(+), 26 deletions(-)
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 90da247..d84e294 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -279,16 +279,18 @@ static int icmp_nlattr_tuple_size(void)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int icmp_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeout = data;
-
+ struct nf_icmp_net *in = icmp_pernet(net);
if (tb[CTA_TIMEOUT_ICMP_TIMEOUT]) {
*timeout =
ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) * HZ;
} else {
/* Set default ICMP timeout. */
- *timeout = nf_ct_icmp_timeout;
+ *timeout = in->timeout;
}
return 0;
}
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 12ca315..7db08f8 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -286,16 +286,19 @@ static int icmpv6_nlattr_tuple_size(void)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int icmpv6_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeout = data;
+ struct nf_icmp_net *in = icmpv6_pernet(net);
if (tb[CTA_TIMEOUT_ICMPV6_TIMEOUT]) {
*timeout =
ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMPV6_TIMEOUT])) * HZ;
} else {
/* Set default ICMPv6 timeout. */
- *timeout = nf_ct_icmpv6_timeout;
+ *timeout = in->timeout;
}
return 0;
}
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index bc2ed4c..db6727a 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -712,9 +712,11 @@ static int dccp_nlattr_size(void)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
- struct dccp_net *dn = dccp_pernet(&init_net);
+ struct dccp_net *dn = dccp_pernet(net);
unsigned int *timeouts = data;
int i;
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 42b9cd6..9c3fa0a 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -75,7 +75,9 @@ static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int generic_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeout = data;
@@ -84,7 +86,7 @@ static int generic_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
ntohl(nla_get_be32(tb[CTA_TIMEOUT_GENERIC_TIMEOUT])) * HZ;
else {
/* Set default generic timeout. */
- *timeout = nf_ct_generic_timeout;
+ *timeout = generic_pernet(net)->timeout;
}
return 0;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 8d70452..afb8179 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -304,13 +304,15 @@ static void gre_destroy(struct nf_conn *ct)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int gre_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int gre_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeouts = data;
-
+ struct netns_proto_gre *net_gre = gre_pernet(net);
/* set default timeouts for GRE. */
- timeouts[GRE_CT_UNREPLIED] = gre_timeouts[GRE_CT_UNREPLIED];
- timeouts[GRE_CT_REPLIED] = gre_timeouts[GRE_CT_REPLIED];
+ timeouts[GRE_CT_UNREPLIED] = net_gre->gre_timeouts[GRE_CT_UNREPLIED];
+ timeouts[GRE_CT_REPLIED] = net_gre->gre_timeouts[GRE_CT_REPLIED];
if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) {
timeouts[GRE_CT_UNREPLIED] =
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 291cef4..06926d0 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -562,14 +562,17 @@ static int sctp_nlattr_size(void)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeouts = data;
+ struct sctp_net *sn = sctp_pernet(net);
int i;
/* set default SCTP timeouts. */
for (i=0; i<SCTP_CONNTRACK_MAX; i++)
- timeouts[i] = sctp_timeouts[i];
+ timeouts[i] = sn->timeouts[i];
/* there's a 1:1 mapping between attributes and protocol states. */
for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index c72b8de..9da405a 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1259,14 +1259,16 @@ static int tcp_nlattr_tuple_size(void)
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int tcp_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeouts = data;
int i;
-
+ struct nf_tcp_net *tn = tcp_pernet(net);
/* set default TCP timeouts. */
for (i=0; i<TCP_CONNTRACK_TIMEOUT_MAX; i++)
- timeouts[i] = tcp_timeouts[i];
+ timeouts[i] = tn->timeouts[i];
if (tb[CTA_TIMEOUT_TCP_SYN_SENT]) {
timeouts[TCP_CONNTRACK_SYN_SENT] =
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index c38ab58..c58e050 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -156,13 +156,15 @@ static int udp_error(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int udp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int udp_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeouts = data;
-
+ struct nf_udp_net *un = udp_pernet(net);
/* set default timeouts for UDP. */
- timeouts[UDP_CT_UNREPLIED] = udp_timeouts[UDP_CT_UNREPLIED];
- timeouts[UDP_CT_REPLIED] = udp_timeouts[UDP_CT_REPLIED];
+ timeouts[UDP_CT_UNREPLIED] = un->timeouts[UDP_CT_UNREPLIED];
+ timeouts[UDP_CT_REPLIED] = un->timeouts[UDP_CT_REPLIED];
if (tb[CTA_TIMEOUT_UDP_UNREPLIED]) {
timeouts[UDP_CT_UNREPLIED] =
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index cb3dc81..abae474 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -172,13 +172,15 @@ static int udplite_error(struct net *net, struct nf_conn *tmpl,
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_cttimeout.h>
-static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
+static int udplite_timeout_nlattr_to_obj(struct nlattr *tb[],
+ struct net *net,
+ void *data)
{
unsigned int *timeouts = data;
-
+ struct udplite_net *un = udplite_pernet(net);
/* set default timeouts for UDPlite. */
- timeouts[UDPLITE_CT_UNREPLIED] = udplite_timeouts[UDPLITE_CT_UNREPLIED];
- timeouts[UDPLITE_CT_REPLIED] = udplite_timeouts[UDPLITE_CT_REPLIED];
+ timeouts[UDPLITE_CT_UNREPLIED] = un->timeouts[UDPLITE_CT_UNREPLIED];
+ timeouts[UDPLITE_CT_REPLIED] = un->timeouts[UDPLITE_CT_REPLIED];
if (tb[CTA_TIMEOUT_UDPLITE_UNREPLIED]) {
timeouts[UDPLITE_CT_UNREPLIED] =
--
1.7.7.6
^ permalink raw reply related
* [PATCH 15/17] netfilter: cleanup sysctl for l4proto and l3proto
From: Gao feng @ 2012-04-27 9:38 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev, serge.hallyn, ebiederm, dlezcano,
Gao feng
In-Reply-To: <1335519484-6089-1-git-send-email-gaofeng@cn.fujitsu.com>
delete no useless sysctl data for l4proto and l3proto.
Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
---
include/net/netfilter/nf_conntrack_l3proto.h | 2 --
include/net/netfilter/nf_conntrack_l4proto.h | 10 ----------
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 1 -
net/ipv4/netfilter/nf_conntrack_proto_icmp.c | 8 --------
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | 5 -----
net/netfilter/nf_conntrack_proto_generic.c | 8 --------
net/netfilter/nf_conntrack_proto_sctp.c | 15 ---------------
net/netfilter/nf_conntrack_proto_tcp.c | 15 ---------------
net/netfilter/nf_conntrack_proto_udp.c | 15 ---------------
net/netfilter/nf_conntrack_proto_udplite.c | 12 ------------
10 files changed, 0 insertions(+), 91 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index d6df8c7..6f7c13f 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -64,9 +64,7 @@ struct nf_conntrack_l3proto {
size_t nla_size;
#ifdef CONFIG_SYSCTL
- struct ctl_table_header *ctl_table_header;
const char *ctl_table_path;
- struct ctl_table *ctl_table;
#endif /* CONFIG_SYSCTL */
/* Init l3proto pernet data */
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index 637c743..b271b6f 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -95,16 +95,6 @@ struct nf_conntrack_l4proto {
const struct nla_policy *nla_policy;
} ctnl_timeout;
#endif
-
-#ifdef CONFIG_SYSCTL
- struct ctl_table_header **ctl_table_header;
- struct ctl_table *ctl_table;
- unsigned int *ctl_table_users;
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- struct ctl_table_header *ctl_compat_table_header;
- struct ctl_table *ctl_compat_table;
-#endif
-#endif
int *net_id;
/* Init l4proto pernet data */
int (*init_net)(struct net *net, u_int8_t compat);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index bfe3a7c..676e4c9 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -379,7 +379,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
#endif
#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
.ctl_table_path = "net/ipv4/netfilter",
- .ctl_table = ip_ct_sysctl_table,
#endif
.init_net = ipv4_init_net,
.me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index f468d10..90da247 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -313,7 +313,6 @@ icmp_timeout_nla_policy[CTA_TIMEOUT_ICMP_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *icmp_sysctl_header;
static struct ctl_table icmp_sysctl_table[] = {
{
.procname = "nf_conntrack_icmp_timeout",
@@ -394,12 +393,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
.nla_policy = icmp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_header = &icmp_sysctl_header,
- .ctl_table = icmp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- .ctl_compat_table = icmp_compat_sysctl_table,
-#endif
-#endif
.init_net = icmp_init_net,
};
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 3cb422e..12ca315 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -320,7 +320,6 @@ icmpv6_timeout_nla_policy[CTA_TIMEOUT_ICMPV6_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *icmpv6_sysctl_header;
static struct ctl_table icmpv6_sysctl_table[] = {
{
.procname = "nf_conntrack_icmpv6_timeout",
@@ -376,9 +375,5 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
.nla_policy = icmpv6_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_header = &icmpv6_sysctl_header,
- .ctl_table = icmpv6_sysctl_table,
-#endif
.init_net = icmpv6_init_net,
};
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index cba718c..42b9cd6 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -111,7 +111,6 @@ generic_timeout_nla_policy[CTA_TIMEOUT_GENERIC_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *generic_sysctl_header;
static struct ctl_table generic_sysctl_table[] = {
{
.procname = "nf_conntrack_generic_timeout",
@@ -183,13 +182,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
.nla_policy = generic_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_header = &generic_sysctl_header,
- .ctl_table = generic_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- .ctl_compat_table = generic_compat_sysctl_table,
-#endif
-#endif
.init_net = generic_init_net,
};
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 3f0fdf8..291cef4 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -610,8 +610,6 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
#ifdef CONFIG_SYSCTL
-static unsigned int sctp_sysctl_table_users;
-static struct ctl_table_header *sctp_sysctl_header;
static struct ctl_table sctp_sysctl_table[] = {
{
.procname = "nf_conntrack_sctp_timeout_closed",
@@ -791,14 +789,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
.nla_policy = sctp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &sctp_sysctl_table_users,
- .ctl_table_header = &sctp_sysctl_header,
- .ctl_table = sctp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- .ctl_compat_table = sctp_compat_sysctl_table,
-#endif
-#endif
.net_id = &sctp_net_id,
.init_net = sctp_init_net,
};
@@ -834,11 +824,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#endif
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &sctp_sysctl_table_users,
- .ctl_table_header = &sctp_sysctl_header,
- .ctl_table = sctp_sysctl_table,
-#endif
.net_id = &sctp_net_id,
.init_net = sctp_init_net,
};
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 77bae1ef..c72b8de 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1363,8 +1363,6 @@ static const struct nla_policy tcp_timeout_nla_policy[CTA_TIMEOUT_TCP_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static unsigned int tcp_sysctl_table_users;
-static struct ctl_table_header *tcp_sysctl_header;
static struct ctl_table tcp_sysctl_table[] = {
{
.procname = "nf_conntrack_tcp_timeout_syn_sent",
@@ -1635,14 +1633,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
.nla_policy = tcp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &tcp_sysctl_table_users,
- .ctl_table_header = &tcp_sysctl_header,
- .ctl_table = tcp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- .ctl_compat_table = tcp_compat_sysctl_table,
-#endif
-#endif
.init_net = tcp_init_net,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
@@ -1680,11 +1670,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
.nla_policy = tcp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &tcp_sysctl_table_users,
- .ctl_table_header = &tcp_sysctl_header,
- .ctl_table = tcp_sysctl_table,
-#endif
.init_net = tcp_init_net,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 072ef9c..c38ab58 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -199,8 +199,6 @@ udp_timeout_nla_policy[CTA_TIMEOUT_UDP_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static unsigned int udp_sysctl_table_users;
-static struct ctl_table_header *udp_sysctl_header;
static struct ctl_table udp_sysctl_table[] = {
{
.procname = "nf_conntrack_udp_timeout",
@@ -307,14 +305,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
.nla_policy = udp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &udp_sysctl_table_users,
- .ctl_table_header = &udp_sysctl_header,
- .ctl_table = udp_sysctl_table,
-#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
- .ctl_compat_table = udp_compat_sysctl_table,
-#endif
-#endif
.init_net = udp_init_net,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
@@ -347,11 +337,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
.nla_policy = udp_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &udp_sysctl_table_users,
- .ctl_table_header = &udp_sysctl_header,
- .ctl_table = udp_sysctl_table,
-#endif
.init_net = udp_init_net,
};
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 1e90cf5..cb3dc81 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -215,8 +215,6 @@ udplite_timeout_nla_policy[CTA_TIMEOUT_UDPLITE_MAX+1] = {
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
#ifdef CONFIG_SYSCTL
-static unsigned int udplite_sysctl_table_users;
-static struct ctl_table_header *udplite_sysctl_header;
static struct ctl_table udplite_sysctl_table[] = {
{
.procname = "nf_conntrack_udplite_timeout",
@@ -288,11 +286,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
.nla_policy = udplite_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &udplite_sysctl_table_users,
- .ctl_table_header = &udplite_sysctl_header,
- .ctl_table = udplite_sysctl_table,
-#endif
.net_id = &udplite_net_id,
.init_net = udplite_init_net,
};
@@ -326,11 +319,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
.nla_policy = udplite_timeout_nla_policy,
},
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
-#ifdef CONFIG_SYSCTL
- .ctl_table_users = &udplite_sysctl_table_users,
- .ctl_table_header = &udplite_sysctl_header,
- .ctl_table = udplite_sysctl_table,
-#endif
.net_id = &udplite_net_id,
.init_net = udplite_init_net,
};
--
1.7.7.6
^ 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