From bunk@fs.tum.de Sun Aug 1 07:28:14 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 07:28:20 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i71ESAPm020056 for ; Sun, 1 Aug 2004 07:28:13 -0700 Received: (qmail 28287 invoked from network); 1 Aug 2004 14:20:58 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 1 Aug 2004 14:20:58 -0000 Date: Sun, 1 Aug 2004 16:27:59 +0200 From: Adrian Bunk To: Marcelo Tosatti , Stephen Hemminger Cc: linux-kernel@vger.kernel.org, davem@redhat.com, netdev@oss.sgi.com Subject: [2.4 patch] CONFIG_NET_SCH_NETEM Configure.help entry Message-ID: <20040801142759.GQ2746@fs.tum.de> References: <20040731142658.GA6497@logos.cnet> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040731142658.GA6497@logos.cnet> User-Agent: Mutt/1.5.6i X-archive-position: 7388 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev On Sat, Jul 31, 2004 at 11:26:59AM -0300, Marcelo Tosatti wrote: >... > Summary of changes from v2.4.27-rc3 to v2.4.27-rc4 > ============================================ >... > Stephen Hemminger: > o [PKT_SCHED]: Update to network emulation QOS scheduler > o [PKT_SCHED]: One small netem fixes > o [BRIDGE]: Fix assertion failure in 2.4.27-rc3 > o [PKT_SCHED]: netem update for 2.4 >... The Configure.help entry was forgotten: Signed-off-by: Adrian Bunk --- linux-2.4.27-rc4-full/Documentation/Configure.help.old 2004-08-01 16:20:15.000000000 +0200 +++ linux-2.4.27-rc4-full/Documentation/Configure.help 2004-08-01 16:22:23.000000000 +0200 @@ -10949,13 +10949,15 @@ whenever you want). If you want to compile it as a module, say M here and read . -Network delay simualtor -CONFIG_NET_SCH_DELAY - Say Y if you want to delay packets by a fixed amount of - time. This is often useful to simulate network delay when +CONFIG_NET_SCH_NETEM + Say Y if you want to emulate network delay, loss, and packet + re-ordering. This is often useful to simulate networks when testing applications or protocols. - - This code is also available as a module called sch_delay.o + + To compile this driver as a module, choose M here: the module + will be called sch_netem. + + If unsure, say N. Ingress Qdisc CONFIG_NET_SCH_INGRESS From bunk@fs.tum.de Sun Aug 1 07:33:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 07:33:22 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i71EXG3b020415 for ; Sun, 1 Aug 2004 07:33:17 -0700 Received: (qmail 28500 invoked from network); 1 Aug 2004 14:26:05 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 1 Aug 2004 14:26:05 -0000 Date: Sun, 1 Aug 2004 16:33:07 +0200 From: Adrian Bunk To: Stephen Hemminger Cc: linux-kernel@vger.kernel.org, davem@redhat.com, netdev@oss.sgi.com Subject: [2.6 patch] update NET_SCH_NETEM help text Message-ID: <20040801143307.GR2746@fs.tum.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-archive-position: 7389 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev The patch below contains the following changes for the NET_SCH_NETEM help text: - correct the module name - "If unsure, say N." Signed-off-by: Adrian Bunk --- linux-2.6.8-rc2-mm1-full/net/sched/Kconfig.old 2004-08-01 16:28:22.000000000 +0200 +++ linux-2.6.8-rc2-mm1-full/net/sched/Kconfig 2004-08-01 16:29:12.000000000 +0200 @@ -207,19 +207,21 @@ config NET_SCH_NETEM tristate "Network emulator" depends on NET_SCHED help Say Y if you want to emulate network delay, loss, and packet re-ordering. This is often useful to simulate networks when testing applications or protocols. To compile this driver as a module, choose M here: the module - will be called sch_delay. + will be called sch_netem. + + If unsure, say N. config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_SCHED help If you say Y here, you will be able to police incoming bandwidth and drop packets when this bandwidth exceeds your desired rate. If unsure, say Y. From rddunlap@osdl.org Sun Aug 1 10:43:38 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:43:44 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HhbY4027638 for ; Sun, 1 Aug 2004 10:43:38 -0700 Received: from dragon.pdx.osdl.net (dragon.pdx.osdl.net [172.20.1.27]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i71HhP116814; Sun, 1 Aug 2004 10:43:26 -0700 Date: Sun, 1 Aug 2004 10:22:47 -0700 From: "Randy.Dunlap" To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver Message-Id: <20040801102247.33363e99.rddunlap@osdl.org> In-Reply-To: <200407311521.i6VFLcOC022100@nlp0.cs.usyd.edu.au> References: <200407311521.i6VFLcOC022100@nlp0.cs.usyd.edu.au> Organization: OSDL X-Mailer: Sylpheed version 0.9.10 (GTK+ 1.2.10; i686-pc-linux-gnu) X-Face: +5V?h'hZQPB9kW Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7390 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rddunlap@osdl.org Precedence: bulk X-list: netdev (moving this to netdev mailing list) On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | I would like to be able to boot the kernel with parameters that | will allow control of the tulip device. On some ethernet devices | this used to be possible via (something like): | | ether=0,0,1,0,eth0 | | which would pass the four numeric parameters (as, I think, dev->irq, | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | controlled eth0. A convention adopted by some net drivers then allowed | dev->mem_start to be interpretted as a set of flags that would control | device characteristics (e.g. full-duplex vs half-duplex mode). | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | if (dev->mem_start & MEDIA_MASK) | tp->default_port = dev->mem_start & MEDIA_MASK; | | suggests that this might still work. However, I have been unable | to force dev->mem_start in that driver to become non-zero via any | kernel boot-time parameters. My limited understanding of the code | that precedes the above lines in that file suggests that the "dev" | structure is not what it used to be... The driver never calls netdev_boot_setup_check(), which is what would give the driver its command line parameters. Did this work in early 2.6.x? There have been several changes in this area. The driver can't do a simple call to netdev_boot_setup_check() because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, and those values come from PCI config space for PCI drivers. The driver could create a fake for that purpose, but it's more likely that ethtool or mii-tool should be used to change media/speed etc... Although now that I look at the driver source code, I don't see ethtool or mii-tool support for those options. | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | mentions "ether=..." but marks it as obsolete, replaced by | the equivalent "netdev=...". Elsewhere in that file, the entry | for "netdev=..." describes what appears to be the functionality | that I seek. | | So, is it still possible to perform the same sort of control | operations on a tulip driver via kernel boot-time parameters | as one can do via module load-time parameters? If so, how? The current tulip-core driver supports setting only the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image (using mem_start, as you noted above). When modular, it supports that plus forcing full duplex and MTU for jumbo frames. Anyone have more definite answers on this? -- ~Randy From kaber@trash.net Sun Aug 1 10:51:35 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:51:44 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HpYw8028091 for ; Sun, 1 Aug 2004 10:51:35 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 74DC919F353; Sun, 1 Aug 2004 19:51:25 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id B89CB3940EE; Sun, 1 Aug 2004 19:51:20 +0200 (CEST) Message-ID: <410D2E30.2050104@trash.net> Date: Sun, 01 Aug 2004 19:53:52 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Tomasz Paszkowski Cc: "David S. Miller" , hadi@cyberus.ca, devik@cdi.cz, netdev@oss.sgi.com Subject: Re: Fw: hfsc and huge set of rules References: <20040729211844.61e8d328.davem@redhat.com> <410A2449.3020701@trash.net> <20040730110815.GA7812@krezus.e-wro.net> In-Reply-To: <20040730110815.GA7812@krezus.e-wro.net> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7391 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Tomasz Paszkowski wrote: >On Fri, Jul 30, 2004 at 12:34:49PM +0200, Patrick McHardy wrote: > > >>hfsc_destroy_qdisc takes O(n) time wrt. the number of classes, >>but 5-6 seconds is still long. If all these classes contain inner >>qdiscs other than the default, I guess removing the classes from >>dev->qdisc_list in qdisc_destroy takes up most of the time, with >>n O(n) operations. The __qdisc_destroy rcu callback also calls >>reset before destroy, I don't know any qdisc where this is really >>neccessary. Without inner qdiscs, I need to see the script first to >>judge what's going wrong. Tomasz ? >> >> > >http://www.e-wro.pl/~acid/tc.batch.gz. In my opinion it's not the case >of expensive algorithms, but the number of classes. With this rule set loaded >(tc -b tc.batch) command: > >for i in 'e1.903 e0.930 e0.931 e0.932' ; do > tc qdisc del dev ${i} root >done >completly freezes machine for about 5-6 seconds. > > I've done some profiles with your script (on an old kernel without the lockless loopback patch), qdisc_destroy takes up 89% of the time when destroying the qdiscs. These are the exact results: - execute the script on unpatched kernel: time: real 2m28.822s user 0m2.347s sys 2m25.395s top 5 in profile: 799773 65.4986 vmlinux vmlinux qdisc_lookup 199964 16.3763 vmlinux vmlinux qdisc_destroy 92504 7.5758 sch_hfsc.ko sch_hfsc hfsc_adjust_levels 36722 3.0074 sch_hfsc.ko sch_hfsc hfsc_get_class 12471 1.0213 vmlinux vmlinux mark_offset_tsc - execute the script on kernel using double-linked lists for dev->qdisc_list: time: real 0m51.804s user 0m2.286s sys 0m48.795s top 5 in profile: 201152 49.6049 vmlinux vmlinux qdisc_lookup 92706 22.8617 sch_hfsc.ko sch_hfsc hfsc_adjust_levels 37140 9.1589 sch_hfsc.ko sch_hfsc hfsc_get_class 12310 3.0357 sch_hfsc.ko sch_hfsc hfsc_bind_tcf 12190 3.0061 sch_hfsc.ko sch_hfsc hfsc_change_class - destroy the qdiscs on unpatched kernel: time: real 0m13.258s user 0m0.019s sys 0m13.206s top 5 in profile: 29839 89.5367 vmlinux vmlinux qdisc_destroy 1229 3.6878 sch_hfsc.ko sch_hfsc hfsc_reset_class 338 1.0142 vmlinux vmlinux mark_offset_tsc 289 0.8672 vmlinux vmlinux qdisc_reset 287 0.8612 sch_hfsc.ko sch_hfsc rtsc_init - destroy the qdiscs on kernel using double-linked lists for dev->qdisc_list: time: real 0m0.389s user 0m0.019s sys 0m0.363s top 5 in profile: 1261 33.6896 sch_hfsc.ko sch_hfsc hfsc_reset_class 311 8.3088 sch_hfsc.ko sch_hfsc rtsc_init 277 7.4005 vmlinux vmlinux qdisc_reset 187 4.9960 vmlinux vmlinux free_block 181 4.8357 vmlinux vmlinux kfree So double-linked lists clearly solve your problem. Using a hash would speed up creating the qdiscs even more, but it wastes too much memory in my opinion. I'm going to send a patch after I've fixed the other problems with qdisc_destroy. >I was trying do modify the code od hfsc_qdisc_destroy scheduling another >task using schedule_task (), but i don't have enough knowledge to do deal >with proper locking of qdisc structures. > > That doesn't work, hfsc_qdisc_destroy is called under a lock. Regards Patrick From kaber@trash.net Sun Aug 1 10:53:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:53:51 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HrkLp028447 for ; Sun, 1 Aug 2004 10:53:46 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 7A7C519F353; Sun, 1 Aug 2004 19:53:37 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id D39343940EE; Sun, 1 Aug 2004 19:53:32 +0200 (CEST) Message-ID: <410D2EB4.1060205@trash.net> Date: Sun, 01 Aug 2004 19:56:04 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: devik Cc: "David S. Miller" , hadi@cyberus.ca, netdev@oss.sgi.com, tomasz.paszkowski@e-wro.pl Subject: Re: Fw: hfsc and huge set of rules References: In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7392 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev devik wrote: >Also IIRC class lookup is done before each remove. With >hashing size a few tens of buckets the complexity >starts to be very near to O(n^2). > > I think the hash size of HTB, HFSC and CBQ should be increased, the hash function performs well even with 2^16. With HFSC using many classes doesn't scale well right now, but with the rbtree patches it will. Regards Patrick >devik > >On Fri, 30 Jul 2004, Patrick McHardy wrote: > > > >>David S. Miller wrote: >> >> >>>Looks like qdisc destruction has some expensive algorithms. >>>Any quick ideas about the root culprit at least in the hfsc >>>case? He says htb does it too. >>> >>> >>hfsc_destroy_qdisc takes O(n) time wrt. the number of classes, >>but 5-6 seconds is still long. If all these classes contain inner >>qdiscs other than the default, I guess removing the classes from >>dev->qdisc_list in qdisc_destroy takes up most of the time, with >>n O(n) operations. The __qdisc_destroy rcu callback also calls >>reset before destroy, I don't know any qdisc where this is really >>neccessary. Without inner qdiscs, I need to see the script first to >>judge what's going wrong. Tomasz ? >> >> From JDrabb@tampabay.rr.com Sun Aug 1 11:15:54 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 11:16:01 -0700 (PDT) Received: from ms-smtp-03.tampabay.rr.com (ms-smtp-03-smtplb.tampabay.rr.com [65.32.5.133]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71IFrin029245 for ; Sun, 1 Aug 2004 11:15:54 -0700 Received: from [192.168.1.101] (189-66.35-65.tampabay.rr.com [65.35.66.189]) by ms-smtp-03.tampabay.rr.com (8.12.10/8.12.7) with ESMTP id i71IFgfP011721; Sun, 1 Aug 2004 14:15:42 -0400 (EDT) Message-ID: <410D3377.3030505@tampabay.rr.com> Date: Sun, 01 Aug 2004 14:16:23 -0400 From: James Drabb User-Agent: Mozilla Thunderbird 0.7.1 (X11/20040626) X-Accept-Language: en-us, en MIME-Version: 1.0 To: netdev@oss.sgi.com CC: c-d.hailfinger.kernel.2004@gmx.net, manfred@colorfullife.com Subject: forcedeth Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Symantec AntiVirus Scan Engine X-archive-position: 7393 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: JDrabb@tampabay.rr.com Precedence: bulk X-list: netdev I am having some issues with the forcedeth driver. jim@keelie $ modinfo forcedeth parm: max_interrupt_work:forcedeth maximum events handled per interrupt author: Manfred Spraul description: Reverse Engineered nForce ethernet driver license: GPL vermagic: 2.6.7-1 686 REGPARM gcc-3.3 depends: alias: pci:v000010DEd000001C3sv*sd*bc*sc*i* alias: pci:v000010DEd00000066sv*sd*bc*sc*i* alias: pci:v000010DEd000000D6sv*sd*bc*sc*i* jim@keelie $ uname -a Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 GNU/Linux My system is an Athlon XP 2800+, on an MSI K7N2 Delta Mobo based on the NForce 2 chipset. I have a dual boot with WinXP and Fedora Core 2 and spend 99% of my time in FC2. Once in a while I shut the system down. When I boot from a cold boot right into FC2, the forcedeth driver appears not to work. I am not able to get to the net over my cable mode. Bringing eth0 up and down, unplugging the network cable does nothing. However, if I reboot into WinXP, and then reboot right away back into FC2, the forcedeth driver works like a champ. Is there anything I can do to look into what might be causing this issue? Any more information I may be able to send to help? Thanks for any help, -- James Drabb Senior Programmer Davenport, FL USA From scarfboy@gmail.com Sun Aug 1 12:03:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:03:43 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.204]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71J3ajP030662 for ; Sun, 1 Aug 2004 12:03:37 -0700 Received: by mproxy.gmail.com with SMTP id 73so103371rnk for ; Sun, 01 Aug 2004 12:03:32 -0700 (PDT) Received: by 10.38.181.17 with SMTP id d17mr222682rnf; Sun, 01 Aug 2004 12:03:32 -0700 (PDT) Message-ID: Date: Sun, 1 Aug 2004 21:03:32 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: <20040731231836.A31121@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_60_22762740.1091387012317" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> X-archive-position: 7394 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_60_22762740.1091387012317 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline On Sat, 31 Jul 2004 23:18:36 +0200, Francois Romieu wrote: > > Right, both computers now run 2.6.8-rc2-mm1. It's better. Roughly > > speaking, the top *benchmark* speeds, rouding slightly up, are: > > udp: 33MB/s (using ~26Kints) one way, 12MB/s (9Kints/s) the other, > > tcp: 22MB/s (16Kints)one way, 12MB/s (9Kints/s) the other. > > > > (The 9Kints ca be 12 when the packet size is 1K or 2K) > > Can you give a try to a napi version of the module (it is a compile-time > option) ? > You may want higher {r/w}mem_max as well as renicing ksoftirqd with > a strongly < 0 value on the celeron client. That's with NAPI on both. I notice r/wmem has an effect, but it's not much. Although on my new computer it seems moot as there's something weird going on with interrupts with my botherboard. > > Oddly enough, the slow direction is sending from my new computer > > (XP1700, KT333, 1GB ram) to my old (both running linux and the > > mentioned kernel). I'm fairly sure this is due to the fact that my > > The r8169 driver has been reported to be faster on Rx than on Tx so your > observation makes sense. How does that make sense? When one side receives, the other sends, hrm? They're two identical cards, it should be entirely symmetrical assuming equal hardware - not faster on the years older hardware. > [...] > > I guess I'll have to settle for this. I'm just annoyed that the 'giga' > > is basically a joke, especially on my setup. > > It should be possible to make things slightly better for the celeron box > as a client. I'll cook up a patch. The celeron box is the server, that's the entire point. Anyhow, it's much faster in transmission than my new computer right now due to said mobo problem, so I *want* it as the server. > Would you be kind enough to do some ftp transfer test where the celeron > box retrieves data and send the 'vmstat 1' output of the client during > the test ? Sure, but I can tell you right now with reasonable certaintly that my new computer won't top 9000interrupts/sec, i.e. 9000 packets per second, and therefore do the 12MB/s at most, and probably less; interruptwise, my new computer is the bottleneck, and I'm guessing UDP is faster because TCP is limited by the amount of packets, or in the other direction ACKs, it can send per second. Transfers to the celeron are a relatively pointless measure because of my new computer being horribly interrupt limited at the moment. That may have started when I installed the gbit card, but mostly because it disturbs the mobo's precious and unguessable hardware balance. I'll try figuring out if I can solve it, but basically it just involves swapping around cards until it works better, so that'ld take a while. Attached are the vmstats for an ftp and nfs transfer, as measured from my old computer (the nfs and ftp server). Both were going at a pretty low speed, sub-9000 packets; this may have to do with drive fragmentation, my hard drives are rather full at the moment. Also, the logs on the client (my new computer) while sending data to my old one. These were made at a different time, and I believe the transfer rate was better (6MB for ftp, 9MB for nfs) than for the -to-old- logs, which were worse, and varied more. --Bart ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="ftp-put-to-old-computer__lin-mm-to-lin-mm_larger" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ftp-put-to-old-computer__lin-mm-to-lin-mm_larger" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg IDQ4NTMyICAyOTY0OCAxNzU0NjQgICAgMCAgICAwICAgMTAxICAgIDMxICAyNzMgICAxNjkgMTUg IDIgODAgIDIKIDAgIDAgICAgICAwICA0ODUzMiAgMjk2NDggMTc1NDY4ICAgIDAgICAgMCAgICAg MCAgICAgMCAxMDA3ICAgICA5ICAwICAxIDk5ICAwCiAxICAwICAgICAgMCAgNDU3OTYgIDI5NjQ4 IDE3ODIxMiAgICAwICAgIDAgICAgIDAgICAgIDAgMjg3MyAgICAzNSAgMiAzMyA2NSAgMAogMSAg MCAgICAgIDAgIDM5MjE2ICAyOTY0OCAxODQ1MzIgICAgMCAgICAwICAgICAwICAgICAwIDUxMzEg ICAgMzYgIDcgNzYgMTcgIDAKIDEgIDAgICAgICAwICAzMjgyMCAgMjk2NDggMTkxMzQ4ICAgIDAg ICAgMCAgICAgMCAgICAgMCA0OTM4ICAgIDUyICA3IDc3IDE2ICAwCiAwICAxICAgICAgMCAgMjg3 ODggIDI5OTA4IDE5NTAyOCAgICAwICAgIDAgICAgIDAgIDQ2MjggMzI3NiAgICA0MSAgNCA0NyAy NiAyMwogMSAgMSAgICAgIDAgIDI0MzA4ICAyOTkwOCAxOTkwMjAgICAgMCAgICAwICAgICAwICA4 NjU2IDQyMTEgICAgNDAgIDggOTAgIDAgIDIKIDEgIDAgICAgICAwICAyMDU5NiAgMjk5MDggMjAy NzI0ICAgIDAgICAgMCAgICAgMCAgNjUwMCAzOTY0ICAgMjU3ICA2IDk0ICAwICAwCiAxICAwICAg ICAgMCAgMTM5NDAgIDI5OTA4IDIwOTQwNCAgICAwICAgIDAgICAgIDAgICAgIDAgNTk5NCAgICAx NCAgOCA5MiAgMCAgMAogMSAgMCAgICAgIDAgICA3MjE2ICAyOTkwOCAyMTYxMTYgICAgMCAgICAw ICAgICAwICAgICA4IDU5OTYgICAgMTIgIDYgOTQgIDAgIDAKIDEgIDAgICAgICAwICAgMjQwOCAg Mjk4NDAgMjIxMDg0ICAgIDAgICAgMCAgICAgMCAgICAgOCA1OTMxICAgIDI4ICA4IDkyICAwICAw CiAxICAwICAgICAgMCAgIDI4NTYgIDI5NzQwIDIyMTMyMCAgICAwICAgIDAgICAgIDAgIDExODQg NTU3NCAgICA1MSAgNSA5NSAgMCAgMAogMSAgMSAgICAgIDAgICAyNTM2ICAzMDQwMCAyMjE0MDAg ICAgMCAgICAwICAgICAwICA2NTI0IDQ4ODYgICAgOTAgIDYgOTQgIDAgIDAKIDEgIDIgICAgICAw ICAgMjg1NiAgMzAyNzYgMjIxNTgwICAgIDAgICAgMCAgICAgMCAgNzc4MCA0Mjc5ICAgIDczICA3 IDkzICAwICAwCiAxICAyICAgICAgMCAgIDI0MDggIDMwMjQ4IDIyMjM2OCAgICAwICAgIDAgICAg IDAgIDYzNjggNDI1MSAgICA3MyAgNSA5NSAgMCAgMAogMSAgMiAgICAgIDAgICAyMjQ0ICAyOTkw NCAyMjMyNjAgICAgMCAgICAwICAgICAwICA2MzQ0IDQ5NTIgICAgNjggIDYgOTQgIDAgIDAKIDEg IDIgICAgICAwICAgMzExNiAgMjk2MzYgMjIyOTYwICAgIDAgICAgMCAgICAgMCAgNTI0NCA0MTYz ICAgIDgxICA4IDkyICAwICAwCiAxICAxICAgICAgMCAgIDI0NzIgIDI5NTI4IDIyMzk2OCAgICAw ICAgIDAgICAgIDAgIDU2NjQgNDczMSAgIDEwMSAgNyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAy OTIwICAyOTQxNiAyMjQwMjAgICAgMCAgICAwICAgICAwICAxMjY4IDUxMjQgICAxOTQgIDYgOTQg IDAgIDAKIDEgIDAgICAgICAwICAgMjk4NCAgMjkxMzIgMjI0NjI4ICAgIDAgICAgMCAgICAgMCAg IDYzNiA1ODI1ICAgIDQwICA4IDkyICAwICAwCiAxICAwICAgICAgMCAgIDIyODAgIDI4OTQ0IDIy NTc5NiAgICAwICAgIDAgICAgIDAgIDY2NjggNDgwNyAgICA3MyAgNiA5NCAgMCAgMApwcm9jcyAt LS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVt LS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBz byAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAyICAwICAgICAgMCAgIDIyNjAg IDI4NjY4IDIyNjM1MiAgICAwICAgIDAgICAgIDAgIDM5NzYgNDk3MyAgICA3NyAgNyA5MyAgMCAg MAogMSAgMCAgICAgIDAgICAyNDA4ICAyODQyMCAyMjY2NjQgICAgMCAgICAwICAgICAwICA1MzIw IDQ1MTQgICAgOTYgIDYgOTQgIDAgIDAKIDEgIDEgICAgICAwICAgMjY2NCAgMjgzNjggMjI2NDgw ICAgIDAgICAgMCAgICAgMCAxOTI2NCAzMjYxICAgIDQ0ICA2IDk0ICAwICAwCiAxICAxICAgICAg MCAgIDI0NzYgIDI4Mjg4IDIyNjczMiAgICAwICAgIDAgICAgIDAgMTYxODQgMjEyNCAgIDI1MiAg NyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIwICAyODA1NiAyMjY5NjggICAgMCAgICAwICAg ICAwICAgNTM2IDM4OTggICAgNjcgIDcgOTMgIDAgIDAKIDEgIDAgICAgICAwICAgMjgwNCAgMjc2 OTYgMjI3NzAwICAgIDAgICAgMCAgICAgMCAgICAgOCA1ODYzICAgIDUzICA2IDk0ICAwICAwCiAx ICAwICAgICAgMCAgIDI5ODQgIDI3NTA0IDIyNzkyOCAgICAwICAgIDAgICAgIDAgICAgIDggNTky OSAgICA3MCAgNyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIwICAyNzAwOCAyMjg2NDggICAg MCAgICAwICAgICAwICAgICA0IDU5NDkgICAgNTMgIDkgOTEgIDAgIDAKIDEgIDAgICAgICAwICAg MjQwOCAgMjY4NDAgMjI5NDY4ICAgIDAgICAgMCAgICAgMCAgMTQzNiA1NTQzICAgIDUwICA2IDk0 ICAwICAwCiAyICAwICAgICAgMCAgIDI3OTIgIDI2ODA4IDIyODU2MCAgICAwICAgIDAgICAgIDAg MzU1MzIgMzY4NSAgICA0NiAgOCA5MiAgMCAgMAogMSAgMSAgICAgIDAgICAzMDY0ICAyNjcxNiAy Mjg5MTYgICAgMCAgICAwICAgICAwICAgICAwIDIwODUgICAyMTcgIDggOTIgIDAgIDAKIDEgIDAg ICAgICAwICAgMjk4NCAgMjY1MjAgMjI5NTcyICAgIDAgICAgMCAgICAgMCAgIDE2MCAzNzUxICAg IDY5ICA2IDk0ICAwICAwCiAxICAwICAgICAgMCAgIDI1MzYgIDI2MzUyIDIzMDMyNCAgICAwICAg IDAgICAgIDAgICAgIDggNTk1MyAgICA1MCAgOCA5MiAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIw ICAyNDExNiAyMzIzMzIgICAgMCAgICAwICAgICAwICAgICA4IDU4OTQgICAgNTMgIDcgOTMgIDAg IDAKIDEgIDAgICAgICAwICAgMzA0OCAgMjI0MjAgMjM0MTgwICAgIDAgICAgMCAgICAgMCAgICAg NCA1OTQ1ICAgIDQ4ICA2IDk0ICAwICAwCiAxICAwICAgICAgMCAgIDMxMTIgIDIxMDY0IDIzNTM5 NiAgICAwICAgIDAgICAgIDAgIDEzNDggNTQ3NiAgICA1NSAgNyA5MSAgMiAgMAogMSAgMSAgICAg IDAgICAxOTQ0ICAyMDU3MiAyMzY1MDggICAgMCAgICAwICAgICAwIDM1NjUyIDM2MjggICAgNTIg IDYgOTQgIDAgIDAKIDAgIDIgICAgICAwICAgMjEzMiAgMjAwNTYgMjM3MDQ4ICAgIDAgICAgMCAg MTA2NCAgICAgMCAxMTI1ICAgMTUwICA3IDIyICAwIDcwCiAxICAxICAgICAgMCAgIDMxODggIDE4 OTg0IDIzNjQwOCAgICAwICAgIDAgICAyMjQgICAgIDAgMTA3NyAgIDEwOCA2MSAxMCAgMCAyOQog MCAgMCAgICAgIDAgICA0NjE2ICAxODk4NCAyMzY0MDggICAgMCAgICAwICAgICAwICAgMTQ0IDEw MzQgICAgMzQgIDIgIDIgODMgMTMKIDAgIDAgICAgICAwICAgNDYxNiAgMTg5ODQgMjM2NDA4ICAg IDAgICAgMCAgICAgMCAgICAgMCAxMDA2ICAgIDEwICAwICAwIDEwMCAgMApwcm9jcyAtLS0tLS0t LS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVtLS0gLS0t LWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBzbyAgICBi aSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAxICAwICAgICAgMCAxNzg1MTYgIDE4OTg0 ICA2MzY3NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwOSAgICAxMiAgMCAzMyA2NyAgMAogMCAg MCAgICAgIDAgMTc3NTcyICAyMDE4MCAgNjM2ODAgICAgMCAgICAwICAgIDQ4ICAxMTkyIDEwMzMg ICAgNzMgIDEgIDQgNzAgMjUKIDAgIDAgICAgICAwIDE3NzU3MiAgMjAxODAgIDYzNjgwICAgIDAg ICAgMCAgICAgMCAgICAgMCAxMDA4ICAgIDEwICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc3 ODkyICAyMDIxNiAgNjM2ODAgICAgMCAgICAwICAgICAwICAxMTI0IDEyMjQgICAgMzkgIDAgIDMg NDAgNTcKIDAgIDAgICAgICAwIDE3Nzg5MiAgMjAyMTYgIDYzNjg0ICAgIDAgICAgMCAgICAgMCAg ICAgMCAxMDY3ICAgIDEzICAwICAxIDg1IDE0CiAwICAwICAgICAgMCAxNzc4OTIgIDIwMjIwICA2 MzY4OCAgICAwICAgIDAgICAgIDggICAgIDAgMTAxMSAgICAxNiAgMCAgMCA5OSAgMQo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="nfs-to-old-computer__lin-mm-to-lin-mm" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="nfs-to-old-computer__lin-mm-to-lin-mm" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg MTc4MjQwICAyMDM2MCAgNjM2ODggICAgMCAgICAwICAgMTAxICAgIDMzICAyNzYgICAxNjkgMTUg IDIgODAgIDIKIDAgIDAgICAgICAwIDE3ODI0MCAgMjA0MDAgIDYzNjk2ICAgIDAgICAgMCAgICAg OCAgICA2OCAxMDE5ICAgIDI3ICAwICAxIDk2ICAzCiAwICAwICAgICAgMCAxNzgyNDAgIDIwNDAw ICA2MzY5NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwNiAgICAgOCAgMCAgMCAxMDAgIDAKIDAg IDAgICAgICAwIDE3ODI0MCAgMjA0MDAgIDYzNjk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMDA4 ICAgIDE0ICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc4MjQwICAyMDQwMCAgNjM2OTYgICAg MCAgICAwICAgICAwICAgICAwIDEwMDQgICAgMTIgIDAgIDAgMTAwICAwCiAwICAwICAgICAgMCAx NzgyNDAgIDIwNDAwICA2MzY5NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwNSAgICAxNCAgMCAg MCAxMDAgIDAKIDAgIDAgICAgICAwIDE3ODI0MCAgMjA0MTIgIDYzNjk2ICAgIDAgICAgMCAgICAg MCAgICAyMCAxMDExICAgIDIwICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc4MTc2ICAyMDQ2 MCAgNjM2OTYgICAgMCAgICAwICAgICA0ICAgIDcyIDEwMjQgICAgMzcgIDAgIDAgOTkgIDEKIDEg IDAgICAgICAwIDE3MTAxMiAgMjA0NjggIDcwNTEyICAgIDAgICAgMCAgICAgMCAgICAgMCAyNTg5 ICAgMjIyICAwIDc1IDI1ICAwCiAxICAwICAgICAgMCAxNjIyNDQgIDIwNDc2ICA3OTI4MCAgICAw ICAgIDAgICAgIDAgICAgIDAgNTQ5NyAgIDI4OSAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwIDE1 MzczMiAgMjA0ODQgIDg4MDQ4ICAgIDAgICAgMCAgICAgMCAgICAgMCA1NjE4ICAxMjE0ICAwIDEw MCAgMCAgMAogMSAgMSAgICAgIDAgMTQ1NTQwICAyMTAxNiAgOTUyODAgICAgMCAgICAwICAgICAw ICA1ODQ4IDQ4ODcgICA1MjggIDEgOTkgIDAgIDAKIDEgIDEgICAgICAwIDEzOTI2OCAgMjEwMjAg MTAxNTUyICAgIDAgICAgMCAgICAgMCAgNTI3NiA0NDE0ICAxMjYwICAwIDEwMCAgMCAgMAogMSAg MiAgICAgIDAgMTMyMjI4ICAyMTAyOCAxMDg2NTYgICAgMCAgICAwICAgICAwICAyODI4IDQ5OTIg IDU1MDAgIDAgMTAwICAwICAwCiAxICAyICAgICAgMCAxMjUzODAgIDIxMDM2IDExNTQwOCAgICAw ICAgIDAgICAgIDAgIDQzMjAgNDg4NSAgNjAyNCAgMCAxMDAgIDAgIDAKIDEgIDIgICAgICAwIDEx OTA0NCAgMjEwNDAgMTIxODQwICAgIDAgICAgMCAgICAgMCAgNTc2MCA1MzUyICA1ODI5ICAwIDEw MCAgMCAgMAogMSAgMiAgICAgIDAgMTEzOTg4ICAyMTA0OCAxMjY4MzIgICAgMCAgICAwICAgICAw ICA2MTk2IDQyNjggIDQ3MzEgIDEgOTkgIDAgIDAKIDIgIDEgICAgICAwIDEwOTc2NCAgMjEwNTIg MTMwODg4ICAgIDAgICAgMCAgICAgMCAgNTIyNCA0MDExICAzNzY2ICAwIDY0ICAwIDM2CiAxICAw ICAgICAgMCAxMDM4NzYgIDIxMDU2IDEzNjgxMiAgICAwICAgIDAgICAgIDAgIDc4NzYgNDgzMSAg NTYxOCAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwICA5NjUxNiAgMjEwNjQgMTQzOTE2ICAgIDAg ICAgMCAgICAgMCAgICAgMCA1NTI5ICA2NjcxICAwIDEwMCAgMCAgMAogMSAgMCAgICAgIDAgIDkx MzMyICAyMTA2OCAxNDkwNjggICAgMCAgICAwICAgICAwICA5MzQ4IDM4MDQgIDQ4NjQgIDAgMTAw ICAwICAwCnByb2NzIC0tLS0tLS0tLS0tbWVtb3J5LS0tLS0tLS0tLSAtLS1zd2FwLS0gLS0tLS1p by0tLS0gLS1zeXN0ZW0tLSAtLS0tY3B1LS0tLQogciAgYiAgIHN3cGQgICBmcmVlICAgYnVmZiAg Y2FjaGUgICBzaSAgIHNvICAgIGJpICAgIGJvICAgaW4gICAgY3MgdXMgc3kgaWQgd2EKIDIgIDEg ICAgICAwICA4Mjk0OCAgMjEwNzYgMTU3MDY0ICAgIDAgICAgMCAgICAgMCAgNjcyNCA2Mjg3ICA3 NTAzICAwIDEwMCAgMCAgMAogMSAgMSAgICAgIDAgIDc5MzY0ICAyMTM1NiAxNTk4NDggICAgMCAg ICAwICAgICAwIDM2MjIwIDE5NjcgIDI3MTkgIDAgMTAwICAwICAwCiAxICAxICAgICAgMCAgNzYy MjggIDIxMzYwIDE2MzMzNiAgICAwICAgIDAgICAgIDAgICAgIDAgMjA2NCAgMzMzNSAgMCAxMDAg IDAgIDAKIDEgIDAgICAgICAwICA3MTYyMCAgMjEzNjQgMTY4MjI0ICAgIDAgICAgMCAgICAgMCAg IDI4MCAzNDIyICA0NTc2ICAxIDk5ICAwICAwCiAxICAwICAgICAgMCAgNjc3MTYgIDIxNDI0IDE3 MjA5MiAgICAwICAgIDAgICAgIDAgMTA4MDggMzY4MSAgMzc3NSAgMCA1NiAgMCA0NAogMSAgMCAg ICAgIDAgIDU5Mzk2ICAyMTQzMiAxODAyODQgICAgMCAgICAwICAgICAwICAgICAwIDYzNTYgIDc2 NzYgIDAgMTAwICAwICAwCiAxICAwICAgICAgMCAgNTEwMTIgIDIxNDQwIDE4ODUzNiAgICAwICAg IDAgICAgIDAgICAgIDAgNjM3OSAgNzczOSAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwICA0MjYy OCAgMjE0NDggMTk2ODM2ICAgIDAgICAgMCAgICAgMCAgICAgMCA2NDY1ICA3NzcyICAwIDEwMCAg MCAgMAogMSAgMSAgICAgIDAgIDM1NDYwICAyMTUzMiAyMDMyNTYgICAgMCAgICAwICAgICAwIDMz MzM2IDQ4MzYgIDU5ODYgIDAgMTAwICAwICAwCiAxICAxICAgICAgMCAgMzIxOTYgIDIxNTM2IDIw Njg1MiAgICAwICAgIDAgICAgIDAgICAgIDAgMjE4MCAgMzQzMCAgMCAxMDAgIDAgIDAKIDEgIDAg ICAgICAwICAyNzkwOCAgMjE1NDAgMjExMjUyICAgIDAgICAgMCAgICAgMCAgIDM3NiAzMDIxICA0 MTY1ICAwIDEwMCAgMCAgMAogMSAgMCAgICAgIDAgIDE5NjUyICAyMTU0OCAyMTk0MjggICAgMCAg ICAwICAgICAwICAgICA0IDYxNTQgIDc2NjEgIDAgMTAwICAwICAwCiAxICAwICAgICAgMCAgMTE1 MjQgIDIxNTU2IDIyNzUwNCAgICAwICAgIDAgICAgIDAgICAgIDQgNjQxNiAgNzU2MyAgMCAxMDAg IDAgIDAKIDEgIDAgICAgICAwICAgMzEyOCAgMjE1NjQgMjM1NzcyICAgIDAgICAgMCAgICAgMCAg ICAgMCA2NDMyICA3NzQ2ICAxIDk5ICAwICAwCiAzICAwICAgICAgMCAgIDIzNTIgIDE3NDI4IDI0 MDk4OCAgICAwICAgIDAgICAgIDAgIDM2MDQgNTQxMSAgNTk4MiAgMCAxMDAgIDAgIDAKIDAgIDIg ICAgICAwICAgMjgxNiAgMTYwODAgMjQxMDY0ICAgIDAgICAgMCAgICAgMCAzMjg2MCA0NjQzICAz MzY0ICAwIDg1ICAwIDE1CiAyICAxICAgICAgMCAgIDI4MzIgIDE1NjA0IDI0MTk0NCAgICAwICAg IDAgICAgIDAgICAyOTIgMjA5MSAgMjU5MSAgMCA4NCAgMCAxNgogMiAgMSAgICAgIDAgICAyNjAw ICAxNDgzNiAyNDM1MDQgICAgMCAgICAwICAgICAwICAzNjQwIDMzNTggIDQxNjcgIDAgMTAwICAw ICAwCiAyICAwICAgICAgMCAgIDI4NTYgIDEzODM2IDI0NDY2NCAgICAwICAgIDAgICAgIDAgIDU3 OTYgNDM5NiAgMTkzMSAgMCAxMDAgIDAgIDAKIDAgIDEgICAgICAwICAgMjIyNCAgMTM1MzIgMjQ1 NzQwICAgIDAgICAgMCAgICAgMCAgNDIyNCAyOTcwICAyMzEyICAwIDM1ICAwIDY1CiAwICAxICAg ICAgMCAgIDMwNjAgIDEzNDA0IDI0NDgyOCAgICAwICAgIDAgICAgIDAgIDgwMjggMTY2MCAgICA1 MiAgMCAgNSAgMCA5NQpwcm9jcyAtLS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0t IC0tLS0taW8tLS0tIC0tc3lzdGVtLS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAg IGJ1ZmYgIGNhY2hlICAgc2kgICBzbyAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdh CiAyICAwICAgICAgMCAgIDI3MzYgIDEzMzgwIDI0NTcwOCAgICAwICAgIDAgICAgIDAgIDMxNDgg MzMxMCAgMjMxNyAgMCA0MiAgMCA1OAogMSAgMCAgICAgIDAgICAyODU2ICAxMjYxNiAyNDY1MDAg ICAgMCAgICAwICAgICAwICAgICAwIDY4OTIgIDU3OTIgIDAgMTAwICAwICAwCiAxICAxICAgICAg MCAgIDI3MzIgIDEyMzk2IDI0NzU0NCAgICAwICAgIDAgICAgIDAgIDI2MjQgNjI4NyAgMTEzMSAg MCAxMDAgIDAgIDAKIDEgIDEgICAgICAwICAgMjUzNiAgMTIxMDAgMjQ4MTk2ICAgIDAgICAgMCAg ICAgMCAxMTQwNCAzOTQwICAgMjUxICAwIDEwMCAgMCAgMAo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="clientlog-ftpput" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="clientlog-ftpput" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg MTk4MzEyICA3MDMzNiAyNTgyNDAgICAgMCAgICAwICAgMjk5ICAgIDg1IDE1MzYgICA3NjcgIDgg IDYgNzggIDgKIDAgIDAgICAgICAwIDE5ODIyOCAgNzAzMzYgMjU4MzA4ICAgIDAgICAgMCAgICA2 OCAgICAgMCAxNDM3ICAgNDYzICAzICAxIDk0ICAyCiAwICAwICAgICAgMCAxOTgyMjggIDcwMzM2 IDI1ODMwOCAgICAwICAgIDAgICAgIDAgICAgIDAgMjAxMyAgMTU4OSAxMSAgNiA4MyAgMAogMCAg MSAgICAgIDAgMTk2NjUyICA3MDM4OCAyNTk4MjAgICAgMCAgICAwICAxNTA2ICAgIDkyIDIzMjkg ICA1NDAgIDIgIDMgODcgIDgKIDAgIDAgICAgICAwIDE5MDI0MCAgNzAzOTIgMjY2MjA4ICAgIDAg ICAgMCAgNjQxNCAgICAgMCA2NTY3ICAgODA4ICAwIDExIDg0ICA1CiAwICAwICAgICAgMCAxODM2 MDQgIDcwNDAwIDI3Mjg2NCAgICAwICAgIDAgIDY2NjIgICAgIDAgNjYxOCAgIDgxNCAgMCAxMCA4 NCAgNgogMCAgMCAgICAgIDAgMTc5MjM2ICA3MDQwNCAyNzcyMTIgICAgMCAgICAwICA0MzU3ICAg ICAwIDUzMDMgIDEzMDUgIDYgMTAgODEgIDMKIDAgIDAgICAgICAwIDE3NTAyNCAgNzA0MDggMjgx NDI0ICAgIDAgICAgMCAgNDIyOCAgICAgMCA0NTQ1ICAgNzEyICAxICA3IDg5ICAzCiAwICAwICAg ICAgMCAxNjc4MzIgIDcwNDI4IDI4ODEzNiAgICAwICAgIDAgIDY3MTggICAgMjAgNzM2OSAgMTAy NiAgOCAxMyA3MyAgNgogMCAgMCAgICAgIDAgMTYwNDkyICA3MDQzMiAyOTQ3OTYgICAgMCAgICAw ICA2NjYzICAgICAwIDY2NDggICA5MDYgIDAgIDkgODUgIDUKIDAgIDAgICAgICAwIDE1MzIzNiAg NzA0NDAgMzAxMzg0ICAgIDAgICAgMCAgNjUzNCAgICAgMCA2NjEyICAgOTA1ICAxIDExIDgzICA1 CiAwICAwICAgICAgMCAxNDU3NDggIDcwNDQ4IDMwODEwOCAgICAwICAgIDAgIDY3OTEgICAgIDAg NjY5NiAgIDkyNiAgMSAxMSA4MSAgNwogMCAgMCAgICAgIDAgMTQyNjEyICA3MDQ0OCAzMTA5NjQg ICAgMCAgICAwICAyODE4ICAgICAwIDM0NzcgICA2NDggIDEgIDUgOTIgIDIKIDAgIDAgICAgICAw IDE0MjYxMiAgNzA0NjAgMzEwOTUyICAgIDAgICAgMCAgICAgMCAgICAyMCAxMTEyICAgNTAwICAw ICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTM1OTU2ICA3MDQ2OCAzMTY5OTYgICAgMCAgICAwICA2 MDIyICAgICAwIDYxMjkgICA4NTYgIDEgMTAgODQgIDUKIDAgIDAgICAgICAwIDEyODcyNCAgNzA0 NzIgMzIzNTIwICAgIDAgICAgMCAgNjUzNSAgICAgMCA2NjcwICAgODg4ICAxIDEzIDgwICA2CiAw ICAwICAgICAgMCAxMjEzNjQgIDcwNDgwIDMzMDE3NiAgICAwICAgIDAgIDY2NjIgICAgIDAgNjYw NiAgIDg5NCAgMCAxMSA4MyAgNgogMCAgMCAgICAgIDAgMTE0MDA0ICA3MDQ4OCAzMzY4MzIgICAg MCAgICAwICA2NjYzICAgICAwIDY2NzggICA5MjUgIDEgMTIgODEgIDYKIDAgIDAgICAgICAwIDEw NzE1NiAgNzA1MDQgMzQyOTM2ICAgIDAgICAgMCAgNjE1MCAgICAyMCA2MzYwICAgODY3ICAxIDEw IDgyICA2CiAwICAwICAgICAgMCAxMDQzNDAgIDcwNTA4IDM0NTUxNiAgICAwICAgIDAgIDI1NjIg ICAgIDAgMzIwMCAgIDY4NSAgMSAgNSA5MSAgMwogMCAgMCAgICAgIDAgMTAxMzk2ICA3MDUwOCAz NDgxNjggICAgMCAgICAwICAyNjkxICAgICAwIDMzMzggICA2NDUgIDAgIDMgOTUgIDIKcHJvY3Mg LS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAtLXN5c3Rl bS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAgIHNpICAg c28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMiAgMCAgICAgIDAgIDk0MTY0 ICA3MDUxNiAzNTQ3NTYgICAgMCAgICAwICA2NTM0ICAgICAwIDY2OTggICA5MDQgIDEgMTEgODIg IDYKIDAgIDAgICAgICAwICA4Njc0MCAgNzA1MjQgMzYxNDEyICAgIDAgICAgMCAgNjY2MyAgICAg MCA2NjY4ICAgOTM1ICA0IDEyIDc3ICA2CiAwICAwICAgICAgMCAgNzkzODAgIDcwNTQwIDM2ODA2 MCAgICAwICAgIDAgIDY2NjIgICAgMjAgNjY1MSAgIDg5NyAgMSAxMSA4MyAgNQogMCAgMCAgICAg IDAgIDcyMDIwICA3MDU0OCAzNzQ3MTYgICAgMCAgICAwICA2NjYzICAgICAwIDY2ODUgICA5MDMg IDEgMTEgODIgIDYKIDAgIDAgICAgICAwICA2NjcyMCAgNzA1NTIgMzc5Njc2ICAgIDAgICAgMCAg NDk5NyAgICAgMCA1Nzc3ICAgODcxICAyICA4IDg1ICA0CiAxICAwICAgICAgMCAgNjQxNDggIDcw NTU2IDM4MTk4NCAgICAwICAgIDAgIDIzMDYgICAgIDAgMzMwOSAgMTAzOSAgNSAgNiA4NyAgMgog MCAgMCAgICAgIDAgIDYwNzY0ICA3MDU1NiAzODUwNDQgICAgMCAgICAwICAzMDc1ICAgICAwIDQw MTMgICA2MzEgIDEgIDYgOTEgIDIKIDAgIDAgICAgICAwICA1MzQwNCAgNzA1NzYgMzkxNjg4ICAg IDAgICAgMCAgNjY2MiAgICAyMCA3MzAyICAxMzkwICA1IDE1IDc0ICA2CiAxICAwICAgICAgMCAg NDY0MTIgIDcwNTgwIDM5ODAwOCAgICAwICAgIDAgIDYyNzggICAgIDAgNjgyNCAgMTQ1OSAgNiAx NSA3NSAgNAogMCAgMCAgICAgIDAgIDQ2NDEyICA3MDU4MCAzOTgwMDggICAgMCAgICAwICAgICAw ICAgICAwIDExOTEgICA0MDAgIDEgIDEgOTggIDAKIDAgIDAgICAgICAwICA0NjQxMiAgNzA1ODAg Mzk4MDA4ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMDkxICAgMzk2ICAwICAxIDk5ICAwCiAwICAw ICAgICAgMCAgNDY0MTIgIDcwNTgwIDM5ODAwOCAgICAwICAgIDAgICAgIDAgICAgIDAgMTExMyAg IDQzNiAgMSAgMCA5OSAgMAogMCAgMCAgICAgIDAgIDQ2NDEyICA3MDU5MiAzOTc5OTYgICAgMCAg ICAwICAgICAwICAgIDIwIDExMjcgICA1NjMgIDIgIDAgOTggIDAKIDAgIDAgICAgICAwICA0NjQx MiAgNzA1OTIgMzk3OTk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMTcxICAgNjE3ICAzICAxIDk2 ICAwCiAwICAwICAgICAgMCAgNDY0MjggIDcwNTkyIDM5Nzk5NiAgICAwICAgIDAgICAgIDAgICAg IDAgMTMwMCAgIDU4MCAgMyAgMSA5NiAgMAogMCAgMCAgICAgIDAgIDQ2NDI4ICA3MDU5MiAzOTc5 OTYgICAgMCAgICAwICAgICAwICAgICAwIDEwOTcgICA0MDkgIDEgIDAgOTkgIDAKIDAgIDAgICAg ICAwICA0NjQyOCAgNzA1OTIgMzk3OTk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMjAzICAgODA0 ICA1ICAxIDk0ICAwCiAwICAwICAgICAgMCAgNDYzMDAgIDcwNjQwIDM5ODAxNiAgICAwICAgIDAg ICAgIDAgICAxMTIgMTIzNiAgMTI3MyAxMSAgMyA4NiAgMAogMCAgMCAgICAgIDAgIDQ2MzAwICA3 MDY0MCAzOTgwMTYgICAgMCAgICAwICAgICAwICAgICAwIDE1NjggIDE1NzQgMTMgIDQgODMgIDAK IDAgIDAgICAgICAwICA0NjYyMCAgNzA2NDAgMzk4MDE2ICAgIDAgICAgMCAgICAgMCAgICAgMCAy Mjk4ICAxNDM5IDEyICA2IDgyICAwCiAwICAwICAgICAgMCAgNDY2NDggIDcwNjQwIDM5ODAxNiAg ICAwICAgIDAgICAgIDAgICAgIDAgMTQwOCAgIDkwOCAgNSAgMiA5MyAgMAo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="clientlog-nfsput" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="clientlog-nfsput" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg IDE2Nzc2IDI5MjAxMiAxNjY5ODggICAgMCAgICAwICAgMjc2ICAgIDg3IDE1MjEgICA3NzAgIDgg IDYgNzggIDgKIDAgIDAgICAgICAwICAxNjc0OCAyOTIwMTIgMTY2OTg4ICAgIDAgICAgMCAgICAg MCAgICAgMCAxNDc2ICAgNDE2ICAzICAxIDk2ICAwCiAwICAwICAgICAgMCAgMTY3NDggMjkyMDEy IDE2Njk4OCAgICAwICAgIDAgICAgIDAgICAgIDAgMjY0MCAgMTU2NCAxMiAgNiA4MiAgMAogMCAg MCAgICAgIDAgIDE2NzQ4IDI5MjAxMiAxNjY5ODggICAgMCAgICAwICAgICAwICAgICAwIDExMDQg ICA0MjYgIDEgIDAgOTkgIDAKIDAgIDAgICAgICAwICAxNjc0OCAyOTIwMTIgMTY2OTg4ICAgIDAg ICAgMCAgICAgMCAgICAgMCAxMjE5ICAgNDM1ICAxICAxIDk4ICAwCiAwICAxICAgICAgMCAgMTUz NTYgMjkyMDUyIDE2ODMwOCAgICAwICAgIDAgICA3NDQgICAgODAgMTI1OSAgIDQ4OCAgMSAgMiA5 MyAgNAogMCAgMSAgICAgIDAgICA1MDM2IDI4NjU4MCAxODQ1MjQgICAgMCAgICAwICA5NDc2ICAg ICAwIDEyODQgICA2MjIgIDMgMTQgIDAgODMKIDAgIDEgICAgICAwICAgNDU4OCAyNzU2MzYgMTk4 ODY4ICAgIDAgICAgMCAgOTM0OCAgICAgMCAxMzAxICAgNjY0ICA0IDE3ICAwIDc5CiAwICAxICAg ICAgMCAgIDQ5NzIgMjY5Mzc2IDIwNjM1MiAgICAwICAgIDAgIDQ2MjUgICAgIDAgMTI2MyAgIDU2 NCAgMSAgOCAgMCA5MQogMSAgMSAgICAgIDAgICA1MjQ4IDI2NDI2OCAyMTIyMDggICAgMCAgICAw ICAzNzI1ICAgICAwIDE0OTUgICA2ODcgIDUgIDggIDAgODcKIDEgIDEgICAgICAwICAgNTI5MiAy Mzg3NjQgMjQzNzY0ICAgIDAgICAgMCAxOTM1OCAgICAxNiAyMTI5ICAxODg2IDE2IDM4ICAwIDQ3 CiAwICAxICAgICAgMCAgIDUxNjQgMjEyMzMyIDI3NDg4OCAgICAwICAgIDAgMTk2MTMgICAgIDgg MjE2MCAgMTAyMyAgNyAzNiAgMCA1NwogMCAgMSAgICAgIDAgICA1MDA4IDE5OTcxMiAyODkxNDAg ICAgMCAgICAwIDE0NzM5ICAgICAwIDM5MzggICA5MjEgIDYgMzIgIDAgNjIKIDAgIDEgICAgICAw ICAgNTM0NCAxODA5ODAgMzEyMDIwICAgIDAgICAgMCAxODU3OCAgICAgMCA4MTE2ICAxMTQ5ICA2 IDQ0ICAwIDQ5CiAwICAxICAgICAgMCAgIDQ5NjAgMTczMDQ4IDMyMjg3NiAgICAwICAgIDAgIDg4 NTIgICAgIDAgNzk4OCAgMTA4NiAgNCAyNSAgMCA3MQogMCAgMSAgICAgIDAgICA1MzYwIDE2MzY0 MCAzMzQxODggICAgMCAgICAwICA4NDc0ICAgICAwIDY1NzggIDEwMTIgIDUgMjIgIDAgNzMKIDAg IDIgICAgICAwICAgNTI4OCAxNTQ2NzYgMzQ2MjgwICAgIDAgICAgMCAgOTczMCAgICAgNCA0NDYz ICAgOTE1ICA0IDIzICAwIDcyCiAwICAyICAgICAgMCAgIDUzNDggMTQ1MTQwIDM1ODMzMiAgICAw ICAgIDAgIDc4MTIgICAgMTIgNzA1NiAgMTE2OCAgNCAyNSAgMCA3MQogMCAgMSAgICAgIDAgICA1 MzY4IDEzOTE1MiAzNjY1NjQgICAgMCAgICAwICA1MDY1ICAgICAwIDc3OTggIDEwNjIgIDMgMTgg IDAgNzkKIDAgIDEgICAgICAwICAgNTAxMiAxMzM3ODAgMzcyODIwICAgIDAgICAgMCAgMzg1NSAg ICAgMCA3ODU0ICAgOTk1ICAzIDE4ICAwIDc5CiAwICAxICAgICAgMCAgIDUwMTIgMTMwMjA4IDM3 NzAwNCAgICAwICAgIDAgIDI1NzEgICAgIDAgNzg0MSAgIDk2NyAgMyAxNCAgMCA4Mwpwcm9jcyAt LS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVt LS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBz byAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAxICAxICAgICAgMCAgIDUxMzYg MTI4MjkyIDM3OTA1NiAgICAwICAgIDAgIDExNjEgICAgIDAgNzI3MCAgMjAzOSAxMiAxNiAgMCA3 MgogMCAgMSAgICAgIDAgICA0NzYwIDEyMDY1NiAzODgzOTIgICAgMCAgICAwICA1OTA0ICAgICAw IDQwNTkgICA4MDUgIDQgMTUgIDAgODEKIDAgIDIgICAgICAwICAgNTUzNiAxMTE2ODggMzk3NDk2 ICAgIDAgICAgMCAgNTc2MiAgICAxMiA0MTk1ICAgODk5ICAzIDE1ICAwIDgyCiAxICAxICAgICAg MCAgIDU1MjggMTA4MDMyIDQwMTc2NCAgICAwICAgIDAgIDI3MjEgICAgIDQgMzYwNSAgIDg1MSAg MyAxMSAgMCA4NgogMCAgMSAgICAgIDAgICA1Mjc2IDEwMDk1MiA0MTAyMDQgICAgMCAgICAwICA1 MjQzICAgICAwIDc2NDEgIDEwNDUgIDIgMjAgIDAgNzgKIDAgIDEgICAgICAwICAgNDYzNiAgOTU1 MzIgNDE3MTg4ICAgIDAgICAgMCAgNDI4OSAgICAgMCA3NjIxICAxMDQyICAzIDE1ICAwIDgxCiAw ICAxICAgICAgMCAgIDU2MTIgIDkwODA4IDQyMTQzNiAgICAwICAgIDAgIDI3ODEgICAgIDAgNzYw OSAgMTA1MyAgMiAxNCAgMCA4NAogMCAgMSAgICAgIDAgICA1Mjc2ICA4MDcyNCA0MzM2OTYgICAg MCAgICAwICA3MjU2ICAgICA0IDc3NDggIDEwOTMgIDMgMjIgIDAgNzQKIDAgIDAgICAgICAwICAg NDkwOCAgNjk4NzIgNDQ2MDQ0ICAgIDAgICAgMCAgNzUzMyAgICAyMCA1MDc0ICAgOTQ4ICA0IDE3 IDYxIDE3CiAwICAwICAgICAgMCAgIDQ5MDggIDY5ODcyIDQ0NjA0NCAgICAwICAgIDAgICAgIDAg ICAgIDAgMzgwMyAgIDYxMCAgMCAgMyA5NyAgMAogMCAgMCAgICAgIDAgICA0OTA4ICA2OTg3MiA0 NDYwNDQgICAgMCAgICAwICAgICAwICAgICAwIDUwNjQgICA3MTMgIDEgIDMgOTYgIDAKIDAgIDAg ICAgICAwICAgNDk3MiAgNjk4NzIgNDQ2MDQ0ICAgIDAgICAgMCAgICAgMCAgICAgMCA2OTc4ICAg ODY0ICAwICA4IDkyICAwCiAwICAwICAgICAgMCAgIDUxNjQgIDY5ODcyIDQ0NjA0NCAgICAwICAg IDAgICAgIDAgICAgIDAgNzQ5MyAgIDkxNCAgMCAgNiA5NCAgMAogMCAgMCAgICAgIDAgICA1MTY0 ICA2OTg4NCA0NDYwMzIgICAgMCAgICAwICAgICAwICAgIDIwIDEyMDcgICA0MTkgIDEgIDEgOTgg IDAKIDAgIDAgICAgICAwICAgNjM4MCAgNjk4ODQgNDQ2MDMyICAgIDAgICAgMCAgICAgMCAgICAg MCA0OTkyICAgNzEyICAwICA2IDk0ICAwCiAwICAwICAgICAgMCAgIDY1MDggIDY5ODg0IDQ0NjAz MiAgICAwICAgIDAgICAgIDAgICAgIDAgNzM5NCAgIDkxNSAgMCAgNSA5NSAgMAogMCAgMCAgICAg IDAgICA2NTcyICA2OTg4NCA0NDYwMzIgICAgMCAgICAwICAgICAwICAgICAwIDM4NTggICA2MTkg IDEgIDUgOTQgIDAKIDAgIDAgICAgICAwICAgNjYzNiAgNjk4ODQgNDQ2MTAwICAgIDAgICAgMCAg ICAxMiAgICAgMCA1NzAwICAgODIwICAxICA0IDk0ICAxCiAwICAwICAgICAgMCAgIDc2MDAgIDY5 OTI4IDQ0NjA1NiAgICAwICAgIDAgICAgIDAgICAxMDQgNTg2MCAgIDc4MyAgMSAgNyA5MiAgMAog MCAgMCAgICAgIDAgICA4MTE2ICA2OTkyOCA0NDYwNTYgICAgMCAgICAwICAgICAwICAgICAwIDU0 ODkgICA3NjIgIDMgIDYgOTEgIDAKIDAgIDAgICAgICAwICAgODQ0MCAgNjk5MjggNDQ2MDU2ICAg IDAgICAgMCAgICAgMCAgICAgMCA2MDIwICAgODUyICAxICA2IDkzICAwCnByb2NzIC0tLS0tLS0t LS0tbWVtb3J5LS0tLS0tLS0tLSAtLS1zd2FwLS0gLS0tLS1pby0tLS0gLS1zeXN0ZW0tLSAtLS0t Y3B1LS0tLQogciAgYiAgIHN3cGQgICBmcmVlICAgYnVmZiAgY2FjaGUgICBzaSAgIHNvICAgIGJp ICAgIGJvICAgaW4gICAgY3MgdXMgc3kgaWQgd2EKIDEgIDAgICAgICAwICAgODU2OCAgNjk5Mjgg NDQ2MDU2ICAgIDAgICAgMCAgICAgMCAgICAgMCA1NDMzICAgODIyICAxICA1IDk0ICAwCiAwICAw ICAgICAgMCAgMTA0ODggIDY5OTQ0IDQ0NjA0MCAgICAwICAgIDAgICAgIDcgICAgIDAgMjA5OSAg IDcyOCAgNCAgNiA4NiAgNAogMCAgMCAgICAgIDAgIDEwNDgwICA2OTk1NiA0NDYwOTYgICAgMCAg ICAwICAgICAwICAgIDIwIDEyMjQgICA5NTIgIDQgIDEgOTUgIDAKIDAgIDAgICAgICAwICAxMDQ4 MCAgNjk5NTYgNDQ2MDk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMjgzICAgNDY1ICAyICAxIDk3 ICAwCiAwICAwICAgICAgMCAxOTkyNTIgIDY5OTU2IDI1NzYwMCAgICAwICAgIDAgICAgIDAgICAg IDAgMTc3OSAgMTMwMCAgOSAgNyA4NCAgMAogMCAgMCAgICAgIDAgMTk5MjUyICA2OTk1NiAyNTc2 MDAgICAgMCAgICAwICAgICAwICAgICAwIDE0NDUgIDEyMDUgMTkgIDQgNzcgIDAK ------=_Part_60_22762740.1091387012317-- From jgarzik@pobox.com Sun Aug 1 12:03:48 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:03:53 -0700 (PDT) Received: from www.linux.org.uk (IDENT:93@parcelfarce.linux.theplanet.co.uk [195.92.249.252]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71J3jMr030684 for ; Sun, 1 Aug 2004 12:03:48 -0700 Received: from rdu74-153-143.nc.rr.com ([24.74.153.143] helo=pobox.com) by www.linux.org.uk with asmtp (TLSv1:AES256-SHA:256) (Exim 4.33) id 1BrLcR-0005Pa-LB; Sun, 01 Aug 2004 20:03:39 +0100 Message-ID: <410D3E77.4090303@pobox.com> Date: Sun, 01 Aug 2004 15:03:19 -0400 From: Jeff Garzik User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Chris Wright CC: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH] ethtool_get_regs copy right number of bytes to user References: <20040615155541.Q21045@build.pdx.osdl.net> In-Reply-To: <20040615155541.Q21045@build.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7395 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jgarzik@pobox.com Precedence: bulk X-list: netdev applied From manfred@colorfullife.com Sun Aug 1 12:13:25 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:13:30 -0700 (PDT) Received: from dbl.q-ag.de (dbl.q-ag.de [213.172.117.3] (may be forged)) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71JDNut031783 for ; Sun, 1 Aug 2004 12:13:24 -0700 Received: from colorfullife.com (dbl [127.0.0.1]) by dbl.q-ag.de (8.12.3/8.12.3/Debian-6.6) with ESMTP id i71JCbuG024874; Sun, 1 Aug 2004 21:12:39 +0200 Message-ID: <410D4120.2020604@colorfullife.com> Date: Sun, 01 Aug 2004 21:14:40 +0200 From: Manfred Spraul User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: James Drabb CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> In-Reply-To: <410D3377.3030505@tampabay.rr.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7396 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: manfred@colorfullife.com Precedence: bulk X-list: netdev James Drabb wrote: > jim@keelie $ uname -a > Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 > GNU/Linux There should be a message in the dmesg log about the driver version: If it's less than 0.28: could you try a newer kernel? 0.28 is definitively in 2.5.8-rc1-mm1 and later. I could also send you just the forcedeth.c file, then you don't have to upgrade the whole kernel. > However, if I reboot into WinXP, and then reboot right away back into > FC2, the forcedeth driver works like a champ. Probably the phy reset and/or the media detection do not work properly. That part is completely rewritten in 0.28. I'm interested in two infos: - with 2.6.7 (probably version 0.25), after booting into winXP first: what does # ethtool eth0 report? Then unplug the network cable. Run ethtool again. Does it report "Link detected: No"? What if you plug the network cable back in? - The same thing with the 0.28 driver. Note that the phy initialization in 0.28 is not perfect either: it seems there is a race between the phy reset and the media detection. You might have to wait 2 seconds or so between modprobe and ifup. -- Manfred From JDrabb@tampabay.rr.com Sun Aug 1 15:00:47 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 15:00:54 -0700 (PDT) Received: from ms-smtp-04.tampabay.rr.com (ms-smtp-04-smtplb.tampabay.rr.com [65.32.5.134]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71M0kjG005473 for ; Sun, 1 Aug 2004 15:00:47 -0700 Received: from [192.168.1.101] (189-66.35-65.tampabay.rr.com [65.35.66.189]) by ms-smtp-04.tampabay.rr.com (8.12.10/8.12.7) with ESMTP id i71M0Z7t029887; Sun, 1 Aug 2004 18:00:35 -0400 (EDT) Message-ID: <410D682F.4090809@tampabay.rr.com> Date: Sun, 01 Aug 2004 18:01:19 -0400 From: James Drabb User-Agent: Mozilla Thunderbird 0.7.1 (X11/20040626) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Manfred Spraul CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> <410D4120.2020604@colorfullife.com> In-Reply-To: <410D4120.2020604@colorfullife.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Symantec AntiVirus Scan Engine X-archive-position: 7397 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: JDrabb@tampabay.rr.com Precedence: bulk X-list: netdev Manfred Spraul wrote: > James Drabb wrote: > >> jim@keelie $ uname -a >> Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 >> GNU/Linux > > > There should be a message in the dmesg log about the driver version: If > it's less than 0.28: could you try a newer kernel? 0.28 is definitively > in 2.5.8-rc1-mm1 and later. I could also send you just the forcedeth.c > file, then you don't have to upgrade the whole kernel. dmesg shows version 0.25. > Probably the phy reset and/or the media detection do not work properly. > That part is completely rewritten in 0.28. > > I'm interested in two infos: > - with 2.6.7 (probably version 0.25), after booting into winXP first: > what does > # ethtool eth0 > report? Then unplug the network cable. Run ethtool again. Does it report > "Link detected: No"? What if you plug the network cable back in? ethtool eth0 shows: Settings for eth0: Supports Wake-on: g Wake-on: d Link detected: yes Unplugging the network cable showed the same settings: Settings for eth0: Supports Wake-on: g Wake-on: d Link detected: yes > -- > Manfred Please send me the latest forcedeth.c and I will give it a go. Do you have the makefile so I can compile the module outside of the kernel? Thanks, Jim Drabb -- James Drabb Senior Programmer Davenport, FL USA From laforge@netfilter.org Sun Aug 1 16:03:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 16:04:03 -0700 (PDT) Received: from ganesha.gnumonks.org (Debian-exim@ganesha.gnumonks.org [213.95.27.120]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71N3reK007511 for ; Sun, 1 Aug 2004 16:03:55 -0700 Received: from dsl-082-083-225-237.arcor-ip.net ([82.83.225.237] helo=sunbeam.gnumonks.org) by ganesha.gnumonks.org with asmtp (TLSv1:RC4-SHA:128) (Exim 4.30) id 1BrPMl-00027N-JB; Mon, 02 Aug 2004 01:03:43 +0200 Received: from laforge by sunbeam.gnumonks.org with local (Exim 4.34) id 1BrPMg-00050K-Ab; Mon, 02 Aug 2004 01:03:38 +0200 Date: Mon, 2 Aug 2004 01:03:38 +0200 From: Harald Welte To: David Miller Cc: Netfilter Development Mailinglist , netdev@oss.sgi.com, immidi_kiran@yahoo.com Subject: [PATCH 2.6] NETFILTER: new ip_conntrack_sctp Message-ID: <20040801230338.GE18758@sunbeam2> Mail-Followup-To: Harald Welte , David Miller , Netfilter Development Mailinglist , netdev@oss.sgi.com, immidi_kiran@yahoo.com Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="6e7ZaeXHKrTJCxdu" Content-Disposition: inline User-Agent: Mutt/1.5.6+20040523i X-archive-position: 7398 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: laforge@netfilter.org Precedence: bulk X-list: netdev --6e7ZaeXHKrTJCxdu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Dave! Incremental to all other patches so far, there is also the new SCTP conntrack helper by Kiran Kumar. Please apply for 2.6.9 ++, thanks. Signed-off-by: Kiran Kumar Immidi Signed-off-by: Harald Welte Please apply, thanks. diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.8-rc2-nf= quilt-nfp/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack.h 200= 4-08-02 00:51:27.793033003 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack.h= 2004-08-02 00:52:49.107882646 +0200 @@ -51,10 +51,12 @@ =20 #include #include +#include =20 /* per conntrack: protocol private data */ union ip_conntrack_proto { /* insert conntrack proto private data here */ + struct ip_ct_sctp sctp; struct ip_ct_tcp tcp; struct ip_ct_icmp icmp; }; diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_sctp.h linux-2.6.8-r= c2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_sctp.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_sctp.= h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_s= ctp.h 2004-08-02 00:52:49.088883383 +0200 @@ -0,0 +1,25 @@ +#ifndef _IP_CONNTRACK_SCTP_H +#define _IP_CONNTRACK_SCTP_H +/* SCTP tracking. */ + +enum sctp_conntrack { + SCTP_CONNTRACK_NONE, + SCTP_CONNTRACK_CLOSED, + SCTP_CONNTRACK_COOKIE_WAIT, + SCTP_CONNTRACK_COOKIE_ECHOED, + SCTP_CONNTRACK_ESTABLISHED, + SCTP_CONNTRACK_SHUTDOWN_SENT, + SCTP_CONNTRACK_SHUTDOWN_RECD, + SCTP_CONNTRACK_SHUTDOWN_ACK_SENT, + SCTP_CONNTRACK_MAX +}; + +struct ip_ct_sctp +{ + enum sctp_conntrack state; + + u_int32_t vtag[IP_CT_DIR_MAX]; + u_int32_t ttag[IP_CT_DIR_MAX]; +}; + +#endif /* _IP_CONNTRACK_SCTP_H */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.6.8-= rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_tuple.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_tuple= =2Eh 2004-06-16 07:19:43.000000000 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_t= uple.h 2004-08-02 00:52:49.143881251 +0200 @@ -25,6 +25,9 @@ struct { u_int16_t id; } icmp; + struct { + u_int16_t port; + } sctp; }; =20 /* The manipulable part of the tuple. */ @@ -55,6 +58,9 @@ struct { u_int8_t type, code; } icmp; + struct { + u_int16_t port; + } sctp; } u; =20 /* The protocol. */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/sysctl.h linux-2.6.8-rc2-nfquilt-nfp/include/lin= ux/sysctl.h --- linux-2.6.8-rc2-nfquilt/include/linux/sysctl.h 2004-08-01 23:52:00.0215= 86979 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/sysctl.h 2004-08-02 00:52:49.= 146881135 +0200 @@ -410,6 +410,13 @@ NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=3D12, NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=3D13, NET_IPV4_NF_CONNTRACK_BUCKETS=3D14, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=3D15, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=3D16, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=3D17, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=3D18, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=3D19, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=3D20, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=3D21, }; =20 /* /proc/sys/net/ipv6 */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/Kconfig linux-2.6.8-rc2-nfquilt-nfp/net/ipv= 4/netfilter/Kconfig --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/Kconfig 2004-08-02 00:51:27.= 223055074 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/Kconfig 2004-08-02 00:52= :49.115882336 +0200 @@ -636,5 +636,9 @@ tristate 'SCTP protocol match support' depends on IP_NF_IPTABLES =20 +config IP_NF_CT_PROTO_SCTP + tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' + depends on IP_NF_CONNTRACK && EXPERIMENTAL + endmenu =20 diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/Makefile linux-2.6.8-rc2-nfquilt-nfp/net/ip= v4/netfilter/Makefile --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/Makefile 2004-08-02 00:51:27= =2E224055035 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/Makefile 2004-08-02 00:5= 2:49.117882259 +0200 @@ -19,6 +19,9 @@ # connection tracking obj-$(CONFIG_IP_NF_CONNTRACK) +=3D ip_conntrack.o =20 +# SCTP protocol connection tracking +obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) +=3D ip_conntrack_proto_sctp.o + # connection tracking helpers obj-$(CONFIG_IP_NF_AMANDA) +=3D ip_conntrack_amanda.o obj-$(CONFIG_IP_NF_TFTP) +=3D ip_conntrack_tftp.o diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.8-rc2-n= fquilt-nfp/net/ipv4/netfilter/ip_conntrack_proto_sctp.c --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 19= 70-01-01 01:00:00.000000000 +0100 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/ip_conntrack_proto_sctp.= c 2004-08-02 00:52:49.098882995 +0200 @@ -0,0 +1,650 @@ +/* + * Connection tracking protocol helper module for SCTP. + *=20 + * SCTP is defined in RFC 2960. References to various sections in this cod= e=20 + * are to this RFC. + *=20 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Added support for proc manipulation of timeouts. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__) +#else +#define DEBUGP(format, args...) +#endif + +/* Protects conntrack->proto.sctp */ +static DECLARE_RWLOCK(sctp_lock); + +/* FIXME: Examine ipfilter's timeouts and conntrack transitions more + closely. They're more complex. --RR=20 + + And so for me for SCTP :D -Kiran */ + +static const char *sctp_conntrack_names[] =3D { + "NONE", + "CLOSED", + "COOKIE_WAIT", + "COOKIE_ECHOED", + "ESTABLISHED", + "SHUTDOWN_SENT", + "SHUTDOWN_RECD", + "SHUTDOWN_ACK_SENT", +}; + +#define SECS * HZ +#define MINS * 60 SECS +#define HOURS * 60 MINS +#define DAYS * 24 HOURS + +unsigned long ip_ct_sctp_timeout_closed =3D 10 SECS; +unsigned long ip_ct_sctp_timeout_cookie_wait =3D 3 SECS; +unsigned long ip_ct_sctp_timeout_cookie_echoed =3D 3 SECS; +unsigned long ip_ct_sctp_timeout_established =3D 5 DAYS; +unsigned long ip_ct_sctp_timeout_shutdown_sent =3D 300 SECS / 1000; +unsigned long ip_ct_sctp_timeout_shutdown_recd =3D 300 SECS / 1000; +unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =3D 3 SECS; + +static unsigned long * sctp_timeouts[] +=3D { 0, /* SCTP_CONNTRACK_NONE */ + &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */ + &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */ + &ip_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED= */ + &ip_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */ + &ip_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT= */ + &ip_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD= */ + &ip_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_= SENT */ + }; + +#define sNO SCTP_CONNTRACK_NONE +#define sCL SCTP_CONNTRACK_CLOSED +#define sCW SCTP_CONNTRACK_COOKIE_WAIT +#define sCE SCTP_CONNTRACK_COOKIE_ECHOED +#define sES SCTP_CONNTRACK_ESTABLISHED +#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT +#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD +#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT +#define sIV SCTP_CONNTRACK_MAX + +/*=20 + These are the descriptions of the states: + +NOTE: These state names are tantalizingly similar to the states of an=20 +SCTP endpoint. But the interpretation of the states is a little different, +considering that these are the states of the connection and not of an end= =20 +point. Please note the subtleties. -Kiran + +NONE - Nothing so far. +COOKIE WAIT - We have seen an INIT chunk in the original direction, = or also=20 + an INIT_ACK chunk in the reply direction. +COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direc= tion. +ESTABLISHED - We have seen a COOKIE_ACK in the reply direction. +SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original directio= n. +SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin. +SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opp= osite + to that of the SHUTDOWN chunk. +CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the directio= n of=20 + the SHUTDOWN chunk. Connection is closed. +*/ + +/* TODO + - I have assumed that the first INIT is in the original direction.=20 + This messes things when an INIT comes in the reply direction in CLOSED + state. + - Check the error type in the reply dir before transitioning from=20 +cookie echoed to closed. + - Sec 5.2.4 of RFC 2960 + - Multi Homing support. +*/ + +/* SCTP conntrack state transitions */ +static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] =3D { + { +/* ORIGINAL */ +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ +/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA}, +/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA}, +/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, +/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA}, +/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA}, +/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have S= tale cookie*/ +/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big= TODO */ +/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come i= n orig dir */ +/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL} + }, + { +/* REPLY */ +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ +/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL= Big TODO */ +/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA}, +/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, +/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA}, +/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA}, +/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA}, +/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come i= n reply dir */ +/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA}, +/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL} + } +}; + +static int sctp_pkt_to_tuple(const struct sk_buff *skb, + unsigned int dataoff, + struct ip_conntrack_tuple *tuple) +{ + sctp_sctphdr_t hdr; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + /* Actually only need first 8 bytes. */ + if (skb_copy_bits(skb, dataoff, &hdr, 8) !=3D 0) + return 0; + + tuple->src.u.sctp.port =3D hdr.source; + tuple->dst.u.sctp.port =3D hdr.dest; + + return 1; +} + +static int sctp_invert_tuple(struct ip_conntrack_tuple *tuple, + const struct ip_conntrack_tuple *orig) +{ + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + tuple->src.u.sctp.port =3D orig->dst.u.sctp.port; + tuple->dst.u.sctp.port =3D orig->src.u.sctp.port; + return 1; +} + +/* Print out the per-protocol part of the tuple. */ +static unsigned int sctp_print_tuple(char *buffer, + const struct ip_conntrack_tuple *tuple) +{ + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + return sprintf(buffer, "sport=3D%hu dport=3D%hu ", + ntohs(tuple->src.u.sctp.port), + ntohs(tuple->dst.u.sctp.port)); +} + +/* Print out the private part of the conntrack. */ +static unsigned int sctp_print_conntrack(char *buffer, + const struct ip_conntrack *conntrack) +{ + enum sctp_conntrack state; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + READ_LOCK(&sctp_lock); + state =3D conntrack->proto.sctp.state; + READ_UNLOCK(&sctp_lock); + + return sprintf(buffer, "%s ", sctp_conntrack_names[state]); +} + +#define for_each_sctp_chunk(skb, sch, offset, count) \ +for (offset =3D skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count =3D = 0; \ + offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \ + offset +=3D (htons(sch.length) + 3) & ~3, count++) + +/* Some validity checks to make sure the chunks are fine */ +static int do_basic_checks(struct ip_conntrack *conntrack, + const struct sk_buff *skb, + char *map) +{ + u_int32_t offset, count; + sctp_chunkhdr_t sch; + int flag; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + flag =3D 0; + + for_each_sctp_chunk (skb, sch, offset, count) { + DEBUGP("Chunk Num: %d Type: %d\n", count, sch.type); + + if (sch.type =3D=3D SCTP_CID_INIT=20 + || sch.type =3D=3D SCTP_CID_INIT_ACK + || sch.type =3D=3D SCTP_CID_SHUTDOWN_COMPLETE) { + flag =3D 1; + } + + /* Cookie Ack/Echo chunks not the first OR=20 + Init / Init Ack / Shutdown compl chunks not the only chunks */ + if ((sch.type =3D=3D SCTP_CID_COOKIE_ACK=20 + || sch.type =3D=3D SCTP_CID_COOKIE_ECHO + || flag) + && count !=3D0 ) { + DEBUGP("Basic checks failed\n"); + return 1; + } + + if (map) { + set_bit (sch.type, (void *)map); + } + } + + DEBUGP("Basic checks passed\n"); + return 0; +} + +static int new_state(enum ip_conntrack_dir dir, + enum sctp_conntrack cur_state, + int chunk_type) +{ + int i; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + DEBUGP("Chunk type: %d\n", chunk_type); + + switch (chunk_type) { + case SCTP_CID_INIT:=20 + DEBUGP("SCTP_CID_INIT\n"); + i =3D 0; break; + case SCTP_CID_INIT_ACK:=20 + DEBUGP("SCTP_CID_INIT_ACK\n"); + i =3D 1; break; + case SCTP_CID_ABORT:=20 + DEBUGP("SCTP_CID_ABORT\n"); + i =3D 2; break; + case SCTP_CID_SHUTDOWN:=20 + DEBUGP("SCTP_CID_SHUTDOWN\n"); + i =3D 3; break; + case SCTP_CID_SHUTDOWN_ACK:=20 + DEBUGP("SCTP_CID_SHUTDOWN_ACK\n"); + i =3D 4; break; + case SCTP_CID_ERROR:=20 + DEBUGP("SCTP_CID_ERROR\n"); + i =3D 5; break; + case SCTP_CID_COOKIE_ECHO:=20 + DEBUGP("SCTP_CID_COOKIE_ECHO\n"); + i =3D 6; break; + case SCTP_CID_COOKIE_ACK:=20 + DEBUGP("SCTP_CID_COOKIE_ACK\n"); + i =3D 7; break; + case SCTP_CID_SHUTDOWN_COMPLETE:=20 + DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n"); + i =3D 8; break; + default: + /* Other chunks like DATA, SACK, HEARTBEAT and + its ACK do not cause a change in state */ + DEBUGP("Unknown chunk type, Will stay in %s\n",=20 + sctp_conntrack_names[cur_state]); + return cur_state; + } + + DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",=20 + dir, sctp_conntrack_names[cur_state], chunk_type, + sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]); + + return sctp_conntracks[dir][i][cur_state]; +} + +/* Returns verdict for packet, or -1 for invalid. */ +static int sctp_packet(struct ip_conntrack *conntrack, + const struct sk_buff *skb, + enum ip_conntrack_info ctinfo) +{ + enum sctp_conntrack newconntrack, oldsctpstate; + sctp_sctphdr_t sctph; + sctp_chunkhdr_t sch; + u_int32_t offset, count; + char map[256 / sizeof (char)] =3D {0}; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) !=3D = 0) + return -1; + + if (do_basic_checks(conntrack, skb, map) !=3D 0) + return -1; + + /* Check the verification tag (Sec 8.5) */ + if (!test_bit(SCTP_CID_INIT, (void *)map) + && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map) + && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map) + && !test_bit(SCTP_CID_ABORT, (void *)map) + && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map) + && (sctph.vtag !=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { + DEBUGP("Verification tag check failed\n"); + return -1; + } + + oldsctpstate =3D newconntrack =3D SCTP_CONNTRACK_MAX; + for_each_sctp_chunk (skb, sch, offset, count) { + WRITE_LOCK(&sctp_lock); + + /* Special cases of Verification tag check (Sec 8.5.1) */ + if (sch.type =3D=3D SCTP_CID_INIT) { + /* Sec 8.5.1 (A) */ + if (sctph.vtag !=3D 0) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_ABORT) { + /* Sec 8.5.1 (B) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) + && !(sctph.vtag =3D=3D conntrack->proto.sctp.vtag + [1 - CTINFO2DIR(ctinfo)])) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_SHUTDOWN_COMPLETE) { + /* Sec 8.5.1 (C) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) + && !(sctph.vtag =3D=3D conntrack->proto.sctp.vtag + [1 - CTINFO2DIR(ctinfo)]=20 + && (sch.flags & 1))) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_COOKIE_ECHO) { + /* Sec 8.5.1 (D) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])= ) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } + + oldsctpstate =3D conntrack->proto.sctp.state; + newconntrack =3D new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch.type); + + /* Invalid */ + if (newconntrack =3D=3D SCTP_CONNTRACK_MAX) { + DEBUGP("ip_conntrack_sctp: Invalid dir=3D%i ctype=3D%u conntrack=3D%u\n= ", + CTINFO2DIR(ctinfo), sch.type, oldsctpstate); + WRITE_UNLOCK(&sctp_lock); + return -1; + } + + /* If it is an INIT or an INIT ACK note down the vtag */ + if (sch.type =3D=3D SCTP_CID_INIT=20 + || sch.type =3D=3D SCTP_CID_INIT_ACK) { + sctp_inithdr_t inithdr; + + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t), + &inithdr, sizeof(inithdr)) !=3D 0) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + DEBUGP("Setting vtag %x for dir %d\n",=20 + inithdr.init_tag, CTINFO2DIR(ctinfo)); + conntrack->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =3D inithdr.init_tag; + } + + conntrack->proto.sctp.state =3D newconntrack; + WRITE_UNLOCK(&sctp_lock); + } + + ip_ct_refresh(conntrack, *sctp_timeouts[newconntrack]); + + if (oldsctpstate =3D=3D SCTP_CONNTRACK_COOKIE_ECHOED + && CTINFO2DIR(ctinfo) =3D=3D IP_CT_DIR_REPLY + && newconntrack =3D=3D SCTP_CONNTRACK_ESTABLISHED) { + DEBUGP("Setting assured bit\n"); + set_bit(IPS_ASSURED_BIT, &conntrack->status); + } + + return NF_ACCEPT; +} + +/* Called when a new connection for this protocol found. */ +static int sctp_new(struct ip_conntrack *conntrack,=20 + const struct sk_buff *skb) +{ + enum sctp_conntrack newconntrack; + sctp_sctphdr_t sctph; + sctp_chunkhdr_t sch; + u_int32_t offset, count; + char map[256 / sizeof (char)] =3D {0}; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) !=3D = 0) + return -1; + + if (do_basic_checks(conntrack, skb, map) !=3D 0) + return -1; + + /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ + if ((test_bit (SCTP_CID_ABORT, (void *)map)) + || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)) + || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) { + return -1; + } + + newconntrack =3D SCTP_CONNTRACK_MAX; + for_each_sctp_chunk (skb, sch, offset, count) { + /* Don't need lock here: this conntrack not in circulation yet */ + newconntrack =3D new_state (IP_CT_DIR_ORIGINAL,=20 + SCTP_CONNTRACK_NONE, sch.type); + + /* Invalid: delete conntrack */ + if (newconntrack =3D=3D SCTP_CONNTRACK_MAX) { + DEBUGP("ip_conntrack_sctp: invalid new deleting.\n"); + return 0; + } + + /* Copy the vtag into the state info */ + if (sch.type =3D=3D SCTP_CID_INIT) { + if (sctph.vtag =3D=3D 0) { + sctp_inithdr_t inithdr; + + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t),=20 + &inithdr, sizeof(inithdr)) !=3D 0) { + return -1; + } + + DEBUGP("Setting vtag %x for new conn\n",=20 + inithdr.init_tag); + + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =3D=20 + inithdr.init_tag; + } else { + /* Sec 8.5.1 (A) */ + return -1; + } + } + /* If it is a shutdown ack OOTB packet, we expect a return + shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ + else { + DEBUGP("Setting vtag %x for new conn OOTB\n",=20 + sctph.vtag); + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =3D sctph.vtag; + } + + conntrack->proto.sctp.state =3D newconntrack; + } + + return 1; +} + +static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp, + const struct sk_buff *skb) +{ + /* To be implemented */ + return 0; +} + +struct ip_conntrack_protocol ip_conntrack_protocol_sctp =3D {=20 + .list =3D { NULL, NULL },=20 + .proto =3D IPPROTO_SCTP,=20 + .name =3D "sctp", + .pkt_to_tuple =3D sctp_pkt_to_tuple,=20 + .invert_tuple =3D sctp_invert_tuple,=20 + .print_tuple =3D sctp_print_tuple,=20 + .print_conntrack =3D sctp_print_conntrack, + .packet =3D sctp_packet,=20 + .new =3D sctp_new,=20 + .destroy =3D NULL,=20 + .exp_matches_pkt =3D sctp_exp_matches_pkt,=20 + .me =3D THIS_MODULE=20 +}; + +#ifdef CONFIG_SYSCTL +static ctl_table ip_ct_sysctl_table[] =3D { + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, + .procname =3D "ip_conntrack_sctp_timeout_closed", + .data =3D &ip_ct_sctp_timeout_closed, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, + .procname =3D "ip_conntrack_sctp_timeout_cookie_wait", + .data =3D &ip_ct_sctp_timeout_cookie_wait, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, + .procname =3D "ip_conntrack_sctp_timeout_cookie_echoed", + .data =3D &ip_ct_sctp_timeout_cookie_echoed, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, + .procname =3D "ip_conntrack_sctp_timeout_established", + .data =3D &ip_ct_sctp_timeout_established, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_sent", + .data =3D &ip_ct_sctp_timeout_shutdown_sent, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_recd", + .data =3D &ip_ct_sctp_timeout_shutdown_recd, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_ack_sent", + .data =3D &ip_ct_sctp_timeout_shutdown_ack_sent, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_netfilter_table[] =3D { + { + .ctl_name =3D NET_IPV4_NETFILTER, + .procname =3D "netfilter", + .mode =3D 0555, + .child =3D ip_ct_sysctl_table, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_ipv4_table[] =3D { + { + .ctl_name =3D NET_IPV4, + .procname =3D "ipv4", + .mode =3D 0555, + .child =3D ip_ct_netfilter_table, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_net_table[] =3D { + { + .ctl_name =3D CTL_NET, + .procname =3D "net", + .mode =3D 0555,=20 + .child =3D ip_ct_ipv4_table, + }, + { .ctl_name =3D 0 } +}; + +static struct ctl_table_header *ip_ct_sysctl_header; +#endif + +int __init init(void) +{ + int ret; + + ret =3D ip_conntrack_protocol_register(&ip_conntrack_protocol_sctp); + if (ret) { + printk("ip_conntrack_proto_sctp: protocol register failed\n"); + goto out; + } + +#ifdef CONFIG_SYSCTL + ip_ct_sysctl_header =3D register_sysctl_table(ip_ct_net_table, 0); + if (ip_ct_sysctl_header =3D=3D NULL) { + printk("ip_conntrack_proto_sctp: can't register to sysctl.\n"); + goto cleanup; + } +#endif + + return ret; + + cleanup: +#ifdef CONFIG_SYSCTL + ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); +#endif + out: + DEBUGP("SCTP conntrack module loading %s\n",=20 + ret ? "failed": "succeeded"); + return ret; +} + +void __exit fini(void) +{ + ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); +#ifdef CONFIG_SYSCTL + unregister_sysctl_table(ip_ct_sysctl_header); +#endif + DEBUGP("SCTP conntrack module unloaded\n"); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kiran Kumar Immidi"); +MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP= "); --=20 - Harald Welte http://www.netfilter.org/ =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D "Fragmentation is like classful addressing -- an interesting early architectural error that shows how much experimentation was going on while IP was being designed." -- Paul Vixie --6e7ZaeXHKrTJCxdu Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFBDXbKXaXGVTD0i/8RAuE0AKCpndyX/rb5mdL8ryi/8ZIk8a8V4gCfWeme AXWAfdrWrFUBmvMdhd9nWIY= =w/3I -----END PGP SIGNATURE----- --6e7ZaeXHKrTJCxdu-- From davem@redhat.com Sun Aug 1 19:23:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:23:07 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722MxAj014040 for ; Sun, 1 Aug 2004 19:23:02 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722Lle1017554; Sun, 1 Aug 2004 22:21:47 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722Lla12942; Sun, 1 Aug 2004 22:21:47 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722L3XV020332; Sun, 1 Aug 2004 22:21:04 -0400 Date: Sun, 1 Aug 2004 19:20:41 -0700 From: "David S. Miller" To: Adrian Bunk Cc: marcelo.tosatti@cyclades.com, shemminger@osdl.org, linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: Re: [2.4 patch] CONFIG_NET_SCH_NETEM Configure.help entry Message-Id: <20040801192041.48bbc395.davem@redhat.com> In-Reply-To: <20040801142759.GQ2746@fs.tum.de> References: <20040731142658.GA6497@logos.cnet> <20040801142759.GQ2746@fs.tum.de> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7399 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Applied, thanks Adrian. From davem@redhat.com Sun Aug 1 19:23:40 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:23:46 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722NdHk014131 for ; Sun, 1 Aug 2004 19:23:39 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722MWe1017665; Sun, 1 Aug 2004 22:22:32 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722MWa13003; Sun, 1 Aug 2004 22:22:32 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722LmUX020510; Sun, 1 Aug 2004 22:21:49 -0400 Date: Sun, 1 Aug 2004 19:21:26 -0700 From: "David S. Miller" To: Adrian Bunk Cc: shemminger@osdl.org, linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: Re: [2.6 patch] update NET_SCH_NETEM help text Message-Id: <20040801192126.064ad0ac.davem@redhat.com> In-Reply-To: <20040801143307.GR2746@fs.tum.de> References: <20040801143307.GR2746@fs.tum.de> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7400 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Sun, 1 Aug 2004 16:33:07 +0200 Adrian Bunk wrote: > The patch below contains the following changes for the NET_SCH_NETEM > help text: > - correct the module name > - "If unsure, say N." Also applied, thanks. From davem@redhat.com Sun Aug 1 19:29:23 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:29:31 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722TNCa014826 for ; Sun, 1 Aug 2004 19:29:23 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722TEe1019278; Sun, 1 Aug 2004 22:29:14 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722TEa14187; Sun, 1 Aug 2004 22:29:14 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722SVQB023174; Sun, 1 Aug 2004 22:28:31 -0400 Date: Sun, 1 Aug 2004 19:28:09 -0700 From: "David S. Miller" To: Harald Welte Cc: netfilter-devel@lists.netfilter.org, netdev@oss.sgi.com, immidi_kiran@yahoo.com Subject: Re: [PATCH 2.6] NETFILTER: new ip_conntrack_sctp Message-Id: <20040801192809.5ab29c25.davem@redhat.com> In-Reply-To: <20040801230338.GE18758@sunbeam2> References: <20040801230338.GE18758@sunbeam2> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7401 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 01:03:38 +0200 Harald Welte wrote: > Incremental to all other patches so far Not really. Harald you really need to fixup your diff scripts wrt. handling non-netfilter files. Every diff you've sent me in this whole set against linux/sysctl.h has rejected, including this one. In this instance, none of the tcp-window-tracking sysctls were in the sysctl.h file you diffed against. I fixed this up by hand, so don't worry about this instance. From werner@almesberger.net Sun Aug 1 19:51:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:51:19 -0700 (PDT) Received: from host.almesberger.net (almesberger.net [63.105.73.238]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722pCle015454 for ; Sun, 1 Aug 2004 19:51:13 -0700 Received: from almesberger.net (vpnwa-home [10.200.0.2]) by host.almesberger.net (8.11.6/8.9.3) with ESMTP id i722pA432049; Sun, 1 Aug 2004 19:51:10 -0700 Received: (from werner@localhost) by almesberger.net (8.11.6/8.11.6) id i722p2T12467; Sun, 1 Aug 2004 23:51:02 -0300 Date: Sun, 1 Aug 2004 23:51:02 -0300 From: Werner Almesberger To: Suparna Bhattacharya Cc: netdev@oss.sgi.com Subject: net-AIO and real-time TCP (blue sky research) Message-ID: <20040801235102.K1276@almesberger.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-archive-position: 7402 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: werner@almesberger.net Precedence: bulk X-list: netdev Hi Suparna, I'm copying this to netdev, because people there may get a good chuckle out of this outlandish idea as well :-) At OLS we were chatting about using AIO also for networking. While this concept didn't seem to rank particularly high on the lunacy scale, it didn't appear overly useful either. About the only possibly interesting new functionality, besides the possibility to connect this with some eccentric TCP offloading and zero-copy scheme, would be - when applied to TCP - to make unACKed data in the out-of-order buffer available to user space. Now, it occurred to me that this may lead to something a lot more exciting: a step towards making TCP real-time capable. I'm using the term "real-time" loosely here, as in "there's a deadline, but we're flexible". I haven't followed what's going on at IETF in that area for a while, and I'm sure plenty of other people must have thought of similar schemes before, but since this seems nicer and maybe even simpler than some, let me describe it anyway. First of all, one of the main complaints of the real-time networking people is that TCP stubbornly insists on retransmitting every single segment until it is absolutely certain that the segment has been received, even if the real-time application has long since moved on. Now, with net-AIO, the application could already get all the data that has arrived after a lost segment. That's a good start, but TCP will still try to retransmit. So the next step would be to have a means to indicate that we've lost interest in the outcome of a pending AIO operation, and - as a side effect - communicate this also to TCP, so that TCP can stop trying, and do something more useful instead. Let's call this operation aio_forget(). For disk IO, this may work just like aio_cancel(). Now, aio_forget() would be a great tool for making TCP blissfully ignorant of any losses, actually making it very TCP-unfriendly. So the next step would be to record the fact that we've just forgotten some segments, but still need to make the peer aware of the fact that there (may) have been losses, and to slow down accordingly. Obviously, if we have reason to believe that the peer already knows of a loss in the general vicinity, no action is needed. Reliably communicating a loss isn't trivial, but there should be good background material in the context of ECN. Of course, if ECN is available, we may just use that. Otherwise, we may have to force a retransmission, to be sure that the peer has noticed. (And, if the forgotten segment(s) should arrive while TCP is trying to indicate a loss, it should stop doing so.) Now, assuming we have a solution for indicating losses that is satisfying both in terms of congestion control and in terms of efficiency, there are still a few things that would be nice to have, that this approach doesn't solve: - message boundaries and segment-message alignment. Not being able to use messages just because a few of their bytes ended up in a lost (and then aio_forgotten) segment would be just too bad. In some cases, it may be possible to just set the MSS to a suitable value. Also, recovering message boundaries after a loss may be tricky. - there's no direct provision for allowing adaptive coding. Of course, this is a fairly orthogonal problem. - as time passes, the sender may want to remove or substitute data it had already enqueued, e.g because there is less bandwidth than originally anticipated. So there may be a place for aio_forget() at the sender side too. Now, why could this scheme be "nicer" than just inventing some new protocol that is designed to do all these things ? The main thing that "looks good" is that this mechanism could use all of TCP, and may not even need major maintenance if some minor aspect of TCP congestion control gets changed. Anyway, this may be peculiar enough for someone to spin the idea a little further. In the worst case, I might just have provided additional evidence that, if you just search long enough, there's a perfectly plausible problem for every solution :-) - Werner -- _________________________________________________________________________ / Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net / /_http://www.almesberger.net/____________________________________________/ From davem@redhat.com Sun Aug 1 19:53:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:53:09 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722r2QQ015700 for ; Sun, 1 Aug 2004 19:53:02 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722qfe1023684; Sun, 1 Aug 2004 22:52:41 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722qfa17865; Sun, 1 Aug 2004 22:52:41 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722pwgP031055; Sun, 1 Aug 2004 22:51:58 -0400 Date: Sun, 1 Aug 2004 19:51:35 -0700 From: "David S. Miller" To: Kazunori Miyazawa Cc: herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kazunori@miyazawa.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-Id: <20040801195135.16734846.davem@redhat.com> In-Reply-To: <20040730171205.114f22ba.kazunori@miyazawa.org> References: <20040730171205.114f22ba.kazunori@miyazawa.org> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7403 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Fri, 30 Jul 2004 17:12:05 +0900 Kazunori Miyazawa wrote: > I consider copying flowi(fl_rt) uses too much stack at the moment. > I'll re-send the fixed patch again. I agree, and let's defer this patch until we resolve that. It is simple to fix, I think. From herbert@gondor.apana.org.au Mon Aug 2 00:42:34 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 00:43:21 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i727gWcJ028544 for ; Mon, 2 Aug 2004 00:42:33 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrXSX-0000qR-00; Mon, 02 Aug 2004 17:42:14 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrXS7-0004Gy-00; Mon, 02 Aug 2004 17:41:47 +1000 Date: Mon, 2 Aug 2004 17:41:47 +1000 To: Kazunori Miyazawa Cc: davem@redhat.com, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, Alexey Kuznetsov Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-ID: <20040802074147.GA16381@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040730171205.114f22ba.kazunori@miyazawa.org> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7404 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev On Fri, Jul 30, 2004 at 05:12:05PM +0900, Kazunori Miyazawa wrote: > > This patch separates xfrm_lookup from ip6_dst_lookup > to support srcrt correctly. ip6_dst_lookup should be > called with next hop. however xfrm_lookup should be > called with final destination. It fixes them. Thanks for the patch. This raises an interesting question. Is it really correct to look at the first hop address when doing the route lookup? The problem is that if we use the first-hop address as the dst when doing the route lookup then we may end up with incorrect MTU information. This is because the MTU to the final destination may well be smaller than the MTU to the first hop. It seems that Alexey thought about this six years ago according to the rthdr comment in icmpv6_rcv(). Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From herbert@gondor.apana.org.au Mon Aug 2 02:32:07 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:32:16 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729W5sL030546 for ; Mon, 2 Aug 2004 02:32:07 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrZAh-0001VE-00; Mon, 02 Aug 2004 19:31:56 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrZAf-00058H-00; Mon, 02 Aug 2004 19:31:53 +1000 Date: Mon, 2 Aug 2004 19:31:53 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: [1/2] [IPSEC] Remove unnecessary inet_ecn.h inclusions Message-ID: <20040802093153.GA19706@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="GvXjxJ+pjyke8COw" Content-Disposition: inline User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7405 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Dave: This is a couple of clean-ups stemming from the xfrm_output change. I should've removed the inet_ecn.h inclusions in that change as the ECN code has been moved to xfrm[46]_output.c. This patch does exactly that. Signed-off-by: Herbert Xu Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p1 ===== net/ipv4/ah4.c 1.38 vs edited ===== --- 1.38/net/ipv4/ah4.c 2004-07-30 21:16:40 +10:00 +++ edited/net/ipv4/ah4.c 2004-08-02 17:44:36 +10:00 @@ -1,6 +1,5 @@ #include #include -#include #include #include #include ===== net/ipv4/esp4.c 1.53 vs edited ===== --- 1.53/net/ipv4/esp4.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/esp4.c 2004-08-02 17:44:49 +10:00 @@ -1,6 +1,5 @@ #include #include -#include #include #include #include ===== net/ipv4/ipcomp.c 1.28 vs edited ===== --- 1.28/net/ipv4/ipcomp.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/ipcomp.c 2004-08-02 17:44:55 +10:00 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include ===== net/ipv4/xfrm4_tunnel.c 1.13 vs edited ===== --- 1.13/net/ipv4/xfrm4_tunnel.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/xfrm4_tunnel.c 2004-08-02 17:44:30 +10:00 @@ -7,7 +7,6 @@ #include #include #include -#include int xfrm4_tunnel_check_size(struct sk_buff *skb) { ===== net/ipv6/ah6.c 1.38 vs edited ===== --- 1.38/net/ipv6/ah6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/ah6.c 2004-08-02 17:45:20 +10:00 @@ -26,7 +26,6 @@ #include #include -#include #include #include #include ===== net/ipv6/esp6.c 1.34 vs edited ===== --- 1.34/net/ipv6/esp6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/esp6.c 2004-08-02 17:45:23 +10:00 @@ -26,7 +26,6 @@ #include #include -#include #include #include #include ===== net/ipv6/ipcomp6.c 1.19 vs edited ===== --- 1.19/net/ipv6/ipcomp6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/ipcomp6.c 2004-08-02 17:45:25 +10:00 @@ -32,7 +32,6 @@ */ #include #include -#include #include #include #include --GvXjxJ+pjyke8COw-- From herbert@gondor.apana.org.au Mon Aug 2 02:35:12 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:35:17 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729ZAXZ030888 for ; Mon, 2 Aug 2004 02:35:11 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrZDg-0001Ws-00; Mon, 02 Aug 2004 19:35:00 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrZDg-00059H-00; Mon, 02 Aug 2004 19:35:00 +1000 Date: Mon, 2 Aug 2004 19:35:00 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: [2/2] [IPSEC] Move xfrm[46]_tunnel_check_size into xfrm[46]_output.c Message-ID: <20040802093500.GA19747@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="82I3+IH0IqGh5yIs" Content-Disposition: inline In-Reply-To: <20040802093153.GA19706@gondor.apana.org.au> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7406 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This patch moves xfrm[46]_tunnel_check_size() into xfrm[46]_output.c where it can be made static since it's only used there. While moving the icmp.h inclusions over I also discovered that the tunnel files are missing an inclusion of net/protocol.h. So I've added them as well. Signed-off-by: Herbert Xu Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p2 ===== include/net/xfrm.h 1.62 vs edited ===== --- 1.62/include/net/xfrm.h 2004-08-02 07:15:02 +10:00 +++ edited/include/net/xfrm.h 2004-08-02 18:02:32 +10:00 @@ -821,12 +821,10 @@ extern int xfrm4_output(struct sk_buff **pskb); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); -extern int xfrm4_tunnel_check_size(struct sk_buff *skb); extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); extern int xfrm6_output(struct sk_buff **pskb); extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); -extern int xfrm6_tunnel_check_size(struct sk_buff *skb); extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); ===== net/ipv4/xfrm4_output.c 1.1 vs edited ===== --- 1.1/net/ipv4/xfrm4_output.c 2004-07-11 04:53:15 +10:00 +++ edited/net/ipv4/xfrm4_output.c 2004-08-02 17:58:15 +10:00 @@ -13,6 +13,7 @@ #include #include #include +#include /* Add encapsulation header. * @@ -65,6 +66,30 @@ top_iph->protocol = IPPROTO_IPIP; memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); +} + +static int xfrm4_tunnel_check_size(struct sk_buff *skb) +{ + int mtu, ret = 0; + struct dst_entry *dst; + struct iphdr *iph = skb->nh.iph; + + if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE) + goto out; + + IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; + + if (!(iph->frag_off & htons(IP_DF))) + goto out; + + dst = skb->dst; + mtu = dst_pmtu(dst) - dst->header_len - dst->trailer_len; + if (skb->len > mtu) { + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); + ret = -EMSGSIZE; + } +out: + return ret; } int xfrm4_output(struct sk_buff **pskb) ===== net/ipv4/xfrm4_tunnel.c 1.14 vs edited ===== --- 1.14/net/ipv4/xfrm4_tunnel.c 2004-08-02 17:53:26 +10:00 +++ edited/net/ipv4/xfrm4_tunnel.c 2004-08-02 18:06:32 +10:00 @@ -6,31 +6,7 @@ #include #include #include -#include - -int xfrm4_tunnel_check_size(struct sk_buff *skb) -{ - int mtu, ret = 0; - struct dst_entry *dst; - struct iphdr *iph = skb->nh.iph; - - if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE) - goto out; - - IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; - - if (!(iph->frag_off & htons(IP_DF))) - goto out; - - dst = skb->dst; - mtu = dst_pmtu(dst) - dst->header_len - dst->trailer_len; - if (skb->len > mtu) { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); - ret = -EMSGSIZE; - } -out: - return ret; -} +#include static int ipip_output(struct sk_buff **pskb) { ===== net/ipv6/xfrm6_output.c 1.1 vs edited ===== --- 1.1/net/ipv6/xfrm6_output.c 2004-07-30 12:17:21 +10:00 +++ edited/net/ipv6/xfrm6_output.c 2004-08-02 18:01:03 +10:00 @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,23 @@ top_iph->hop_limit = iph->hop_limit; ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); +} + +static int xfrm6_tunnel_check_size(struct sk_buff *skb) +{ + int mtu, ret = 0; + struct dst_entry *dst = skb->dst; + + mtu = dst_pmtu(dst) - sizeof(struct ipv6hdr); + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + + if (skb->len > mtu) { + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + ret = -EMSGSIZE; + } + + return ret; } int xfrm6_output(struct sk_buff **pskb) ===== net/ipv6/xfrm6_tunnel.c 1.4 vs edited ===== --- 1.4/net/ipv6/xfrm6_tunnel.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/xfrm6_tunnel.c 2004-08-02 18:07:06 +10:00 @@ -27,8 +27,8 @@ #include #include #include -#include #include +#include #include #include @@ -342,25 +342,6 @@ } EXPORT_SYMBOL(xfrm6_tunnel_free_spi); - -int xfrm6_tunnel_check_size(struct sk_buff *skb) -{ - int mtu, ret = 0; - struct dst_entry *dst = skb->dst; - - mtu = dst_pmtu(dst) - sizeof(struct ipv6hdr); - if (mtu < IPV6_MIN_MTU) - mtu = IPV6_MIN_MTU; - - if (skb->len > mtu) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - ret = -EMSGSIZE; - } - - return ret; -} - -EXPORT_SYMBOL(xfrm6_tunnel_check_size); static int xfrm6_tunnel_output(struct sk_buff **pskb) { ===== net/xfrm/xfrm_export.c 1.2 vs edited ===== --- 1.2/net/xfrm/xfrm_export.c 2004-06-18 16:20:58 +10:00 +++ edited/net/xfrm/xfrm_export.c 2004-08-02 17:58:32 +10:00 @@ -35,7 +35,6 @@ EXPORT_SYMBOL(xfrm4_rcv); EXPORT_SYMBOL(xfrm4_tunnel_register); EXPORT_SYMBOL(xfrm4_tunnel_deregister); -EXPORT_SYMBOL(xfrm4_tunnel_check_size); EXPORT_SYMBOL(xfrm_register_type); EXPORT_SYMBOL(xfrm_unregister_type); EXPORT_SYMBOL(xfrm_get_type); --82I3+IH0IqGh5yIs-- From ptsjohol@cc.jyu.fi Mon Aug 2 02:58:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:58:20 -0700 (PDT) Received: from posti5.jyu.fi (posti5.jyu.fi [130.234.4.34]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729wCVX002631 for ; Mon, 2 Aug 2004 02:58:13 -0700 Received: from silmu.st.jyu.fi (IDENT:KCtRHLQSWRfY1ggLLWY2hN3kjBDFjO1g@silmu.st.jyu.fi [130.234.4.64]) by posti5.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i729vicn005376; Mon, 2 Aug 2004 12:57:45 +0300 Date: Mon, 2 Aug 2004 12:57:41 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: <20040731143330.A25736@electric-eye.fr.zoreil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti5.jyu.fi; Mon, 02 Aug 2004 12:57:47 +0300 X-archive-position: 7407 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev On Sat, 31 Jul 2004, Francois Romieu wrote: > Pasi Sjoholm : > [interesting report] >> The hardest part is to tell where the problem is but I think that >> rtl8139_poll-function would be good place to start looking for the bug? >> readprofile didn't tell much.. Where to go next? I'm not so good >> programmer that I could find the right place to fix.. > In case it could make a difference: did you check if CONFIG_8139_OLD_RX_RESET > changes the behavior or not ? Yep, I tried that one also, didn't help a thing. > If it does not, I'd welcome a test report + log with the two attached patch > applied. The first one is just a placebo but the second one could help. We are making some sort of a progress but not enough. Patch r8139-20.patch didn't help. I made some printk(...)-debug messages and that part of a code was never ran. With both patch applied and RTL8139DEBUG = 1 I couldn't make the driver crash but without DEBUG it did crash. I assume that it has something to with fact that syslog did take so much io-bandwidth. (a couple of minutes log was ~1GB =)) But without: -- @@ -2024,17 +2024,17 @@ static int rtl8139_rx(struct net_device cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); + } - /* Clear out errors and receive interrupts */ - status = RTL_R16 (IntrStatus) & RxAckBits; - if (likely(status != 0)) { - if (unlikely(status & (RxFIFOOver | RxOverflow))) { - tp->stats.rx_errors++; - if (status & RxFIFOOver) - tp->stats.rx_fifo_errors++; - } - RTL_W16_F (IntrStatus, RxAckBits); + /* Clear out errors and receive interrupts */ + status = RTL_R16 (IntrStatus) & RxAckBits; + if (likely(status != 0)) { + if (unlikely(status & (RxFIFOOver | RxOverflow))) { + tp->stats.rx_errors++; + if (status & RxFIFOOver) + tp->stats.rx_fifo_errors++; } + RTL_W16_F (IntrStatus, RxAckBits); } done: -- the driver crashed... even with debug-option was turned on. Everytime the ksoftirqd started to take cpu-time there were this line in the logs: -- Aug 2 12:10:37 139_interrupt: eth0:..... -- Notice the 139... it should read rtl8139_interrupt: Here is a snapshot from the log file when driver is crashing: Full logfile is available from: http://www.cc.jyu.fi/~ptsjohol/syslog-debug.gz -- Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 03ac BufAddr 036c, free to 039c, Cmd 0c. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0000. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0001. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 0484 BufAddr 0444, free to 0474, Cmd 0c. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0000. Aug 2 12:10:37 139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. ...... ...... Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. -- -- Pasi Sjöholm From ptsjohol@cc.jyu.fi Mon Aug 2 03:03:39 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 03:03:44 -0700 (PDT) Received: from posti6.jyu.fi (posti6.jyu.fi [130.234.4.43]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72A3cR6003493 for ; Mon, 2 Aug 2004 03:03:39 -0700 Received: from silmu.st.jyu.fi (IDENT:oxRA6s6O4mJuvi+sWEjRqL5K3wIrdnnK@silmu.st.jyu.fi [130.234.4.64]) by posti6.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i72A3Iob001597; Mon, 2 Aug 2004 13:03:18 +0300 Date: Mon, 2 Aug 2004 13:03:15 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti6.jyu.fi; Mon, 02 Aug 2004 13:03:19 +0300 X-archive-position: 7408 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev I forgot to mention that it was quite hard to crash the driver with that /* Clear out errors and receive interrupts */-patch. Took about 15minutes everytime, when normally it takes about 2mins. On Mon, 2 Aug 2004, Pasi Sjoholm wrote: > With both patch applied and RTL8139DEBUG = 1 I couldn't make the driver > crash but without DEBUG it did crash. I assume that it has something to > with fact that syslog did take so much io-bandwidth. (a couple of minutes log > was ~1GB =)) > > But without: > > -- > @@ -2024,17 +2024,17 @@ static int rtl8139_rx(struct net_device > > cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; > RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); > + } > > - /* Clear out errors and receive interrupts */ > - status = RTL_R16 (IntrStatus) & RxAckBits; > - if (likely(status != 0)) { > - if (unlikely(status & (RxFIFOOver | RxOverflow))) > { > - tp->stats.rx_errors++; > - if (status & RxFIFOOver) > - tp->stats.rx_fifo_errors++; > - } > - RTL_W16_F (IntrStatus, RxAckBits); > + /* Clear out errors and receive interrupts */ > + status = RTL_R16 (IntrStatus) & RxAckBits; > + if (likely(status != 0)) { > + if (unlikely(status & (RxFIFOOver | RxOverflow))) { > + tp->stats.rx_errors++; > + if (status & RxFIFOOver) > + tp->stats.rx_fifo_errors++; > } > + RTL_W16_F (IntrStatus, RxAckBits); > } > > done: > -- > > the driver crashed... even with debug-option was turned on. > Everytime the ksoftirqd started to take cpu-time there were this line in > the logs: From ak@suse.de Mon Aug 2 04:46:42 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 04:46:48 -0700 (PDT) Received: from Cantor.suse.de (cantor.suse.de [195.135.220.2]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72BkfUC009561 for ; Mon, 2 Aug 2004 04:46:41 -0700 Received: from hermes.suse.de (hermes-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by Cantor.suse.de (Postfix) with ESMTP id B3C839A8D29; Mon, 2 Aug 2004 13:45:07 +0200 (CEST) Date: Mon, 2 Aug 2004 13:45:06 +0200 From: Andi Kleen To: "David S. Miller" Cc: Jeff Garzik , tmattox@gmail.com, hadi@cyberus.ca, netdev@oss.sgi.com Subject: Re: [RFC,PATCH] fastroute dead code... Message-ID: <20040802114506.GC25951@wotan.suse.de> References: <20040730060348.GA22854@havoc.gtf.org> <20040730193515.GA11365@havoc.gtf.org> <20040730131004.2be1274d.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040730131004.2be1274d.davem@redhat.com> X-archive-position: 7409 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ak@suse.de Precedence: bulk X-list: netdev On Fri, Jul 30, 2004 at 01:10:04PM -0700, David S. Miller wrote: > On Fri, 30 Jul 2004 15:35:15 -0400 > Jeff Garzik wrote: > > > It is dead code, as-is, in the kernel. It would require patches to > > actually work at all. > > > > It is impossible that fastrouting is being actively used, without patches. > > I totally agree. And people can always resurrect it from the > repository history or an old tarball if they wish. > > I think it should be killed entirely, and that's what I'm going > to do. The s390 people used to use it for local forwarding between partitions. I don't know if they still do however. -Andi > From bruce@cs.usyd.edu.au Mon Aug 2 06:41:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:41:24 -0700 (PDT) Received: from staff.cs.usyd.edu.au (staff.cs.usyd.edu.au [129.78.8.1]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72DfF2n018446 for ; Mon, 2 Aug 2004 06:41:17 -0700 Received: from nlp0.cs.usyd.edu.au. [129.78.10.52] by staff.cs.usyd.edu.au.; Mon, 02 Aug 2004 23:41:09 +1000 Received: from nlp0.cs.usyd.edu.au (localhost.cs.usyd.edu.au [127.0.0.1]) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8) with ESMTP id i72Df9Yo021571 for ; Mon, 2 Aug 2004 23:41:09 +1000 Received: (from bruce@localhost) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8/Submit) id i72Df9TP021569 for netdev@oss.sgi.com; Mon, 2 Aug 2004 23:41:09 +1000 Message-Id: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> Date: Mon, 02 Aug 2004 23:29:20 +1000 From: bruce@it.usyd.edu.au (Bruce Janson) Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver To: netdev@oss.sgi.com Cc: bruce@it.usyd.edu.au X-archive-position: 7410 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bruce@it.usyd.edu.au Precedence: bulk X-list: netdev Hi Randy, Thanks for your reply. From rddunlap@osdl.org Mon Aug 02 03:43:31 2004 ... To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev ... (moving this to netdev mailing list) ... [OK, but please Cc me explicitly as I don't subscribe to netdev.] On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | I would like to be able to boot the kernel with parameters that | will allow control of the tulip device. On some ethernet devices | this used to be possible via (something like): | | ether=0,0,1,0,eth0 | | which would pass the four numeric parameters (as, I think, dev->irq, | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | controlled eth0. A convention adopted by some net drivers then allowed | dev->mem_start to be interpretted as a set of flags that would control | device characteristics (e.g. full-duplex vs half-duplex mode). | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | if (dev->mem_start & MEDIA_MASK) | tp->default_port = dev->mem_start & MEDIA_MASK; | | suggests that this might still work. However, I have been unable | to force dev->mem_start in that driver to become non-zero via any | kernel boot-time parameters. My limited understanding of the code | that precedes the above lines in that file suggests that the "dev" | structure is not what it used to be... The driver never calls netdev_boot_setup_check(), which is what would give the driver its command line parameters. Did this work in early 2.6.x? There have been several changes in this area. ... No idea. This is the first in the 2.6 kernel series that I have tried. The driver can't do a simple call to netdev_boot_setup_check() because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, and those values come from PCI config space for PCI drivers. The driver could create a fake for that purpose, but it's more likely that ethtool or mii-tool should be used to change media/speed etc... Although now that I look at the driver source code, I don't see ethtool or mii-tool support for those options. ... Yes (tried that too :-(). | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | mentions "ether=..." but marks it as obsolete, replaced by | the equivalent "netdev=...". Elsewhere in that file, the entry | for "netdev=..." describes what appears to be the functionality | that I seek. | | So, is it still possible to perform the same sort of control | operations on a tulip driver via kernel boot-time parameters | as one can do via module load-time parameters? If so, how? The current tulip-core driver supports setting only the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image (using mem_start, as you noted above). ... Sorry, I don't follow the above. Would you mind giving me an example, please, of how for the tulip driver I might set the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image? Regards, bruce. From shinemohamed_j@naturesoft.net Mon Aug 2 06:54:04 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:54:10 -0700 (PDT) Received: from naturesoft.net ([203.145.184.221]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72Drw4i019218 for ; Mon, 2 Aug 2004 06:54:03 -0700 Received: from shine.naturesoft.com ([192.168.0.84]) by naturesoft.net with esmtp (Exim 3.35 #1) id 1BrcyI-0005qE-00; Mon, 02 Aug 2004 19:05:22 +0530 Subject: [TRIVIAL PATCH]mistake in the comment in include/linux/wireless.h From: Shine Mohamed Jabbar Reply-To: shinemohamed_j@naturesoft.net To: davem@redhat.com Cc: jt@hpl.hp.com, netdev@oss.sgi.com Content-Type: multipart/mixed; boundary="=-kVZOS8vuCIva4VAmkT5m" Organization: Naturesoft Message-Id: <1091454063.25300.109.camel@shine.naturesoft.com> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 (1.4.6-2) Date: Mon, 02 Aug 2004 19:11:03 +0530 X-archive-position: 7411 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shinemohamed_j@naturesoft.net Precedence: bulk X-list: netdev --=-kVZOS8vuCIva4VAmkT5m Content-Type: text/plain Content-Transfer-Encoding: 7bit [Resend - forgot to cc to netdev ML] Hi Dave, There is a mistake in the comment given in the include/linux/wireless.h. The given patch will fix it. Please apply if its useful. Regards, Shine Mohamed Jabbar --=-kVZOS8vuCIva4VAmkT5m Content-Description: Content-Disposition: attachment; filename=diff.patch Content-Type: text/x-patch; charset=UTF-8 Content-Transfer-Encoding: 7bit --- linux-2.6.8-rc2-bk11/include/linux/wireless.h.orig 2004-08-02 17:39:11.891418904 +0530 +++ linux-2.6.8-rc2-bk11/include/linux/wireless.h 2004-08-02 17:35:56.309151928 +0530 @@ -47,12 +47,12 @@ * # include/net/iw_handler.h * * Note as well that /proc/net/wireless implementation has now moved in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Wireless Events (2002 -> onward) : * -------------------------------- * Events are defined at the end of this file, and implemented in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Other comments : * -------------- --=-kVZOS8vuCIva4VAmkT5m-- From yoshfuji@linux-ipv6.org Mon Aug 2 06:59:19 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:59:26 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72DxJVW019590 for ; Mon, 2 Aug 2004 06:59:19 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id BEE3233CE5; Mon, 2 Aug 2004 22:59:40 +0900 (JST) Date: Mon, 02 Aug 2004 06:59:40 -0700 (PDT) Message-Id: <20040802.065940.86004622.yoshfuji@linux-ipv6.org> To: suckfish@ihug.co.nz Cc: davem@redhat.com, pekkas@netcore.fi, linux-kernel@vger.kernel.org, yoshfuji@linux-ipv6.org, netdev@oss.sgi.com Subject: Re: [PATCH] Trivial ipv6 fix. From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <1091434328.16469.5.camel@localhost.localdomain> References: <1091434328.16469.5.camel@localhost.localdomain> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7412 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <1091434328.16469.5.camel@localhost.localdomain> (at Mon, 02 Aug 2004 20:12:08 +1200), Ralph Loader says: > ipv6_addr_hash doesn't do what it's comment says. The comment was > probably what was intended, not that it'll make much difference in > practice. Oops, David, please apply this. > Signed-off-by: Ralph Loader Signed-off-by: Hideaki YOSHIFUJI ===== include/net/addrconf.h 1.17 vs edited ===== --- 1.17/include/net/addrconf.h 2004-07-29 02:00:50 +09:00 +++ edited/include/net/addrconf.h 2004-08-02 22:57:38 +09:00 @@ -178,8 +178,8 @@ * This will include the IEEE address token on links that support it. */ - word = addr->s6_addr[2] ^ addr->s6_addr32[3]; - word ^= (word>>16); + word = addr->s6_addr32[2] ^ addr->s6_addr32[3]; + word ^= (word >> 16); word ^= (word >> 8); return ((word ^ (word >> 4)) & 0x0f); -- Hideaki YOSHIFUJI @ USAGI Project GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA From kumar.gala@freescale.com Mon Aug 2 06:59:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:00:03 -0700 (PDT) Received: from motgate2.mot.com (motgate2.mot.com [144.189.100.101]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72DxuoY019709 for ; Mon, 2 Aug 2004 06:59:56 -0700 Received: from az33exr02.mot.com (az33exr02.mot.com [10.64.251.232]) by motgate2.mot.com (Motorola/Motgate2) with ESMTP id i72Dt6QO007583; Mon, 2 Aug 2004 06:55:06 -0700 (MST) Received: from [192.168.123.112] ([163.14.1.11]) by az33exr02.mot.com (Motorola/az33exr02) with ESMTP id i72DvZVh017469; Mon, 2 Aug 2004 08:57:35 -0500 In-Reply-To: <41058139.5040400@pobox.com> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> Content-Transfer-Encoding: 7bit Cc: Andy Fleming , Kumar Gala , netdev@oss.sgi.com, dwmw2@infradead.org, hadi@cyberus.ca, Andy Fleming From: Kumar Gala Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 08:59:21 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7413 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev Jeff, Any update on this review of Andy's latest fixes? thanks - kumar On Jul 26, 2004, at 5:10 PM, Jeff Garzik wrote: > Andy Fleming wrote: >> Argh. We found a couple bugs in that last patch. This patch fixes >> those bugs. However, please note that the patch is done against the >> original submission from weeks ago. This patch replaces my most >> recent patch. > > > Thanks, I'll look it over. > > I've been away celebrating (or mourning) my 30th birthday, and have > several patches to run through. I'll add it to the pile, though it > may be a few days before I get to it. > > Jeff From bernie@step.polymtl.ca Mon Aug 2 07:06:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:07:02 -0700 (PDT) Received: from tomts16-srv.bellnexxia.net (tomts16.bellnexxia.net [209.226.175.4]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72E6uAK020279 for ; Mon, 2 Aug 2004 07:06:56 -0700 Received: from [192.168.0.100] ([67.68.201.22]) by tomts16-srv.bellnexxia.net (InterMail vM.5.01.06.10 201-253-122-130-110-20040306) with ESMTP id <20040802140651.YVTU9492.tomts16-srv.bellnexxia.net@[192.168.0.100]> for ; Mon, 2 Aug 2004 10:06:51 -0400 Message-ID: <410E4C16.6070604@step.polymtl.ca> Date: Mon, 02 Aug 2004 10:13:42 -0400 From: Bertrand Guay-Paquet User-Agent: Mozilla Thunderbird 0.7.2 (Windows/20040707) X-Accept-Language: en-us, en MIME-Version: 1.0 To: netdev@oss.sgi.com Subject: skb_clone slower than copying skb data Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7414 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bernie@step.polymtl.ca Precedence: bulk X-list: netdev Hello, I am writing a patch for the usbnet driver to add support for the Prolific PL2501 USB host-to-host cable. My question is entirely related to netdev business however, so please read on. In order to achieve Win32 interropability, the driver needs to receive up to 6 ethernet packets wrapped up in a single skb. My current implementation for reading the contained individual packets is: (simplified to show relevant parts) for (each packet in skb except last one) { length = packet_length(); if (!(skb2 = alloc_skb(length, GFP_ATOMIC))) return -ENOMEM; //Copy the data related to the current ethernet packet memcpy(skb_put(skb2, length), skb->data, length); //Jump to next ethernet packet skb_pull(skb, length); netif_rx(skb2); } //Process last packet netif_rx(skb); ========== This works very well but uses unnecessary memory for the memcpy. I then tried: (again simplified to show relevant parts): for (each packet in skb except last one) { length = packet_length(); if (!(skb2 = skb_clone(skb, GFP_ATOMIC))) return -ENOMEM; //Copy the data related to the current ethernet packet skb_trim(skb2, length); //Jump to next ethernet packet skb_pull(skb, length); netif_rx(skb2); } //Process last packet netif_rx(skb); ========== This works as well, but the throughput is cut in half. How can this be so? Is skb_clone combined with netif_rx supposed to be so slow? I have searched other uses of skb_clone and have not found any similar to mine so I do not know if this is normal behaviour or not. I have tried using skb_clone with 2.4.26 and 2.6.7 with the same results. Any help would be greatly appreciated! Bertrand From SRS0+c8a65e14805b63b7c82e+344+infradead.org+hch@phoenix-150906.srs.infradead.org Mon Aug 2 07:09:33 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:09:40 -0700 (PDT) Received: from phoenix.infradead.org (imladris.demon.co.uk [193.237.130.41]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72E9TPW020621 for ; Mon, 2 Aug 2004 07:09:32 -0700 Received: from hch by phoenix.infradead.org with local (Exim 4.30 #5 (Red Hat Linux)) id 1BrdUv-0001Oz-TA; Mon, 02 Aug 2004 15:09:05 +0100 Date: Mon, 2 Aug 2004 15:09:05 +0100 From: Christoph Hellwig To: Kumar Gala Cc: Jeff Garzik , Andy Fleming , Kumar Gala , netdev@oss.sgi.com, dwmw2@infradead.org, hadi@cyberus.ca, Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Message-ID: <20040802150905.A5381@infradead.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com>; from kumar.gala@freescale.com on Mon, Aug 02, 2004 at 08:59:21AM -0500 X-SRS-Rewrite: SMTP reverse-path rewritten from by phoenix.infradead.org See http://www.infradead.org/rpr.html X-archive-position: 7415 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: hch@infradead.org Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 08:59:21AM -0500, Kumar Gala wrote: > Jeff, > > Any update on this review of Andy's latest fixes? > > thanks > > - kumar So when will you fix the modular compile? From kumar.gala@freescale.com Mon Aug 2 07:12:08 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:12:13 -0700 (PDT) Received: from motgate3.mot.com (motgate3.mot.com [144.189.100.103]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72EC851021014 for ; Mon, 2 Aug 2004 07:12:08 -0700 Received: from az33exr02.mot.com (az33exr02.mot.com [10.64.251.232]) by motgate3.mot.com (Motorola/Motgate3) with ESMTP id i72EBkiC003772; Mon, 2 Aug 2004 07:11:49 -0700 (MST) Received: from [192.168.123.112] ([163.14.1.11]) by az33exr02.mot.com (Motorola/az33exr02) with ESMTP id i72E9xVh005035; Mon, 2 Aug 2004 09:10:00 -0500 In-Reply-To: <20040802150905.A5381@infradead.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> <20040802150905.A5381@infradead.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit Cc: Jeff Garzik , , Kumar Gala , , Andy Fleming , From: Kumar Gala Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 09:11:44 -0500 To: Christoph Hellwig X-Mailer: Apple Mail (2.618) X-archive-position: 7416 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev hch, Will look at it today. Was not aware of this still not work. thanks - kumar On Aug 2, 2004, at 9:09 AM, Christoph Hellwig wrote: > On Mon, Aug 02, 2004 at 08:59:21AM -0500, Kumar Gala wrote: >> Jeff, >> >> Any update on this review of Andy's latest fixes? >> >> thanks >> >> - kumar > > So when will you fix the modular compile? From kumar.gala@freescale.com Mon Aug 2 08:26:47 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 08:26:54 -0700 (PDT) Received: from motgate8.mot.com (motgate8.mot.com [129.188.136.8]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72FQla5026193 for ; Mon, 2 Aug 2004 08:26:47 -0700 Received: from il06exr02.mot.com (il06exr02.mot.com [129.188.137.132]) by motgate8.mot.com (Motorola/Motgate8) with ESMTP id i72FRSRC017075; Mon, 2 Aug 2004 08:27:29 -0700 (MST) Received: from [10.82.17.247] ([10.82.17.247]) by il06exr02.mot.com (Motorola/il06exr02) with ESMTP id i72FPMO6000950; Mon, 2 Aug 2004 10:25:23 -0500 In-Reply-To: <9DFF23E1E33391449FDC324526D1F25902833769@sjc1exm02.pmc_nt.nt.pmc-sierra.bc.ca> References: <9DFF23E1E33391449FDC324526D1F25902833769@sjc1exm02.pmc_nt.nt.pmc-sierra.bc.ca> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: <578EC36E-E498-11D8-939F-000393DBC2E8@freescale.com> Content-Transfer-Encoding: 7bit Cc: Jeff Garzik , , , , Ralf Baechle From: Kumar Gala Subject: Re: [RFC,PATCH] fastroute dead code... Date: Mon, 2 Aug 2004 10:26:36 -0500 To: Manish Lachwani X-Mailer: Apple Mail (2.618) X-archive-position: 7417 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev I want to say an internal group in Freescale has seen similar style performance improvements for integrated gig-e controllers in 2.4. - kumar On Jul 30, 2004, at 3:31 PM, Manish Lachwani wrote: > Is this a 2.6 issue or a 2.4 issue? This is because I am using 2.4.21 > kernel and so do the customers of the board. This board supports 1.0 > Ghz PMC-Sierra Rm9000 processor. With fast routing, the IP forwarding > numbers are about 900 Kpps. While in the case where there is no fast > routing, the numbers are about 450 Kpps (NAPI enabled) > > I still have not done any 2.6 benchmarking since the board support is > not completely functional in 2.6 as yet. > > Thanks > Manish > > -----Original Message----- > From: jamal [mailto:hadi@cyberus.ca] > Sent: Friday, July 30, 2004 1:35 PM > To: Manish Lachwani > Cc: Jeff Garzik; tmattox@gmail.com; netdev@oss.sgi.com; Ralf Baechle > Subject: Re: [RFC,PATCH] fastroute dead code... > > > On Fri, 2004-07-30 at 16:10, David S. Miller wrote: >> On Fri, 30 Jul 2004 15:35:15 -0400 >> Jeff Garzik wrote: >> >>> It is dead code, as-is, in the kernel. It would require patches to >>> actually work at all. >>> >>> It is impossible that fastrouting is being actively used, without >>> patches. >> >> I totally agree. And people can always resurrect it from the >> repository history or an old tarball if they wish. > > Patches are needed for the driver to use that code. So its not entirely > dead code i.e it is referenced from fastroute enabled drivers. > Sample (really old) code found at: > http://ftp.iasi.roedu.net/mirrors/ftp.inr.ac.ru/ip-routing/fastroute/ > > >> I think it should be killed entirely, and that's what I'm going >> to do. > > Nod from here. > Before you kill it lets hear from Ralf who is acquinted with someone > that uses it and sings praises of it (although i personaly dont believe > it ;->). > > cheers, > jamal From rddunlap@osdl.org Mon Aug 2 08:47:34 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 08:47:39 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72FlV39026753 for ; Mon, 2 Aug 2004 08:47:33 -0700 Received: from midway.verizon.net (build.pdx.osdl.net [172.20.1.2]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72FlG130409; Mon, 2 Aug 2004 08:47:16 -0700 Date: Mon, 2 Aug 2004 08:38:37 -0700 From: "Randy.Dunlap" To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev@oss.sgi.com, bruce@it.usyd.edu.au Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver Message-Id: <20040802083837.131a17e3.rddunlap@osdl.org> In-Reply-To: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> References: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> Organization: OSDL X-Mailer: Sylpheed version 0.9.8a (GTK+ 1.2.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7418 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rddunlap@osdl.org Precedence: bulk X-list: netdev On Mon, 02 Aug 2004 23:29:20 +1000 Bruce Janson wrote: | Hi Randy, | Thanks for your reply. | | (moving this to netdev mailing list) | ... | | [OK, but please Cc me explicitly as I don't subscribe to netdev.] | | On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | | | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | | I would like to be able to boot the kernel with parameters that | | will allow control of the tulip device. On some ethernet devices | | this used to be possible via (something like): | | | | ether=0,0,1,0,eth0 | | | | which would pass the four numeric parameters (as, I think, dev->irq, | | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | | controlled eth0. A convention adopted by some net drivers then allowed | | dev->mem_start to be interpretted as a set of flags that would control | | device characteristics (e.g. full-duplex vs half-duplex mode). | | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | | | if (dev->mem_start & MEDIA_MASK) | | tp->default_port = dev->mem_start & MEDIA_MASK; | | | | suggests that this might still work. However, I have been unable | | to force dev->mem_start in that driver to become non-zero via any | | kernel boot-time parameters. My limited understanding of the code | | that precedes the above lines in that file suggests that the "dev" | | structure is not what it used to be... | | The driver never calls netdev_boot_setup_check(), which is | what would give the driver its command line parameters. | | Did this work in early 2.6.x? There have been several changes | in this area. | ... | | No idea. This is the first in the 2.6 kernel series that I have | tried. | | The driver can't do a simple call to netdev_boot_setup_check() | because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, | and those values come from PCI config space for PCI drivers. | The driver could create a fake for that purpose, but it's | more likely that ethtool or mii-tool should be used to change | media/speed etc... Although now that I look at the driver source | code, I don't see ethtool or mii-tool support for those options. | ... | | Yes (tried that too :-(). Which/what have you tried? Is it possible for you to use the tulip driver as modular instead of builtin? With modular, you can set the parameters... but your environment may not allow modular? | | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | | mentions "ether=..." but marks it as obsolete, replaced by | | the equivalent "netdev=...". Elsewhere in that file, the entry | | for "netdev=..." describes what appears to be the functionality | | that I seek. | | | | So, is it still possible to perform the same sort of control | | operations on a tulip driver via kernel boot-time parameters | | as one can do via module load-time parameters? If so, how? | | The current tulip-core driver supports setting only the default transceiver | (media type) on the kernel boot/command line when the driver is built into | the kernel image (using mem_start, as you noted above). | ... | | Sorry, I don't follow the above. Would you mind giving me an example, | please, of how for the tulip driver I might set the default transceiver | (media type) on the kernel boot/command line when the driver is built | into the kernel image? No, I can't. tulip-core uses to mean transceiver, but like I said above, it never calls netdev_boot_setup_check() to get that data, so it's useless currently. Sorry. I'm hoping that someone else will chime in with suggestions for the right thing to do here. -- ~Randy From bruce@cs.usyd.edu.au Mon Aug 2 09:32:43 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 09:32:51 -0700 (PDT) Received: from staff.cs.usyd.edu.au (staff.cs.usyd.edu.au [129.78.8.1]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72GWfit027725 for ; Mon, 2 Aug 2004 09:32:42 -0700 Received: from nlp0.cs.usyd.edu.au. [129.78.10.52] by staff.cs.usyd.edu.au.; Tue, 03 Aug 2004 02:32:34 +1000 Received: from nlp0.cs.usyd.edu.au (localhost.cs.usyd.edu.au [127.0.0.1]) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8) with ESMTP id i72GWYYo022014 for ; Tue, 3 Aug 2004 02:32:34 +1000 Received: (from bruce@localhost) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8/Submit) id i72GWYfs022012 for netdev@oss.sgi.com; Tue, 3 Aug 2004 02:32:34 +1000 Message-Id: <200408021632.i72GWYfs022012@nlp0.cs.usyd.edu.au> Date: Tue, 03 Aug 2004 01:58:46 +1000 From: bruce@it.usyd.edu.au (Bruce Janson) Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver To: netdev@oss.sgi.com Cc: bruce@it.usyd.edu.au X-archive-position: 7419 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bruce@it.usyd.edu.au Precedence: bulk X-list: netdev From rddunlap@osdl.org Tue Aug 03 01:47:23 2004 ... On Mon, 02 Aug 2004 23:29:20 +1000 Bruce Janson wrote: ... | On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | | | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | | I would like to be able to boot the kernel with parameters that | | will allow control of the tulip device. On some ethernet devices | | this used to be possible via (something like): | | | | ether=0,0,1,0,eth0 | | | | which would pass the four numeric parameters (as, I think, dev->irq, | | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | | controlled eth0. A convention adopted by some net drivers then allowed | | dev->mem_start to be interpretted as a set of flags that would control | | device characteristics (e.g. full-duplex vs half-duplex mode). | | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | | | if (dev->mem_start & MEDIA_MASK) | | tp->default_port = dev->mem_start & MEDIA_MASK; | | | | suggests that this might still work. However, I have been unable | | to force dev->mem_start in that driver to become non-zero via any | | kernel boot-time parameters. My limited understanding of the code | | that precedes the above lines in that file suggests that the "dev" | | structure is not what it used to be... | | The driver never calls netdev_boot_setup_check(), which is | what would give the driver its command line parameters. | | Did this work in early 2.6.x? There have been several changes | in this area. | ... | | No idea. This is the first in the 2.6 kernel series that I have | tried. | | The driver can't do a simple call to netdev_boot_setup_check() | because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, | and those values come from PCI config space for PCI drivers. | The driver could create a fake for that purpose, but it's | more likely that ethtool or mii-tool should be used to change | media/speed etc... Although now that I look at the driver source | code, I don't see ethtool or mii-tool support for those options. | ... | | Yes (tried that too :-(). Which/what have you tried? ... By that I meant that I had tried to use ethtool to change settings after boot and found that the tulip driver did not support use of ethtool in that way. I have not tried mii-tool (recently). However, neither of these are a satisfactory solution as I need to have the interace come up in the desired mode initially, not some time later. | | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | | mentions "ether=..." but marks it as obsolete, replaced by | | the equivalent "netdev=...". Elsewhere in that file, the entry | | for "netdev=..." describes what appears to be the functionality | | that I seek. | | | | So, is it still possible to perform the same sort of control | | operations on a tulip driver via kernel boot-time parameters | | as one can do via module load-time parameters? If so, how? | | The current tulip-core driver supports setting only the default transceiver | (media type) on the kernel boot/command line when the driver is built into | the kernel image (using mem_start, as you noted above). | ... | | Sorry, I don't follow the above. Would you mind giving me an example, | please, of how for the tulip driver I might set the default transceiver | (media type) on the kernel boot/command line when the driver is built | into the kernel image? No, I can't. tulip-core uses to mean transceiver, but like I said above, it never calls netdev_boot_setup_check() to get that data, so it's useless currently. Sorry. ... No need to apologise. All I wanted to hear was that someone who actually understood the code agreed that the tulip driver, this boot-time parameter setting mechanism and the documentation (such as it is) are currently mutually buggered :-). Now that I know that, I can stop beating my head against the wall trying to work out what I have done wrong and instead, get on with working around this limitation. Many thanks! :-) From rmk+netdev=oss.sgi.com@arm.linux.org.uk Mon Aug 2 12:02:28 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:02:35 -0700 (PDT) Received: from caramon.arm.linux.org.uk (caramon.arm.linux.org.uk [212.18.232.186]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72J2QZR003078 for ; Mon, 2 Aug 2004 12:02:28 -0700 Received: from flint.arm.linux.org.uk ([2002:d412:e8ba:1:201:2ff:fe14:8fad]) by caramon.arm.linux.org.uk with asmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.33) id 1Bri4Z-0004Qi-B6; Mon, 02 Aug 2004 20:02:11 +0100 Received: from rmk by flint.arm.linux.org.uk with local (Exim 4.33) id 1Bri4Y-0002Wk-Cq; Mon, 02 Aug 2004 20:02:10 +0100 Date: Mon, 2 Aug 2004 20:02:10 +0100 From: Russell King To: "David S. Miller" Cc: jgarzik@pobox.com, shemminger@osdl.org, netdev@oss.sgi.com, greg@kroah.com Subject: Re: [Fwd: pcmcia ether drivers can't be unloaded] Message-ID: <20040802200210.A9498@flint.arm.linux.org.uk> References: <41068BEF.7010200@pobox.com> <20040727233614.B30782@flint.arm.linux.org.uk> <20040727171929.17858c7b.davem@redhat.com> <20040728165024.A8475@flint.arm.linux.org.uk> <20040728085419.773c4d94.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <20040728085419.773c4d94.davem@redhat.com>; from davem@redhat.com on Wed, Jul 28, 2004 at 08:54:19AM -0700 X-archive-position: 7420 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rmk@arm.linux.org.uk Precedence: bulk X-list: netdev On Wed, Jul 28, 2004 at 08:54:19AM -0700, David S. Miller wrote: > On Wed, 28 Jul 2004 16:50:24 +0100 > Russell King wrote: > > > On Tue, Jul 27, 2004 at 05:19:29PM -0700, David S. Miller wrote: > > > I totally disagree. This is a bogus argument for two reasons: > > > > You may disagree, that is your option. However, facts are facts - > > this is how the PCMCIA layer currently works, and short of rewriting > > the whole damned thing it isn't going to change. Sorry. > > Stephen offered a solution, moving this stray refcount into a toplevel > pcmcia bus type object. We are not constrained by how the PCMCIA layer > currently works, just as we were not constrained a year ago by how the > generic network device handling worked when it was totally broken in > this area. We just fixed it instead of whining. Sorry, I'm not the one whining here. I just have _ZERO_ time at the moment because I'm still in Canada and only have sporadic access to stuff. Sorry if this doesn't meet your requirements, but this is the best I can offer you at the moment. In short, my best and only answer is "tough, live with it until I can investigate." -- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core From manfred@colorfullife.com Mon Aug 2 12:37:31 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:37:40 -0700 (PDT) Received: from dbl.q-ag.de (dbl.q-ag.de [213.172.117.3] (may be forged)) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72JbItf010698 for ; Mon, 2 Aug 2004 12:37:29 -0700 Received: from colorfullife.com (dbl [127.0.0.1]) by dbl.q-ag.de (8.12.3/8.12.3/Debian-6.6) with ESMTP id i72JaXuG014435; Mon, 2 Aug 2004 21:36:34 +0200 Message-ID: <410E9841.8000100@colorfullife.com> Date: Mon, 02 Aug 2004 21:38:41 +0200 From: Manfred Spraul User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: James Drabb CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> <410D4120.2020604@colorfullife.com> <410D682F.4090809@tampabay.rr.com> In-Reply-To: <410D682F.4090809@tampabay.rr.com> Content-Type: multipart/mixed; boundary="------------090405070803030805000201" X-archive-position: 7421 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: manfred@colorfullife.com Precedence: bulk X-list: netdev This is a multi-part message in MIME format. --------------090405070803030805000201 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit James Drabb wrote: >> Manfred > > -- > > Please send me the latest forcedeth.c and I will give it a go. Do you > have the makefile so I can compile the module outside of the kernel? > No - you need the 2.6.7 tree as the base. Attached is the patch against 2.6.7 I'm again interested in the same sequence as you did after booting into WinXP, just without WinXP: modprobe, wait, ifup, ethtool, unplug cable, ethtool, plug cable back in, ethtool Always wait ~ 5 seconds before calling ethtool. The patch is a special version, it already contains a timer that polls for phy state changes and prints them into the kernel log (dmesg). -- Manfred --------------090405070803030805000201 Content-Type: text/plain; name="patch-fff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-fff" // $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 6 // SUBLEVEL = 7 // EXTRAVERSION = --- 2.6/drivers/net/forcedeth.c 2004-08-02 21:19:05.979380576 +0200 +++ build-2.6/drivers/net/forcedeth.c 2004-08-02 21:16:47.678405520 +0200 @@ -10,8 +10,11 @@ * trademarks of NVIDIA Corporation in the United States and other * countries. * - * Copyright (C) 2003 Manfred Spraul + * Copyright (C) 2003,4 Manfred Spraul * Copyright (C) 2004 Andrew de Quincey (wol support) + * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane + * IRQ rate fixes, bigendian fixes, cleanups, verification) + * Copyright (c) 2004 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,15 +63,18 @@ * 0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac * addresses, really stop rx if already running * in nv_start_rx, clean up a bit. - * (C) Carl-Daniel Hailfinger * 0.20: 07 Dec 2003: alloc fixes * 0.21: 12 Jan 2004: additional alloc fix, nic polling fix. * 0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup - * on close. - * (C) Carl-Daniel Hailfinger, Manfred Spraul + * on close. * 0.23: 26 Jan 2004: various small cleanups * 0.24: 27 Feb 2004: make driver even less anonymous in backtraces * 0.25: 09 Mar 2004: wol support + * 0.26: 03 Jun 2004: netdriver specific annotation, sparse-related fixes + * 0.27: 19 Jun 2004: Gigabit support, new descriptor rings, + * added CK804/MCP04 device IDs, code fixes + * for registers, link status and other minor fixes. + * 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -80,7 +86,8 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.25" +#define FORCEDETH_VERSION "0.28a" +#define DRV_NAME "forcedeth" #include #include @@ -117,12 +124,14 @@ #define DEV_IRQMASK_1 0x0002 #define DEV_IRQMASK_2 0x0004 #define DEV_NEED_TIMERIRQ 0x0008 +#define DEV_NEED_LINKTIMER 0x0010 enum { NvRegIrqStatus = 0x000, #define NVREG_IRQSTAT_MIIEVENT 0x040 #define NVREG_IRQSTAT_MASK 0x1ff NvRegIrqMask = 0x004, +#define NVREG_IRQ_RX_ERROR 0x0001 #define NVREG_IRQ_RX 0x0002 #define NVREG_IRQ_RX_NOBUF 0x0004 #define NVREG_IRQ_TX_ERR 0x0008 @@ -132,7 +141,7 @@ enum { #define NVREG_IRQ_TX1 0x0100 #define NVREG_IRQMASK_WANTED_1 0x005f #define NVREG_IRQMASK_WANTED_2 0x0147 -#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) +#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) NvRegUnknownSetupReg6 = 0x008, #define NVREG_UNKSETUP6_VAL 3 @@ -159,7 +168,7 @@ enum { NvRegOffloadConfig = 0x90, #define NVREG_OFFLOAD_HOMEPHY 0x601 -#define NVREG_OFFLOAD_NORMAL 0x5ee +#define NVREG_OFFLOAD_NORMAL RX_NIC_BUFSIZE NvRegReceiverControl = 0x094, #define NVREG_RCVCTL_START 0x01 NvRegReceiverStatus = 0x98, @@ -168,6 +177,8 @@ enum { NvRegRandomSeed = 0x9c, #define NVREG_RNDSEED_MASK 0x00ff #define NVREG_RNDSEED_FORCE 0x7f00 +#define NVREG_RNDSEED_FORCE2 0x2d00 +#define NVREG_RNDSEED_FORCE3 0x7400 NvRegUnknownSetupReg1 = 0xA0, #define NVREG_UNKSETUP1_VAL 0x16070f @@ -181,6 +192,9 @@ enum { NvRegMulticastMaskA = 0xB8, NvRegMulticastMaskB = 0xBC, + NvRegPhyInterface = 0xC0, +#define PHY_RGMII 0x10000000 + NvRegTxRingPhysAddr = 0x100, NvRegRxRingPhysAddr = 0x104, NvRegRingSizes = 0x108, @@ -189,12 +203,12 @@ enum { NvRegUnknownTransmitterReg = 0x10c, NvRegLinkSpeed = 0x110, #define NVREG_LINKSPEED_FORCE 0x10000 -#define NVREG_LINKSPEED_10 10 +#define NVREG_LINKSPEED_10 1000 #define NVREG_LINKSPEED_100 100 -#define NVREG_LINKSPEED_1000 1000 +#define NVREG_LINKSPEED_1000 50 NvRegUnknownSetupReg5 = 0x130, #define NVREG_UNKSETUP5_BIT31 (1<<31) - NvRegUnknownSetupReg3 = 0x134, + NvRegUnknownSetupReg3 = 0x13c, #define NVREG_UNKSETUP3_VAL1 0x200010 NvRegTxRxControl = 0x144, #define NVREG_TXRXCTL_KICK 0x0001 @@ -213,15 +227,15 @@ enum { NvRegAdapterControl = 0x188, #define NVREG_ADAPTCTL_START 0x02 #define NVREG_ADAPTCTL_LINKUP 0x04 -#define NVREG_ADAPTCTL_PHYVALID 0x4000 +#define NVREG_ADAPTCTL_PHYVALID 0x40000 #define NVREG_ADAPTCTL_RUNNING 0x100000 #define NVREG_ADAPTCTL_PHYSHIFT 24 NvRegMIISpeed = 0x18c, #define NVREG_MIISPEED_BIT8 (1<<8) #define NVREG_MIIDELAY 5 NvRegMIIControl = 0x190, -#define NVREG_MIICTL_INUSE 0x10000 -#define NVREG_MIICTL_WRITE 0x08000 +#define NVREG_MIICTL_INUSE 0x08000 +#define NVREG_MIICTL_WRITE 0x00400 #define NVREG_MIICTL_ADDRSHIFT 5 NvRegMIIData = 0x194, NvRegWakeUpFlags = 0x200, @@ -253,34 +267,63 @@ enum { #define NVREG_POWERSTATE_D3 0x0003 }; +/* Big endian: should work, but is untested */ struct ring_desc { u32 PacketBuffer; - u16 Length; - u16 Flags; + u32 FlagLen; }; -#define NV_TX_LASTPACKET (1<<0) -#define NV_TX_RETRYERROR (1<<3) -#define NV_TX_LASTPACKET1 (1<<8) -#define NV_TX_DEFERRED (1<<10) -#define NV_TX_CARRIERLOST (1<<11) -#define NV_TX_LATECOLLISION (1<<12) -#define NV_TX_UNDERFLOW (1<<13) -#define NV_TX_ERROR (1<<14) -#define NV_TX_VALID (1<<15) - -#define NV_RX_DESCRIPTORVALID (1<<0) -#define NV_RX_MISSEDFRAME (1<<1) -#define NV_RX_SUBSTRACT1 (1<<3) -#define NV_RX_ERROR1 (1<<7) -#define NV_RX_ERROR2 (1<<8) -#define NV_RX_ERROR3 (1<<9) -#define NV_RX_ERROR4 (1<<10) -#define NV_RX_CRCERR (1<<11) -#define NV_RX_OVERFLOW (1<<12) -#define NV_RX_FRAMINGERR (1<<13) -#define NV_RX_ERROR (1<<14) -#define NV_RX_AVAIL (1<<15) +#define FLAG_MASK_V1 0xffff0000 +#define FLAG_MASK_V2 0xffffc000 +#define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) +#define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2) + +#define NV_TX_LASTPACKET (1<<16) +#define NV_TX_RETRYERROR (1<<19) +#define NV_TX_LASTPACKET1 (1<<24) +#define NV_TX_DEFERRED (1<<26) +#define NV_TX_CARRIERLOST (1<<27) +#define NV_TX_LATECOLLISION (1<<28) +#define NV_TX_UNDERFLOW (1<<29) +#define NV_TX_ERROR (1<<30) +#define NV_TX_VALID (1<<31) + +#define NV_TX2_LASTPACKET (1<<29) +#define NV_TX2_RETRYERROR (1<<18) +#define NV_TX2_LASTPACKET1 (1<<23) +#define NV_TX2_DEFERRED (1<<25) +#define NV_TX2_CARRIERLOST (1<<26) +#define NV_TX2_LATECOLLISION (1<<27) +#define NV_TX2_UNDERFLOW (1<<28) +/* error and valid are the same for both */ +#define NV_TX2_ERROR (1<<30) +#define NV_TX2_VALID (1<<31) + +#define NV_RX_DESCRIPTORVALID (1<<16) +#define NV_RX_MISSEDFRAME (1<<17) +#define NV_RX_SUBSTRACT1 (1<<18) +#define NV_RX_ERROR1 (1<<23) +#define NV_RX_ERROR2 (1<<24) +#define NV_RX_ERROR3 (1<<25) +#define NV_RX_ERROR4 (1<<26) +#define NV_RX_CRCERR (1<<27) +#define NV_RX_OVERFLOW (1<<28) +#define NV_RX_FRAMINGERR (1<<29) +#define NV_RX_ERROR (1<<30) +#define NV_RX_AVAIL (1<<31) + +#define NV_RX2_DESCRIPTORVALID (1<<29) +#define NV_RX2_SUBSTRACT1 (1<<25) +#define NV_RX2_ERROR1 (1<<18) +#define NV_RX2_ERROR2 (1<<19) +#define NV_RX2_ERROR3 (1<<20) +#define NV_RX2_ERROR4 (1<<21) +#define NV_RX2_CRCERR (1<<22) +#define NV_RX2_OVERFLOW (1<<23) +#define NV_RX2_FRAMINGERR (1<<24) +/* error and avail are the same for both */ +#define NV_RX2_ERROR (1<<30) +#define NV_RX2_AVAIL (1<<31) /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ 0x270 @@ -306,28 +349,67 @@ struct ring_desc { /* General driver defaults */ #define NV_WATCHDOG_TIMEO (5*HZ) -#define DEFAULT_MTU 1500 /* also maximum supported, at least for now */ #define RX_RING 128 -#define TX_RING 16 -/* limited to 1 packet until we understand NV_TX_LASTPACKET */ -#define TX_LIMIT_STOP 10 -#define TX_LIMIT_START 5 +#define TX_RING 64 +/* + * If your nic mysteriously hangs then try to reduce the limits + * to 1/0: It might be required to set NV_TX_LASTPACKET in the + * last valid ring entry. But this would be impossible to + * implement - probably a disassembly error. + */ +#define TX_LIMIT_STOP 63 +#define TX_LIMIT_START 62 /* rx/tx mac addr + type + vlan + align + slack*/ -#define RX_NIC_BUFSIZE (DEFAULT_MTU + 64) +#define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) /* even more slack */ -#define RX_ALLOC_BUFSIZE (DEFAULT_MTU + 128) +#define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) #define OOM_REFILL (1+HZ/20) #define POLL_WAIT (1+HZ/100) +#define LINK_TIMEOUT (3*HZ) + +#define DESC_VER_1 0x0 +#define DESC_VER_2 0x02100 + +/* PHY defines */ +#define PHY_OUI_MARVELL 0x5043 +#define PHY_OUI_CICADA 0x03f1 +#define PHYID1_OUI_MASK 0x03ff +#define PHYID1_OUI_SHFT 6 +#define PHYID2_OUI_MASK 0xfc00 +#define PHYID2_OUI_SHFT 10 +#define PHY_INIT1 0x0f000 +#define PHY_INIT2 0x0e00 +#define PHY_INIT3 0x01000 +#define PHY_INIT4 0x0200 +#define PHY_INIT5 0x0004 +#define PHY_INIT6 0x02000 +#define PHY_GIGABIT 0x0100 + +#define PHY_TIMEOUT 0x1 +#define PHY_ERROR 0x2 + +#define PHY_100 0x1 +#define PHY_1000 0x2 +#define PHY_HALF 0x100 + +/* FIXME: MII defines that should be added to */ +#define MII_1000BT_CR 0x09 +#define MII_1000BT_SR 0x0a +#define ADVERTISE_1000FULL 0x0200 +#define ADVERTISE_1000HALF 0x0100 +#define LPA_1000FULL 0x0800 +#define LPA_1000HALF 0x0400 + /* * SMP locking: * All hardware access under dev->priv->lock, except the performance * critical parts: * - rx is (pseudo-) lockless: it relies on the single-threading provided - * by the arch code for interrupts. + * by the arch code for interrupts. * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission * needs dev->priv->lock :-( * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. @@ -345,12 +427,15 @@ struct fe_priv { int duplex; int phyaddr; int wolenabled; + unsigned int phy_oui; + u16 gigabit; /* General data: RO fields */ dma_addr_t ring_addr; struct pci_dev *pci_dev; u32 orig_mac[2]; u32 irqmask; + u32 desc_ver; /* rx specific fields. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); @@ -363,6 +448,11 @@ struct fe_priv { struct timer_list oom_kick; struct timer_list nic_poll; + /* media detection workaround. + * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); + */ + int need_linktimer; + unsigned long link_timeout; /* * tx specific fields. */ @@ -370,7 +460,7 @@ struct fe_priv { unsigned int next_tx, nic_tx; struct sk_buff *tx_skbuff[TX_RING]; dma_addr_t tx_dma[TX_RING]; - u16 tx_flags; + u32 tx_flags; }; /* @@ -395,6 +485,12 @@ static inline void pci_push(u8 * base) readl(base); } +static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) +{ + return le32_to_cpu(prd->FlagLen) + & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); +} + static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, int delay, int delaymax, const char *msg) { @@ -421,24 +517,18 @@ static int reg_delay(struct net_device * static int mii_rw(struct net_device *dev, int addr, int miireg, int value) { u8 *base = get_hwbase(dev); - int was_running; u32 reg; int retval; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); - was_running = 0; - reg = readl(base + NvRegAdapterControl); - if (reg & NVREG_ADAPTCTL_RUNNING) { - was_running = 1; - writel(reg & ~NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - } + reg = readl(base + NvRegMIIControl); if (reg & NVREG_MIICTL_INUSE) { writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl); udelay(NV_MIIBUSY_DELAY); } - reg = NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; + reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; if (value != MII_READ) { writel(value, base + NvRegMIIData); reg |= NVREG_MIICTL_WRITE; @@ -460,19 +550,117 @@ static int mii_rw(struct net_device *dev dev->name, miireg, addr); retval = -1; } else { - /* FIXME: why is that required? */ - udelay(50); retval = readl(base + NvRegMIIData); dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n", dev->name, miireg, addr, retval); } - if (was_running) { - reg = readl(base + NvRegAdapterControl); - writel(reg | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - } + return retval; } +static int phy_reset(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + u32 miicontrol; + unsigned int tries = 0; + + miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + miicontrol |= BMCR_RESET; + if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { + return -1; + } + + /* wait for 500ms */ + msleep(500); + + /* must wait till reset is deasserted */ + while (miicontrol & BMCR_RESET) { + msleep(10); + miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + /* FIXME: 100 tries seem excessive */ + if (tries++ > 100) + return -1; + } + return 0; +} + +static int phy_init(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + u8 *base = get_hwbase(dev); + u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; + + /* set advertise register */ + reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); + reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|0x800|0x400); + if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { + printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + /* get phy interface type */ + phyinterface = readl(base + NvRegPhyInterface); + + /* see if gigabit phy */ + mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + if (mii_status & PHY_GIGABIT) { + np->gigabit = PHY_GIGABIT; + mii_control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); + mii_control_1000 &= ~ADVERTISE_1000HALF; + if (phyinterface & PHY_RGMII) + mii_control_1000 |= ADVERTISE_1000FULL; + else + mii_control_1000 &= ~ADVERTISE_1000FULL; + + if (mii_rw(dev, np->phyaddr, MII_1000BT_CR, mii_control_1000)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + else + np->gigabit = 0; + + /* reset the phy */ + if (phy_reset(dev)) { + printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + /* phy vendor specific configuration */ + if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { + phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); + phy_reserved &= ~(PHY_INIT1 | PHY_INIT2); + phy_reserved |= (PHY_INIT3 | PHY_INIT4); + if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); + phy_reserved |= PHY_INIT5; + if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_oui == PHY_OUI_CICADA) { + phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); + phy_reserved |= PHY_INIT6; + if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + + /* restart auto negotiation */ + mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); + if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { + return PHY_ERROR; + } + + return 0; +} + static void nv_start_rx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -487,6 +675,8 @@ static void nv_start_rx(struct net_devic writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); + dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", + dev->name, np->duplex, np->linkspeed); pci_push(base); } @@ -497,8 +687,8 @@ static void nv_stop_rx(struct net_device dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); writel(0, base + NvRegReceiverControl); reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, - NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); + NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, + KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); udelay(NV_RXSTOP_DELAY2); writel(0, base + NvRegLinkSpeed); @@ -520,8 +710,8 @@ static void nv_stop_tx(struct net_device dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); writel(0, base + NvRegTransmitterControl); reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, - NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); + NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, + KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); writel(0, base + NvRegUnknownTransmitterReg); @@ -529,13 +719,14 @@ static void nv_stop_tx(struct net_device static void nv_txrx_reset(struct net_device *dev) { + struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); - writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); - writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl); pci_push(base); } @@ -650,11 +841,12 @@ static int nv_alloc_rx(struct net_device { struct fe_priv *np = get_nvpriv(dev); unsigned int refill_rx = np->refill_rx; + int nr; while (np->cur_rx != refill_rx) { - int nr = refill_rx % RX_RING; struct sk_buff *skb; + nr = refill_rx % RX_RING; if (np->rx_skbuff[nr] == NULL) { skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); @@ -669,10 +861,9 @@ static int nv_alloc_rx(struct net_device np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); - np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE); wmb(); - np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL); - dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", + np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); + dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", dev->name, refill_rx); refill_rx++; } @@ -703,15 +894,13 @@ static int nv_init_ring(struct net_devic int i; np->next_tx = np->nic_tx = 0; - for (i = 0; i < TX_RING; i++) { - np->tx_ring[i].Flags = 0; - } + for (i = 0; i < TX_RING; i++) + np->tx_ring[i].FlagLen = 0; np->cur_rx = RX_RING; np->refill_rx = 0; - for (i = 0; i < RX_RING; i++) { - np->rx_ring[i].Flags = 0; - } + for (i = 0; i < RX_RING; i++) + np->rx_ring[i].FlagLen = 0; return nv_alloc_rx(dev); } @@ -720,7 +909,7 @@ static void nv_drain_tx(struct net_devic struct fe_priv *np = get_nvpriv(dev); int i; for (i = 0; i < TX_RING; i++) { - np->tx_ring[i].Flags = 0; + np->tx_ring[i].FlagLen = 0; if (np->tx_skbuff[i]) { pci_unmap_single(np->pci_dev, np->tx_dma[i], np->tx_skbuff[i]->len, @@ -737,7 +926,7 @@ static void nv_drain_rx(struct net_devic struct fe_priv *np = get_nvpriv(dev); int i; for (i = 0; i < RX_RING; i++) { - np->rx_ring[i].Flags = 0; + np->rx_ring[i].FlagLen = 0; wmb(); if (np->rx_skbuff[i]) { pci_unmap_single(np->pci_dev, np->rx_dma[i], @@ -769,11 +958,10 @@ static int nv_start_xmit(struct sk_buff PCI_DMA_TODEVICE); np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring[nr].Length = cpu_to_le16(skb->len-1); spin_lock_irq(&np->lock); wmb(); - np->tx_ring[nr].Flags = np->tx_flags; + np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", dev->name, np->next_tx); { @@ -792,7 +980,7 @@ static int nv_start_xmit(struct sk_buff if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP) netif_stop_queue(dev); spin_unlock_irq(&np->lock); - writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl); + writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl); pci_push(get_hwbase(dev)); return 0; } @@ -805,27 +993,42 @@ static int nv_start_xmit(struct sk_buff static void nv_tx_done(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); + u32 Flags; + int i; - while (np->nic_tx < np->next_tx) { - struct ring_desc *prd; - int i = np->nic_tx % TX_RING; + while (np->nic_tx != np->next_tx) { + i = np->nic_tx % TX_RING; - prd = &np->tx_ring[i]; + Flags = le32_to_cpu(np->tx_ring[i].FlagLen); dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", - dev->name, np->nic_tx, prd->Flags); - if (prd->Flags & cpu_to_le16(NV_TX_VALID)) + dev->name, np->nic_tx, Flags); + if (Flags & NV_TX_VALID) break; - if (prd->Flags & cpu_to_le16(NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| - NV_TX_UNDERFLOW|NV_TX_ERROR)) { - if (prd->Flags & cpu_to_le16(NV_TX_UNDERFLOW)) - np->stats.tx_fifo_errors++; - if (prd->Flags & cpu_to_le16(NV_TX_CARRIERLOST)) - np->stats.tx_carrier_errors++; - np->stats.tx_errors++; + if (np->desc_ver == DESC_VER_1) { + if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| + NV_TX_UNDERFLOW|NV_TX_ERROR)) { + if (Flags & NV_TX_UNDERFLOW) + np->stats.tx_fifo_errors++; + if (Flags & NV_TX_CARRIERLOST) + np->stats.tx_carrier_errors++; + np->stats.tx_errors++; + } else { + np->stats.tx_packets++; + np->stats.tx_bytes += np->tx_skbuff[i]->len; + } } else { - np->stats.tx_packets++; - np->stats.tx_bytes += np->tx_skbuff[i]->len; + if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| + NV_TX2_UNDERFLOW|NV_TX2_ERROR)) { + if (Flags & NV_TX2_UNDERFLOW) + np->stats.tx_fifo_errors++; + if (Flags & NV_TX2_CARRIERLOST) + np->stats.tx_carrier_errors++; + np->stats.tx_errors++; + } else { + np->stats.tx_packets++; + np->stats.tx_bytes += np->tx_skbuff[i]->len; + } } pci_unmap_single(np->pci_dev, np->tx_dma[i], np->tx_skbuff[i]->len, @@ -875,9 +1078,9 @@ static void nv_tx_timeout(struct net_dev static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); + u32 Flags; for (;;) { - struct ring_desc *prd; struct sk_buff *skb; int len; int i; @@ -885,11 +1088,13 @@ static void nv_rx_process(struct net_dev break; /* we scanned the whole ring - do not continue */ i = np->cur_rx % RX_RING; - prd = &np->rx_ring[i]; + Flags = le32_to_cpu(np->rx_ring[i].FlagLen); + len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver); + dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", - dev->name, np->cur_rx, prd->Flags); + dev->name, np->cur_rx, Flags); - if (prd->Flags & cpu_to_le16(NV_RX_AVAIL)) + if (Flags & NV_RX_AVAIL) break; /* still owned by hardware, */ /* @@ -903,7 +1108,7 @@ static void nv_rx_process(struct net_dev { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",prd->Flags); + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags); for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); @@ -912,41 +1117,69 @@ static void nv_rx_process(struct net_dev dprintk("\n"); } /* look at what we actually got: */ - if (!(prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID))) - goto next_pkt; - - - len = le16_to_cpu(prd->Length); + if (np->desc_ver == DESC_VER_1) { + if (!(Flags & NV_RX_DESCRIPTORVALID)) + goto next_pkt; - if (prd->Flags & cpu_to_le16(NV_RX_MISSEDFRAME)) { - np->stats.rx_missed_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_CRCERR)) { - np->stats.rx_crc_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_OVERFLOW)) { - np->stats.rx_over_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_ERROR)) { - /* framing errors are soft errors, the rest is fatal. */ - if (prd->Flags & cpu_to_le16(NV_RX_FRAMINGERR)) { - if (prd->Flags & cpu_to_le16(NV_RX_SUBSTRACT1)) { - len--; + if (Flags & NV_RX_MISSEDFRAME) { + np->stats.rx_missed_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_OVERFLOW) { + np->stats.rx_over_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_ERROR) { + /* framing errors are soft errors, the rest is fatal. */ + if (Flags & NV_RX_FRAMINGERR) { + if (Flags & NV_RX_SUBSTRACT1) { + len--; + } + } else { + np->stats.rx_errors++; + goto next_pkt; } - } else { + } + } else { + if (!(Flags & NV_RX2_DESCRIPTORVALID)) + goto next_pkt; + + if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX2_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX2_OVERFLOW) { + np->stats.rx_over_errors++; np->stats.rx_errors++; goto next_pkt; } + if (Flags & NV_RX2_ERROR) { + /* framing errors are soft errors, the rest is fatal. */ + if (Flags & NV_RX2_FRAMINGERR) { + if (Flags & NV_RX2_SUBSTRACT1) { + len--; + } + } else { + np->stats.rx_errors++; + goto next_pkt; + } + } } /* got a valid packet - forward it to the network core */ skb = np->rx_skbuff[i]; @@ -971,7 +1204,7 @@ next_pkt: */ static int nv_change_mtu(struct net_device *dev, int new_mtu) { - if (new_mtu > DEFAULT_MTU) + if (new_mtu > ETH_DATA_LEN) return -EINVAL; dev->mtu = new_mtu; return 0; @@ -1035,6 +1268,8 @@ static void nv_set_multicast(struct net_ writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); + dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n", + dev->name); nv_start_rx(dev); spin_unlock_irq(&np->lock); } @@ -1042,16 +1277,62 @@ static void nv_set_multicast(struct net_ static int nv_update_linkspeed(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); - int adv, lpa, newls, newdup; + u8 *base = get_hwbase(dev); + int adv, lpa; + int newls = np->linkspeed; + int newdup = np->duplex; + int mii_status; + int retval = 0; + u32 control_1000, status_1000, phyreg; + + /* BMSR_LSTATUS is latched, read it twice: + * we want the current value. + */ + mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + + if (!(mii_status & BMSR_LSTATUS)) { + dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n", + dev->name); + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; + newdup = 0; + retval = 0; + goto set_speed; + } + + /* check auto negotiation is complete */ + if (!(mii_status & BMSR_ANEGCOMPLETE)) { + /* still in autonegotiation - configure nic for 10 MBit HD and wait. */ + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; + newdup = 0; + retval = 0; + dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name); + goto set_speed; + } + + retval = 1; + if (np->gigabit == PHY_GIGABIT) { + control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); + status_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_SR, MII_READ); + + if ((control_1000 & ADVERTISE_1000FULL) && + (status_1000 & LPA_1000FULL)) { + dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n", + dev->name); + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000; + newdup = 1; + goto set_speed; + } + } adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", dev->name, adv, lpa); - /* FIXME: handle parallel detection properly, handle gigabit ethernet */ + /* FIXME: handle parallel detection properly */ lpa = lpa & adv; - if (lpa & LPA_100FULL) { + if (lpa & LPA_100FULL) { newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; newdup = 1; } else if (lpa & LPA_100HALF) { @@ -1068,47 +1349,75 @@ static int nv_update_linkspeed(struct ne newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } - if (np->duplex != newdup || np->linkspeed != newls) { - np->duplex = newdup; - np->linkspeed = newls; - return 1; - } - return 0; + +set_speed: + if (np->duplex == newdup && np->linkspeed == newls) + return retval; + + dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n", + dev->name, np->linkspeed, np->duplex, newls, newdup); + + np->duplex = newdup; + np->linkspeed = newls; + + if (np->gigabit == PHY_GIGABIT) { + phyreg = readl(base + NvRegRandomSeed); + phyreg &= ~(0x3FF00); + if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) + phyreg |= NVREG_RNDSEED_FORCE3; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + phyreg |= NVREG_RNDSEED_FORCE2; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + phyreg |= NVREG_RNDSEED_FORCE; + writel(phyreg, base + NvRegRandomSeed); + } + + phyreg = readl(base + NvRegPhyInterface); + phyreg &= ~(PHY_HALF|PHY_100|PHY_1000); + if (np->duplex == 0) + phyreg |= PHY_HALF; + if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + phyreg |= PHY_100; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + phyreg |= PHY_1000; + writel(phyreg, base + NvRegPhyInterface); + + writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), + base + NvRegMisc1); + pci_push(base); + writel(np->linkspeed, base + NvRegLinkSpeed); + pci_push(base); + + return retval; } static void nv_link_irq(struct net_device *dev) { - struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); u32 miistat; - int miival; miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); - printk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat); +printk(KERN_INFO "%s: link change notification, status 0x%x.\n", dev->name, miistat); - miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); - if (miival & BMSR_ANEGCOMPLETE) { - nv_update_linkspeed(dev); - - if (netif_carrier_ok(dev)) { - nv_stop_rx(dev); + if (miistat & (NVREG_MIISTAT_LINKCHANGE)) { + if (nv_update_linkspeed(dev)) { + if (netif_carrier_ok(dev)) { + nv_stop_rx(dev); + } else { + netif_carrier_on(dev); + printk(KERN_INFO "%s: link up.\n", dev->name); + } + nv_start_rx(dev); } else { - netif_carrier_on(dev); - printk(KERN_INFO "%s: link up.\n", dev->name); - } - writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), - base + NvRegMisc1); - nv_start_rx(dev); - } else { - if (netif_carrier_ok(dev)) { - netif_carrier_off(dev); - printk(KERN_INFO "%s: link down.\n", dev->name); - nv_stop_rx(dev); + if (netif_carrier_ok(dev)) { + netif_carrier_off(dev); + printk(KERN_INFO "%s: link down.\n", dev->name); + nv_stop_rx(dev); + } } - writel(np->linkspeed, base + NvRegLinkSpeed); - pci_push(base); } + dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) @@ -1135,7 +1444,7 @@ static irqreturn_t nv_nic_irq(int foo, v spin_unlock(&np->lock); } - if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { + if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { nv_rx_process(dev); if (nv_alloc_rx(dev)) { spin_lock(&np->lock); @@ -1150,6 +1459,12 @@ static irqreturn_t nv_nic_irq(int foo, v nv_link_irq(dev); spin_unlock(&np->lock); } + if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { + spin_lock(&np->lock); + nv_link_irq(dev); + spin_unlock(&np->lock); + np->link_timeout = jiffies + LINK_TIMEOUT; + } if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); @@ -1157,7 +1472,7 @@ static irqreturn_t nv_nic_irq(int foo, v if (events & (NVREG_IRQ_UNKNOWN)) { printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", dev->name, events); - } + } if (i > max_interrupt_work) { spin_lock(&np->lock); /* disable interrupts on the nic */ @@ -1210,21 +1525,27 @@ static int nv_open(struct net_device *de writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(0, base + NvRegPacketFilterFlags); + + writel(0, base + NvRegTransmitterControl); + writel(0, base + NvRegReceiverControl); + writel(0, base + NvRegAdapterControl); + + /* 2) initialize descriptor rings */ + oom = nv_init_ring(dev); + writel(0, base + NvRegLinkSpeed); writel(0, base + NvRegUnknownTransmitterReg); nv_txrx_reset(dev); writel(0, base + NvRegUnknownSetupReg6); - /* 2) initialize descriptor rings */ np->in_shutdown = 0; - oom = nv_init_ring(dev); /* 3) set mac address */ { u32 mac[2]; - mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + + mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); @@ -1232,53 +1553,31 @@ static int nv_open(struct net_device *de writel(mac[1], base + NvRegMacAddrB); } - /* 4) continue setup */ + /* 4) give hw rings */ + writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), + base + NvRegRingSizes); + + /* 5) continue setup */ np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; np->duplex = 0; + + writel(np->linkspeed, base + NvRegLinkSpeed); writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); - writel(0, base + NvRegTxRxControl); + writel(np->desc_ver, base + NvRegTxRxControl); pci_push(base); - writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl); reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); - writel(0, base + NvRegUnknownSetupReg4); - - /* 5) Find a suitable PHY */ - writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); - for (i = 1; i < 32; i++) { - int id1, id2; - spin_lock_irq(&np->lock); - id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); - spin_unlock_irq(&np->lock); - if (id1 < 0 || id1 == 0xffff) - continue; - spin_lock_irq(&np->lock); - id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); - spin_unlock_irq(&np->lock); - if (id2 < 0 || id2 == 0xffff) - continue; - dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", - dev->name, id1, id2, i); - np->phyaddr = i; - - spin_lock_irq(&np->lock); - nv_update_linkspeed(dev); - spin_unlock_irq(&np->lock); - - break; - } - if (i == 32) { - printk(KERN_INFO "%s: open: failing due to lack of suitable PHY.\n", - dev->name); - ret = -EINVAL; - goto out_drain; - } + writel(0, base + NvRegUnknownSetupReg4); + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); + writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); /* 6) continue setup */ - writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), - base + NvRegMisc1); + writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); @@ -1290,17 +1589,12 @@ static int nv_open(struct net_device *de writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2); writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval); writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); - writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID, + writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); + writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); - /* 7) start packet processing */ - writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); - writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); - writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), - base + NvRegRingSizes); - i = readl(base + NvRegPowerState); if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); @@ -1308,13 +1602,9 @@ static int nv_open(struct net_device *de pci_push(base); udelay(10); writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); - writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - writel(0, base + NvRegIrqMask); pci_push(base); - writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - pci_push(base); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); @@ -1323,6 +1613,7 @@ static int nv_open(struct net_device *de if (ret) goto out_drain; + /* ask for interrupts */ writel(np->irqmask, base + NvRegIrqMask); spin_lock_irq(&np->lock); @@ -1331,18 +1622,27 @@ static int nv_open(struct net_device *de writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); + /* One manual link speed update: Interrupts are enabled, future link + * speed changes cause interrupts and are handled by nv_link_irq(). + */ + { + u32 miistat; + miistat = readl(base + NvRegMIIStatus); + writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); + dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); + } + ret = nv_update_linkspeed(dev); nv_start_rx(dev); nv_start_tx(dev); netif_start_queue(dev); - if (oom) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - if (mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE) { + if (ret) { netif_carrier_on(dev); } else { printk("%s: no link during initialization.\n", dev->name); netif_carrier_off(dev); } - + if (oom) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); spin_unlock_irq(&np->lock); return 0; @@ -1424,7 +1724,7 @@ static int __devinit nv_probe(struct pci pci_set_master(pci_dev); - err = pci_request_regions(pci_dev, dev->name); + err = pci_request_regions(pci_dev, DRV_NAME); if (err < 0) goto out_disable; @@ -1447,6 +1747,14 @@ static int __devinit nv_probe(struct pci goto out_relreg; } + /* handle different descriptor versions */ + if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || + pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || + pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3) + np->desc_ver = DESC_VER_1; + else + np->desc_ver = DESC_VER_2; + err = -ENOMEM; dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ); if (!dev->base_addr) @@ -1506,15 +1814,63 @@ static int __devinit nv_probe(struct pci writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; - np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID); - if (id->driver_data & DEV_NEED_LASTPACKET1) - np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1); + if (np->desc_ver == DESC_VER_1) { + np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; + if (id->driver_data & DEV_NEED_LASTPACKET1) + np->tx_flags |= NV_TX_LASTPACKET1; + } else { + np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; + if (id->driver_data & DEV_NEED_LASTPACKET1) + np->tx_flags |= NV_TX2_LASTPACKET1; + } if (id->driver_data & DEV_IRQMASK_1) np->irqmask = NVREG_IRQMASK_WANTED_1; if (id->driver_data & DEV_IRQMASK_2) np->irqmask = NVREG_IRQMASK_WANTED_2; if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; + if (id->driver_data & DEV_NEED_LINKTIMER) { + np->need_linktimer = 1; + np->link_timeout = jiffies + LINK_TIMEOUT; + } else { + np->need_linktimer = 0; + } + + /* find a suitable phy */ + for (i = 1; i < 32; i++) { + int id1, id2; + + spin_lock_irq(&np->lock); + id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); + spin_unlock_irq(&np->lock); + if (id1 < 0 || id1 == 0xffff) + continue; + spin_lock_irq(&np->lock); + id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); + spin_unlock_irq(&np->lock); + if (id2 < 0 || id2 == 0xffff) + continue; + + id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; + id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; + dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", + pci_name(pci_dev), id1, id2, i); + np->phyaddr = i; + np->phy_oui = id1 | id2; + break; + } + if (i == 32) { + /* PHY in isolate mode? No phy attached and user wants to + * test loopback? Very odd, but can be correct. + */ + printk(KERN_INFO "%s: open: Could not find a valid PHY.\n", + pci_name(pci_dev)); + } + + if (i != 32) { + /* reset it */ + phy_init(dev); + } err = register_netdev(dev); if (err) { @@ -1569,21 +1925,77 @@ static void __devexit nv_remove(struct p static struct pci_device_id pci_tbl[] = { { /* nForce Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x1C3, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_1, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ, + .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce2 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x0066, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_3, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_4, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, }, { /* nForce3 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x00D6, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_5, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_6, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_7, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* CK804 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_8, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* CK804 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_9, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* MCP04 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_10, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* MCP04 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_11, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, @@ -1610,9 +2022,9 @@ static void __exit exit_nic(void) pci_unregister_driver(&driver); } -MODULE_PARM(max_interrupt_work, "i"); +module_param(max_interrupt_work, int, 0); MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt"); - + MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); MODULE_LICENSE("GPL"); --- 2.6/include/linux/pci_ids.h 2004-08-02 21:19:11.940474352 +0200 +++ build-2.6/include/linux/pci_ids.h 2004-08-02 21:17:46.234503640 +0200 @@ -1061,21 +1061,33 @@ #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 +#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 +#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 +#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 +#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 +#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 +#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 +#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e #define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 +#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 @@ -1103,6 +1115,7 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc +#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 #define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 --------------090405070803030805000201-- From vkondra@mail.ru Mon Aug 2 12:39:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:39:30 -0700 (PDT) Received: from mx2.mail.ru (mx2.mail.ru [194.67.23.122]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72JdGMx011061 for ; Mon, 2 Aug 2004 12:39:16 -0700 Received: from [82.80.15.190] (port=14176 helo=[192.168.10.2]) by mx2.mail.ru with esmtp id 1BrieL-000IEm-00 for netdev@oss.sgi.com; Mon, 02 Aug 2004 23:39:10 +0400 From: Vladimir Kondratiev To: netdev@oss.sgi.com Subject: TGe overview #3 Date: Mon, 2 Aug 2004 22:38:57 +0300 User-Agent: KMail/1.6.82 MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart6500354.cgk6mvoYQD"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Message-Id: <200408022239.04871.vkondra@mail.ru> X-Spam: Not detected X-archive-position: 7422 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: vkondra@mail.ru Precedence: bulk X-list: netdev --nextPart6500354.cgk6mvoYQD Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =46inally, let's review Traffic Streams. There are 2 different concepts: logical layer (admission) and completely ne= w=20 media access mechanism HCCA (Hybrid Coordinator Channel Access). Idea behind HCCA is similar to PCF (Point Coordinator Function) from old=20 802.11 standard. Hybrid Coordinator (HC), which have to be AP, decides who= =20 will talk when. Technically it is implemented as following: All time divided into contention based (EDCA TXOP's) and contention free CA= P=20 (Controlled AccessPhase). When HC want to start CAP, it simply starts it=20 after PIFS interval of idle media. PIFS is shorter then any interval betwee= n=20 EDCA frame exchange sequences, thus HC will preempt any EDCA flow at his=20 will. Then, HC can either transmit frames, or it may send Contention Free=20 Poll (CFP) frame to some STA. This frame gives to the STA "polled" TXOP, in= =20 contrast with EDCA TXOP. CFP frame provides TXOP duration. Now, admission control. For HCCA it is the only mechanism. But, admission=20 control may be activated also for 2 high priority EDCA categories. =46or EDCA it mean the following: one can't use these categories as it was= =20 described in EDCA, instead, TID should be obtained. For EDCA this mechanism= =20 used to control bandwidth allocation. But remember, EDCA is contention base= d=20 policy, without any guarantee. TID's 8-15 dedicates to TS (Traffic Streams). In order to obtain TID, STA=20 should send request to AP. Corresponded frame called ADDTS, it contain=20 traffic specification: requested bandwidth, delay, periodicity, frame size= =20 etc. AP may accept or decline this request. It may also come with counter=20 proposal with different parameters. TS may be up-stream, down-stream, or bi-direction If TS accepted by AP, AP provides schedule information. This information=20 consist of Service Interval (SI) - interval between successive Service=20 Periods (SP), during which AP serves this TS, and Start Time. Start time have the following meaning: STA may request exact timing in ADDT= S=20 request. In this case, it will be served at precise times StartTime+n*SI.=20 This used for power save: STA may identify itself as power down, but wake u= p=20 for its stream. Obvious usage is .11 phones. Here, important QoS related part is: AP admin decides upon admission control policy. For "legacy stations", that= =20 don't speak TS (stations implementing WME spec), it may provide only 2 low= =20 priority access categories. These STA will be severely impacted in=20 performance. STA have to know TGE in order to get real performance. And, STA need to kno= w=20 how to identify streams (RSVP like). One additional feature: DLP (Direct Link Protocol). Unrelated to anything=20 else. Idea is to let 2 stations to talk directly. Link establishment is=20 through AP, but later they send frames directly, reducing media time 2x. Th= is=20 is important for applications like streaming of high definition TV, for whi= ch=20 "usual" way when AP forward frames, is unacceptable. P.S. I did not covered many other stuff which is not related directly to Qo= S. --nextPart6500354.cgk6mvoYQD Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) iD8DBQBBDphYqxdj7mhC6o0RAmzAAKCFDMlYn7QuujVswZshlWPTZehMMQCgpXEw 7UWwHkUzYOgsx0c61i82UpU= =QGXS -----END PGP SIGNATURE----- --nextPart6500354.cgk6mvoYQD-- From akpm@osdl.org Mon Aug 2 14:23:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 14:23:57 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72LNo8Z016626 for ; Mon, 2 Aug 2004 14:23:50 -0700 Received: from akpm.pao.digeo.com (build.pdx.osdl.net [172.20.1.2]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72LNd131100; Mon, 2 Aug 2004 14:23:39 -0700 Date: Mon, 2 Aug 2004 14:27:06 -0700 From: Andrew Morton To: Matthias Andree Cc: netdev@oss.sgi.com Subject: Re: 2.6.8-rc2-mm1 breaks PPPoE for me (was: 2.6.8-rc2-mm1) Message-Id: <20040802142706.46100c6d.akpm@osdl.org> In-Reply-To: <20040731100947.GA7453@merlin.emma.line.org> References: <20040728020444.4dca7e23.akpm@osdl.org> <20040731100947.GA7453@merlin.emma.line.org> X-Mailer: Sylpheed version 0.9.7 (GTK+ 1.2.10; i586-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7423 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: akpm@osdl.org Precedence: bulk X-list: netdev Matthias Andree wrote: > > On Wed, 28 Jul 2004, Andrew Morton wrote: > > > ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.8-rc2/2.6.8-rc2-mm1/ > ... > > gcc35-pppoe.c.patch > > gcc-3.5 fixes > > Andrew, > > I'm not sure if my problem is related to this patch, but in > 2.6.8-rc2-mm1, PPPoE doesn't work for me, kernel compiled with gcc (GCC) > 3.3.1 (SuSE Linux), a vanilla 2.6.7 is fine with the same compiler. > > pppd[5685]: Plugin /usr/lib/pppd/2.4.1/pppoe.so loaded. > pppd[5685]: PPPoE Plugin Initialized > pppd[5685]: pppd 2.4.1 started by root, uid 0 > pppd[5685]: Sending PADI > pppd[5685]: HOST_UNIQ successful match > pppd[5685]: Failed to negotiate PPPoE connection: 25 Inappropriate ioctl for device > pppd[5685]: Exit. > > A successful pppd session start, with 2.6.7, looks like this: > > pppd[5070]: PPPoE Plugin Initialized > pppd[5070]: pppd 2.4.1 started by root, uid 0 > pppd[5070]: Sending PADI > pppd[5070]: HOST_UNIQ successful match > pppd[5070]: HOST_UNIQ successful match > pppd[5070]: Got connection: 164b > pppd[5070]: Connecting PPPoE socket: 00:90:1a:XX:XX:XX 4b16 eth1 0x808a560 > /sbin/hotplug[5166]: INTERFACE=ppp0 > pppd[5070]: Using interface ppp0 > pppd[5070]: Connect: ppp0 <--> eth1 > pppd[5070]: Setting MTU to 1492. > pppd[5070]: Couldn't increase MRU to 1500 > pppd[5070]: Setting MTU to 1492. > pppd[5070]: local IP address 217.81.XXX.XXX > pppd[5070]: remote IP address 217.5.XXX.XXX > pppd[5070]: Script /etc/ppp/ip-up finished (pid 5180), status = 0x0 > I'm a bit stumped by this - I'm not aware of any change which would have caused the pppoe device to start returning -ENOTTY. Is this still happening? Are you sure the relevant modules are loaded? Could you capture an strace of pppd while it's happening? From afleming@freescale.com Mon Aug 2 15:19:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:19:52 -0700 (PDT) Received: from motgate3.mot.com (motgate3.mot.com [144.189.100.103]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72MJhZt018057 for ; Mon, 2 Aug 2004 15:19:46 -0700 Received: from az33exr04.mot.com (pobox4.mot.com [10.64.251.243]) by motgate3.mot.com (Motorola/Motgate3) with ESMTP id i72MJKiC008676; Mon, 2 Aug 2004 15:19:20 -0700 (MST) Received: from [10.82.17.240] ([10.82.17.240]) by az33exr04.mot.com (Motorola/az33exr04) with ESMTP id i72KJBoa015263; Mon, 2 Aug 2004 15:19:11 -0500 In-Reply-To: <20040707032913.GA1822@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit Cc: Andy Fleming , Kumar Gala , "" , jamal , "" , Christoph Hellwig From: Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 17:19:13 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7424 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: afleming@freescale.com Precedence: bulk X-list: netdev Here's an updated patch which fixes module support which does this: * More cleanup/minor bug fixes * Added locking to PHY read/write wrappers * Fixed module support * Removed fastroute code As before, this patch replaces the previous ones I have submitted. Thanks, Andy Fleming From bunk@fs.tum.de Mon Aug 2 15:33:52 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:33:58 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72MXoCC018554 for ; Mon, 2 Aug 2004 15:33:51 -0700 Received: (qmail 22776 invoked from network); 2 Aug 2004 22:26:27 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 2 Aug 2004 22:26:27 -0000 Date: Tue, 3 Aug 2004 00:33:32 +0200 From: Adrian Bunk To: Jeff Garzik Cc: linux-net@vger.kernel.org, Netdev , linux-kernel@vger.kernel.org Subject: [2.6 patch] fix net/hamradio/dmascc with gcc 3.4 Message-ID: <20040802223332.GP2746@fs.tum.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-archive-position: 7425 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev Trying to compile net/hamradio/dmascc.c in 2.6.8-rc2-mm2 with gcc 3.4 results in compile errors starting with the following: <-- snip --> ... CC drivers/net/hamradio/dmascc.o drivers/net/hamradio/dmascc.c: In function `scc_isr': drivers/net/hamradio/dmascc.c:250: sorry, unimplemented: inlining failed in call to 'z8530_isr': function body not available drivers/net/hamradio/dmascc.c:969: sorry, unimplemented: called from here drivers/net/hamradio/dmascc.c:250: sorry, unimplemented: inlining failed in call to 'z8530_isr': function body not available drivers/net/hamradio/dmascc.c:978: sorry, unimplemented: called from here make[3]: *** [drivers/net/hamradio/dmascc.o] Error 1 <-- snip --> The patch below moves all inline functions above their first caller. diffstat output: drivers/net/hamradio/dmascc.c | 290 ++++++++++++++++------------------ 1 files changed, 144 insertions(+), 146 deletions(-) Signed-off-by: Adrian Bunk --- linux-2.6.7-mm7-full-gcc3.4/drivers/net/hamradio/dmascc.c.old 2004-07-13 00:55:54.000000000 +0200 +++ linux-2.6.7-mm7-full-gcc3.4/drivers/net/hamradio/dmascc.c 2004-07-13 01:01:06.000000000 +0200 @@ -246,8 +246,14 @@ static struct net_device_stats *scc_get_stats(struct net_device *dev); static int scc_set_mac_address(struct net_device *dev, void *sa); -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs); +static inline void tx_on(struct scc_priv *priv); +static inline void rx_on(struct scc_priv *priv); +static inline void rx_off(struct scc_priv *priv); +static void start_timer(struct scc_priv *priv, int t, int r15); +static inline unsigned char random(void); + static inline void z8530_isr(struct scc_info *info); +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs); static void rx_isr(struct scc_priv *priv); static void special_condition(struct scc_priv *priv, int rc); static void rx_bh(void *arg); @@ -255,12 +261,6 @@ static void es_isr(struct scc_priv *priv); static void tm_isr(struct scc_priv *priv); -static inline void tx_on(struct scc_priv *priv); -static inline void rx_on(struct scc_priv *priv); -static inline void rx_off(struct scc_priv *priv); -static void start_timer(struct scc_priv *priv, int t, int r15); -static inline unsigned char random(void); - /* Initialization variables */ @@ -945,42 +945,115 @@ } -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs) { - struct scc_info *info = dev_id; +static inline void tx_on(struct scc_priv *priv) { + int i, n; + unsigned long flags; - spin_lock(info->priv[0].register_lock); - /* At this point interrupts are enabled, and the interrupt under service - is already acknowledged, but masked off. + if (priv->param.dma >= 0) { + n = (priv->chip == Z85230) ? 3 : 1; + /* Program DMA controller */ + flags = claim_dma_lock(); + set_dma_mode(priv->param.dma, DMA_MODE_WRITE); + set_dma_addr(priv->param.dma, (int) priv->tx_buf[priv->tx_tail]+n); + set_dma_count(priv->param.dma, priv->tx_len[priv->tx_tail]-n); + release_dma_lock(flags); + /* Enable TX underrun interrupt */ + write_scc(priv, R15, TxUIE); + /* Configure DREQ */ + if (priv->type == TYPE_TWIN) + outb((priv->param.dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3, + priv->card_base + TWIN_DMA_CFG); + else + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB); + /* Write first byte(s) */ + spin_lock_irqsave(priv->register_lock, flags); + for (i = 0; i < n; i++) + write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1); + enable_dma(priv->param.dma); + spin_unlock_irqrestore(priv->register_lock, flags); + } else { + write_scc(priv, R15, TxUIE); + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB); + tx_isr(priv); + } + /* Reset EOM latch if we do not have the AUTOEOM feature */ + if (priv->chip == Z8530) write_scc(priv, R0, RES_EOM_L); +} - Interrupt processing: We loop until we know that the IRQ line is - low. If another positive edge occurs afterwards during the ISR, - another interrupt will be triggered by the interrupt controller - as soon as the IRQ level is enabled again (see asm/irq.h). - Bottom-half handlers will be processed after scc_isr(). This is - important, since we only have small ringbuffers and want new data - to be fetched/delivered immediately. */ +static inline void rx_on(struct scc_priv *priv) { + unsigned long flags; - if (info->priv[0].type == TYPE_TWIN) { - int is, card_base = info->priv[0].card_base; - while ((is = ~inb(card_base + TWIN_INT_REG)) & - TWIN_INT_MSK) { - if (is & TWIN_SCC_MSK) { - z8530_isr(info); - } else if (is & TWIN_TMR1_MSK) { - inb(card_base + TWIN_CLR_TMR1); - tm_isr(&info->priv[0]); - } else { - inb(card_base + TWIN_CLR_TMR2); - tm_isr(&info->priv[1]); - } + /* Clear RX FIFO */ + while (read_scc(priv, R0) & Rx_CH_AV) read_scc_data(priv); + priv->rx_over = 0; + if (priv->param.dma >= 0) { + /* Program DMA controller */ + flags = claim_dma_lock(); + set_dma_mode(priv->param.dma, DMA_MODE_READ); + set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]); + set_dma_count(priv->param.dma, BUF_SIZE); + release_dma_lock(flags); + enable_dma(priv->param.dma); + /* Configure PackeTwin DMA */ + if (priv->type == TYPE_TWIN) { + outb((priv->param.dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3, + priv->card_base + TWIN_DMA_CFG); } - } else z8530_isr(info); - spin_unlock(info->priv[0].register_lock); - return IRQ_HANDLED; + /* Sp. cond. intr. only, ext int enable, RX DMA enable */ + write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx | + WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB); + } else { + /* Reset current frame */ + priv->rx_ptr = 0; + /* Intr. on all Rx characters and Sp. cond., ext int enable */ + write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT | + WT_FN_RDYFN); + } + write_scc(priv, R0, ERR_RES); + write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB); +} + + +static inline void rx_off(struct scc_priv *priv) { + /* Disable receiver */ + write_scc(priv, R3, Rx8); + /* Disable DREQ / RX interrupt */ + if (priv->param.dma >= 0 && priv->type == TYPE_TWIN) + outb(0, priv->card_base + TWIN_DMA_CFG); + else + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN); + /* Disable DMA */ + if (priv->param.dma >= 0) disable_dma(priv->param.dma); +} + + +static void start_timer(struct scc_priv *priv, int t, int r15) { + unsigned long flags; + + outb(priv->tmr_mode, priv->tmr_ctrl); + if (t == 0) { + tm_isr(priv); + } else if (t > 0) { + save_flags(flags); + cli(); + outb(t & 0xFF, priv->tmr_cnt); + outb((t >> 8) & 0xFF, priv->tmr_cnt); + if (priv->type != TYPE_TWIN) { + write_scc(priv, R15, r15 | CTSIE); + priv->rr0 |= CTS; + } + restore_flags(flags); + } } +static inline unsigned char random(void) { + /* See "Numerical Recipes in C", second edition, p. 284 */ + rand = rand * 1664525L + 1013904223L; + return (unsigned char) (rand >> 24); +} + static inline void z8530_isr(struct scc_info *info) { int is, i = 100; @@ -1009,6 +1082,42 @@ } +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs) { + struct scc_info *info = dev_id; + + spin_lock(info->priv[0].register_lock); + /* At this point interrupts are enabled, and the interrupt under service + is already acknowledged, but masked off. + + Interrupt processing: We loop until we know that the IRQ line is + low. If another positive edge occurs afterwards during the ISR, + another interrupt will be triggered by the interrupt controller + as soon as the IRQ level is enabled again (see asm/irq.h). + + Bottom-half handlers will be processed after scc_isr(). This is + important, since we only have small ringbuffers and want new data + to be fetched/delivered immediately. */ + + if (info->priv[0].type == TYPE_TWIN) { + int is, card_base = info->priv[0].card_base; + while ((is = ~inb(card_base + TWIN_INT_REG)) & + TWIN_INT_MSK) { + if (is & TWIN_SCC_MSK) { + z8530_isr(info); + } else if (is & TWIN_TMR1_MSK) { + inb(card_base + TWIN_CLR_TMR1); + tm_isr(&info->priv[0]); + } else { + inb(card_base + TWIN_CLR_TMR2); + tm_isr(&info->priv[1]); + } + } + } else z8530_isr(info); + spin_unlock(info->priv[0].register_lock); + return IRQ_HANDLED; +} + + static void rx_isr(struct scc_priv *priv) { if (priv->param.dma >= 0) { /* Check special condition and perform error reset. See 2.4.7.5. */ @@ -1292,114 +1401,3 @@ break; } } - - -static inline void tx_on(struct scc_priv *priv) { - int i, n; - unsigned long flags; - - if (priv->param.dma >= 0) { - n = (priv->chip == Z85230) ? 3 : 1; - /* Program DMA controller */ - flags = claim_dma_lock(); - set_dma_mode(priv->param.dma, DMA_MODE_WRITE); - set_dma_addr(priv->param.dma, (int) priv->tx_buf[priv->tx_tail]+n); - set_dma_count(priv->param.dma, priv->tx_len[priv->tx_tail]-n); - release_dma_lock(flags); - /* Enable TX underrun interrupt */ - write_scc(priv, R15, TxUIE); - /* Configure DREQ */ - if (priv->type == TYPE_TWIN) - outb((priv->param.dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3, - priv->card_base + TWIN_DMA_CFG); - else - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB); - /* Write first byte(s) */ - spin_lock_irqsave(priv->register_lock, flags); - for (i = 0; i < n; i++) - write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1); - enable_dma(priv->param.dma); - spin_unlock_irqrestore(priv->register_lock, flags); - } else { - write_scc(priv, R15, TxUIE); - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB); - tx_isr(priv); - } - /* Reset EOM latch if we do not have the AUTOEOM feature */ - if (priv->chip == Z8530) write_scc(priv, R0, RES_EOM_L); -} - - -static inline void rx_on(struct scc_priv *priv) { - unsigned long flags; - - /* Clear RX FIFO */ - while (read_scc(priv, R0) & Rx_CH_AV) read_scc_data(priv); - priv->rx_over = 0; - if (priv->param.dma >= 0) { - /* Program DMA controller */ - flags = claim_dma_lock(); - set_dma_mode(priv->param.dma, DMA_MODE_READ); - set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]); - set_dma_count(priv->param.dma, BUF_SIZE); - release_dma_lock(flags); - enable_dma(priv->param.dma); - /* Configure PackeTwin DMA */ - if (priv->type == TYPE_TWIN) { - outb((priv->param.dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3, - priv->card_base + TWIN_DMA_CFG); - } - /* Sp. cond. intr. only, ext int enable, RX DMA enable */ - write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx | - WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB); - } else { - /* Reset current frame */ - priv->rx_ptr = 0; - /* Intr. on all Rx characters and Sp. cond., ext int enable */ - write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT | - WT_FN_RDYFN); - } - write_scc(priv, R0, ERR_RES); - write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB); -} - - -static inline void rx_off(struct scc_priv *priv) { - /* Disable receiver */ - write_scc(priv, R3, Rx8); - /* Disable DREQ / RX interrupt */ - if (priv->param.dma >= 0 && priv->type == TYPE_TWIN) - outb(0, priv->card_base + TWIN_DMA_CFG); - else - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN); - /* Disable DMA */ - if (priv->param.dma >= 0) disable_dma(priv->param.dma); -} - - -static void start_timer(struct scc_priv *priv, int t, int r15) { - unsigned long flags; - - outb(priv->tmr_mode, priv->tmr_ctrl); - if (t == 0) { - tm_isr(priv); - } else if (t > 0) { - save_flags(flags); - cli(); - outb(t & 0xFF, priv->tmr_cnt); - outb((t >> 8) & 0xFF, priv->tmr_cnt); - if (priv->type != TYPE_TWIN) { - write_scc(priv, R15, r15 | CTSIE); - priv->rr0 |= CTS; - } - restore_flags(flags); - } -} - - -static inline unsigned char random(void) { - /* See "Numerical Recipes in C", second edition, p. 284 */ - rand = rand * 1664525L + 1013904223L; - return (unsigned char) (rand >> 24); -} - From romieu@fr.zoreil.com Mon Aug 2 15:36:20 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:36:27 -0700 (PDT) Received: from fr.zoreil.com (electric-eye.fr.zoreil.com [213.41.134.224]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72MaCBJ018892 for ; Mon, 2 Aug 2004 15:36:19 -0700 Received: from electric-eye.fr.zoreil.com (localhost.localdomain [127.0.0.1]) by fr.zoreil.com (8.12.8/8.12.1) with ESMTP id i72MZah9031941; Tue, 3 Aug 2004 00:35:36 +0200 Received: (from romieu@localhost) by electric-eye.fr.zoreil.com (8.12.8/8.12.1) id i72MZF4G031940; Tue, 3 Aug 2004 00:35:15 +0200 Date: Tue, 3 Aug 2004 00:35:15 +0200 From: Francois Romieu To: Pasi Sjoholm Cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , akpm@osdl.org, netdev@oss.sgi.com, brad@brad-x.com, shemminger@osdl.org Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) Message-ID: <20040803003515.A29885@electric-eye.fr.zoreil.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="bp/iNruPH9dso1Pn" Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from ptsjohol@cc.jyu.fi on Mon, Aug 02, 2004 at 01:03:15PM +0300 X-Organisation: Land of Sunshine Inc. X-archive-position: 7426 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: romieu@fr.zoreil.com Precedence: bulk X-list: netdev --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Pasi Sjoholm : > I forgot to mention that it was quite hard to crash the driver with that > /* Clear out errors and receive interrupts */-patch. Took about 15minutes > everytime, when normally it takes about 2mins. I have made a few changes. Please enable the DEBUG option and set msglvl to its maximal value via ethtool. You may test the patches separately if you find some time but the log once both r8139-10.patch and r8139-20.patch are applied would be enough. If the log fills too fast, you may comment out any message which does not belong to rtl8139_rx(). -- Ueimor --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="r8139-10.patch" - read the interruption status word that the driver will ack before the actual processing is done; - avoid a few heavy pci transactions when several packets are received at the same time. drivers/net/8139too.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff -puN drivers/net/8139too.c~r8139-10 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-10 2004-08-02 22:39:24.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-08-02 23:08:00.000000000 +0200 @@ -1934,12 +1934,15 @@ static int rtl8139_rx(struct net_device int received = 0; unsigned char *rx_ring = tp->rx_ring; unsigned int cur_rx = tp->cur_rx; + u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); + status = RTL_R16 (IntrStatus) & RxAckBits; + while (netif_running(dev) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { u32 ring_offset = cur_rx % RX_BUF_LEN; @@ -1947,7 +1950,6 @@ static int rtl8139_rx(struct net_device unsigned int rx_size; unsigned int pkt_size; struct sk_buff *skb; - u16 status; rmb(); @@ -1977,7 +1979,7 @@ static int rtl8139_rx(struct net_device */ if (unlikely(rx_size == 0xfff0)) { tp->xstats.early_rx++; - goto done; + break; } /* If Rx err or invalid rx_size/rx_status received @@ -1989,7 +1991,8 @@ static int rtl8139_rx(struct net_device (rx_size < 8) || (!(rx_status & RxStatusOK)))) { rtl8139_rx_err (rx_status, dev, tp, ioaddr); - return -1; + received = -1; + goto out; } /* Malloc up new buffer, compatible with net-2e. */ @@ -2024,21 +2027,20 @@ static int rtl8139_rx(struct net_device cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); + } + if (received > 0) { /* Clear out errors and receive interrupts */ - status = RTL_R16 (IntrStatus) & RxAckBits; if (likely(status != 0)) { if (unlikely(status & (RxFIFOOver | RxOverflow))) { tp->stats.rx_errors++; - if (status & RxFIFOOver) + if (status & RxFIFOOver) tp->stats.rx_fifo_errors++; } RTL_W16_F (IntrStatus, RxAckBits); } } - done: - #if RTL8139_DEBUG > 1 DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x," " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, @@ -2047,6 +2049,7 @@ static int rtl8139_rx(struct net_device #endif tp->cur_rx = cur_rx; +out: return received; } _ --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="r8139-20.patch" Let's be sure that the driver will make some progress/reset when crap hits the packet size descriptor. drivers/net/8139too.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) diff -puN drivers/net/8139too.c~r8139-20 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-20 2004-08-02 23:21:36.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-08-03 00:13:56.000000000 +0200 @@ -593,6 +593,7 @@ struct rtl8139_private { int time_to_die; struct mii_if_info mii; unsigned int regs_len; + unsigned long fifo_copy_timeout; }; MODULE_AUTHOR ("Jeff Garzik "); @@ -1937,7 +1938,7 @@ static int rtl8139_rx(struct net_device u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," - " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, + " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); @@ -1978,10 +1979,24 @@ static int rtl8139_rx(struct net_device * since EarlyRx is disabled. */ if (unlikely(rx_size == 0xfff0)) { + if (!tp->fifo_copy_timeout) + tp->fifo_copy_timeout = jiffies + 2; + else if (time_after(jiffies, tp->fifo_copy_timeout)) { + DPRINTK ("%s: hung FIFO. Reset.", dev->name); + rx_size = 0; + goto no_early_rx; + } + if (netif_msg_intr(tp)) { + printk(KERN_DEBUG "%s: fifo copy in progress.", + dev->name); + } tp->xstats.early_rx++; break; } +no_early_rx: + tp->fifo_copy_timeout = 0; + /* If Rx err or invalid rx_size/rx_status received * (which happens if we get lost in the ring), * Rx process gets reset, so we abort any further @@ -2049,6 +2064,14 @@ static int rtl8139_rx(struct net_device #endif tp->cur_rx = cur_rx; + + /* + * The receive buffer should be mostly empty. + * Tell NAPI to reenable the Rx irq. + */ + if (tp->fifo_copy_timeout) + received = budget; + out: return received; } _ --bp/iNruPH9dso1Pn-- From shemminger@osdl.org Mon Aug 2 15:38:32 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:38:36 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72McVwt019243 for ; Mon, 2 Aug 2004 15:38:31 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72Mc5114309; Mon, 2 Aug 2004 15:38:05 -0700 Date: Mon, 2 Aug 2004 15:38:05 -0700 From: Stephen Hemminger To: Jamal Hadi Salim , "David S. Miller" Cc: netdev@oss.sgi.com Subject: iproute2 and kernel headers Message-Id: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7427 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev I am willing to put some headers (not all) in with the user level code, provided they are copies since they I can easily update. I don't want to get into keeping an edited set of headers in sync. What headers really seem to change a lot? The obvious ones are: linux/pkt_sched.h linux/tcp_diag.h linux/xfrm.h From davem@redhat.com Mon Aug 2 16:06:16 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:06:21 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72N6FCJ019781 for ; Mon, 2 Aug 2004 16:06:16 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i72N69e1004105; Mon, 2 Aug 2004 19:06:09 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i72N68a13968; Mon, 2 Aug 2004 19:06:08 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i72N5PA1016870; Mon, 2 Aug 2004 19:05:25 -0400 Date: Mon, 2 Aug 2004 16:04:45 -0700 From: "David S. Miller" To: Stephen Hemminger Cc: hadi@znyx.com, netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-Id: <20040802160445.5ef3b251.davem@redhat.com> In-Reply-To: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7428 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 15:38:05 -0700 Stephen Hemminger wrote: > I am willing to put some headers (not all) in with the user level > code, provided they are copies since they I can easily update. I don't want > to get into keeping an edited set of headers in sync. > > What headers really seem to change a lot? The obvious ones are: > > linux/pkt_sched.h > linux/tcp_diag.h > linux/xfrm.h I would add linux/rtnetlink.h From garzik@havoc.gtf.org Mon Aug 2 16:11:23 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:11:28 -0700 (PDT) Received: from havoc.gtf.org (havoc.gtf.org [216.162.42.101]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72NBNSm020257 for ; Mon, 2 Aug 2004 16:11:23 -0700 Received: from havoc.gtf.org (havoc.gtf.org [127.0.0.1]) by havoc.gtf.org (Postfix) with ESMTP id BD2D575A5; Mon, 2 Aug 2004 19:11:12 -0400 (EDT) Received: (from garzik@localhost) by havoc.gtf.org (8.12.10/8.12.10/Submit) id i72NBC2T001012; Mon, 2 Aug 2004 19:11:12 -0400 Date: Mon, 2 Aug 2004 19:11:12 -0400 From: Jeff Garzik To: Andy Fleming Cc: Andy Fleming , Kumar Gala , "" , jamal , "" , Christoph Hellwig Subject: Re: [RFR] gianfar ethernet driver Message-ID: <20040802231112.GA890@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.1i X-archive-position: 7429 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jgarzik@pobox.com Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 05:19:13PM -0500, Andy Fleming wrote: > Here's an updated patch which fixes module support which does this: > > * More cleanup/minor bug fixes > * Added locking to PHY read/write wrappers > * Fixed module support > * Removed fastroute code > > As before, this patch replaces the previous ones I have submitted. the patch? :) Jeff From afleming@freescale.com Mon Aug 2 16:41:18 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:41:32 -0700 (PDT) Received: from motgate8.mot.com (motgate8.mot.com [129.188.136.8]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72NfFkx024061 for ; Mon, 2 Aug 2004 16:41:17 -0700 Received: from il06exr03.mot.com (il06exr03.mot.com [129.188.137.133]) by motgate8.mot.com (Motorola/Motgate8) with ESMTP id i72NQoRC008533; Mon, 2 Aug 2004 16:26:50 -0700 (MST) Received: from [10.82.17.240] ([10.82.17.240]) by il06exr03.mot.com (Motorola/il06exr03) with ESMTP id i72NPrLl003257; Mon, 2 Aug 2004 18:25:53 -0500 In-Reply-To: <20040802231112.GA890@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> <20040802231112.GA890@havoc.gtf.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: multipart/mixed; boundary=Apple-Mail-1--634686679 Message-Id: <4819CC65-E4DB-11D8-999F-000393C30512@freescale.com> Cc: Andy Fleming , , Kumar Gala , jamal , Christoph Hellwig , From: Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 18:25:46 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7430 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: afleming@freescale.com Precedence: bulk X-list: netdev --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed D'oh! --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: application/octet-stream; x-unix-mode=0644; name="patch_2004_8_2" Content-Disposition: attachment; filename=patch_2004_8_2 diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Mon Aug 2 17:03:36 2004 +++ b/drivers/net/Makefile Mon Aug 2 17:03:36 2004 @@ -10,7 +10,9 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac/ obj-$(CONFIG_IXGB) += ixgb/ obj-$(CONFIG_BONDING) += bonding/ -obj-$(CONFIG_GIANFAR) += gianfar.o gianfar_ethtool.o gianfar_phy.o +obj-$(CONFIG_GIANFAR) += gianfar_driver.o + +gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o # # link order important here diff -Nru a/drivers/net/gianfar.c b/drivers/net/gianfar.c --- a/drivers/net/gianfar.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar.c Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -96,15 +96,6 @@ #include "gianfar.h" #include "gianfar_phy.h" -#ifdef CONFIG_NET_FASTROUTE -#include -#include -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) -#define irqreturn_t void -#define IRQ_HANDLED -#endif #define TX_TIMEOUT (1*HZ) #define SKB_ALLOC_TIMEOUT 1000000 @@ -117,9 +108,8 @@ #define RECEIVE(x) netif_rx(x) #endif -#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.0, " -char gfar_driver_name[] = "Gianfar Ethernet"; -char gfar_driver_version[] = "1.0"; +const char gfar_driver_name[] = "Gianfar Ethernet"; +const char gfar_driver_version[] = "1.1"; int startup_gfar(struct net_device *dev); static int gfar_enet_open(struct net_device *dev); @@ -148,24 +138,11 @@ #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct net_device *dev, int *budget); #endif -#ifdef CONFIG_NET_FASTROUTE -static int gfar_accept_fastpath(struct net_device *dev, struct dst_entry *dst); -#endif -static inline int try_fastroute(struct sk_buff *skb, struct net_device *dev, int length); -#ifdef CONFIG_GFAR_NAPI static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); -#else -static int gfar_clean_rx_ring(struct net_device *dev); -#endif static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); +static void gfar_phy_startup_timer(unsigned long data); extern struct ethtool_ops gfar_ethtool_ops; -extern void gfar_gstrings_normon(struct net_device *dev, u32 stringset, - u8 * buf); -extern void gfar_fill_stats_normon(struct net_device *dev, - struct ethtool_stats *dummy, u64 * buf); -extern int gfar_stats_count_normon(struct net_device *dev); - MODULE_AUTHOR("Freescale Semiconductor, Inc"); MODULE_DESCRIPTION("Gianfar Ethernet Driver"); @@ -183,7 +160,7 @@ struct ocp_gfar_data *einfo; int idx; int err = 0; - struct ethtool_ops *dev_ethtool_ops; + int dev_ethtool_ops = 0; einfo = (struct ocp_gfar_data *) ocpdev->def->additions; @@ -197,7 +174,8 @@ /* get a pointer to the register memory which can * configure the PHYs. If it's different from this set, * get the device which has those regs */ - if ((einfo->phyregidx >= 0) && (einfo->phyregidx != ocpdev->def->index)) { + if ((einfo->phyregidx >= 0) && + (einfo->phyregidx != ocpdev->def->index)) { mdiodev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_GFAR, einfo->phyregidx); @@ -222,7 +200,7 @@ /* get a pointer to the register memory */ priv->regs = (struct gfar *) - ioremap(ocpdev->def->paddr, sizeof (struct gfar)); + ioremap(ocpdev->def->paddr, sizeof (struct gfar)); if (priv->regs == NULL) { err = -ENOMEM; @@ -238,6 +216,8 @@ goto phy_regs_fail; } + spin_lock_init(&priv->lock); + ocp_set_drvdata(ocpdev, dev); /* Stop the DMA engine now, in case it was running before */ @@ -269,15 +249,13 @@ gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the dev structure, */ - /* and into the address registers MAC_STNADDR1,2. */ - /* Backwards, because little endian MACs are dumb. */ - /* Don't set the regs if the firmware already did */ memcpy(dev->dev_addr, einfo->mac_addr, MAC_ADDR_LEN); /* Set the dev->base_addr to the gfar reg region */ dev->base_addr = (unsigned long) (priv->regs); SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &ocpdev->dev); /* Fill in the dev structure */ dev->open = gfar_enet_open; @@ -293,37 +271,16 @@ dev->change_mtu = gfar_change_mtu; dev->mtu = 1500; dev->set_multicast_list = gfar_set_multi; - dev->flags |= IFF_MULTICAST; - dev_ethtool_ops = - (struct ethtool_ops *)kmalloc(sizeof(struct ethtool_ops), - GFP_KERNEL); + /* Index into the array of possible ethtool + * ops to catch all 4 possibilities */ + if((priv->einfo->flags & GFAR_HAS_RMON) == 0) + dev_ethtool_ops += 1; - if(dev_ethtool_ops == NULL) { - err = -ENOMEM; - goto ethtool_fail; - } + if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) + dev_ethtool_ops += 2; - memcpy(dev_ethtool_ops, &gfar_ethtool_ops, sizeof(gfar_ethtool_ops)); - - /* If there is no RMON support in this device, we don't - * want to expose non-existant statistics */ - if((priv->einfo->flags & GFAR_HAS_RMON) == 0) { - dev_ethtool_ops->get_strings = gfar_gstrings_normon; - dev_ethtool_ops->get_stats_count = gfar_stats_count_normon; - dev_ethtool_ops->get_ethtool_stats = gfar_fill_stats_normon; - } - - if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) { - dev_ethtool_ops->set_coalesce = NULL; - dev_ethtool_ops->get_coalesce = NULL; - } - - dev->ethtool_ops = dev_ethtool_ops; - -#ifdef CONFIG_NET_FASTROUTE - dev->accept_fastpath = gfar_accept_fastpath; -#endif + dev->ethtool_ops = gfar_op_array[dev_ethtool_ops]; priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; #ifdef CONFIG_GFAR_BUFSTASH @@ -332,27 +289,26 @@ priv->tx_ring_size = DEFAULT_TX_RING_SIZE; priv->rx_ring_size = DEFAULT_RX_RING_SIZE; - /* Initially, coalescing is disabled */ - priv->txcoalescing = 0; - priv->txcount = 0; - priv->txtime = 0; - priv->rxcoalescing = 0; - priv->rxcount = 0; - priv->rxtime = 0; + priv->txcoalescing = DEFAULT_TX_COALESCE; + priv->txcount = DEFAULT_TXCOUNT; + priv->txtime = DEFAULT_TXTIME; + priv->rxcoalescing = DEFAULT_RX_COALESCE; + priv->rxcount = DEFAULT_RXCOUNT; + priv->rxtime = DEFAULT_RXTIME; err = register_netdev(dev); if (err) { printk(KERN_ERR "%s: Cannot register net device, aborting.\n", - dev->name); + dev->name); goto register_fail; } /* Print out the device info */ - printk(DEVICE_NAME, dev->name); + printk(KERN_INFO DEVICE_NAME, dev->name); for (idx = 0; idx < 6; idx++) - printk("%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); - printk("\n"); + printk(KERN_INFO "%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); + printk(KERN_INFO "\n"); /* Even more device info helps when determining which kernel */ /* provided which set of benchmarks. Since this is global for all */ @@ -367,10 +323,7 @@ return 0; - register_fail: - kfree(dev_ethtool_ops); -ethtool_fail: iounmap((void *) priv->phyregs); phy_regs_fail: iounmap((void *) priv->regs); @@ -386,7 +339,6 @@ ocp_set_drvdata(ocpdev, NULL); - kfree(dev->ethtool_ops); iounmap((void *) priv->regs); iounmap((void *) priv->phyregs); free_netdev(dev); @@ -399,26 +351,90 @@ { struct gfar_private *priv = netdev_priv(dev); struct phy_info *curphy; + unsigned int timeout = PHY_INIT_TIMEOUT; + struct gfar *phyregs = priv->phyregs; + struct gfar_mii_info *mii_info; + int err; - priv->link = 1; priv->oldlink = 0; priv->oldspeed = 0; - priv->olddplx = -1; + priv->oldduplex = -1; + + mii_info = kmalloc(sizeof(struct gfar_mii_info), + GFP_KERNEL); + + if(NULL == mii_info) { + printk(KERN_ERR "%s: Could not allocate mii_info\n", + dev->name); + return -ENOMEM; + } + + mii_info->speed = SPEED_1000; + mii_info->duplex = DUPLEX_FULL; + mii_info->pause = 0; + mii_info->link = 1; + + mii_info->advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Full); + mii_info->autoneg = 1; + + mii_info->mii_id = priv->einfo->phyid; + + mii_info->dev = dev; + + mii_info->mdio_read = &read_phy_reg; + mii_info->mdio_write = &write_phy_reg; + + priv->mii_info = mii_info; + + /* Reset the management interface */ + gfar_write(&phyregs->miimcfg, MIIMCFG_RESET); + + /* Setup the MII Mgmt clock speed */ + gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE); + + /* Wait until the bus is free */ + while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) && + timeout--) + cpu_relax(); + + if(timeout <= 0) { + printk(KERN_ERR "%s: The MII Bus is stuck!\n", + dev->name); + err = -1; + goto bus_fail; + } /* get info for this PHY */ - curphy = get_phy_info(dev); + curphy = get_phy_info(priv->mii_info); if (curphy == NULL) { printk(KERN_ERR "%s: No PHY found\n", dev->name); - return -1; + err = -1; + goto no_phy; } - priv->phyinfo = curphy; + mii_info->phyinfo = curphy; - /* Run the commands which configure the PHY */ - phy_run_commands(dev, curphy->config); + /* Run the commands which initialize the PHY */ + if(curphy->init) { + err = curphy->init(priv->mii_info); + + if (err) + goto phy_init_fail; + } return 0; + +phy_init_fail: +no_phy: +bus_fail: + kfree(mii_info); + + return err; } static void init_registers(struct net_device *dev) @@ -494,7 +510,7 @@ spin_lock_irqsave(&priv->lock, flags); /* Tell the kernel the link is down */ - priv->link = 0; + priv->mii_info->link = 0; adjust_link(dev); /* Mask all interrupts */ @@ -521,7 +537,12 @@ gfar_write(®s->maccfg1, tempval); if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - phy_run_commands(dev, priv->phyinfo->shutdown); + /* Clear any pending interrupts */ + mii_clear_phy_interrupt(priv->mii_info); + + /* Disable PHY Interrupts */ + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_DISABLED); } spin_unlock_irqrestore(&priv->lock, flags); @@ -543,15 +564,17 @@ free_skb_resources(priv); - dma_unmap_single(NULL, gfar_read(®s->tbase), - sizeof(struct txbd)*priv->tx_ring_size, - DMA_BIDIRECTIONAL); - dma_unmap_single(NULL, gfar_read(®s->rbase), - sizeof(struct rxbd)*priv->rx_ring_size, - DMA_BIDIRECTIONAL); + dma_free_coherent(NULL, + sizeof(struct txbd8)*priv->tx_ring_size + + sizeof(struct rxbd8)*priv->rx_ring_size, + priv->tx_bd_base, + gfar_read(®s->tbase)); /* Free the buffer descriptors */ - kfree(priv->tx_bd_base); + kfree(priv->mii_info); + + if (priv->mii_info->phyinfo->close) + priv->mii_info->phyinfo->close(priv->mii_info); } /* If there are any tx skbs or rx skbs still around, free them. @@ -610,7 +633,8 @@ { struct txbd8 *txbdp; struct rxbd8 *rxbdp; - unsigned long addr; + dma_addr_t addr; + unsigned long vaddr; int i; struct gfar_private *priv = netdev_priv(dev); struct gfar *regs = priv->regs; @@ -620,32 +644,27 @@ gfar_write(®s->imask, IMASK_INIT_CLEAR); /* Allocate memory for the buffer descriptors */ - addr = - (unsigned int) kmalloc(sizeof (struct txbd8) * priv->tx_ring_size + - sizeof (struct rxbd8) * priv->rx_ring_size, - GFP_KERNEL); + vaddr = (unsigned long) dma_alloc_coherent(NULL, + sizeof (struct txbd8) * priv->tx_ring_size + + sizeof (struct rxbd8) * priv->rx_ring_size, + &addr, GFP_KERNEL); - if (addr == 0) { + if (vaddr == 0) { printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n", dev->name); return -ENOMEM; } - priv->tx_bd_base = (struct txbd8 *) addr; + priv->tx_bd_base = (struct txbd8 *) vaddr; /* enet DMA only understands physical addresses */ - gfar_write(®s->tbase, - dma_map_single(NULL, (void *)addr, - sizeof(struct txbd8) * priv->tx_ring_size, - DMA_BIDIRECTIONAL)); + gfar_write(®s->tbase, addr); /* Start the rx descriptor ring where the tx ring leaves off */ addr = addr + sizeof (struct txbd8) * priv->tx_ring_size; - priv->rx_bd_base = (struct rxbd8 *) addr; - gfar_write(®s->rbase, - dma_map_single(NULL, (void *)addr, - sizeof(struct rxbd8) * priv->rx_ring_size, - DMA_BIDIRECTIONAL)); + vaddr = vaddr + sizeof (struct txbd8) * priv->tx_ring_size; + priv->rx_bd_base = (struct rxbd8 *) vaddr; + gfar_write(®s->rbase, addr); /* Setup the skbuff rings */ priv->tx_skbuff = @@ -755,39 +774,13 @@ } } - /* Grab the PHY interrupt */ - if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - if (request_irq(priv->einfo->interruptPHY, phy_interrupt, - SA_SHIRQ, "phy_interrupt", dev) < 0) { - printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n", - dev->name, priv->einfo->interruptPHY); - - err = -1; - - if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) - goto phy_irq_fail; - else - goto tx_irq_fail; - } - } else { - init_timer(&priv->phy_info_timer); - priv->phy_info_timer.function = &gfar_phy_timer; - priv->phy_info_timer.data = (unsigned long) dev; - mod_timer(&priv->phy_info_timer, jiffies + 2 * HZ); - } - - /* Set up the bottom half queue */ - INIT_WORK(&priv->tq, (void (*)(void *))gfar_phy_change, dev); + /* Set up the PHY change work queue */ + INIT_WORK(&priv->tq, gfar_phy_change, dev); - /* Configure the PHY interrupt */ - phy_run_commands(dev, priv->phyinfo->startup); - - /* Tell the kernel the link is up, and determine the - * negotiated features (speed, duplex) */ - adjust_link(dev); - - if (priv->link == 0) - printk(KERN_INFO "%s: No link detected\n", dev->name); + init_timer(&priv->phy_info_timer); + priv->phy_info_timer.function = &gfar_phy_startup_timer; + priv->phy_info_timer.data = (unsigned long) priv->mii_info; + mod_timer(&priv->phy_info_timer, jiffies + HZ); /* Configure the coalescing support */ if (priv->txcoalescing) @@ -827,8 +820,6 @@ return 0; -phy_irq_fail: - free_irq(priv->einfo->interruptReceive, dev); rx_irq_fail: free_irq(priv->einfo->interruptTransmit, dev); tx_irq_fail: @@ -837,7 +828,16 @@ rx_skb_fail: free_skb_resources(priv); tx_skb_fail: - kfree(priv->tx_bd_base); + dma_free_coherent(NULL, + sizeof(struct txbd8)*priv->tx_ring_size + + sizeof(struct rxbd8)*priv->rx_ring_size, + priv->tx_bd_base, + gfar_read(®s->tbase)); + kfree(priv->mii_info); + + if (priv->mii_info->phyinfo->close) + priv->mii_info->phyinfo->close(priv->mii_info); + return err; } @@ -854,7 +854,7 @@ err = init_phy(dev); - if (err) + if(err) return err; err = startup_gfar(dev); @@ -971,121 +971,6 @@ return 0; } -/********************************************************************** - * gfar_accept_fastpath - * - * Used to authenticate to the kernel that a fast path entry can be - * added to device's routing table cache - * - * Input : pointer to ethernet interface network device structure and - * a pointer to the designated entry to be added to the cache. - * Output : zero upon success, negative upon failure - **********************************************************************/ -#ifdef CONFIG_NET_FASTROUTE -static int gfar_accept_fastpath(struct net_device *dev, struct dst_entry *dst) -{ - struct net_device *odev = dst->dev; - - if ((dst->ops->protocol != __constant_htons(ETH_P_IP)) - || (odev->type != ARPHRD_ETHER) - || (odev->accept_fastpath == NULL)) { - return -1; - } - - return 0; -} -#endif - -/* try_fastroute() -- Checks the fastroute cache to see if a given packet - * can be routed immediately to another device. If it can, we send it. - * If we used a fastroute, we return 1. Otherwise, we return 0. - * Returns 0 if CONFIG_NET_FASTROUTE is not on - */ -static inline int try_fastroute(struct sk_buff *skb, struct net_device *dev, int length) -{ -#ifdef CONFIG_NET_FASTROUTE - struct ethhdr *eth; - struct iphdr *iph; - unsigned int hash; - struct rtable *rt; - struct net_device *odev; - struct gfar_private *priv = netdev_priv(dev); - unsigned int CPU_ID = smp_processor_id(); - - eth = (struct ethhdr *) (skb->data); - - /* Only route ethernet IP packets */ - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - iph = (struct iphdr *) (skb->data + ETH_HLEN); - - /* Generate the hash value */ - hash = ((*(u8 *) &iph->daddr) ^ (*(u8 *) & iph->saddr)) & NETDEV_FASTROUTE_HMASK; - - rt = (struct rtable *) (dev->fastpath[hash]); - if (rt != NULL - && ((*(u32 *) &iph->daddr) == (*(u32 *) &rt->key.dst)) - && ((*(u32 *) &iph->saddr) == (*(u32 *) &rt->key.src)) - && !(rt->u.dst.obsolete)) { - odev = rt->u.dst.dev; - netdev_rx_stat[CPU_ID].fastroute_hit++; - - /* Make sure the packet is: - * 1) IPv4 - * 2) without any options (header length of 5) - * 3) Not a multicast packet - * 4) going to a valid destination - * 5) Not out of time-to-live - */ - if (iph->version == 4 - && iph->ihl == 5 - && (!(eth->h_dest[0] & 0x01)) - && neigh_is_valid(rt->u.dst.neighbour) - && iph->ttl > 1) { - - /* Fast Route Path: Taken if the outgoing device is ready to transmit the packet now */ - if ((!netif_queue_stopped(odev)) - && (!spin_is_locked(odev->xmit_lock)) - && (skb->len <= (odev->mtu + ETH_HLEN + 2 + 4))) { - - skb->pkt_type = PACKET_FASTROUTE; - skb->protocol = __constant_htons(ETH_P_IP); - ip_decrease_ttl(iph); - memcpy(eth->h_source, odev->dev_addr, MAC_ADDR_LEN); - memcpy(eth->h_dest, rt->u.dst.neighbour->ha, MAC_ADDR_LEN); - skb->dev = odev; - - /* Prep the skb for the packet */ - skb_put(skb, length); - - if (odev->hard_start_xmit(skb, odev) != 0) { - panic("%s: FastRoute path corrupted", dev->name); - } - netdev_rx_stat[CPU_ID].fastroute_success++; - } - - /* Semi Fast Route Path: Mark the packet as needing fast routing, but let the - * stack handle getting it to the device */ - else { - skb->pkt_type = PACKET_FASTROUTE; - skb->nh.raw = skb->data + ETH_HLEN; - skb->protocol = __constant_htons(ETH_P_IP); - netdev_rx_stat[CPU_ID].fastroute_defer++; - - /* Prep the skb for the packet */ - skb_put(skb, length); - - if(RECEIVE(skb) == NET_RX_DROP) { - priv->extra_stats.kernel_dropped++; - } - } - - return 1; - } - } - } -#endif /* CONFIG_NET_FASTROUTE */ - return 0; -} static int gfar_change_mtu(struct net_device *dev, int new_mtu) { @@ -1148,8 +1033,7 @@ startup_gfar(dev); } - if (!netif_queue_stopped(dev)) - netif_schedule(dev); + netif_schedule(dev); } /* Interrupt Handler for Transmit complete */ @@ -1315,7 +1199,7 @@ #else spin_lock(&priv->lock); - gfar_clean_rx_ring(dev); + gfar_clean_rx_ring(dev, priv->rx_ring_size); /* If we are coalescing interrupts, update the timer */ /* Otherwise, clear it */ @@ -1336,7 +1220,7 @@ /* gfar_process_frame() -- handle one incoming packet if skb - * isn't NULL. Try the fastroute before using the stack */ + * isn't NULL. */ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length) { @@ -1350,17 +1234,15 @@ priv->stats.rx_dropped++; priv->extra_stats.rx_skbmissing++; } else { - if(try_fastroute(skb, dev, length) == 0) { - /* Prep the skb for the packet */ - skb_put(skb, length); - - /* Tell the skb what kind of packet this is */ - skb->protocol = eth_type_trans(skb, dev); - - /* Send the packet up the stack */ - if (RECEIVE(skb) == NET_RX_DROP) { - priv->extra_stats.kernel_dropped++; - } + /* Prep the skb for the packet */ + skb_put(skb, length); + + /* Tell the skb what kind of packet this is */ + skb->protocol = eth_type_trans(skb, dev); + + /* Send the packet up the stack */ + if (RECEIVE(skb) == NET_RX_DROP) { + priv->extra_stats.kernel_dropped++; } } @@ -1368,14 +1250,10 @@ } /* gfar_clean_rx_ring() -- Processes each frame in the rx ring - * until all are gone (or, in the case of NAPI, the budget/quota - * has been reached). Returns the number of frames handled + * until the budget/quota has been reached. Returns the number + * of frames handled */ -#ifdef CONFIG_GFAR_NAPI static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) -#else -static int gfar_clean_rx_ring(struct net_device *dev) -#endif { struct rxbd8 *bdp; struct sk_buff *skb; @@ -1386,12 +1264,7 @@ /* Get the first full descriptor */ bdp = priv->cur_rx; -#ifdef CONFIG_GFAR_NAPI -#define GFAR_RXDONE() ((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0)) -#else -#define GFAR_RXDONE() (bdp->status & RXBD_EMPTY) -#endif - while (!GFAR_RXDONE()) { + while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { skb = priv->rx_skbuff[priv->skb_currx]; if (!(bdp->status & @@ -1407,7 +1280,6 @@ gfar_process_frame(dev, skb, pkt_len); priv->stats.rx_bytes += pkt_len; - } else { count_errors(bdp->status, priv); @@ -1462,7 +1334,6 @@ if (rx_work_limit > dev->quota) rx_work_limit = dev->quota; - spin_lock(&priv->lock); howmany = gfar_clean_rx_ring(dev, rx_work_limit); dev->quota -= howmany; @@ -1489,8 +1360,6 @@ priv->rxclean = 1; } - spin_unlock(priv->lock); - return (rx_work_limit < 0) ? 1 : 0; } #endif @@ -1586,10 +1455,14 @@ struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); - /* Run the commands which acknowledge the interrupt */ - phy_run_commands(dev, priv->phyinfo->ack_int); + /* Clear the interrupt */ + mii_clear_phy_interrupt(priv->mii_info); + + /* Disable PHY interrupts */ + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_DISABLED); - /* Schedule the bottom half */ + /* Schedule the phy change */ schedule_work(&priv->tq); return IRQ_HANDLED; @@ -1600,18 +1473,24 @@ { struct net_device *dev = (struct net_device *) data; struct gfar_private *priv = netdev_priv(dev); - int timeout = HZ / 1000 + 1; + int result = 0; /* Delay to give the PHY a chance to change the * register state */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); + msleep(1); - /* Run the commands which check the link state */ - phy_run_commands(dev, priv->phyinfo->handle_int); + /* Update the link, speed, duplex */ + result = priv->mii_info->phyinfo->read_status(priv->mii_info); - /* React to the change in state */ - adjust_link(dev); + /* Adjust the known status as long as the link + * isn't still coming up */ + if((0 == result) || (priv->mii_info->link == 0)) + adjust_link(dev); + + /* Reenable interrupts, if needed */ + if (priv->einfo->flags & GFAR_HAS_PHY_INTR) + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_ENABLED); } /* Called every so often on systems that don't interrupt @@ -1623,7 +1502,72 @@ schedule_work(&priv->tq); - mod_timer(&priv->phy_info_timer, jiffies + 2 * HZ); + mod_timer(&priv->phy_info_timer, jiffies + + GFAR_PHY_CHANGE_TIME * HZ); +} + +/* Keep trying aneg for some time + * If, after GFAR_AN_TIMEOUT seconds, it has not + * finished, we switch to forced. + * Either way, once the process has completed, we either + * request the interrupt, or switch the timer over to + * using gfar_phy_timer to check status */ +static void gfar_phy_startup_timer(unsigned long data) +{ + int result; + static int secondary = GFAR_AN_TIMEOUT; + struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data; + struct gfar_private *priv = netdev_priv(mii_info->dev); + + /* Configure the Auto-negotiation */ + result = mii_info->phyinfo->config_aneg(mii_info); + + /* If autonegotiation failed to start, and + * we haven't timed out, reset the timer, and return */ + if (result && secondary--) { + mod_timer(&priv->phy_info_timer, jiffies + HZ); + return; + } else if (result) { + /* Couldn't start autonegotiation. + * Try switching to forced */ + mii_info->autoneg = 0; + result = mii_info->phyinfo->config_aneg(mii_info); + + /* Forcing failed! Give up */ + if(result) { + printk(KERN_ERR "%s: Forcing failed!\n", + mii_info->dev->name); + return; + } + } + + /* Kill the timer so it can be restarted */ + del_timer_sync(&priv->phy_info_timer); + + /* Grab the PHY interrupt, if necessary/possible */ + if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { + if (request_irq(priv->einfo->interruptPHY, + phy_interrupt, + SA_SHIRQ, + "phy_interrupt", + mii_info->dev) < 0) { + printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n", + mii_info->dev->name, + priv->einfo->interruptPHY); + } else { + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_ENABLED); + return; + } + } + + /* Start the timer again, this time in order to + * handle a change in status */ + init_timer(&priv->phy_info_timer); + priv->phy_info_timer.function = &gfar_phy_timer; + priv->phy_info_timer.data = (unsigned long) mii_info->dev; + mod_timer(&priv->phy_info_timer, jiffies + + GFAR_PHY_CHANGE_TIME * HZ); } /* Called every time the controller might need to be made @@ -1637,12 +1581,13 @@ struct gfar_private *priv = netdev_priv(dev); struct gfar *regs = priv->regs; u32 tempval; + struct gfar_mii_info *mii_info = priv->mii_info; - if (priv->link) { + if (mii_info->link) { /* Now we make sure that we can be in full duplex mode. * If not, we operate in half-duplex mode. */ - if (priv->duplexity != priv->olddplx) { - if (!(priv->duplexity)) { + if (mii_info->duplex != priv->oldduplex) { + if (!(mii_info->duplex)) { tempval = gfar_read(®s->maccfg2); tempval &= ~(MACCFG2_FULL_DUPLEX); gfar_write(®s->maccfg2, tempval); @@ -1658,11 +1603,11 @@ dev->name); } - priv->olddplx = priv->duplexity; + priv->oldduplex = mii_info->duplex; } - if (priv->speed != priv->oldspeed) { - switch (priv->speed) { + if (mii_info->speed != priv->oldspeed) { + switch (mii_info->speed) { case 1000: tempval = gfar_read(®s->maccfg2); tempval = @@ -1679,14 +1624,14 @@ default: printk(KERN_WARNING "%s: Ack! Speed (%d) is not 10/100/1000!\n", - dev->name, priv->speed); + dev->name, mii_info->speed); break; } printk(KERN_INFO "%s: Speed %dBT\n", dev->name, - priv->speed); + mii_info->speed); - priv->oldspeed = priv->speed; + priv->oldspeed = mii_info->speed; } if (!priv->oldlink) { @@ -1700,7 +1645,7 @@ printk(KERN_INFO "%s: Link is down\n", dev->name); priv->oldlink = 0; priv->oldspeed = 0; - priv->olddplx = -1; + priv->oldduplex = -1; netif_carrier_off(dev); } } @@ -1900,11 +1845,7 @@ int rc; rc = ocp_register_driver(&gfar_driver); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) if (rc != 0) { -#else - if (rc == 0) { -#endif ocp_unregister_driver(&gfar_driver); return -ENODEV; } diff -Nru a/drivers/net/gianfar.h b/drivers/net/gianfar.h --- a/drivers/net/gianfar.h Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar.h Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -42,15 +42,7 @@ #include #include #include - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) #include -#else -#include -#define work_struct tq_struct -#define schedule_work schedule_task -#endif - #include #include #include @@ -70,8 +62,13 @@ #define MAC_ADDR_LEN 6 -extern char gfar_driver_name[]; -extern char gfar_driver_version[]; +#define PHY_INIT_TIMEOUT 100000 +#define GFAR_PHY_CHANGE_TIME 2 + +#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, " +#define DRV_NAME "gfar-enet" +extern const char gfar_driver_name[]; +extern const char gfar_driver_version[]; /* These need to be powers of 2 for this driver */ #ifdef CONFIG_GFAR_NAPI @@ -105,11 +102,13 @@ #define GFAR_100_TIME 2560 #define GFAR_10_TIME 25600 +#define DEFAULT_TX_COALESCE 1 #define DEFAULT_TXCOUNT 16 -#define DEFAULT_TXTIME 32768 +#define DEFAULT_TXTIME 400 +#define DEFAULT_RX_COALESCE 1 #define DEFAULT_RXCOUNT 16 -#define DEFAULT_RXTIME 32768 +#define DEFAULT_RXTIME 400 #define TBIPA_VALUE 0x1f #define MIIMCFG_INIT_VALUE 0x00000007 @@ -467,8 +466,7 @@ * empty and completely full conditions. The empty/ready indicator in * the buffer descriptor determines the actual condition. */ -struct gfar_private -{ +struct gfar_private { /* pointers to arrays of skbuffs for tx and rx */ struct sk_buff ** tx_skbuff; struct sk_buff ** rx_skbuff; @@ -496,7 +494,6 @@ struct txbd8 *cur_tx; /* Next free ring entry */ struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */ - struct phy_info *phyinfo; struct gfar *phyregs; struct work_struct tq; struct timer_list phy_info_timer; @@ -509,15 +506,14 @@ unsigned int rx_ring_size; wait_queue_head_t rxcleanupq; unsigned int rxclean; - int link; /* current link state */ - int oldlink; - int duplexity; /* Indicates negotiated duplex state */ - int olddplx; - int speed; /* Indicates negotiated speed */ - int oldspeed; - + /* Info structure initialized by board setup code */ struct ocp_gfar_data *einfo; + + struct gfar_mii_info *mii_info; + int oldspeed; + int oldduplex; + int oldlink; }; extern inline u32 gfar_read(volatile unsigned *addr) @@ -532,6 +528,6 @@ out_be32(addr, val); } - +extern struct ethtool_ops *gfar_op_array[]; #endif /* __GIANFAR_H */ diff -Nru a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c --- a/drivers/net/gianfar_ethtool.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_ethtool.c Mon Aug 2 17:03:36 2004 @@ -1,18 +1,18 @@ /* - * drivers/net/gianfar_ethtool.c + * drivers/net/gianfar_ethtool.c * - * Gianfar Ethernet Driver - * Ethtool support for Gianfar Enet - * Based on e1000 ethtool support + * Gianfar Ethernet Driver + * Ethtool support for Gianfar Enet + * Based on e1000 ethtool support * - * Author: Andy Fleming - * Maintainer: Kumar Gala (kumar.gala@freescale.com) + * Author: Andy Fleming + * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. * - * This software may be used and distributed according to - * the terms of the GNU Public License, Version 2, incorporated herein - * by reference. + * This software may be used and distributed according to + * the terms of the GNU Public License, Version 2, incorporated herein + * by reference. */ #include @@ -58,64 +58,64 @@ void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); static char stat_gstrings[][ETH_GSTRING_LEN] = { - "RX Dropped by Kernel", - "RX Large Frame Errors", - "RX Short Frame Errors", - "RX Non-Octet Errors", - "RX CRC Errors", - "RX Overrun Errors", - "RX Busy Errors", - "RX Babbling Errors", - "RX Truncated Frames", - "Ethernet Bus Error", - "TX Babbling Errors", - "TX Underrun Errors", - "RX SKB Missing Errors", - "TX Timeout Errors", - "tx&rx 64B frames", - "tx&rx 65-127B frames", - "tx&rx 128-255B frames", - "tx&rx 256-511B frames", - "tx&rx 512-1023B frames", - "tx&rx 1024-1518B frames", - "tx&rx 1519-1522B Good VLAN", - "RX bytes", - "RX Packets", - "RX FCS Errors", - "Receive Multicast Packet", - "Receive Broadcast Packet", - "RX Control Frame Packets", - "RX Pause Frame Packets", - "RX Unknown OP Code", - "RX Alignment Error", - "RX Frame Length Error", - "RX Code Error", - "RX Carrier Sense Error", - "RX Undersize Packets", - "RX Oversize Packets", - "RX Fragmented Frames", - "RX Jabber Frames", - "RX Dropped Frames", - "TX Byte Counter", - "TX Packets", - "TX Multicast Packets", - "TX Broadcast Packets", - "TX Pause Control Frames", - "TX Deferral Packets", - "TX Excessive Deferral Packets", - "TX Single Collision Packets", - "TX Multiple Collision Packets", - "TX Late Collision Packets", - "TX Excessive Collision Packets", - "TX Total Collision", - "RESERVED", - "TX Dropped Frames", - "TX Jabber Frames", - "TX FCS Errors", - "TX Control Frames", - "TX Oversize Frames", - "TX Undersize Frames", - "TX Fragmented Frames", + "rx-dropped-by-kernel", + "rx-large-frame-errors", + "rx-short-frame-errors", + "rx-non-octet-errors", + "rx-crc-errors", + "rx-overrun-errors", + "rx-busy-errors", + "rx-babbling-errors", + "rx-truncated-frames", + "ethernet-bus-error", + "tx-babbling-errors", + "tx-underrun-errors", + "rx-skb-missing-errors", + "tx-timeout-errors", + "tx-rx-64-frames", + "tx-rx-65-127-frames", + "tx-rx-128-255-frames", + "tx-rx-256-511-frames", + "tx-rx-512-1023-frames", + "tx-rx-1024-1518-frames", + "tx-rx-1519-1522-good-vlan", + "rx-bytes", + "rx-packets", + "rx-fcs-errors", + "receive-multicast-packet", + "receive-broadcast-packet", + "rx-control-frame-packets", + "rx-pause-frame-packets", + "rx-unknown-op-code", + "rx-alignment-error", + "rx-frame-length-error", + "rx-code-error", + "rx-carrier-sense-error", + "rx-undersize-packets", + "rx-oversize-packets", + "rx-fragmented-frames", + "rx-jabber-frames", + "rx-dropped-frames", + "tx-byte-counter", + "tx-packets", + "tx-multicast-packets", + "tx-broadcast-packets", + "tx-pause-control-frames", + "tx-deferral-packets", + "tx-excessive-deferral-packets", + "tx-single-collision-packets", + "tx-multiple-collision-packets", + "tx-late-collision-packets", + "tx-excessive-collision-packets", + "tx-total-collision", + "reserved", + "tx-dropped-frames", + "tx-jabber-frames", + "tx-fcs-errors", + "tx-control-frames", + "tx-oversize-frames", + "tx-undersize-frames", + "tx-fragmented-frames", }; /* Fill in an array of 64-bit statistics from various sources. @@ -125,7 +125,7 @@ void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u32 *rmon = (u32 *) & priv->regs->rmon; u64 *extra = (u64 *) & priv->extra_stats; struct gfar_stats *stats = (struct gfar_stats *) buf; @@ -154,7 +154,7 @@ struct ethtool_stats *dummy, u64 * buf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u64 *extra = (u64 *) & priv->extra_stats; for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) { @@ -171,7 +171,7 @@ void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { - strncpy(drvinfo->driver, gfar_driver_name, GFAR_INFOSTR_LEN); + strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN); strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN); @@ -184,7 +184,7 @@ /* Return the current settings in the ethtool_cmd structure */ int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); uint gigabit_support = priv->einfo->flags & GFAR_HAS_GIGABIT ? SUPPORTED_1000baseT_Full : 0; uint gigabit_advert = @@ -201,10 +201,10 @@ | ADVERTISED_100baseT_Full | gigabit_advert | ADVERTISED_Autoneg); - cmd->speed = priv->speed; - cmd->duplex = priv->duplexity; + cmd->speed = priv->mii_info->speed; + cmd->duplex = priv->mii_info->duplex; cmd->port = PORT_MII; - cmd->phy_address = priv->einfo->phyid; + cmd->phy_address = priv->mii_info->mii_id; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = AUTONEG_ENABLE; cmd->maxtxpkt = priv->txcount; @@ -223,7 +223,7 @@ void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u32 *theregs = (u32 *) priv->regs; u32 *buf = (u32 *) regbuf; @@ -231,13 +231,6 @@ buf[i] = theregs[i]; } -/* Return the link state 1 is up, 0 is down */ -u32 gfar_get_link(struct net_device *dev) -{ - struct gfar_private *priv = (struct gfar_private *) dev->priv; - return (u32) priv->link; -} - /* Fill in a buffer with the strings which correspond to the * stats */ void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) @@ -252,7 +245,7 @@ unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->speed) { + switch (priv->mii_info->speed) { case 1000: count = GFAR_GBIT_TIME; break; @@ -276,7 +269,7 @@ unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->speed) { + switch (priv->mii_info->speed) { case 1000: count = GFAR_GBIT_TIME; break; @@ -298,7 +291,7 @@ * structure. */ int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); cvals->rx_max_coalesced_frames = priv->rxcount; @@ -344,7 +337,7 @@ */ int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); /* Set up rx coalescing */ if ((cvals->rx_coalesce_usecs == 0) || @@ -386,7 +379,7 @@ * jumbo are ignored by the driver */ void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; @@ -409,7 +402,7 @@ int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { u32 tempval; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); int err = 0; if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) @@ -473,7 +466,7 @@ .get_drvinfo = gfar_gdrvinfo, .get_regs_len = gfar_reglen, .get_regs = gfar_get_regs, - .get_link = gfar_get_link, + .get_link = ethtool_op_get_link, .get_coalesce = gfar_gcoalesce, .set_coalesce = gfar_scoalesce, .get_ringparam = gfar_gringparam, @@ -481,4 +474,52 @@ .get_strings = gfar_gstrings, .get_stats_count = gfar_stats_count, .get_ethtool_stats = gfar_fill_stats, +}; + +struct ethtool_ops gfar_normon_nocoalesce_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings_normon, + .get_stats_count = gfar_stats_count_normon, + .get_ethtool_stats = gfar_fill_stats_normon, +}; + +struct ethtool_ops gfar_nocoalesce_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings, + .get_stats_count = gfar_stats_count, + .get_ethtool_stats = gfar_fill_stats, +}; + +struct ethtool_ops gfar_normon_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_coalesce = gfar_gcoalesce, + .set_coalesce = gfar_scoalesce, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings_normon, + .get_stats_count = gfar_stats_count_normon, + .get_ethtool_stats = gfar_fill_stats_normon, +}; + +struct ethtool_ops *gfar_op_array[] = { + &gfar_ethtool_ops, + &gfar_normon_ethtool_ops, + &gfar_nocoalesce_ethtool_ops, + &gfar_normon_nocoalesce_ethtool_ops }; diff -Nru a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c --- a/drivers/net/gianfar_phy.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_phy.c Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -38,21 +38,31 @@ #include #include #include +#include #include "gianfar.h" #include "gianfar_phy.h" +static void config_genmii_advert(struct gfar_mii_info *mii_info); +static void genmii_setup_forced(struct gfar_mii_info *mii_info); +static void genmii_restart_aneg(struct gfar_mii_info *mii_info); +static int gbit_config_aneg(struct gfar_mii_info *mii_info); +static int genmii_config_aneg(struct gfar_mii_info *mii_info); +static int genmii_update_link(struct gfar_mii_info *mii_info); +static int genmii_read_status(struct gfar_mii_info *mii_info); +u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum); +void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val); + /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -void write_phy_reg(struct net_device *dev, u16 regnum, u16 value) +void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); struct gfar *regbase = priv->phyregs; - struct ocp_gfar_data *einfo = priv->einfo; /* Set the PHY address and the register address we want to write */ - gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum); + gfar_write(®base->miimadd, (mii_id << 8) | regnum); /* Write out the value we want */ gfar_write(®base->miimcon, value); @@ -65,19 +75,18 @@ /* Reads from register regnum in the PHY for device dev, */ /* returning the value. Clears miimcom first. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -u16 read_phy_reg(struct net_device *dev, u16 regnum) +int read_phy_reg(struct net_device *dev, int mii_id, int regnum) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); struct gfar *regbase = priv->phyregs; - struct ocp_gfar_data *einfo = priv->einfo; u16 value; /* Set the PHY address and the register address we want to read */ - gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum); + gfar_write(®base->miimadd, (mii_id << 8) | regnum); /* Clear miimcom, and then initiate a read */ gfar_write(®base->miimcom, 0); - gfar_write(®base->miimcom, MIIM_READ_COMMAND); + gfar_write(®base->miimcom, MII_READ_COMMAND); /* Wait for the transaction to finish */ while (gfar_read(®base->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) @@ -89,362 +98,557 @@ return value; } -/* returns which value to write to the control register. */ -/* For 10/100 the value is slightly different. */ -u16 mii_cr_init(u16 mii_reg, struct net_device * dev) +void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - struct ocp_gfar_data *einfo = priv->einfo; + if(mii_info->phyinfo->ack_interrupt) + mii_info->phyinfo->ack_interrupt(mii_info); +} - if (einfo->flags & GFAR_HAS_GIGABIT) - return MIIM_CONTROL_INIT; - else - return MIIM_CR_INIT; + +void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts) +{ + mii_info->interrupts = interrupts; + if(mii_info->phyinfo->config_intr) + mii_info->phyinfo->config_intr(mii_info); +} + + +/* Writes MII_ADVERTISE with the appropriate values, after + * sanitizing advertise to make sure only supported features + * are advertised + */ +static void config_genmii_advert(struct gfar_mii_info *mii_info) +{ + u32 advertise; + u16 adv; + + /* Only allow advertising what this PHY supports */ + mii_info->advertising &= mii_info->phyinfo->features; + advertise = mii_info->advertising; + + /* Setup standard advertisement */ + adv = phy_read(mii_info, MII_ADVERTISE); + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); + if (advertise & ADVERTISED_10baseT_Half) + adv |= ADVERTISE_10HALF; + if (advertise & ADVERTISED_10baseT_Full) + adv |= ADVERTISE_10FULL; + if (advertise & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + phy_write(mii_info, MII_ADVERTISE, adv); +} + +static void genmii_setup_forced(struct gfar_mii_info *mii_info) +{ + u16 ctrl; + u32 features = mii_info->phyinfo->features; + + ctrl = phy_read(mii_info, MII_BMCR); + + ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE); + ctrl |= BMCR_RESET; + + switch(mii_info->speed) { + case SPEED_1000: + if(features & (SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full)) { + ctrl |= BMCR_SPEED1000; + break; + } + mii_info->speed = SPEED_100; + case SPEED_100: + if (features & (SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full)) { + ctrl |= BMCR_SPEED100; + break; + } + mii_info->speed = SPEED_10; + case SPEED_10: + if (features & (SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full)) + break; + default: /* Unsupported speed! */ + printk(KERN_ERR "%s: Bad speed!\n", + mii_info->dev->name); + break; + } + + phy_write(mii_info, MII_BMCR, ctrl); +} + + +/* Enable and Restart Autonegotiation */ +static void genmii_restart_aneg(struct gfar_mii_info *mii_info) +{ + u16 ctl; + + ctl = phy_read(mii_info, MII_BMCR); + ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); + phy_write(mii_info, MII_BMCR, ctl); +} + + +static int gbit_config_aneg(struct gfar_mii_info *mii_info) +{ + u16 adv; + u32 advertise; + + if(mii_info->autoneg) { + /* Configure the ADVERTISE register */ + config_genmii_advert(mii_info); + advertise = mii_info->advertising; + + adv = phy_read(mii_info, MII_1000BASETCONTROL); + adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | + MII_1000BASETCONTROL_HALFDUPLEXCAP); + if (advertise & SUPPORTED_1000baseT_Half) + adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; + if (advertise & SUPPORTED_1000baseT_Full) + adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; + phy_write(mii_info, MII_1000BASETCONTROL, adv); + + /* Start/Restart aneg */ + genmii_restart_aneg(mii_info); + } else + genmii_setup_forced(mii_info); + + return 0; +} + +static int marvell_config_aneg(struct gfar_mii_info *mii_info) +{ + /* The Marvell PHY has an errata which requires + * that certain registers get written in order + * to restart autonegotiation */ + phy_write(mii_info, MII_BMCR, BMCR_RESET); + + phy_write(mii_info, 0x1d, 0x1f); + phy_write(mii_info, 0x1e, 0x200c); + phy_write(mii_info, 0x1d, 0x5); + phy_write(mii_info, 0x1e, 0); + phy_write(mii_info, 0x1e, 0x100); + + gbit_config_aneg(mii_info); + + return 0; +} +static int genmii_config_aneg(struct gfar_mii_info *mii_info) +{ + if (mii_info->autoneg) { + config_genmii_advert(mii_info); + genmii_restart_aneg(mii_info); + } else + genmii_setup_forced(mii_info); + + return 0; } -#define BRIEF_GFAR_ERRORS -/* Wait for auto-negotiation to complete */ -u16 mii_parse_sr(u16 mii_reg, struct net_device * dev) + +static int genmii_update_link(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + u16 status; - unsigned int timeout = GFAR_AN_TIMEOUT; + /* Do a fake read */ + phy_read(mii_info, MII_BMSR); - if (mii_reg & MIIM_STATUS_LINK) - priv->link = 1; + /* Read link and autonegotiation status */ + status = phy_read(mii_info, MII_BMSR); + if ((status & BMSR_LSTATUS) == 0) + mii_info->link = 0; else - priv->link = 0; + mii_info->link = 1; - /* Only auto-negotiate if the link has just gone up */ - if (priv->link && !priv->oldlink) { - while ((!(mii_reg & MIIM_STATUS_AN_DONE)) && timeout--) - mii_reg = read_phy_reg(dev, MIIM_STATUS); - -#if defined(BRIEF_GFAR_ERRORS) - if (mii_reg & MIIM_STATUS_AN_DONE) - printk(KERN_INFO "%s: Auto-negotiation done\n", - dev->name); - else - printk(KERN_INFO "%s: Auto-negotiation timed out\n", - dev->name); -#endif - } + /* If we are autonegotiating, and not done, + * return an error */ + if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE)) + return -EAGAIN; return 0; } -/* Determine the speed and duplex which was negotiated */ -u16 mii_parse_88E1011_psr(u16 mii_reg, struct net_device * dev) +static int genmii_read_status(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - unsigned int speed; + u16 status; + int err; - if (priv->link) { - if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) - priv->duplexity = 1; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + if (mii_info->autoneg) { + status = phy_read(mii_info, MII_LPA); + + if (status & (LPA_10FULL | LPA_100FULL)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + if (status & (LPA_100FULL | LPA_100HALF)) + mii_info->speed = SPEED_100; else - priv->duplexity = 0; + mii_info->speed = SPEED_10; + mii_info->pause = 0; + } + /* On non-aneg, we assume what we put in BMCR is the speed, + * though magic-aneg shouldn't prevent this case from occurring + */ - speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); + return 0; +} +static int marvell_read_status(struct gfar_mii_info *mii_info) +{ + u16 status; + int err; - switch (speed) { - case MIIM_88E1011_PHYSTAT_GBIT: - priv->speed = 1000; - break; - case MIIM_88E1011_PHYSTAT_100: - priv->speed = 100; - break; - default: - priv->speed = 10; - break; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int speed; + status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); + +#if 0 + /* If speed and duplex aren't resolved, + * return an error. Isn't this handled + * by checking aneg? + */ + if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) + return -EAGAIN; +#endif + + /* Get the duplexity */ + if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + + /* Get the speed */ + speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; + switch(speed) { + case MII_M1011_PHY_SPEC_STATUS_1000: + mii_info->speed = SPEED_1000; + break; + case MII_M1011_PHY_SPEC_STATUS_100: + mii_info->speed = SPEED_100; + break; + default: + mii_info->speed = SPEED_10; + break; } - } else { - priv->speed = 0; - priv->duplexity = 0; + mii_info->pause = 0; } return 0; } -u16 mii_parse_cis8201(u16 mii_reg, struct net_device * dev) + +static int cis820x_read_status(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - unsigned int speed; + u16 status; + int err; - if (priv->link) { - if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX) - priv->duplexity = 1; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int speed; + + status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); + if (status & MII_CIS8201_AUXCONSTAT_DUPLEX) + mii_info->duplex = DUPLEX_FULL; else - priv->duplexity = 0; + mii_info->duplex = DUPLEX_HALF; - speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED; + speed = status & MII_CIS8201_AUXCONSTAT_SPEED; switch (speed) { - case MIIM_CIS8201_AUXCONSTAT_GBIT: - priv->speed = 1000; + case MII_CIS8201_AUXCONSTAT_GBIT: + mii_info->speed = SPEED_1000; break; - case MIIM_CIS8201_AUXCONSTAT_100: - priv->speed = 100; + case MII_CIS8201_AUXCONSTAT_100: + mii_info->speed = SPEED_100; break; default: - priv->speed = 10; + mii_info->speed = SPEED_10; break; } - } else { - priv->speed = 0; - priv->duplexity = 0; } return 0; } -u16 mii_parse_dm9161_scsr(u16 mii_reg, struct net_device * dev) +static int marvell_ack_interrupt(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + /* Clear the interrupts by reading the reg */ + phy_read(mii_info, MII_M1011_IEVENT); - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) - priv->speed = 100; + return 0; +} + +static int marvell_config_intr(struct gfar_mii_info *mii_info) +{ + if(mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); else - priv->speed = 10; + phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); + + return 0; +} + +static int cis820x_init(struct gfar_mii_info *mii_info) +{ + phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, + MII_CIS8201_AUXCONSTAT_INIT); + phy_write(mii_info, MII_CIS8201_EXT_CON1, + MII_CIS8201_EXTCON1_INIT); + + return 0; +} + +static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info) +{ + phy_read(mii_info, MII_CIS8201_ISTAT); - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) - priv->duplexity = 1; + return 0; +} + +static int cis820x_config_intr(struct gfar_mii_info *mii_info) +{ + if(mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); else - priv->duplexity = 0; + phy_write(mii_info, MII_CIS8201_IMASK, 0); return 0; } -u16 dm9161_wait(u16 mii_reg, struct net_device *dev) +#define DM9161_DELAY 10 + +static int dm9161_read_status(struct gfar_mii_info *mii_info) { - int timeout = HZ; - int secondary = 10; - u16 temp; - - do { - - /* Davicom takes a bit to come up after a reset, - * so wait here for a bit */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); - - temp = read_phy_reg(dev, MIIM_STATUS); - - secondary--; - } while ((!(temp & MIIM_STATUS_AN_DONE)) && secondary); - - return 0; -} - -static struct phy_info phy_info_M88E1011S = { - 0x01410c6, - "Marvell 88E1011S", - 4, - (const struct phy_cmd[]) { /* config */ - /* Reset and configure the PHY */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr}, - /* Clear the IEVENT register */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - /* Set up the mask */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - /* Clear the interrupt */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Check the status */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr}, - /* Enable Interrupts */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL}, - {miim_end,} - }, -}; + u16 status; + int err; + + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + status = phy_read(mii_info, MII_DM9161_SCSR); + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) + mii_info->speed = SPEED_100; + else + mii_info->speed = SPEED_10; + + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + } + + return 0; +} + + +static int dm9161_config_aneg(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv = mii_info->priv; + + if(0 == priv->resetdone) + return -EAGAIN; + + return 0; +} + +static void dm9161_timer(unsigned long data) +{ + struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data; + struct dm9161_private *priv = mii_info->priv; + u16 status = phy_read(mii_info, MII_BMSR); + + if (status & BMSR_ANEGCOMPLETE) { + priv->resetdone = 1; + } else + mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); +} + +static int dm9161_init(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv; + + /* Allocate the private data structure */ + priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL); + + if (NULL == priv) + return -ENOMEM; + + mii_info->priv = priv; + + /* Reset is not done yet */ + priv->resetdone = 0; + + /* Isolate the PHY */ + phy_write(mii_info, MII_BMCR, BMCR_ISOLATE); + + /* Do not bypass the scrambler/descrambler */ + phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); + + /* Clear 10BTCSR to default */ + phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); + + /* Reconnect the PHY, and enable Autonegotiation */ + phy_write(mii_info, MII_BMCR, BMCR_ANENABLE); + + /* Start a timer for DM9161_DELAY seconds to wait + * for the PHY to be ready */ + init_timer(&priv->timer); + priv->timer.function = &dm9161_timer; + priv->timer.data = (unsigned long) mii_info; + mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); + + return 0; +} -/* Cicada 8204 */ -static struct phy_info phy_info_cis8204 = { - 0x3f11, +static void dm9161_close(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv = mii_info->priv; + + del_timer_sync(&priv->timer); + kfree(priv); +} + +#if 0 +static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info) +{ + phy_read(mii_info, MII_DM9161_INTR); + + return 0; +} +#endif + +/* Cicada 820x */ +static struct phy_info phy_info_cis820x = { + 0x000fc440, "Cicada Cis8204", - 6, - (const struct phy_cmd[]) { /* config */ - /* Override PHY config settings */ - {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, - /* Set up the interface mode */ - {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Enable interrupts */ - {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_CIS8204_IMASK, 0x0, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - /* Enable interrupts */ - {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_CIS8204_IMASK, 0x0, NULL}, - {miim_end,} - }, + 0x000fffc0, + .features = MII_GBIT_FEATURES, + .init = &cis820x_init, + .config_aneg = &gbit_config_aneg, + .read_status = &cis820x_read_status, + .ack_interrupt = &cis820x_ack_interrupt, + .config_intr = &cis820x_config_intr, }; -/* Cicada 8201 */ -static struct phy_info phy_info_cis8201 = { - 0xfc41, - "CIS8201", - 4, - (const struct phy_cmd[]) { /* config */ - /* Override PHY config settings */ - {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, - /* Set up the interface mode */ - {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {miim_end,} - }, +static struct phy_info phy_info_dm9161 = { + .phy_id = 0x0181b880, + .name = "Davicom DM9161E", + .phy_id_mask = 0x0ffffff0, + .init = dm9161_init, + .config_aneg = dm9161_config_aneg, + .read_status = dm9161_read_status, + .close = dm9161_close, }; -static struct phy_info phy_info_dm9161 = { - 0x0181b88, - "Davicom DM9161E", - 4, - (const struct phy_cmd[]) { /* config */ - {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, - /* Do not bypass the scrambler/descrambler */ - {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, - /* Clear 10BTCSR to default */ - {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CR_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Restart Auto Negotiation */ - {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, dm9161_wait}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr}, - /* Clear any pending interrupts */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - {MIIM_STATUS, miim_read, NULL}, - {MIIM_STATUS, miim_read, mii_parse_sr}, - {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, +static struct phy_info phy_info_marvell = { + .phy_id = 0x01410c00, + .phy_id_mask = 0xffffff00, + .name = "Marvell 88E1101", + .features = MII_GBIT_FEATURES, + .config_aneg = &marvell_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, +}; + +static struct phy_info phy_info_genmii= { + .phy_id = 0x00000000, + .phy_id_mask = 0x00000000, + .name = "Generic MII", + .features = MII_BASIC_FEATURES, + .config_aneg = genmii_config_aneg, + .read_status = genmii_read_status, }; static struct phy_info *phy_info[] = { - &phy_info_cis8201, - &phy_info_cis8204, - &phy_info_M88E1011S, + &phy_info_cis820x, + &phy_info_marvell, &phy_info_dm9161, + &phy_info_genmii, NULL }; +u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum) +{ + u16 retval; + unsigned long flags; + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); + + return retval; +} + +void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val) +{ + unsigned long flags; + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + mii_info->mdio_write(mii_info->dev, + mii_info->mii_id, + regnum, val); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); +} + /* Use the PHY ID registers to determine what type of PHY is attached * to device dev. return a struct phy_info structure describing that PHY */ -struct phy_info * get_phy_info(struct net_device *dev) +struct phy_info * get_phy_info(struct gfar_mii_info *mii_info) { u16 phy_reg; u32 phy_ID; int i; struct phy_info *theInfo = NULL; + struct net_device *dev = mii_info->dev; /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = read_phy_reg(dev, MIIM_PHYIR1); + phy_reg = phy_read(mii_info, MII_PHYSID1); phy_ID = (phy_reg & 0xffff) << 16; /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = read_phy_reg(dev, MIIM_PHYIR2); + phy_reg = phy_read(mii_info, MII_PHYSID2); phy_ID |= (phy_reg & 0xffff); /* loop through all the known PHY types, and find one that */ /* matches the ID we read from the PHY. */ for (i = 0; phy_info[i]; i++) - if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) + if (phy_info[i]->phy_id == + (phy_ID & phy_info[i]->phy_id_mask)) { theInfo = phy_info[i]; + break; + } + /* This shouldn't happen, as we have generic PHY support */ if (theInfo == NULL) { printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID); return NULL; @@ -454,51 +658,4 @@ } return theInfo; -} - -/* Take a list of struct phy_cmd, and, depending on the values, either */ -/* read or write, using a helper function if provided */ -/* It is assumed that all lists of struct phy_cmd will be terminated by */ -/* mii_end. */ -void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd) -{ - int i; - u16 result; - struct gfar_private *priv = (struct gfar_private *) dev->priv; - struct gfar *phyregs = priv->phyregs; - - /* Reset the management interface */ - gfar_write(&phyregs->miimcfg, MIIMCFG_RESET); - - /* Setup the MII Mgmt clock speed */ - gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE); - - /* Wait until the bus is free */ - while (gfar_read(&phyregs->miimind) & MIIMIND_BUSY) - cpu_relax(); - - for (i = 0; cmd->mii_reg != miim_end; i++) { - /* The command is a read if mii_data is miim_read */ - if (cmd->mii_data == miim_read) { - /* Read the value of the PHY reg */ - result = read_phy_reg(dev, cmd->mii_reg); - - /* If a function was supplied, we need to let it process */ - /* the result. */ - if (cmd->funct != NULL) - (*(cmd->funct)) (result, dev); - } else { /* Otherwise, it's a write */ - /* If a function was supplied, it will provide - * the value to write */ - /* Otherwise, the value was supplied in cmd->mii_data */ - if (cmd->funct != NULL) - result = (*(cmd->funct)) (0, dev); - else - result = cmd->mii_data; - - /* Write the appropriate value to the PHY reg */ - write_phy_reg(dev, cmd->mii_reg, result); - } - cmd++; - } } diff -Nru a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h --- a/drivers/net/gianfar_phy.h Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_phy.h Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -19,135 +19,144 @@ #ifndef __GIANFAR_PHY_H #define __GIANFAR_PHY_H -#define miim_end ((u32)-2) -#define miim_read ((u32)-1) +#define MII_end ((u32)-2) +#define MII_read ((u32)-1) #define MIIMIND_BUSY 0x00000001 #define MIIMIND_NOTVALID 0x00000004 -#define MIIM_CONTROL 0x00 -#define MIIM_CONTROL_RESET 0x00008000 -#define MIIM_CONTROL_INIT 0x00001140 -#define MIIM_ANEN 0x00001000 - -#define MIIM_CR 0x00 -#define MIIM_CR_RST 0x00008000 -#define MIIM_CR_INIT 0x00001000 - -#define MIIM_STATUS 0x1 -#define MIIM_STATUS_AN_DONE 0x00000020 -#define MIIM_STATUS_LINK 0x0004 - -#define MIIM_PHYIR1 0x2 -#define MIIM_PHYIR2 0x3 - -#define GFAR_AN_TIMEOUT 0x000fffff - -#define MIIM_ANLPBPA 0x5 -#define MIIM_ANLPBPA_HALF 0x00000040 -#define MIIM_ANLPBPA_FULL 0x00000020 - -#define MIIM_ANEX 0x6 -#define MIIM_ANEX_NP 0x00000004 -#define MIIM_ANEX_PRX 0x00000002 +#define GFAR_AN_TIMEOUT 2000 +/* 1000BT control (Marvell & BCM54xx at least) */ +#define MII_1000BASETCONTROL 0x09 +#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200 +#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100 /* Cicada Extended Control Register 1 */ -#define MIIM_CIS8201_EXT_CON1 0x17 -#define MIIM_CIS8201_EXTCON1_INIT 0x0000 +#define MII_CIS8201_EXT_CON1 0x17 +#define MII_CIS8201_EXTCON1_INIT 0x0000 /* Cicada Interrupt Mask Register */ -#define MIIM_CIS8204_IMASK 0x19 -#define MIIM_CIS8204_IMASK_IEN 0x8000 -#define MIIM_CIS8204_IMASK_SPEED 0x4000 -#define MIIM_CIS8204_IMASK_LINK 0x2000 -#define MIIM_CIS8204_IMASK_DUPLEX 0x1000 -#define MIIM_CIS8204_IMASK_MASK 0xf000 +#define MII_CIS8201_IMASK 0x19 +#define MII_CIS8201_IMASK_IEN 0x8000 +#define MII_CIS8201_IMASK_SPEED 0x4000 +#define MII_CIS8201_IMASK_LINK 0x2000 +#define MII_CIS8201_IMASK_DUPLEX 0x1000 +#define MII_CIS8201_IMASK_MASK 0xf000 /* Cicada Interrupt Status Register */ -#define MIIM_CIS8204_ISTAT 0x1a -#define MIIM_CIS8204_ISTAT_STATUS 0x8000 -#define MIIM_CIS8204_ISTAT_SPEED 0x4000 -#define MIIM_CIS8204_ISTAT_LINK 0x2000 -#define MIIM_CIS8204_ISTAT_DUPLEX 0x1000 +#define MII_CIS8201_ISTAT 0x1a +#define MII_CIS8201_ISTAT_STATUS 0x8000 +#define MII_CIS8201_ISTAT_SPEED 0x4000 +#define MII_CIS8201_ISTAT_LINK 0x2000 +#define MII_CIS8201_ISTAT_DUPLEX 0x1000 /* Cicada Auxiliary Control/Status Register */ -#define MIIM_CIS8201_AUX_CONSTAT 0x1c -#define MIIM_CIS8201_AUXCONSTAT_INIT 0x0004 -#define MIIM_CIS8201_AUXCONSTAT_DUPLEX 0x0020 -#define MIIM_CIS8201_AUXCONSTAT_SPEED 0x0018 -#define MIIM_CIS8201_AUXCONSTAT_GBIT 0x0010 -#define MIIM_CIS8201_AUXCONSTAT_100 0x0008 +#define MII_CIS8201_AUX_CONSTAT 0x1c +#define MII_CIS8201_AUXCONSTAT_INIT 0x0004 +#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 +#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 +#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 +#define MII_CIS8201_AUXCONSTAT_100 0x0008 /* 88E1011 PHY Status Register */ -#define MIIM_88E1011_PHY_STATUS 0x11 -#define MIIM_88E1011_PHYSTAT_SPEED 0xc000 -#define MIIM_88E1011_PHYSTAT_GBIT 0x8000 -#define MIIM_88E1011_PHYSTAT_100 0x4000 -#define MIIM_88E1011_PHYSTAT_DUPLEX 0x2000 -#define MIIM_88E1011_PHYSTAT_LINK 0x0400 - -#define MIIM_88E1011_IEVENT 0x13 -#define MIIM_88E1011_IEVENT_CLEAR 0x0000 - -#define MIIM_88E1011_IMASK 0x12 -#define MIIM_88E1011_IMASK_INIT 0x6400 -#define MIIM_88E1011_IMASK_CLEAR 0x0000 - -/* DM9161 Control register values */ -#define MIIM_DM9161_CR_STOP 0x0400 -#define MIIM_DM9161_CR_RSTAN 0x1200 +#define MII_M1011_PHY_SPEC_STATUS 0x11 +#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000 +#define MII_M1011_PHY_SPEC_STATUS_100 0x4000 +#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000 +#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000 +#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800 +#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400 + +#define MII_M1011_IEVENT 0x13 +#define MII_M1011_IEVENT_CLEAR 0x0000 + +#define MII_M1011_IMASK 0x12 +#define MII_M1011_IMASK_INIT 0x6400 +#define MII_M1011_IMASK_CLEAR 0x0000 -#define MIIM_DM9161_SCR 0x10 -#define MIIM_DM9161_SCR_INIT 0x0610 +#define MII_DM9161_SCR 0x10 +#define MII_DM9161_SCR_INIT 0x0610 /* DM9161 Specified Configuration and Status Register */ -#define MIIM_DM9161_SCSR 0x11 -#define MIIM_DM9161_SCSR_100F 0x8000 -#define MIIM_DM9161_SCSR_100H 0x4000 -#define MIIM_DM9161_SCSR_10F 0x2000 -#define MIIM_DM9161_SCSR_10H 0x1000 +#define MII_DM9161_SCSR 0x11 +#define MII_DM9161_SCSR_100F 0x8000 +#define MII_DM9161_SCSR_100H 0x4000 +#define MII_DM9161_SCSR_10F 0x2000 +#define MII_DM9161_SCSR_10H 0x1000 /* DM9161 Interrupt Register */ -#define MIIM_DM9161_INTR 0x15 -#define MIIM_DM9161_INTR_PEND 0x8000 -#define MIIM_DM9161_INTR_DPLX_MASK 0x0800 -#define MIIM_DM9161_INTR_SPD_MASK 0x0400 -#define MIIM_DM9161_INTR_LINK_MASK 0x0200 -#define MIIM_DM9161_INTR_MASK 0x0100 -#define MIIM_DM9161_INTR_DPLX_CHANGE 0x0010 -#define MIIM_DM9161_INTR_SPD_CHANGE 0x0008 -#define MIIM_DM9161_INTR_LINK_CHANGE 0x0004 -#define MIIM_DM9161_INTR_INIT 0x0000 -#define MIIM_DM9161_INTR_STOP \ -(MIIM_DM9161_INTR_DPLX_MASK | MIIM_DM9161_INTR_SPD_MASK \ - | MIIM_DM9161_INTR_LINK_MASK | MIIM_DM9161_INTR_MASK) +#define MII_DM9161_INTR 0x15 +#define MII_DM9161_INTR_PEND 0x8000 +#define MII_DM9161_INTR_DPLX_MASK 0x0800 +#define MII_DM9161_INTR_SPD_MASK 0x0400 +#define MII_DM9161_INTR_LINK_MASK 0x0200 +#define MII_DM9161_INTR_MASK 0x0100 +#define MII_DM9161_INTR_DPLX_CHANGE 0x0010 +#define MII_DM9161_INTR_SPD_CHANGE 0x0008 +#define MII_DM9161_INTR_LINK_CHANGE 0x0004 +#define MII_DM9161_INTR_INIT 0x0000 +#define MII_DM9161_INTR_STOP \ +(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ + | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) /* DM9161 10BT Configuration/Status */ -#define MIIM_DM9161_10BTCSR 0x12 -#define MIIM_DM9161_10BTCSR_INIT 0x7800 +#define MII_DM9161_10BTCSR 0x12 +#define MII_DM9161_10BTCSR_INIT 0x7800 - -#define MIIM_READ_COMMAND 0x00000001 - -/* - * struct phy_cmd: A command for reading or writing a PHY register - * - * mii_reg: The register to read or write - * - * mii_data: For writes, the value to put in the register. - * A value of -1 indicates this is a read. - * - * funct: A function pointer which is invoked for each command. - * For reads, this function will be passed the value read - * from the PHY, and process it. - * For writes, the result of this function will be written - * to the PHY register - */ -struct phy_cmd { - u32 mii_reg; - u32 mii_data; - u16 (*funct) (u16 mii_reg, struct net_device * dev); +#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ + SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | \ + SUPPORTED_100baseT_Full | \ + SUPPORTED_Autoneg | \ + SUPPORTED_TP | \ + SUPPORTED_MII) + +#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ + SUPPORTED_1000baseT_Half | \ + SUPPORTED_1000baseT_Full) + +#define MII_READ_COMMAND 0x00000001 + +#define MII_INTERRUPT_DISABLED 0x0 +#define MII_INTERRUPT_ENABLED 0x1 +/* Taken from mii_if_info and sungem_phy.h */ +struct gfar_mii_info { + /* Information about the PHY type */ + /* And management functions */ + struct phy_info *phyinfo; + + /* forced speed & duplex (no autoneg) + * partner speed & duplex & pause (autoneg) + */ + int speed; + int duplex; + int pause; + + /* The most recently read link state */ + int link; + + /* Enabled Interrupts */ + u32 interrupts; + + u32 advertising; + int autoneg; + int mii_id; + + /* private data pointer */ + /* For use by PHYs to maintain extra state */ + void *priv; + + /* Provided by host chip */ + struct net_device *dev; + + /* A lock to ensure that only one thing can read/write + * the MDIO bus at a time */ + spinlock_t mdio_lock; + + /* Provided by ethernet driver */ + int (*mdio_read) (struct net_device *dev, int mii_id, int reg); + void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); }; /* struct phy_info: a structure which defines attributes for a PHY @@ -155,38 +164,50 @@ * id will contain a number which represents the PHY. During * startup, the driver will poll the PHY to find out what its * UID--as defined by registers 2 and 3--is. The 32-bit result - * gotten from the PHY will be shifted right by "shift" bits to + * gotten from the PHY will be ANDed with phy_id_mask to * discard any bits which may change based on revision numbers * unimportant to functionality * - * The struct phy_cmd entries represent pointers to an arrays of - * commands which tell the driver what to do to the PHY. + * There are 6 commands which take a gfar_mii_info structure. + * Each PHY must declare config_aneg, and read_status. */ struct phy_info { - u32 id; - char *name; - unsigned int shift; - /* Called to configure the PHY, and modify the controller - * based on the results */ - const struct phy_cmd *config; - - /* Called when starting up the controller. Usually sets - * up the interrupt for state changes */ - const struct phy_cmd *startup; - - /* Called inside the interrupt handler to acknowledge - * the interrupt */ - const struct phy_cmd *ack_int; - - /* Called in the bottom half to handle the interrupt */ - const struct phy_cmd *handle_int; - - /* Called when bringing down the controller. Usually stops - * the interrupts from being generated */ - const struct phy_cmd *shutdown; + u32 phy_id; + char *name; + unsigned int phy_id_mask; + u32 features; + + /* Called to initialize the PHY */ + int (*init)(struct gfar_mii_info *mii_info); + + /* Called to suspend the PHY for power */ + int (*suspend)(struct gfar_mii_info *mii_info); + + /* Reconfigures autonegotiation (or disables it) */ + int (*config_aneg)(struct gfar_mii_info *mii_info); + + /* Determines the negotiated speed and duplex */ + int (*read_status)(struct gfar_mii_info *mii_info); + + /* Clears any pending interrupts */ + int (*ack_interrupt)(struct gfar_mii_info *mii_info); + + /* Enables or disables interrupts */ + int (*config_intr)(struct gfar_mii_info *mii_info); + + /* Clears up any memory if needed */ + void (*close)(struct gfar_mii_info *mii_info); }; -struct phy_info *get_phy_info(struct net_device *dev); -void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd); +struct phy_info *get_phy_info(struct gfar_mii_info *mii_info); +int read_phy_reg(struct net_device *dev, int mii_id, int regnum); +void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value); +void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info); +void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts); + +struct dm9161_private { + struct timer_list timer; + int resetdone; +}; #endif /* GIANFAR_PHY_H */ diff -Nru a/include/linux/mii.h b/include/linux/mii.h --- a/include/linux/mii.h Mon Aug 2 17:03:36 2004 +++ b/include/linux/mii.h Mon Aug 2 17:03:36 2004 @@ -33,7 +33,8 @@ #define MII_NCONFIG 0x1c /* Network interface config */ /* Basic mode control register. */ -#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ #define BMCR_CTST 0x0080 /* Collision test */ #define BMCR_FULLDPLX 0x0100 /* Full duplex */ #define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed On Aug 2, 2004, at 18:11, Jeff Garzik wrote: > On Mon, Aug 02, 2004 at 05:19:13PM -0500, Andy Fleming wrote: >> Here's an updated patch which fixes module support which does this: >> >> * More cleanup/minor bug fixes >> * Added locking to PHY read/write wrappers >> * Fixed module support >> * Removed fastroute code >> >> As before, this patch replaces the previous ones I have submitted. > > the patch? :) > > Jeff > --Apple-Mail-1--634686679-- From matthias.andree@gmx.de Mon Aug 2 17:09:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:09:54 -0700 (PDT) Received: from mail.dt.e-technik.uni-dortmund.de (IDENT:7RfVXN0v6r7rTx3dughqjqVtOTfrqSoX@mail.dt.E-Technik.Uni-Dortmund.DE [129.217.163.1]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7309jrR025163 for ; Mon, 2 Aug 2004 17:09:46 -0700 Received: from m2a2.dyndns.org (pD9E1ED50.dip.t-dialin.net [217.225.237.80]) by mail.dt.e-technik.uni-dortmund.de (Postfix) with ESMTP id 49E492BDA5; Tue, 3 Aug 2004 02:09:40 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by merlin.emma.line.org (Postfix) with ESMTP id 87AF9C2C65; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Received: from merlin.emma.line.org ([127.0.0.1]) by localhost (m2a2.dyndns.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 05176-02; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Received: by merlin.emma.line.org (Postfix, from userid 500) id 28218C1104; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Date: Tue, 3 Aug 2004 02:03:54 +0200 From: Matthias Andree To: Andrew Morton Cc: Matthias Andree , netdev@oss.sgi.com Subject: Re: 2.6.8-rc2-mm1 breaks PPPoE for me (was: 2.6.8-rc2-mm1) Message-ID: <20040803000354.GA5327@merlin.emma.line.org> References: <20040728020444.4dca7e23.akpm@osdl.org> <20040731100947.GA7453@merlin.emma.line.org> <20040802142706.46100c6d.akpm@osdl.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040802142706.46100c6d.akpm@osdl.org> User-Agent: Mutt/1.5.6i X-Virus-Scanned: by amavisd-new at m2a2.dyndns.org X-archive-position: 7431 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: matthias.andree@gmx.de Precedence: bulk X-list: netdev On Mon, 02 Aug 2004, Andrew Morton wrote: > I'm a bit stumped by this - I'm not aware of any change which would have > caused the pppoe device to start returning -ENOTTY. > > Is this still happening? Are you sure the relevant modules are loaded? > Could you capture an strace of pppd while it's happening? It happens in 2.6.8-rc2-mm2, too. The strace is inconclusive. Setup description: I am running pppd 2.4.1 (SuSE 8.2 RPM) with the PPPOE plugin tied to eth1: PCI: Enabling device 0000:00:0b.0 (0004 -> 0005) ACPI: PCI interrupt 0000:00:0b.0[A] -> GSI 19 (level, low) -> IRQ 19 0000:00:0b.0: 3Com PCI 3c905 Boomerang 100baseTx at 0xd400. Vers LK1.1.19 eth1: Dropping NETIF_F_SG since no checksum feature. I am starting pppd via DJB's daemontools (http://cr.yp.to/daemontools.html), with this run file: #! /bin/sh exec strace -ff -F -o /tmp/dump-pppd /usr/sbin/pppd call pppoe Starting pppd from a bash (in an xterm, only thing I've tried) works, I get a connection. Writing such a pppd command into inittab yields ENOENT rather than ENOTTY and fails as well. The strace looks unhelpful to me, the only occurrence of ENOTTY is: readlink("/proc/self/fd/0", "/dev/null", 511) = 9 ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffff700) = -1 ENOTTY (Inappropriate ioctl for device) ltrace reveals this happens inside getlogin() - and pppd appears to fall back to getpwuid. I'd think this is unrelated for I have the same lines with a working kernel as well. Using rp-pppoe as pty (instead of the plugin) doesn't work either, the PPP link is negotiated properly but my log is full of "martian address" log entries as though it was receiving its own packets externally. How strange. I wonder if this is an strace artifact... No useful debugging information. I hope someone can reproduce this. :-( -- Matthias Andree Encrypted mail welcome: my GnuPG key ID is 0x052E7D95 (PGP/MIME preferred) From davem@redhat.com Mon Aug 2 17:09:55 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:10:01 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7309s6o025172 for ; Mon, 2 Aug 2004 17:09:55 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i7309fe1015846; Mon, 2 Aug 2004 20:09:41 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i7309fa28153; Mon, 2 Aug 2004 20:09:41 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i7308vtZ014741; Mon, 2 Aug 2004 20:08:58 -0400 Date: Mon, 2 Aug 2004 17:08:17 -0700 From: "David S. Miller" To: yoshfuji@linux-ipv6.org Cc: suckfish@ihug.co.nz, pekkas@netcore.fi, linux-kernel@vger.kernel.org, yoshfuji@linux-ipv6.org, netdev@oss.sgi.com Subject: Re: [PATCH] Trivial ipv6 fix. Message-Id: <20040802170817.3f9be894.davem@redhat.com> In-Reply-To: <20040802.065940.86004622.yoshfuji@linux-ipv6.org> References: <1091434328.16469.5.camel@localhost.localdomain> <20040802.065940.86004622.yoshfuji@linux-ipv6.org> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by oss.sgi.com id i7309s6o025172 X-archive-position: 7432 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 02 Aug 2004 06:59:40 -0700 (PDT) YOSHIFUJI Hideaki / $B5HF#1QL@(B wrote: > In article <1091434328.16469.5.camel@localhost.localdomain> (at Mon, 02 Aug 2004 20:12:08 +1200), Ralph Loader says: > > > ipv6_addr_hash doesn't do what it's comment says. The comment was > > probably what was intended, not that it'll make much difference in > > practice. > > Oops, David, please apply this. Done, thanks guys. From davem@redhat.com Mon Aug 2 17:11:07 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:11:15 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730B6eu025460 for ; Mon, 2 Aug 2004 17:11:07 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i730Ate1016125; Mon, 2 Aug 2004 20:10:55 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i730Ata28669; Mon, 2 Aug 2004 20:10:55 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i730ABRe015548; Mon, 2 Aug 2004 20:10:11 -0400 Date: Mon, 2 Aug 2004 17:09:30 -0700 From: "David S. Miller" To: Herbert Xu Cc: netdev@oss.sgi.com Subject: Re: [1/2] [IPSEC] Remove unnecessary inet_ecn.h inclusions Message-Id: <20040802170930.2073894f.davem@redhat.com> In-Reply-To: <20040802093153.GA19706@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7433 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 19:31:53 +1000 Herbert Xu wrote: > I should've removed the inet_ecn.h inclusions in that change as the > ECN code has been moved to xfrm[46]_output.c. This patch does exactly > that. Ok, applied. From achirica@telefonica.net Mon Aug 2 17:12:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:12:27 -0700 (PDT) Received: from pc22.admin.cnc (194-179-2-161.mad.ttd.net [194.179.2.161]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730CKSx026003 for ; Mon, 2 Aug 2004 17:12:21 -0700 Received: from tudela.mad.ttd.net (tudela.gestion.cnc [172.24.8.233]) by pc22.admin.cnc (8.11.2/8.11.2/SuSE Linux 8.11.1-0.5) with ESMTP id i730CAq05669; Tue, 3 Aug 2004 02:12:10 +0200 Received: from localhost (localhost [127.0.0.1]) by tudela.mad.ttd.net (8.11.6/8.11.6) with ESMTP id i730C9g13773; Tue, 3 Aug 2004 02:12:09 +0200 (MEST) Date: Tue, 3 Aug 2004 02:12:09 +0200 (MEST) From: Javier Achirica X-Sender: To: cc: Jeff Garzik , Subject: Re: [PATCH 2.6] airo.c set_bit bug In-Reply-To: <20040723002114.GA11815@bougret.hpl.hp.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-archive-position: 7434 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: achirica@telefonica.net Precedence: bulk X-list: netdev Thanks. Applied. I haven't found any other occurrence. Javier Achirica On Thu, 22 Jul 2004, Jean Tourrilhes wrote: > Hi Javier, > > Managed to find a bug in the usage of set_bit/clear_bit in the > airo driver. I'm not sure if I caught all occurence of this pattern, > and not sure about exact consequences of the bug, but we might as well > fix it... > Patch below... > > Have fun... > > Jean > > -------------------------------------------------------- > > --- linux/drivers/net/wireless/airo.j1.c Thu Jul 22 15:27:48 2004 > +++ linux/drivers/net/wireless/airo.c Thu Jul 22 15:29:11 2004 > @@ -1808,7 +1808,8 @@ static int writeConfigRid(struct airo_in > if (!test_bit (FLAG_COMMIT, &ai->flags)) > return SUCCESS; > > - clear_bit (FLAG_COMMIT | FLAG_RESET, &ai->flags); > + clear_bit (FLAG_COMMIT, &ai->flags); > + clear_bit (FLAG_RESET, &ai->flags); > checkThrottle(ai); > cfgr = ai->config; > > @@ -6158,7 +6159,8 @@ static int airo_set_txpow(struct net_dev > readCapabilityRid(local, &cap_rid); > > if (vwrq->disabled) { > - set_bit (FLAG_RADIO_OFF | FLAG_COMMIT, &local->flags); > + set_bit (FLAG_RADIO_OFF, &local->flags); > + set_bit (FLAG_COMMIT, &local->flags); > return -EINPROGRESS; /* Call commit handler */ > } > if (vwrq->flags != IW_TXPOW_MWATT) { > From davem@redhat.com Mon Aug 2 17:12:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:13:03 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730Cw08026236 for ; Mon, 2 Aug 2004 17:12:58 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i730Coe1016484; Mon, 2 Aug 2004 20:12:50 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i730Coa29031; Mon, 2 Aug 2004 20:12:50 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i730C7SI016381; Mon, 2 Aug 2004 20:12:07 -0400 Date: Mon, 2 Aug 2004 17:11:26 -0700 From: "David S. Miller" To: Herbert Xu Cc: netdev@oss.sgi.com Subject: Re: [2/2] [IPSEC] Move xfrm[46]_tunnel_check_size into xfrm[46]_output.c Message-Id: <20040802171126.09dc4887.davem@redhat.com> In-Reply-To: <20040802093500.GA19747@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> <20040802093500.GA19747@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7435 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 19:35:00 +1000 Herbert Xu wrote: > This patch moves xfrm[46]_tunnel_check_size() into xfrm[46]_output.c > where it can be made static since it's only used there. > > While moving the icmp.h inclusions over I also discovered that the > tunnel files are missing an inclusion of net/protocol.h. So I've > added them as well. The net/xfrm.h hunk failed, but I fixed that up by hand. Applied, thanks. From zdzichu@irc.pl Mon Aug 2 17:15:03 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:15:09 -0700 (PDT) Received: from mother.ds.pg.gda.pl (serwer.tvgawex.pl [212.122.214.2]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i730F1Ct026770 for ; Mon, 2 Aug 2004 17:15:02 -0700 Received: (qmail 8739 invoked by uid 1000); 3 Aug 2004 00:14:59 -0000 Date: Tue, 3 Aug 2004 02:14:59 +0200 From: Tomasz Torcz To: netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-ID: <20040803001459.GA8637@irc.pl> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-2 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> User-Agent: Mutt/1.5.4i X-archive-position: 7436 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: zdzichu@irc.pl Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 03:38:05PM -0700, Stephen Hemminger wrote: > I am willing to put some headers (not all) in with the user level > code, provided they are copies since they I can easily update. I don't want > to get into keeping an edited set of headers in sync. Aren't linux-libc-headers (*) sufficient? * - http://ep09.pld-linux.org/~mmazur/linux-libc-headers/ -- Tomasz Torcz To co nierealne - tutaj jest normalne. zdzichu@irc.-nie.spam-.pl Ziomale na ¿ycie maj± tu patenty specjalne. From jesse.brandeburg@intel.com Mon Aug 2 19:07:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:07:57 -0700 (PDT) Received: from fmsfmr003.fm.intel.com (fmr10.intel.com [192.55.52.30]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7327oIC032489 for ; Mon, 2 Aug 2004 19:07:50 -0700 Received: from petasus.fm.intel.com (petasus.fm.intel.com [10.1.192.37]) by fmsfmr003.fm.intel.com (8.12.9-20030918-01/8.12.9/d: major-outer.mc,v 1.15 2004/01/30 18:16:28 root Exp $) with ESMTP id i73285eH015744 for ; Tue, 3 Aug 2004 02:08:05 GMT Received: from fmsmsxvs043.fm.intel.com (fmsmsxvs043.fm.intel.com [132.233.42.129]) by petasus.fm.intel.com (8.12.9-20030918-01/8.12.9/d: major-inner.mc,v 1.11 2004/07/29 22:51:53 root Exp $) with SMTP id i7327eal012712 for ; Tue, 3 Aug 2004 02:07:40 GMT Received: from Westville2.jf.intel.com ([134.134.3.161]) by fmsmsxvs043.fm.intel.com (SAVSMTP 3.1.2.35) with SMTP id M2004080219074112919 ; Mon, 02 Aug 2004 19:07:41 -0700 Date: Mon, 2 Aug 2004 18:51:21 -0700 (PDT) From: Jesse Brandeburg To: netdev@oss.sgi.com Subject: [PATCH 2.6] ixgb - fix bug in transmit cleanup for ppc64 Message-ID: ReplyTo: "Jesse Brandeburg" MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Scanned-By: MIMEDefang 2.31 (www . roaringpenguin . com / mimedefang) X-archive-position: 7437 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jesse.brandeburg@intel.com Precedence: bulk X-list: netdev This fixes an endianness error when on PPC64 arch. Signed off by: Jesse Brandeburg diff -Nurp --exclude=CVS linux-2.6.7/drivers/net/ixgb/ixgb_main.c linux-2.6.7_mod/drivers/net/ixgb/ixgb_main.c --- linux-2.6.7/drivers/net/ixgb/ixgb_main.c 2004-06-16 05:19:01.000000000 +0000 +++ linux-2.6.7_mod/drivers/net/ixgb/ixgb_main.c 2004-08-03 01:34:52.000000000 +0000 @@ -1677,7 +1677,7 @@ static boolean_t ixgb_clean_tx_irq(struc eop = tx_ring->buffer_info[i].next_to_watch; eop_desc = IXGB_TX_DESC(*tx_ring, eop); - while (eop_desc->status & cpu_to_le32(IXGB_TX_DESC_STATUS_DD)) { + while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) { for (cleaned = FALSE; !cleaned;) { tx_desc = IXGB_TX_DESC(*tx_ring, i); From davem@redhat.com Mon Aug 2 19:11:00 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:11:06 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i732Ax7T000474 for ; Mon, 2 Aug 2004 19:11:00 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i732Aee1010321; Mon, 2 Aug 2004 22:10:40 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i732Aea22704; Mon, 2 Aug 2004 22:10:40 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i7329uCl008359; Mon, 2 Aug 2004 22:09:56 -0400 Date: Mon, 2 Aug 2004 19:09:14 -0700 From: "David S. Miller" To: Herbert Xu Cc: kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-Id: <20040802190914.303ccfbe.davem@redhat.com> In-Reply-To: <20040802074147.GA16381@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7438 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 17:41:47 +1000 Herbert Xu wrote: > This raises an interesting question. Is it really correct to look at > the first hop address when doing the route lookup? > > The problem is that if we use the first-hop address as the dst when > doing the route lookup then we may end up with incorrect MTU information. > This is because the MTU to the final destination may well be smaller than > the MTU to the first hop. > > It seems that Alexey thought about this six years ago according to > the rthdr comment in icmpv6_rcv(). When the ICMP6 packet comes back in such a case, the type zero routing header will be suitable edited. So at least we can determine which exact destination address the PMTU information applies to. But I understand what the problem is. We cannot update the destination cache entry for destination "D" if the ICMP message is for hop "B" specified in the routing header. Furthermore, we cannot even update a destination cache entry for hop "B" in the case where the routing header specifies --> A --> B --> C --> D because a direct packet destinated for "B" might use a different path than "A" does. An intesting solution would be to use stacked destinations, which do no actual encapsulation (or perhaps do the routing header work) and merely represent the hop-by-hop path. Then the PMTU propagation machinery can be used, and route lookups will go through a slower path to find these special stacked hop-by-hop routes. From scarfboy@gmail.com Mon Aug 2 19:47:54 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:47:58 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.192]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i732lotV001376 for ; Mon, 2 Aug 2004 19:47:53 -0700 Received: by mproxy.gmail.com with SMTP id 73so143907rnk for ; Mon, 02 Aug 2004 19:47:43 -0700 (PDT) Received: by 10.38.81.50 with SMTP id e50mr138197rnb; Mon, 02 Aug 2004 19:47:43 -0700 (PDT) Message-ID: Date: Tue, 3 Aug 2004 04:47:43 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_102_23147333.1091501263553" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> X-archive-position: 7439 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_102_23147333.1091501263553 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Okay, after I Did Stuff(tm) to my new computer, it's capable of generating approximately 50Kints/s, which transates to 66MB/s in a network benchmark (Actually, netio misreports the speeds, probably because of an overflow; I was amused) There's two howevers and one unfortunately, though. The howevers: - it's not in the direction I want -- meaning I should update, which I can live with. But: - the bench speed going from my old computer wend down from ~33mb to ~20MB/s which I can't make any sense of at all, and the practical speeds from the server didn't change for the better, possibly for the worse. I'm not sure, because of... The unfortunately: - After a few minutes, my old computer kernel paniced. I assume this is because it can't handle the incoming traffic, as its own pace of sending (and therefore probably handling interrupts) is more like 20kints/sec than 50. I couldn't tell anything vmstat-wise as during the data going in that direction (un udp; tcp hung around 17MB both ways - which is better thn before, but *still* short of impressive), the ssh shells just stopped responding, and I guess so did vmstat. It's probably being battered in hardware interrupts, I saw high figures. Quite possibly this has to do with renicing ksoftircq (negatively) as someone suggested. However, I am still of the opinion that a difference in processor speeds should not crash anything. The panic looks a lot like the last one; same kernel (napi still enabled for the 8169). Image attached. I'ld like to know what's wrong here, so that I can avoid it. I can deal and live with stupid speeds better than crashing serves. Makes me grumble less, y'know. --Bart Alewijnse ------=_Part_102_23147333.1091501263553 Content-Type: image/gif; name="panic2.gif" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="panic2.gif" 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 ------=_Part_102_23147333.1091501263553-- From romieu@fr.zoreil.com Tue Aug 3 00:51:48 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 00:51:54 -0700 (PDT) Received: from fr.zoreil.com (electric-eye.fr.zoreil.com [213.41.134.224]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i737pl2a014879 for ; Tue, 3 Aug 2004 00:51:48 -0700 Received: from electric-eye.fr.zoreil.com (localhost.localdomain [127.0.0.1]) by fr.zoreil.com (8.12.8/8.12.1) with ESMTP id i737mhh9005238; Tue, 3 Aug 2004 09:48:43 +0200 Received: (from romieu@localhost) by electric-eye.fr.zoreil.com (8.12.8/8.12.1) id i737mgmS005236; Tue, 3 Aug 2004 09:48:42 +0200 Date: Tue, 3 Aug 2004 09:48:42 +0200 From: Francois Romieu To: Bart Alewijnse Cc: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble Message-ID: <20040803094842.B4911@electric-eye.fr.zoreil.com> References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from scarfboy@gmail.com on Tue, Aug 03, 2004 at 04:47:43AM +0200 X-Organisation: Land of Sunshine Inc. X-archive-position: 7440 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: romieu@fr.zoreil.com Precedence: bulk X-list: netdev Bart Alewijnse : [...] > The panic looks a lot like the last one; same kernel (napi still > enabled for the 8169). Image attached. The irq rate are strangely high for a napi version of the r8169 driver. Can you describe your test commands so that I reproduce these here ? -- Ueimor From yoshfuji@linux-ipv6.org Tue Aug 3 00:55:26 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 00:55:32 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i737tPTO015212 for ; Tue, 3 Aug 2004 00:55:26 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id 2A36333CE5; Tue, 3 Aug 2004 16:55:48 +0900 (JST) Date: Tue, 03 Aug 2004 00:55:42 -0700 (PDT) Message-Id: <20040803.005542.104434029.yoshfuji@linux-ipv6.org> To: davem@redhat.com, shemminger@osdl.org Cc: hadi@znyx.com, netdev@oss.sgi.com, yoshfuji@linux-ipv6.org Subject: Re: iproute2 and kernel headers From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040802160445.5ef3b251.davem@redhat.com> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> <20040802160445.5ef3b251.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7441 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040802160445.5ef3b251.davem@redhat.com> (at Mon, 2 Aug 2004 16:04:45 -0700), "David S. Miller" says: > > What headers really seem to change a lot? The obvious ones are: > > > > linux/pkt_sched.h > > linux/tcp_diag.h > > linux/xfrm.h > > I would add linux/rtnetlink.h Then, linux/snmp.h. --yoshfuji From yoshfuji@linux-ipv6.org Tue Aug 3 01:18:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 01:19:02 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i738Itpn016068 for ; Tue, 3 Aug 2004 01:18:55 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id DBE1233CE5; Tue, 3 Aug 2004 17:19:17 +0900 (JST) Date: Tue, 03 Aug 2004 01:19:12 -0700 (PDT) Message-Id: <20040803.011912.128392049.yoshfuji@linux-ipv6.org> To: davem@redhat.com Cc: herbert@gondor.apana.org.au, kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru, yoshfuji@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040802190914.303ccfbe.davem@redhat.com> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> <20040802190914.303ccfbe.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7442 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040802190914.303ccfbe.davem@redhat.com> (at Mon, 2 Aug 2004 19:09:14 -0700), "David S. Miller" says: > An intesting solution would be to use stacked destinations, which > do no actual encapsulation (or perhaps do the routing header work) > and merely represent the hop-by-hop path. Then the PMTU propagation > machinery can be used, and route lookups will go through a slower path > to find these special stacked hop-by-hop routes. Well, I think it would probably be another rt6_info{} member rt6i_srcrt (or something like that). --yoshfuji From yoshfuji@linux-ipv6.org Tue Aug 3 01:59:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 02:00:05 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i738xw9h017014 for ; Tue, 3 Aug 2004 01:59:59 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id 2319533CE5; Tue, 3 Aug 2004 18:00:21 +0900 (JST) Date: Tue, 03 Aug 2004 02:00:15 -0700 (PDT) Message-Id: <20040803.020015.44364045.yoshfuji@linux-ipv6.org> To: davem@redhat.com Cc: kazunori@miyazawa.org, herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, yoshfuji@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040801195135.16734846.davem@redhat.com> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040801195135.16734846.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7443 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040801195135.16734846.davem@redhat.com> (at Sun, 1 Aug 2004 19:51:35 -0700), "David S. Miller" says: > On Fri, 30 Jul 2004 17:12:05 +0900 > Kazunori Miyazawa wrote: > > > I consider copying flowi(fl_rt) uses too much stack at the moment. > > I'll re-send the fixed patch again. > > I agree, and let's defer this patch until we > resolve that. Is the overhead for allocating memory okay? Or, do we allcoate some per-cpu memory while ipv6.o initalization phase? (check: lock? preemption?) Or, will we allocate fl (and fl_rt) per sock{} (ipv6_pinfo{})? (ditto.) We have similar stack usage in other codes, and I would fix them at the same time. Another question just for future reference: how many bytes (approx.) do we accept on stack? Note: sizeof(struct flowi) is 72 bytes (on i386) --yoshfuji From kazunori@miyazawa.org Tue Aug 3 02:22:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 02:22:20 -0700 (PDT) Received: from miyazawa.org (usen-221x116x13x66.ap-US01.usen.ad.jp [221.116.13.66]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i739M6gR023201 for ; Tue, 3 Aug 2004 02:22:06 -0700 Received: from [IPv6:2001:240:5bf:128:a59f:7c54:52e4:e0e8] ([2001:240:5bf:128:a59f:7c54:52e4:e0e8]) (AUTH: LOGIN kazunori, SSL: TLSv1/SSLv3,128bits,RC4-MD5) by miyazawa.org with esmtp; Tue, 03 Aug 2004 18:20:05 +0900 id 00000C4F.410F58C6.00007301 Message-ID: <410F5906.30402@miyazawa.org> Date: Tue, 03 Aug 2004 18:21:10 +0900 From: Kazunori Miyazawa User-Agent: Mozilla Thunderbird 0.7 (Windows/20040616) X-Accept-Language: en-us, en MIME-Version: 1.0 To: YOSHIFUJI Hideaki CC: davem@redhat.com, herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040801195135.16734846.davem@redhat.com> <20040803.020015.44364045.yoshfuji@linux-ipv6.org> In-Reply-To: <20040803.020015.44364045.yoshfuji@linux-ipv6.org> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7444 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kazunori@miyazawa.org Precedence: bulk X-list: netdev YOSHIFUJI Hideaki wrote: > In article <20040801195135.16734846.davem@redhat.com> (at Sun, 1 Aug 2004 19:51:35 -0700), "David S. Miller" says: > > >>On Fri, 30 Jul 2004 17:12:05 +0900 >>Kazunori Miyazawa wrote: >> >> >>>I consider copying flowi(fl_rt) uses too much stack at the moment. >>>I'll re-send the fixed patch again. >> >>I agree, and let's defer this patch until we >>resolve that. > > > Is the overhead for allocating memory okay? > Or, do we allcoate some per-cpu memory while ipv6.o initalization phase? > (check: lock? preemption?) > Or, will we allocate fl (and fl_rt) per sock{} (ipv6_pinfo{})? > (ditto.) > My intention is not high art, just using struct in6_addr instead of struct flowi to store final destination. > We have similar stack usage in other codes, and > I would fix them at the same time. > These might be my changes. I will fix them. > > Another question just for future reference: > how many bytes (approx.) do we accept on stack? > > Note: sizeof(struct flowi) is 72 bytes (on i386) > > --yoshfuji --Kazunori Miyazawa From herbert@gondor.apana.org.au Tue Aug 3 03:55:44 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 03:55:52 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Atgsj016097 for ; Tue, 3 Aug 2004 03:55:44 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1Brwx3-0005cn-00; Tue, 03 Aug 2004 20:55:25 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1Brwwy-0007ZY-00; Tue, 03 Aug 2004 20:55:20 +1000 Date: Tue, 3 Aug 2004 20:55:20 +1000 To: "David S. Miller" Cc: kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-ID: <20040803105520.GA29077@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> <20040802190914.303ccfbe.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040802190914.303ccfbe.davem@redhat.com> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7445 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 07:09:14PM -0700, David S. Miller wrote: > > An intesting solution would be to use stacked destinations, which > do no actual encapsulation (or perhaps do the routing header work) > and merely represent the hop-by-hop path. Then the PMTU propagation > machinery can be used, and route lookups will go through a slower path > to find these special stacked hop-by-hop routes. Yes that's brilliant. We can replace the current rt dst with an rthdr dst + an rt dst. The rt dst will be the same one pointing to the first hop. The rthdr will contain MTU information for that exact path. This will work since any ICMP messages we receive due to MTU issues must carry the entire IP header including the rthdr (or in the case of IPv4 the ?SR option). We can then attribute that MTU to the rthdr dst. The rthdr can even add the option/extension header as a transform. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From ptsjohol@cc.jyu.fi Tue Aug 3 05:33:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 05:33:14 -0700 (PDT) Received: from posti6.jyu.fi (posti6.jyu.fi [130.234.4.43]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73CWjVf027633 for ; Tue, 3 Aug 2004 05:33:06 -0700 Received: from silmu.st.jyu.fi (IDENT:i+l7SQ6073MYpVQbfBUEyZ6AO77O2o0J@silmu.st.jyu.fi [130.234.4.64]) by posti6.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i73CWIob027197; Tue, 3 Aug 2004 15:32:18 +0300 Date: Tue, 3 Aug 2004 15:32:15 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: <20040803003515.A29885@electric-eye.fr.zoreil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti6.jyu.fi; Tue, 03 Aug 2004 15:32:21 +0300 X-archive-position: 7447 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev On Tue, 3 Aug 2004, Francois Romieu wrote: > I have made a few changes. Please enable the DEBUG option and set msglvl > to its maximal value via ethtool. You may test the patches separately if > you find some time but the log once both r8139-10.patch and r8139-20.patch > are applied would be enough. The full logfiles can be downloaded from: http://www.cc.jyu.fi/~ptsjohol/syslog1.gz http://www.cc.jyu.fi/~ptsjohol/syslog2.gz The first log file is with both patchs applied and the second one with one little change to rx8139_rx() to show if it even goes to through " while (netif_running(dev) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {"-section. This was the change which I made.. so you can see in the second log file that there won't be any of these messages after the driver has crashed. /* if (netif_msg_rx_status(tp))*/ printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x," " cur %4.4x.\n", dev->name, rx_status, rx_size, cur_rx); For the first logfile the exact crash time is "13:02:22" and the for the second one it is "14:54:49". > If the log fills too fast, you may comment out any message which does > not belong to rtl8139_rx(). I took out those "exiting with interrupt"-messages. -- Pasi Sjöholm From scarfboy@gmail.com Tue Aug 3 05:32:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 05:32:44 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.202]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73CWGTN027626 for ; Tue, 3 Aug 2004 05:32:37 -0700 Received: by mproxy.gmail.com with SMTP id 73so153437rnk for ; Tue, 03 Aug 2004 05:32:07 -0700 (PDT) Received: by 10.38.81.50 with SMTP id e50mr258492rnb; Tue, 03 Aug 2004 05:32:07 -0700 (PDT) Message-ID: Date: Tue, 3 Aug 2004 14:32:07 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: <20040803094842.B4911@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_9_19135111.1091536327656" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> <20040803094842.B4911@electric-eye.fr.zoreil.com> X-archive-position: 7446 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_9_19135111.1091536327656 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Quite simply a 'netio -s' on one computer, and a 'netio -u 192.168.1.whichever' on the other. I was monitoring with 'vmstat 1' for hardware stuff and bmon to see the actual speed and had a ssh open. The things I've been fiddling with recently to see if it'd make a difference: - Renicing of ksoftirqc to anything between -5 and -17, I don't remember exactly. - Disabling tcp window scaling. I read somewhere that that may help throughhput, but it may be a stupid move. - Some barely thought about (I did read the following: http://lists.samba.org/archive/samba/2003-December/077198.html) window memory buffer size changes, with a 'so that that at least won't be a bottleneck' angle: -------------------- echo 400000 > /proc/sys/net/core/wmem_default echo 512000 > /proc/sys/net/core/wmem_max echo 400000 > /proc/sys/net/core/rmem_default echo 512000 > /proc/sys/net/core/rmem_max echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_mem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_wmem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_rmem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_mem ----------- It seems that windows (in which I have jumbo frames on) doesn' quite need as many interrupts, although I'm not sure that was for the same speed, as I had another kernel panic (attached, this one has a small visible trace). I was running the windows version of netio as a server, and doing a client test with udp. --Bart Alewijnse ------=_Part_9_19135111.1091536327656 Content-Type: image/gif; name="panic3.gif" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="panic3.gif" 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 uIke665CfxIHDXxZ6JXw5BEAADs= ------=_Part_9_19135111.1091536327656-- From kaber@trash.net Tue Aug 3 08:23:08 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:23:15 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FN7sO002811 for ; Tue, 3 Aug 2004 08:23:07 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 353CC19F377; Tue, 3 Aug 2004 17:22:55 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id 7A70A39413B; Tue, 3 Aug 2004 17:22:54 +0200 (CEST) Message-ID: <410FAE65.6010802@trash.net> Date: Tue, 03 Aug 2004 17:25:25 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6 4/5]: remove unneccessary checks for qdisc->dev Content-Type: multipart/mixed; boundary="------------070305030108050302020103" X-archive-position: 7450 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 2129 Lines: 68 This is a multi-part message in MIME format. --------------070305030108050302020103 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit qdisc->dev is always valid, this patch removes a couple of unneccessary checks. --------------070305030108050302020103 Content-Type: text/x-patch; name="04-qdisc-dev-checks.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="04-qdisc-dev-checks.diff" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/03 01:28:36+02:00 kaber@coreworks.de # [PKT_SCHED]: remove unneccessary checks for qdisc->dev # # Signed-off-by: Patrick McHardy # # net/sched/sch_generic.c # 2004/08/03 01:28:15+02:00 kaber@coreworks.de +1 -2 # [PKT_SCHED]: remove unneccessary checks for qdisc->dev # # net/sched/sch_api.c # 2004/08/03 01:28:15+02:00 kaber@coreworks.de +2 -2 # [PKT_SCHED]: remove unneccessary checks for qdisc->dev # diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c --- a/net/sched/sch_api.c 2004-08-03 01:30:00 +02:00 +++ b/net/sched/sch_api.c 2004-08-03 01:30:00 +02:00 @@ -753,7 +753,7 @@ nlh->nlmsg_flags = flags; tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; - tcm->tcm_ifindex = q->dev ? q->dev->ifindex : 0; + tcm->tcm_ifindex = q->dev->ifindex; tcm->tcm_parent = clid; tcm->tcm_handle = q->handle; tcm->tcm_info = atomic_read(&q->refcnt); @@ -970,7 +970,7 @@ nlh->nlmsg_flags = flags; tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; - tcm->tcm_ifindex = q->dev ? q->dev->ifindex : 0; + tcm->tcm_ifindex = q->dev->ifindex; tcm->tcm_parent = q->handle; tcm->tcm_handle = q->handle; tcm->tcm_info = 0; diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-08-03 01:30:00 +02:00 +++ b/net/sched/sch_generic.c 2004-08-03 01:30:00 +02:00 @@ -443,8 +443,7 @@ write_unlock(&qdisc_tree_lock); module_put(ops->owner); - if (qdisc->dev) - dev_put(qdisc->dev); + dev_put(qdisc->dev); if (!(qdisc->flags&TCQ_F_BUILTIN)) kfree(qdisc); } --------------070305030108050302020103-- From kaber@trash.net Tue Aug 3 08:22:35 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:22:41 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FMYGd002692 for ; Tue, 3 Aug 2004 08:22:34 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id E9CD619F377; Tue, 3 Aug 2004 17:22:20 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id F049F39413B; Tue, 3 Aug 2004 17:22:19 +0200 (CEST) Message-ID: <410FAE42.2050909@trash.net> Date: Tue, 03 Aug 2004 17:24:50 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6 3/5]: Use double-linked list for dev->qdisc_list Content-Type: multipart/mixed; boundary="------------030000030800010808020702" X-archive-position: 7449 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 6290 Lines: 235 This is a multi-part message in MIME format. --------------030000030800010808020702 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit This patch changes dev->qdisc_list to a double-linked list. This solves the performance problems when destroying qdiscs with large number of inner qdiscs. --------------030000030800010808020702 Content-Type: text/x-patch; name="03-qdisc_list-list_h.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="03-qdisc_list-list_h.diff" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/03 00:48:50+02:00 kaber@coreworks.de # [PKT_SCHED]: Use double-linked list for dev->qdisc_list # # Signed-off-by: Patrick McHardy # # net/sched/sch_generic.c # 2004/08/03 00:48:19+02:00 kaber@coreworks.de +5 -19 # [PKT_SCHED]: Use double-linked list for dev->qdisc_list # # net/sched/sch_api.c # 2004/08/03 00:48:19+02:00 kaber@coreworks.de +16 -11 # [PKT_SCHED]: Use double-linked list for dev->qdisc_list # # include/net/pkt_sched.h # 2004/08/03 00:48:19+02:00 kaber@coreworks.de +1 -1 # [PKT_SCHED]: Use double-linked list for dev->qdisc_list # # include/linux/netdevice.h # 2004/08/03 00:48:19+02:00 kaber@coreworks.de +1 -1 # [PKT_SCHED]: Use double-linked list for dev->qdisc_list # diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h 2004-08-03 01:11:00 +02:00 +++ b/include/linux/netdevice.h 2004-08-03 01:11:00 +02:00 @@ -362,8 +362,8 @@ struct Qdisc *qdisc; struct Qdisc *qdisc_sleeping; - struct Qdisc *qdisc_list; struct Qdisc *qdisc_ingress; + struct list_head qdisc_list; unsigned long tx_queue_len; /* Max frames per queue allowed */ /* ingress path synchronizer */ diff -Nru a/include/net/pkt_sched.h b/include/net/pkt_sched.h --- a/include/net/pkt_sched.h 2004-08-03 01:11:00 +02:00 +++ b/include/net/pkt_sched.h 2004-08-03 01:11:00 +02:00 @@ -78,11 +78,11 @@ #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 struct Qdisc_ops *ops; - struct Qdisc *next; u32 handle; atomic_t refcnt; struct sk_buff_head q; struct net_device *dev; + struct list_head list; struct tc_stats stats; spinlock_t *stats_lock; diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c --- a/net/sched/sch_api.c 2004-08-03 01:11:00 +02:00 +++ b/net/sched/sch_api.c 2004-08-03 01:11:00 +02:00 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -195,7 +196,7 @@ { struct Qdisc *q; - for (q = dev->qdisc_list; q; q = q->next) { + list_for_each_entry(q, &dev->qdisc_list, list) { if (q->handle == handle) return q; } @@ -421,6 +422,7 @@ memset(sch, 0, size); + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); if (handle == TC_H_INGRESS) @@ -454,8 +456,7 @@ smp_wmb(); if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { qdisc_lock_tree(dev); - sch->next = dev->qdisc_list; - dev->qdisc_list = sch; + list_add_tail(&sch->list, &dev->qdisc_list); qdisc_unlock_tree(dev); #ifdef CONFIG_NET_ESTIMATOR @@ -814,9 +815,9 @@ if (idx > s_idx) s_q_idx = 0; read_lock_bh(&qdisc_tree_lock); - for (q = dev->qdisc_list, q_idx = 0; q; - q = q->next, q_idx++) { - if (q_idx < s_q_idx) + q_idx = 0; + list_for_each_entry(q, &dev->qdisc_list, list) { + if (q_idx++ < s_q_idx) continue; if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { @@ -831,7 +832,7 @@ read_unlock(&dev_base_lock); cb->args[0] = idx; - cb->args[1] = q_idx; + cb->args[1] = q_idx - 1; return skb->len; } @@ -1033,13 +1034,16 @@ return 0; s_t = cb->args[0]; + t = 0; read_lock_bh(&qdisc_tree_lock); - for (q=dev->qdisc_list, t=0; q; q = q->next, t++) { - if (t < s_t) continue; - if (!q->ops->cl_ops) continue; - if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle) + list_for_each_entry(q, &dev->qdisc_list, list) { + if (t < s_t || !q->ops->cl_ops || + (tcm->tcm_parent && + TC_H_MAJ(tcm->tcm_parent) != q->handle)) { + t++; continue; + } if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); arg.w.fn = qdisc_class_dump; @@ -1052,6 +1056,7 @@ cb->args[1] = arg.w.count; if (arg.w.stop) break; + t++; } read_unlock_bh(&qdisc_tree_lock); diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-08-03 01:11:00 +02:00 +++ b/net/sched/sch_generic.c 2004-08-03 01:11:00 +02:00 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -394,6 +395,7 @@ return NULL; memset(sch, 0, size); + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); sch->ops = ops; sch->enqueue = ops->enqueue; @@ -451,20 +453,9 @@ void qdisc_destroy(struct Qdisc *qdisc) { - struct net_device *dev = qdisc->dev; - if (!atomic_dec_and_test(&qdisc->refcnt)) return; - - if (dev) { - struct Qdisc *q, **qp; - for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { - if (q == qdisc) { - *qp = q->next; - break; - } - } - } + list_del(&qdisc->list); call_rcu(&qdisc->q_rcu, __qdisc_destroy); } @@ -484,12 +475,9 @@ printk(KERN_INFO "%s: activation failed\n", dev->name); return; } - write_lock_bh(&qdisc_tree_lock); - qdisc->next = dev->qdisc_list; - dev->qdisc_list = qdisc; + list_add_tail(&qdisc->list, &dev->qdisc_list); write_unlock_bh(&qdisc_tree_lock); - } else { qdisc = &noqueue_qdisc; } @@ -531,7 +519,7 @@ qdisc_lock_tree(dev); dev->qdisc = &noop_qdisc; dev->qdisc_sleeping = &noop_qdisc; - dev->qdisc_list = NULL; + INIT_LIST_HEAD(&dev->qdisc_list); qdisc_unlock_tree(dev); dev_watchdog_init(dev); @@ -552,9 +540,7 @@ qdisc_destroy(qdisc); } #endif - BUG_TRAP(dev->qdisc_list == NULL); BUG_TRAP(!timer_pending(&dev->watchdog_timer)); - dev->qdisc_list = NULL; qdisc_unlock_tree(dev); } --------------030000030800010808020702-- From kaber@trash.net Tue Aug 3 08:23:41 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:23:48 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FNfsZ003069 for ; Tue, 3 Aug 2004 08:23:41 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 7C0E719F378; Tue, 3 Aug 2004 17:23:28 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id 104D139413B; Tue, 3 Aug 2004 17:23:24 +0200 (CEST) Message-ID: <410FAE82.7070604@trash.net> Date: Tue, 03 Aug 2004 17:25:54 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6 5/5]: remove noop_qdisc assignments in destroy functions Content-Type: multipart/mixed; boundary="------------060803040006040108040500" X-archive-position: 7451 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 3603 Lines: 120 This is a multi-part message in MIME format. --------------060803040006040108040500 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit This patch removes useless noop_qdisc assignments in multiple qdiscs destroy functions, the memory where the pointer is stored is freed directly after the destroy function. --------------060803040006040108040500 Content-Type: text/x-patch; name="05-destroy-noop-qdisc.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="05-destroy-noop-qdisc.diff" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/03 03:02:03+02:00 kaber@coreworks.de # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # # Signed-off-by: Patrick McHardy # # net/sched/sch_tbf.c # 2004/08/03 03:01:39+02:00 kaber@coreworks.de +0 -1 # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # # net/sched/sch_red.c # 2004/08/03 03:01:39+02:00 kaber@coreworks.de +0 -5 # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # # net/sched/sch_prio.c # 2004/08/03 03:01:39+02:00 kaber@coreworks.de +1 -3 # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # # net/sched/sch_netem.c # 2004/08/03 03:01:39+02:00 kaber@coreworks.de +0 -2 # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # # net/sched/sch_dsmark.c # 2004/08/03 03:01:39+02:00 kaber@coreworks.de +0 -1 # [PKT_SCHED]: Remove useless noop_qdisc assignments in destroy functions # diff -Nru a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c --- a/net/sched/sch_dsmark.c 2004-08-03 03:03:09 +02:00 +++ b/net/sched/sch_dsmark.c 2004-08-03 03:03:09 +02:00 @@ -383,7 +383,6 @@ tcf_destroy(tp); } qdisc_destroy(p->q); - p->q = &noop_qdisc; kfree(p->mask); } diff -Nru a/net/sched/sch_netem.c b/net/sched/sch_netem.c --- a/net/sched/sch_netem.c 2004-08-03 03:03:09 +02:00 +++ b/net/sched/sch_netem.c 2004-08-03 03:03:09 +02:00 @@ -812,9 +812,7 @@ struct netem_sched_data *q = (struct netem_sched_data *)sch->data; del_timer_sync(&q->timer); - qdisc_destroy(q->qdisc); - q->qdisc = &noop_qdisc; } static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) diff -Nru a/net/sched/sch_prio.c b/net/sched/sch_prio.c --- a/net/sched/sch_prio.c 2004-08-03 03:03:09 +02:00 +++ b/net/sched/sch_prio.c 2004-08-03 03:03:09 +02:00 @@ -208,10 +208,8 @@ tcf_destroy(tp); } - for (prio=0; priobands; prio++) { + for (prio=0; priobands; prio++) qdisc_destroy(q->queues[prio]); - q->queues[prio] = &noop_qdisc; - } } static int prio_tune(struct Qdisc *sch, struct rtattr *opt) diff -Nru a/net/sched/sch_red.c b/net/sched/sch_red.c --- a/net/sched/sch_red.c 2004-08-03 03:03:09 +02:00 +++ b/net/sched/sch_red.c 2004-08-03 03:03:09 +02:00 @@ -434,10 +434,6 @@ return -1; } -static void red_destroy(struct Qdisc *sch) -{ -} - static struct Qdisc_ops red_qdisc_ops = { .next = NULL, .cl_ops = NULL, @@ -449,7 +445,6 @@ .drop = red_drop, .init = red_init, .reset = red_reset, - .destroy = red_destroy, .change = red_change, .dump = red_dump, .owner = THIS_MODULE, diff -Nru a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c --- a/net/sched/sch_tbf.c 2004-08-03 03:03:09 +02:00 +++ b/net/sched/sch_tbf.c 2004-08-03 03:03:09 +02:00 @@ -393,7 +393,6 @@ qdisc_put_rtab(q->R_tab); qdisc_destroy(q->qdisc); - q->qdisc = &noop_qdisc; } static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) --------------060803040006040108040500-- From shemminger@osdl.org Tue Aug 3 08:31:55 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:32:01 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FVsWg003901 for ; Tue, 3 Aug 2004 08:31:55 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73FVg105697; Tue, 3 Aug 2004 08:31:42 -0700 Date: Tue, 3 Aug 2004 08:31:42 -0700 From: Stephen Hemminger To: Tomasz Torcz Cc: netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-Id: <20040803083142.5a4ccaad@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803001459.GA8637@irc.pl> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> <20040803001459.GA8637@irc.pl> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7452 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 797 Lines: 16 On Tue, 3 Aug 2004 02:14:59 +0200 Tomasz Torcz wrote: > On Mon, Aug 02, 2004 at 03:38:05PM -0700, Stephen Hemminger wrote: > > I am willing to put some headers (not all) in with the user level > > code, provided they are copies since they I can easily update. I don't want > > to get into keeping an edited set of headers in sync. > > Aren't linux-libc-headers (*) sufficient? > > * - http://ep09.pld-linux.org/~mmazur/linux-libc-headers/ The theory of that is good, but in practice it would make the problem worse. What iproute2 wants is to have the same kernel data structures as the latest kernel. It is awkward enough making sure to get them from the correct kernel sources, but doing it from a different package would make updating and keeping everything current worse. From shemminger@osdl.org Tue Aug 3 08:36:01 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:36:08 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Fa0aG004303 for ; Tue, 3 Aug 2004 08:36:00 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73FZe106428; Tue, 3 Aug 2004 08:35:40 -0700 Date: Tue, 3 Aug 2004 08:35:40 -0700 From: Stephen Hemminger To: Patrick McHardy Cc: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6 3/5]: Use double-linked list for dev->qdisc_list Message-Id: <20040803083540.13675d64@dell_ss3.pdx.osdl.net> In-Reply-To: <410FAE42.2050909@trash.net> References: <410FAE42.2050909@trash.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7453 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 4755 Lines: 187 On Tue, 03 Aug 2004 17:24:50 +0200 Patrick McHardy wrote: > This patch changes dev->qdisc_list to a double-linked list. This solves > the performance problems when destroying qdiscs with large number of inner > qdiscs. > > Since qdisc lists are using rcu for deletion, you should use the _rcu flavors of list stuff. replace BUG_TRAP(dev->qdisc_list == NULL); with BUG_TRAP(list_empty(&dev->qdisc_list)); I tried a similar patch but was finding the bug_trap() was showing up on deletion so did not trust it. This is what I was experimenting with. ------------ diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h 2004-07-28 15:14:27 -07:00 +++ b/include/linux/netdevice.h 2004-07-28 15:14:27 -07:00 @@ -362,7 +362,7 @@ struct Qdisc *qdisc; struct Qdisc *qdisc_sleeping; - struct Qdisc *qdisc_list; + struct list_head qdisc_list; struct Qdisc *qdisc_ingress; unsigned long tx_queue_len; /* Max frames per queue allowed */ diff -Nru a/include/net/pkt_sched.h b/include/net/pkt_sched.h --- a/include/net/pkt_sched.h 2004-07-28 15:14:27 -07:00 +++ b/include/net/pkt_sched.h 2004-07-28 15:14:27 -07:00 @@ -79,7 +79,7 @@ #define TCQ_F_INGRES 4 int padded; struct Qdisc_ops *ops; - struct Qdisc *next; + struct list_head list; u32 handle; atomic_t refcnt; struct sk_buff_head q; diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c --- a/net/sched/sch_api.c 2004-07-28 15:14:27 -07:00 +++ b/net/sched/sch_api.c 2004-07-28 15:14:27 -07:00 @@ -195,7 +195,7 @@ { struct Qdisc *q; - for (q = dev->qdisc_list; q; q = q->next) { + list_for_each_entry_rcu(q, &dev->qdisc_list, list) { if (q->handle == handle) return q; } @@ -453,8 +453,7 @@ smp_wmb(); if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { qdisc_lock_tree(dev); - sch->next = dev->qdisc_list; - dev->qdisc_list = sch; + list_add_rcu(&sch->list, &dev->qdisc_list); qdisc_unlock_tree(dev); #ifdef CONFIG_NET_ESTIMATOR @@ -812,18 +811,20 @@ continue; if (idx > s_idx) s_q_idx = 0; - read_lock(&qdisc_tree_lock); - for (q = dev->qdisc_list, q_idx = 0; q; - q = q->next, q_idx++) { - if (q_idx < s_q_idx) + + rcu_read_lock(); + + q_idx = 0; + list_for_each_entry_rcu(q, &dev->qdisc_list, list) { + if (q_idx++ < s_q_idx) continue; if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { - read_unlock(&qdisc_tree_lock); + rcu_read_unlock(); goto done; } } - read_unlock(&qdisc_tree_lock); + rcu_read_unlock(); } done: @@ -1033,9 +1034,10 @@ s_t = cb->args[0]; - read_lock(&qdisc_tree_lock); - for (q=dev->qdisc_list, t=0; q; q = q->next, t++) { - if (t < s_t) continue; + rcu_read_lock(); + t = 0; + list_for_each_entry_rcu(q, &dev->qdisc_list, list) { + if (t++ < s_t) continue; if (!q->ops->cl_ops) continue; if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle) continue; @@ -1052,7 +1054,7 @@ if (arg.w.stop) break; } - read_unlock(&qdisc_tree_lock); + rcu_read_unlock(); cb->args[0] = t; diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-07-28 15:14:27 -07:00 +++ b/net/sched/sch_generic.c 2004-07-28 15:14:27 -07:00 @@ -405,6 +405,8 @@ sch->dev = dev; sch->stats_lock = &dev->queue_lock; atomic_set(&sch->refcnt, 1); + INIT_LIST_HEAD(&sch->list); + /* enqueue is accessed locklessly - make sure it's visible * before we set a netdevice's qdisc pointer to sch */ smp_wmb(); @@ -450,23 +452,12 @@ void qdisc_destroy(struct Qdisc *qdisc) { - struct net_device *dev = qdisc->dev; - if (!atomic_dec_and_test(&qdisc->refcnt)) return; - if (dev) { - struct Qdisc *q, **qp; - for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { - if (q == qdisc) { - *qp = q->next; - break; - } - } - } - + if (qdisc->dev) + list_del_rcu(&qdisc->list); call_rcu(&qdisc->q_rcu, __qdisc_destroy); - } @@ -488,8 +479,7 @@ } write_lock(&qdisc_tree_lock); - qdisc->next = dev->qdisc_list; - dev->qdisc_list = qdisc; + list_add_rcu(&qdisc->list, &dev->qdisc_list); write_unlock(&qdisc_tree_lock); } else { @@ -533,7 +523,7 @@ qdisc_lock_tree(dev); dev->qdisc = &noop_qdisc; dev->qdisc_sleeping = &noop_qdisc; - dev->qdisc_list = NULL; + INIT_LIST_HEAD(&dev->qdisc_list); qdisc_unlock_tree(dev); dev_watchdog_init(dev); @@ -554,9 +544,9 @@ qdisc_destroy(qdisc); } #endif - BUG_TRAP(dev->qdisc_list == NULL); + BUG_TRAP(!list_empty(&dev->qdisc_list)); BUG_TRAP(!timer_pending(&dev->watchdog_timer)); - dev->qdisc_list = NULL; + qdisc_unlock_tree(dev); } From shemminger@osdl.org Tue Aug 3 08:38:41 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:38:51 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FceJh004668 for ; Tue, 3 Aug 2004 08:38:40 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73FcK107304; Tue, 3 Aug 2004 08:38:20 -0700 Date: Tue, 3 Aug 2004 08:38:20 -0700 From: Stephen Hemminger To: Patrick McHardy , "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] cache align qdisc data Message-Id: <20040803083820.711c917c@dell_ss3.pdx.osdl.net> In-Reply-To: <410FAE42.2050909@trash.net> References: <410FAE42.2050909@trash.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7454 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 46927 Lines: 1542 This patch has qdisc code use the same interface as the netdevice code to cache align the object private data. Signed-off-by: Stephen Hemminger diff -Nru a/include/net/pkt_sched.h b/include/net/pkt_sched.h --- a/include/net/pkt_sched.h 2004-07-27 11:03:02 -07:00 +++ b/include/net/pkt_sched.h 2004-07-27 11:03:02 -07:00 @@ -77,6 +77,7 @@ #define TCQ_F_BUILTIN 1 #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 + int padded; struct Qdisc_ops *ops; struct Qdisc *next; u32 handle; @@ -93,9 +94,16 @@ * and it will live until better solution will be invented. */ struct Qdisc *__parent; - - char data[0]; }; + +#define QDISC_ALIGN 32 +#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) + +static inline void *qdisc_priv(struct Qdisc *q) +{ + return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); +} struct qdisc_rate_table { diff -Nru a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c --- a/net/sched/sch_cbq.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_cbq.c 2004-07-27 11:03:02 -07:00 @@ -241,7 +241,7 @@ static struct cbq_class * cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *head = &q->link; struct cbq_class **defmap; struct cbq_class *cl = NULL; @@ -344,7 +344,7 @@ static __inline__ void cbq_activate_class(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); int prio = cl->cpriority; struct cbq_class *cl_tail; @@ -368,7 +368,7 @@ static void cbq_deactivate_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); int prio = this->cpriority; struct cbq_class *cl; struct cbq_class *cl_prev = q->active[prio]; @@ -419,7 +419,7 @@ static int cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); int len = skb->len; int ret = NET_XMIT_SUCCESS; struct cbq_class *cl = cbq_classify(skb, sch,&ret); @@ -466,7 +466,7 @@ static int cbq_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int ret; @@ -500,7 +500,7 @@ static void cbq_ovl_classic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -554,7 +554,7 @@ static void cbq_ovl_rclassic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this = cl; do { @@ -573,7 +573,7 @@ static void cbq_ovl_delay(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -609,7 +609,7 @@ static void cbq_ovl_lowprio(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); cl->penalized = jiffies + cl->penalty; @@ -678,7 +678,7 @@ static void cbq_undelay(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); long delay = 0; unsigned pmask; @@ -715,7 +715,7 @@ { int len = skb->len; struct Qdisc *sch = child->__parent; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = q->rx_class; q->rx_class = NULL; @@ -863,7 +863,7 @@ static __inline__ struct cbq_class * cbq_under_limit(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this_cl = cl; if (cl->tparent == NULL) @@ -903,7 +903,7 @@ static __inline__ struct sk_buff * cbq_dequeue_prio(struct Qdisc *sch, int prio) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl_tail, *cl_prev, *cl; struct sk_buff *skb; int deficit; @@ -1006,7 +1006,7 @@ static __inline__ struct sk_buff * cbq_dequeue_1(struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; unsigned activemask; @@ -1025,7 +1025,7 @@ cbq_dequeue(struct Qdisc *sch) { struct sk_buff *skb; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); psched_time_t now; psched_tdiff_t incr; @@ -1150,7 +1150,7 @@ static void cbq_sync_defmap(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *split = cl->split; unsigned h; int i; @@ -1216,7 +1216,7 @@ static void cbq_unlink_class(struct cbq_class *this) { struct cbq_class *cl, **clp; - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); for (clp = &q->classes[cbq_hash(this->classid)]; (cl = *clp) != NULL; clp = &cl->next) { if (cl == this) { @@ -1249,7 +1249,7 @@ static void cbq_link_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); unsigned h = cbq_hash(this->classid); struct cbq_class *parent = this->tparent; @@ -1270,7 +1270,7 @@ static unsigned int cbq_drop(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl, *cl_head; int prio; unsigned int len; @@ -1293,7 +1293,7 @@ static void cbq_reset(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int prio; unsigned h; @@ -1363,7 +1363,7 @@ static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); if (wrr->allot) cl->allot = wrr->allot; @@ -1432,7 +1432,7 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_CBQ_MAX]; struct tc_ratespec *r; @@ -1623,7 +1623,7 @@ static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; @@ -1650,7 +1650,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; unsigned char *b = skb->tail; struct rtattr *rta; @@ -1726,7 +1726,7 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = cbq_class_lookup(q, classid); if (cl) { @@ -1760,7 +1760,7 @@ static void cbq_destroy(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; unsigned h; @@ -1791,7 +1791,7 @@ if (--cl->refcnt == 0) { #ifdef CONFIG_NET_CLS_POLICE - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); spin_lock_bh(&sch->dev->queue_lock); if (q->rx_class == cl) @@ -1808,7 +1808,7 @@ unsigned long *arg) { int err; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)*arg; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_CBQ_MAX]; @@ -2004,7 +2004,7 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; if (cl->filters || cl->children || cl == &q->link) @@ -2042,7 +2042,7 @@ static struct tcf_proto **cbq_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class *)arg; if (cl == NULL) @@ -2054,7 +2054,7 @@ static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *p = (struct cbq_class*)parent; struct cbq_class *cl = cbq_class_lookup(q, classid); @@ -2076,7 +2076,7 @@ static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned h; if (arg->stop) diff -Nru a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c --- a/net/sched/sch_dsmark.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_dsmark.c 2004-07-27 11:03:02 -07:00 @@ -30,7 +30,7 @@ #endif -#define PRIV(sch) ((struct dsmark_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* diff -Nru a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c --- a/net/sched/sch_fifo.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_fifo.c 2004-07-27 11:03:02 -07:00 @@ -45,7 +45,7 @@ static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->stats.backlog + skb->len <= q->limit) { __skb_queue_tail(&sch->q, skb); @@ -106,7 +106,7 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->q.qlen < q->limit) { __skb_queue_tail(&sch->q, skb); @@ -138,7 +138,7 @@ static int fifo_init(struct Qdisc *sch, struct rtattr *opt) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (opt == NULL) { unsigned int limit = sch->dev->tx_queue_len ? : 1; @@ -158,7 +158,7 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_fifo_qopt opt; diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_generic.c 2004-07-27 11:03:02 -07:00 @@ -283,10 +283,9 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; if (list->qlen < qdisc->dev->tx_queue_len) { __skb_queue_tail(list, skb); @@ -304,7 +303,7 @@ pfifo_fast_dequeue(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); struct sk_buff *skb; for (prio = 0; prio < 3; prio++, list++) { @@ -320,10 +319,9 @@ static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; __skb_queue_head(list, skb); qdisc->q.qlen++; @@ -334,7 +332,7 @@ pfifo_fast_reset(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (prio=0; prio < 3; prio++) skb_queue_purge(list+prio); @@ -359,9 +357,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt) { int i; - struct sk_buff_head *list; - - list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (i=0; i<3; i++) skb_queue_head_init(list+i); @@ -385,13 +381,22 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) { + void *p; struct Qdisc *sch; - int size = sizeof(*sch) + ops->priv_size; + int size; + + /* ensure that the Qdisc and the private data are 32-byte aligned */ + size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); + size += ops->priv_size + QDISC_ALIGN_CONST; - sch = kmalloc(size, GFP_KERNEL); - if (!sch) + p = kmalloc(size, GFP_KERNEL); + if (!p) return NULL; - memset(sch, 0, size); + memset(p, 0, size); + + sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); + sch->padded = (char *)sch - (char *)p; skb_queue_head_init(&sch->q); sch->ops = ops; @@ -406,7 +411,7 @@ if (!ops->init || ops->init(sch, NULL) == 0) return sch; - kfree(sch); + kfree(p); return NULL; } @@ -438,7 +443,7 @@ module_put(ops->owner); if (!(qdisc->flags&TCQ_F_BUILTIN)) - kfree(qdisc); + kfree((char *) qdisc - qdisc->padded); } /* Under dev->queue_lock and BH! */ diff -Nru a/net/sched/sch_gred.c b/net/sched/sch_gred.c --- a/net/sched/sch_gred.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_gred.c 2004-07-27 11:03:02 -07:00 @@ -106,7 +106,7 @@ { psched_time_t now; struct gred_sched_data *q=NULL; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); unsigned long qave=0; int i=0; @@ -215,7 +215,7 @@ gred_requeue(struct sk_buff *skb, struct Qdisc* sch) { struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); q= t->tab[(skb->tc_index&0xf)]; /* error checking here -- probably unnecessary */ PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -231,7 +231,7 @@ { struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -264,7 +264,7 @@ struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -300,7 +300,7 @@ { int i; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); __skb_queue_purge(&sch->q); @@ -323,7 +323,7 @@ static int gred_change(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; struct tc_gred_qopt *ctl; struct tc_gred_sopt *sopt; @@ -469,7 +469,7 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct tc_gred_sopt *sopt; struct rtattr *tb[TCA_GRED_STAB]; struct rtattr *tb2[TCA_GRED_DPS]; @@ -502,7 +502,7 @@ struct rtattr *rta; struct tc_gred_qopt *opt = NULL ; struct tc_gred_qopt *dst; - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; int i; unsigned char *b = skb->tail; @@ -593,7 +593,7 @@ static void gred_destroy(struct Qdisc *sch) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); int i; for (i = 0;i < table->DPs; i++) { diff -Nru a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c --- a/net/sched/sch_hfsc.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_hfsc.c 2004-07-27 11:03:02 -07:00 @@ -1016,7 +1016,7 @@ static inline struct hfsc_class * hfsc_find_class(u32 classid, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; list_for_each_entry(cl, &q->clhash[hfsc_hash(classid)], hlist) { @@ -1061,7 +1061,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **tca, unsigned long *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)*arg; struct hfsc_class *parent = NULL; struct rtattr *opt = tca[TCA_OPTIONS-1]; @@ -1204,7 +1204,7 @@ static void hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); hfsc_destroy_filters(&cl->filter_list); qdisc_destroy(cl->qdisc); @@ -1218,7 +1218,7 @@ static int hfsc_delete_class(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl->level > 0 || cl->filter_cnt > 0 || cl == &q->root) @@ -1240,7 +1240,7 @@ static struct hfsc_class * hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -1381,7 +1381,7 @@ static struct tcf_proto ** hfsc_tcf_chain(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl == NULL) @@ -1489,7 +1489,7 @@ static void hfsc_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1523,7 +1523,7 @@ static void hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; u64 next_time = 0; long delay; @@ -1545,7 +1545,7 @@ static int hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; unsigned int i; @@ -1554,7 +1554,6 @@ qopt = RTA_DATA(opt); memset(q, 0, sizeof(struct hfsc_sched)); - sch->stats_lock = &sch->dev->queue_lock; q->defcls = qopt->defcls; for (i = 0; i < HFSC_HSIZE; i++) @@ -1585,7 +1584,7 @@ static int hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt)) @@ -1632,7 +1631,7 @@ static void hfsc_reset_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1651,7 +1650,7 @@ static void hfsc_destroy_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl, *next; unsigned int i; @@ -1666,7 +1665,7 @@ static int hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_hfsc_qopt qopt; @@ -1674,7 +1673,7 @@ RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); sch->stats.qlen = sch->q.qlen; - if (qdisc_copy_stats(skb, &sch->stats, sch->stats_lock) < 0) + if (qdisc_copy_stats(skb, &sch->stats, &sch->dev->queue_lock) < 0) goto rtattr_failure; return skb->len; @@ -1730,7 +1729,7 @@ static struct sk_buff * hfsc_dequeue(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct sk_buff *skb; u64 cur_time; @@ -1799,7 +1798,7 @@ static int hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); __skb_queue_head(&q->requeue, skb); sch->q.qlen++; @@ -1809,7 +1808,7 @@ static unsigned int hfsc_drop(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int len; diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c --- a/net/sched/sch_htb.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_htb.c 2004-07-27 11:03:02 -07:00 @@ -267,7 +267,7 @@ /* find class in global hash table using given handle */ static __inline__ struct htb_class *htb_find(u32 handle, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; if (TC_H_MAJ(handle) != sch->handle) return NULL; @@ -300,7 +300,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -712,7 +712,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) { int ret = NET_XMIT_SUCCESS; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_classify(skb,sch,&ret); @@ -759,7 +759,7 @@ /* TODO: requeuing packet charges it to policers again !! */ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int ret = NET_XMIT_SUCCESS; struct htb_class *cl = htb_classify(skb,sch, &ret); struct sk_buff *tskb; @@ -800,7 +800,7 @@ static void htb_rate_timer(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; /* lock queue so that we can muck with it */ @@ -1060,7 +1060,7 @@ static void htb_delay_by(struct Qdisc *sch,long delay) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); if (delay <= 0) delay = 1; if (unlikely(delay > 5*HZ)) { if (net_ratelimit()) @@ -1077,7 +1077,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) { struct sk_buff *skb = NULL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int level; long min_delay; #ifdef HTB_DEBUG @@ -1147,7 +1147,7 @@ /* try to drop from each class (by prio) until one succeed */ static unsigned int htb_drop(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int prio; for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) { @@ -1172,7 +1172,7 @@ /* always caled under BH & queue lock */ static void htb_reset(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; HTB_DBG(0,1,"htb_reset sch=%p, handle=%X\n",sch,sch->handle); @@ -1210,7 +1210,7 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct rtattr *tb[TCA_HTB_INIT]; struct tc_htb_glob *gopt; int i; @@ -1265,7 +1265,7 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_htb_glob gopt; @@ -1300,7 +1300,7 @@ struct sk_buff *skb, struct tcmsg *tcm) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; unsigned char *b = skb->tail; @@ -1358,7 +1358,7 @@ sch_tree_lock(sch); if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { if (cl->prio_activity) - htb_deactivate ((struct htb_sched*)sch->data,cl); + htb_deactivate (qdisc_priv(sch),cl); /* TODO: is it correct ? Why CBQ doesn't do it ? */ sch->q.qlen -= (*old)->q.qlen; @@ -1379,7 +1379,7 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = htb_find(classid,sch); HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0); @@ -1400,7 +1400,7 @@ static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destrycls clid=%X ref=%d\n", cl?cl->classid:0,cl?cl->refcnt:0); if (!cl->level) { BUG_TRAP(cl->un.leaf.q); @@ -1435,7 +1435,7 @@ /* always caled under BH & queue lock */ static void htb_destroy(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destroy q=%p\n",q); del_timer_sync (&q->timer); @@ -1457,7 +1457,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1484,7 +1484,7 @@ static void htb_put(struct Qdisc *sch, unsigned long arg) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1497,7 +1497,7 @@ u32 parentid, struct rtattr **tca, unsigned long *arg) { int err = -EINVAL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)*arg,*parent; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct qdisc_rate_table *rtab = NULL, *ctab = NULL; @@ -1623,7 +1623,7 @@ static struct tcf_proto **htb_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list; HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl); @@ -1633,7 +1633,7 @@ static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_find (classid,sch); HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt); /*if (cl && !cl->level) return 0; @@ -1654,7 +1654,7 @@ static void htb_unbind_filter(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt); if (cl) @@ -1665,7 +1665,7 @@ static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; if (arg->stop) diff -Nru a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c --- a/net/sched/sch_ingress.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_ingress.c 2004-07-27 11:03:02 -07:00 @@ -40,7 +40,7 @@ #endif -#define PRIV(sch) ((struct ingress_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* Thanks to Doron Oz for this hack diff -Nru a/net/sched/sch_netem.c b/net/sched/sch_netem.c --- a/net/sched/sch_netem.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_netem.c 2004-07-27 11:03:02 -07:00 @@ -603,7 +603,7 @@ */ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; psched_time_t now; long delay; @@ -659,7 +659,7 @@ /* Requeue packets but don't change time stamp */ static int netem_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -670,7 +670,7 @@ static unsigned int netem_drop(struct Qdisc* sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -686,7 +686,7 @@ */ static struct sk_buff *netem_dequeue(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; psched_time_t now; @@ -726,7 +726,7 @@ static void netem_reset(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); skb_queue_purge(&q->delayed); @@ -754,7 +754,7 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct tc_netem_qopt *qopt = RTA_DATA(opt); struct Qdisc *child; int ret; @@ -791,7 +791,7 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (!opt) return -EINVAL; @@ -809,7 +809,7 @@ static void netem_destroy(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); del_timer_sync(&q->timer); @@ -819,7 +819,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_netem_qopt qopt; @@ -841,7 +841,7 @@ static int netem_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct netem_sched_data *q = (struct netem_sched_data*)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -855,7 +855,7 @@ static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -871,7 +871,7 @@ static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -Nru a/net/sched/sch_prio.c b/net/sched/sch_prio.c --- a/net/sched/sch_prio.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_prio.c 2004-07-27 11:03:02 -07:00 @@ -49,7 +49,7 @@ struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); u32 band = skb->priority; struct tcf_result res; @@ -151,7 +151,7 @@ prio_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; struct Qdisc *qdisc; @@ -169,7 +169,7 @@ static unsigned int prio_drop(struct Qdisc* sch) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; unsigned int len; struct Qdisc *qdisc; @@ -189,7 +189,7 @@ prio_reset(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); for (prio=0; priobands; prio++) qdisc_reset(q->queues[prio]); @@ -200,7 +200,7 @@ prio_destroy(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tcf_proto *tp; while ((tp = q->filter_list) != NULL) { @@ -216,7 +216,7 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tc_prio_qopt *qopt = RTA_DATA(opt); int i; @@ -261,7 +261,7 @@ static int prio_init(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int i; for (i=0; idata; + struct prio_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_prio_qopt opt; @@ -297,7 +297,7 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -319,7 +319,7 @@ static struct Qdisc * prio_leaf(struct Qdisc *sch, unsigned long arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -330,7 +330,7 @@ static unsigned long prio_get(struct Qdisc *sch, u32 classid) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = TC_H_MIN(classid); if (band - 1 >= q->bands) @@ -352,7 +352,7 @@ static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct rtattr **tca, unsigned long *arg) { unsigned long cl = *arg; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -361,7 +361,7 @@ static int prio_delete(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; return 0; @@ -371,7 +371,7 @@ static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -383,7 +383,7 @@ static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; if (arg->stop) @@ -404,7 +404,7 @@ static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl) return NULL; diff -Nru a/net/sched/sch_red.c b/net/sched/sch_red.c --- a/net/sched/sch_red.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_red.c 2004-07-27 11:03:02 -07:00 @@ -180,7 +180,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); psched_time_t now; @@ -303,7 +303,7 @@ static int red_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -316,7 +316,7 @@ red_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -330,7 +330,7 @@ static unsigned int red_drop(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -347,7 +347,7 @@ static void red_reset(struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); __skb_queue_purge(&sch->q); sch->stats.backlog = 0; @@ -358,7 +358,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_RED_STAB]; struct tc_red_qopt *ctl; @@ -407,7 +407,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_red_qopt opt; diff -Nru a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c --- a/net/sched/sch_sfq.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_sfq.c 2004-07-27 11:03:02 -07:00 @@ -211,7 +211,7 @@ static unsigned int sfq_drop(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); sfq_index d = q->max_depth; struct sk_buff *skb; unsigned int len; @@ -253,7 +253,7 @@ static int sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -288,7 +288,7 @@ static int sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -324,7 +324,7 @@ static struct sk_buff * sfq_dequeue(struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; sfq_index a, old_a; @@ -369,7 +369,7 @@ static void sfq_perturbation(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); q->perturbation = net_random()&0x1F; q->perturb_timer.expires = jiffies + q->perturb_period; @@ -382,7 +382,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct tc_sfq_qopt *ctl = RTA_DATA(opt); if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) @@ -408,7 +408,7 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); int i; init_timer(&q->perturb_timer); @@ -440,13 +440,13 @@ static void sfq_destroy(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); del_timer(&q->perturb_timer); } static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_sfq_qopt opt; diff -Nru a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c --- a/net/sched/sch_tbf.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_tbf.c 2004-07-27 11:03:02 -07:00 @@ -137,7 +137,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if (skb->len > q->max_size) { @@ -163,7 +163,7 @@ static int tbf_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -174,7 +174,7 @@ static unsigned int tbf_drop(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -194,7 +194,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; skb = q->qdisc->dequeue(q->qdisc); @@ -261,7 +261,7 @@ static void tbf_reset(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); sch->q.qlen = 0; @@ -300,7 +300,7 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt) { int err = -EINVAL; - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_TBF_PTAB]; struct tc_tbf_qopt *qopt; struct qdisc_rate_table *rtab = NULL; @@ -366,7 +366,7 @@ static int tbf_init(struct Qdisc* sch, struct rtattr *opt) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (opt == NULL) return -EINVAL; @@ -383,7 +383,7 @@ static void tbf_destroy(struct Qdisc *sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); del_timer(&q->wd_timer); @@ -398,7 +398,7 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_tbf_qopt opt; @@ -427,7 +427,7 @@ static int tbf_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct tbf_sched_data *q = (struct tbf_sched_data*)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -441,7 +441,7 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -457,7 +457,7 @@ static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -Nru a/net/sched/sch_teql.c b/net/sched/sch_teql.c --- a/net/sched/sch_teql.c 2004-07-27 11:03:02 -07:00 +++ b/net/sched/sch_teql.c 2004-07-27 11:03:02 -07:00 @@ -81,7 +81,7 @@ struct sk_buff_head q; }; -#define NEXT_SLAVE(q) (((struct teql_sched_data*)((q)->data))->next) +#define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next) #define FMASK (IFF_BROADCAST|IFF_POINTOPOINT|IFF_BROADCAST) @@ -91,7 +91,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) { struct net_device *dev = sch->dev; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_tail(&q->q, skb); if (q->q.qlen <= dev->tx_queue_len) { @@ -109,7 +109,7 @@ static int teql_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_head(&q->q, skb); return 0; @@ -118,7 +118,7 @@ static struct sk_buff * teql_dequeue(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct sk_buff *skb; skb = __skb_dequeue(&dat->q); @@ -143,7 +143,7 @@ static void teql_reset(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); skb_queue_purge(&dat->q); sch->q.qlen = 0; @@ -154,7 +154,7 @@ teql_destroy(struct Qdisc* sch) { struct Qdisc *q, *prev; - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct teql_master *master = dat->m; if ((prev = master->slaves) != NULL) { @@ -184,7 +184,7 @@ { struct net_device *dev = sch->dev; struct teql_master *m = (struct teql_master*)sch->ops; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); if (dev->hard_header_len > m->dev->hard_header_len) return -EINVAL; @@ -229,7 +229,7 @@ static int __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) { - struct teql_sched_data *q = (void*)dev->qdisc->data; + struct teql_sched_data *q = qdisc_priv(dev->qdisc); struct neighbour *mn = skb->dst->neighbour; struct neighbour *n = q->ncache; From kaber@trash.net Tue Aug 3 08:47:10 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:47:27 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Fl9bN005592 for ; Tue, 3 Aug 2004 08:47:10 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id BBBC819F359; Tue, 3 Aug 2004 17:47:00 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id 25F0D39413A; Tue, 3 Aug 2004 17:20:06 +0200 (CEST) Message-ID: <410FADBC.6000904@trash.net> Date: Tue, 03 Aug 2004 17:22:36 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6 2/5]: refcount qdisc->dev Content-Type: multipart/mixed; boundary="------------040702070608010202030705" X-archive-position: 7455 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 2185 Lines: 68 This is a multi-part message in MIME format. --------------040702070608010202030705 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit This patch adds refcounting for qdisc->dev to avoid accessing freed memory from the __qdisc_destroy rcu-callback when the device is unregistered. Without refcounting netdev_wait_allrefs could free the device before __qdisc_destroy is done. --------------040702070608010202030705 Content-Type: text/x-patch; name="02-refcount-qdisc-dev.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="02-refcount-qdisc-dev.diff" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/02 23:50:01+02:00 kaber@coreworks.de # [PKT_SCHED: Refcount qdisc->dev for __qdisc_destroy rcu-callback # # Signed-off-by: Patrick McHardy # # net/sched/sch_generic.c # 2004/08/02 23:49:40+02:00 kaber@coreworks.de +3 -0 # [PKT_SCHED: Refcount qdisc->dev for __qdisc_destroy rcu-callback # # net/sched/sch_api.c # 2004/08/02 23:49:40+02:00 kaber@coreworks.de +1 -0 # [PKT_SCHED: Refcount qdisc->dev for __qdisc_destroy rcu-callback # diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c --- a/net/sched/sch_api.c 2004-08-03 01:10:18 +02:00 +++ b/net/sched/sch_api.c 2004-08-03 01:10:18 +02:00 @@ -430,6 +430,7 @@ sch->enqueue = ops->enqueue; sch->dequeue = ops->dequeue; sch->dev = dev; + dev_hold(dev); atomic_set(&sch->refcnt, 1); sch->stats_lock = &dev->queue_lock; if (handle == 0) { diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-08-03 01:10:18 +02:00 +++ b/net/sched/sch_generic.c 2004-08-03 01:10:18 +02:00 @@ -399,6 +399,7 @@ sch->enqueue = ops->enqueue; sch->dequeue = ops->dequeue; sch->dev = dev; + dev_hold(dev); sch->stats_lock = &dev->queue_lock; atomic_set(&sch->refcnt, 1); /* enqueue is accessed locklessly - make sure it's visible @@ -440,6 +441,8 @@ write_unlock(&qdisc_tree_lock); module_put(ops->owner); + if (qdisc->dev) + dev_put(qdisc->dev); if (!(qdisc->flags&TCQ_F_BUILTIN)) kfree(qdisc); } --------------040702070608010202030705-- From kaber@trash.net Tue Aug 3 08:47:10 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 08:47:28 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73FlAoI005593 for ; Tue, 3 Aug 2004 08:47:10 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id CF73619F35A; Tue, 3 Aug 2004 17:47:00 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id 78A62394139; Tue, 3 Aug 2004 17:18:06 +0200 (CEST) Message-ID: <410FAD44.7020503@trash.net> Date: Tue, 03 Aug 2004 17:20:36 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6 1/5]: Fix locking in __qdisc_destroy rcu-callback Content-Type: multipart/mixed; boundary="------------010405060805000700060907" X-archive-position: 7456 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 4779 Lines: 166 This is a multi-part message in MIME format. --------------010405060805000700060907 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The __qdisc_destroy rcu-callback doesn't do any locking when calling ops->reset and ops->destroy. qdisc_destroy is often called from both of these functions and it changes dev->qdisc_list. This patch adds proper locking to __qdisc_destroy. Unfortunately when using qdisc_tree_lock in process context we now also need to disable local bh's to avoid beeing interrupted by the rcu-callback. I'm not sure if RCU callback can be scheduled while the kernel is running in process context, so this may be unneccessary. --------------010405060805000700060907 Content-Type: text/x-patch; name="01-qdisc_destroy-rcu-locking.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="01-qdisc_destroy-rcu-locking.diff" # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/08/02 14:02:29+02:00 kaber@coreworks.de # [PKT_SCHED]: Fix locking in __qdisc_destroy rcu-callback # # Signed-off-by: Patrick McHardy # # net/sched/sch_generic.c # 2004/08/02 14:02:07+02:00 kaber@coreworks.de +12 -12 # [PKT_SCHED]: Fix locking in __qdisc_destroy rcu-callback # # net/sched/sch_api.c # 2004/08/02 14:02:07+02:00 kaber@coreworks.de +5 -5 # [PKT_SCHED]: Fix locking in __qdisc_destroy rcu-callback # diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c --- a/net/sched/sch_api.c 2004-08-03 01:09:43 +02:00 +++ b/net/sched/sch_api.c 2004-08-03 01:09:43 +02:00 @@ -812,18 +812,18 @@ continue; if (idx > s_idx) s_q_idx = 0; - read_lock(&qdisc_tree_lock); + read_lock_bh(&qdisc_tree_lock); for (q = dev->qdisc_list, q_idx = 0; q; q = q->next, q_idx++) { if (q_idx < s_q_idx) continue; if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { - read_unlock(&qdisc_tree_lock); + read_unlock_bh(&qdisc_tree_lock); goto done; } } - read_unlock(&qdisc_tree_lock); + read_unlock_bh(&qdisc_tree_lock); } done: @@ -1033,7 +1033,7 @@ s_t = cb->args[0]; - read_lock(&qdisc_tree_lock); + read_lock_bh(&qdisc_tree_lock); for (q=dev->qdisc_list, t=0; q; q = q->next, t++) { if (t < s_t) continue; if (!q->ops->cl_ops) continue; @@ -1052,7 +1052,7 @@ if (arg.w.stop) break; } - read_unlock(&qdisc_tree_lock); + read_unlock_bh(&qdisc_tree_lock); cb->args[0] = t; diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c --- a/net/sched/sch_generic.c 2004-08-03 01:09:43 +02:00 +++ b/net/sched/sch_generic.c 2004-08-03 01:09:43 +02:00 @@ -45,10 +45,11 @@ The idea is the following: - enqueue, dequeue are serialized via top level device spinlock dev->queue_lock. - - tree walking is protected by read_lock(qdisc_tree_lock) + - tree walking is protected by read_lock_bh(qdisc_tree_lock) and this lock is used only in process context. - - updates to tree are made only under rtnl semaphore, - hence this lock may be made without local bh disabling. + - updates to tree are made under rtnl semaphore or + from softirq context (__qdisc_destroy rcu-callback) + hence this lock needs local bh disabling. qdisc_tree_lock must be grabbed BEFORE dev->queue_lock! */ @@ -56,14 +57,14 @@ void qdisc_lock_tree(struct net_device *dev) { - write_lock(&qdisc_tree_lock); + write_lock_bh(&qdisc_tree_lock); spin_lock_bh(&dev->queue_lock); } void qdisc_unlock_tree(struct net_device *dev) { spin_unlock_bh(&dev->queue_lock); - write_unlock(&qdisc_tree_lock); + write_unlock_bh(&qdisc_tree_lock); } /* @@ -431,10 +432,12 @@ #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif + write_lock(&qdisc_tree_lock); if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); + write_unlock(&qdisc_tree_lock); module_put(ops->owner); if (!(qdisc->flags&TCQ_F_BUILTIN)) @@ -459,12 +462,9 @@ } } } - call_rcu(&qdisc->q_rcu, __qdisc_destroy); - } - void dev_activate(struct net_device *dev) { /* No queueing discipline is attached to device; @@ -482,17 +482,17 @@ return; } - write_lock(&qdisc_tree_lock); + write_lock_bh(&qdisc_tree_lock); qdisc->next = dev->qdisc_list; dev->qdisc_list = qdisc; - write_unlock(&qdisc_tree_lock); + write_unlock_bh(&qdisc_tree_lock); } else { qdisc = &noqueue_qdisc; } - write_lock(&qdisc_tree_lock); + write_lock_bh(&qdisc_tree_lock); dev->qdisc_sleeping = qdisc; - write_unlock(&qdisc_tree_lock); + write_unlock_bh(&qdisc_tree_lock); } spin_lock_bh(&dev->queue_lock); --------------010405060805000700060907-- From romieu@fr.zoreil.com Tue Aug 3 09:52:08 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 09:52:14 -0700 (PDT) Received: from fr.zoreil.com (electric-eye.fr.zoreil.com [213.41.134.224]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Gq6wV007285 for ; Tue, 3 Aug 2004 09:52:07 -0700 Received: from electric-eye.fr.zoreil.com (localhost.localdomain [127.0.0.1]) by fr.zoreil.com (8.12.8/8.12.1) with ESMTP id i73GoSh9010837; Tue, 3 Aug 2004 18:50:28 +0200 Received: (from romieu@localhost) by electric-eye.fr.zoreil.com (8.12.8/8.12.1) id i73GoQ7I010835; Tue, 3 Aug 2004 18:50:26 +0200 Date: Tue, 3 Aug 2004 18:50:26 +0200 From: Francois Romieu To: Pasi Sjoholm Cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , akpm@osdl.org, netdev@oss.sgi.com, brad@brad-x.com, shemminger@osdl.org Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) Message-ID: <20040803185026.A10580@electric-eye.fr.zoreil.com> References: <20040803003515.A29885@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from ptsjohol@cc.jyu.fi on Tue, Aug 03, 2004 at 03:32:15PM +0300 X-Organisation: Land of Sunshine Inc. X-archive-position: 7457 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: romieu@fr.zoreil.com Precedence: bulk X-list: netdev Content-Length: 682 Lines: 17 Pasi Sjoholm : [...] > The first log file is with both patchs applied and the second one with one > little change to rx8139_rx() to show if it even goes to through > > " while (netif_running(dev) && received < budget > && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {"-section. > > This was the change which I made.. so you can see in the second log file > that there won't be any of these messages after the driver has crashed. If you remove the "if (received > 0) {" test in r8139-10.patch and keep both patches applied, I assume you are back to a crash within 15min (instead of within 2min as suggested by the log), right ? -- Ueimor From mmazur@kernel.pl Tue Aug 3 10:17:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 10:17:27 -0700 (PDT) Received: from box.punkt.pl (box.punkt.pl [217.8.180.66]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i73HHJVF008130 for ; Tue, 3 Aug 2004 10:17:20 -0700 Received: (qmail 24887 invoked by uid 0); 3 Aug 2004 17:17:04 -0000 Received: from do-box-z.zwm.punkt.pl (HELO home) (zwm?305-xf.pl@217.197.78.33) by box.punkt.pl with SMTP; 3 Aug 2004 17:17:03 -0000 From: Mariusz Mazur To: Stephen Hemminger Subject: Re: iproute2 and kernel headers Date: Tue, 3 Aug 2004 19:14:40 +0200 User-Agent: KMail/1.6.2 References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> <20040803001459.GA8637@irc.pl> <20040803083142.5a4ccaad@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803083142.5a4ccaad@dell_ss3.pdx.osdl.net> Cc: netdev@oss.sgi.com MIME-Version: 1.0 Content-Disposition: inline Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 8bit Message-Id: <200408031914.40751.mmazur@kernel.pl> X-archive-position: 7458 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: mmazur@kernel.pl Precedence: bulk X-list: netdev Content-Length: 1864 Lines: 38 On wtorek 03 sierpieñ 2004 17:31, Stephen Hemminger wrote: > > > I am willing to put some headers (not all) in with the user level > > > code, provided they are copies since they I can easily update. I don't > > > want to get into keeping an edited set of headers in sync. > > > > Aren't linux-libc-headers (*) sufficient? > > > > * - http://ep09.pld-linux.org/~mmazur/linux-libc-headers/ > > The theory of that is good, but in practice it would make the problem > worse. What iproute2 wants is to have the same kernel data structures as > the latest kernel. It is awkward enough making sure to get them from the > correct kernel sources, but doing it from a different package would make > updating and keeping everything current worse. This message was forwarded to me (I'm the llh maintainer). Llh is being updated by generating a diff between incremental kernel releases, fixing that diff and applying it to the last version of llh. I do have scripts to check wether such an update doesn't break any headers. There is a slight possibility that such an update might omit some crucial changes, but (at least when it comes to network headers) co-developers of my distribution (PLD) will most likely detect that allmost instantly and notify me what's wrong (in such a case I will release a fixed version of llh asap). Since removing all those glibc/linux-headers workarounds from iproute2/iptables was quite a pain for me I would really like to see building against llh at least as an option available from 'configure'. (In case you're wondering - yes, we've been building all the linux network userland stuff against llh for about 8 months now without any problems... quite the opposite actually) -- In the year eighty five ten God is gonna shake his mighty head He'll either say, "I'm pleased where man has been" Or tear it down, and start again From shemminger@osdl.org Tue Aug 3 10:50:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 10:50:43 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Hoan3009008 for ; Tue, 3 Aug 2004 10:50:36 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73HoH101317; Tue, 3 Aug 2004 10:50:17 -0700 Date: Tue, 3 Aug 2004 10:50:17 -0700 From: Stephen Hemminger To: Ben Greear , "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] (1/3) add ethtool ioctl forwarding to vlan Message-Id: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7459 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 2269 Lines: 63 When network devices are used in bridges, the bridge does an ethtool ioctl to pick up the speed; this doesn't work with vlans. This patch makes any ethtool gets forwarded to the under lying real device. It seemed to make sense to do MII as well. Signed-off-by: Stephen Hemminger diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c --- a/net/8021q/vlan.c 2004-07-27 15:45:02 -07:00 +++ b/net/8021q/vlan.c 2004-07-27 15:45:02 -07:00 @@ -358,6 +358,7 @@ new_dev->set_mac_address = vlan_dev_set_mac_address; new_dev->set_multicast_list = vlan_dev_set_multicast_list; new_dev->destructor = free_netdev; + new_dev->do_ioctl = vlan_dev_ioctl; } /* Attach a VLAN device to a mac address (ie Ethernet Card). diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h --- a/net/8021q/vlan.h 2004-07-27 15:45:02 -07:00 +++ b/net/8021q/vlan.h 2004-07-27 15:45:02 -07:00 @@ -65,6 +65,7 @@ int vlan_dev_set_mac_address(struct net_device *dev, void* addr); int vlan_dev_open(struct net_device* dev); int vlan_dev_stop(struct net_device* dev); +int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); int vlan_dev_set_ingress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); int vlan_dev_set_egress_priority(char* dev_name, __u32 skb_prio, short vlan_prio); int vlan_dev_set_vlan_flag(char* dev_name, __u32 flag, short flag_val); diff -Nru a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c --- a/net/8021q/vlan_dev.c 2004-07-27 15:45:02 -07:00 +++ b/net/8021q/vlan_dev.c 2004-07-27 15:45:02 -07:00 @@ -757,6 +757,30 @@ vlan_flush_mc_list(dev); return 0; } + +int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; + int err = -EOPNOTSUPP; + + switch(cmd) { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + if (real_dev->do_ioctl && netif_device_present(real_dev)) { + strncpy(ifr->ifr_name, real_dev->name, IFNAMSIZ); + err = real_dev->do_ioctl(dev, ifr, cmd); + } + break; + + case SIOCETHTOOL: + strncpy(ifr->ifr_name, real_dev->name, IFNAMSIZ); + err = dev_ethtool(ifr); + } + + return err; +} + /** Taken from Gleb + Lennert's VLAN code, and modified... */ void vlan_dev_set_multicast_list(struct net_device *vlan_dev) { From greearb@candelatech.com Tue Aug 3 11:03:14 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 11:03:19 -0700 (PDT) Received: from www.lanforge.com (ns1.lanforge.com [66.165.47.210]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73I2rM9009563 for ; Tue, 3 Aug 2004 11:03:14 -0700 Received: from candelatech.com (evrtwa1-ar2-4-35-049-074.evrtwa1.dsl-verizon.net [4.35.49.74]) (authenticated bits=0) by www.lanforge.com (8.12.8/8.12.8) with ESMTP id i73IHPSb012513; Tue, 3 Aug 2004 11:17:25 -0700 Message-ID: <410FD348.9040301@candelatech.com> Date: Tue, 03 Aug 2004 11:02:48 -0700 From: Ben Greear Organization: Candela Technologies User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Stephen Hemminger CC: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] (1/3) add ethtool ioctl forwarding to vlan References: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7460 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: greearb@candelatech.com Precedence: bulk X-list: netdev Content-Length: 527 Lines: 16 Stephen Hemminger wrote: > When network devices are used in bridges, the bridge does an ethtool > ioctl to pick up the speed; this doesn't work with vlans. > This patch makes any ethtool gets forwarded to the under lying > real device. It seemed to make sense to do MII as well. Looks good to me. I'll also send a patch against 2.6.8 (when it's out) to bring the 2.6 VLAN code up to date with the latest 2.4 stuff. Thanks, Ben -- Ben Greear Candela Technologies Inc http://www.candelatech.com From kaber@trash.net Tue Aug 3 12:15:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 12:15:55 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73JFTDv012584 for ; Tue, 3 Aug 2004 12:15:50 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 86ABD19F355; Tue, 3 Aug 2004 21:15:20 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id 6F092394134; Tue, 3 Aug 2004 21:15:19 +0200 (CEST) Message-ID: <410FE4DD.5000306@trash.net> Date: Tue, 03 Aug 2004 21:17:49 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Stephen Hemminger Cc: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] cache align qdisc data References: <410FAE42.2050909@trash.net> <20040803083820.711c917c@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803083820.711c917c@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7461 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 850 Lines: 32 Stephen Hemminger wrote: >This patch has qdisc code use the same interface as the netdevice code >to cache align the object private data. > > These two hunks look bogus. >diff -Nru a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c >--- a/net/sched/sch_hfsc.c 2004-07-27 11:03:02 -07:00 >+++ b/net/sched/sch_hfsc.c 2004-07-27 11:03:02 -07:00 >@@ -1554,7 +1554,6 @@ > qopt = RTA_DATA(opt); > > memset(q, 0, sizeof(struct hfsc_sched)); >- sch->stats_lock = &sch->dev->queue_lock; > > q->defcls = qopt->defcls; > for (i = 0; i < HFSC_HSIZE; i++) > >@@ -1674,7 +1673,7 @@ > RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); > > sch->stats.qlen = sch->q.qlen; >- if (qdisc_copy_stats(skb, &sch->stats, sch->stats_lock) < 0) >+ if (qdisc_copy_stats(skb, &sch->stats, &sch->dev->queue_lock) < 0) > goto rtattr_failure; > > return skb->len; > > From kaber@trash.net Tue Aug 3 12:20:26 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 12:20:31 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73JKP3o016102 for ; Tue, 3 Aug 2004 12:20:25 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 5F7EE19F355; Tue, 3 Aug 2004 21:20:16 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id ACFC9394133; Tue, 3 Aug 2004 21:20:15 +0200 (CEST) Message-ID: <410FE605.8070606@trash.net> Date: Tue, 03 Aug 2004 21:22:45 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Stephen Hemminger Cc: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6 3/5]: Use double-linked list for dev->qdisc_list References: <410FAE42.2050909@trash.net> <20040803083540.13675d64@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803083540.13675d64@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7462 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 4919 Lines: 193 Stephen Hemminger wrote: >Since qdisc lists are using rcu for deletion, you should use the >_rcu flavors of list stuff. > > RCU is used for dev->qdisc, but not for dev->qdisc_list. >replace BUG_TRAP(dev->qdisc_list == NULL); >with BUG_TRAP(list_empty(&dev->qdisc_list)); > >I tried a similar patch but was finding the bug_trap() was showing up on >deletion so did not trust it. > > The BUG_TRAP is no longer valid with RCU. The qdiscs aren't destroyed immediately, so they are still in the list. Regards Patrick >This is what I was experimenting with. > >------------ >diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h >--- a/include/linux/netdevice.h 2004-07-28 15:14:27 -07:00 >+++ b/include/linux/netdevice.h 2004-07-28 15:14:27 -07:00 >@@ -362,7 +362,7 @@ > > struct Qdisc *qdisc; > struct Qdisc *qdisc_sleeping; >- struct Qdisc *qdisc_list; >+ struct list_head qdisc_list; > struct Qdisc *qdisc_ingress; > unsigned long tx_queue_len; /* Max frames per queue allowed */ > >diff -Nru a/include/net/pkt_sched.h b/include/net/pkt_sched.h >--- a/include/net/pkt_sched.h 2004-07-28 15:14:27 -07:00 >+++ b/include/net/pkt_sched.h 2004-07-28 15:14:27 -07:00 >@@ -79,7 +79,7 @@ > #define TCQ_F_INGRES 4 > int padded; > struct Qdisc_ops *ops; >- struct Qdisc *next; >+ struct list_head list; > u32 handle; > atomic_t refcnt; > struct sk_buff_head q; >diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c >--- a/net/sched/sch_api.c 2004-07-28 15:14:27 -07:00 >+++ b/net/sched/sch_api.c 2004-07-28 15:14:27 -07:00 >@@ -195,7 +195,7 @@ > { > struct Qdisc *q; > >- for (q = dev->qdisc_list; q; q = q->next) { >+ list_for_each_entry_rcu(q, &dev->qdisc_list, list) { > if (q->handle == handle) > return q; > } >@@ -453,8 +453,7 @@ > smp_wmb(); > if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { > qdisc_lock_tree(dev); >- sch->next = dev->qdisc_list; >- dev->qdisc_list = sch; >+ list_add_rcu(&sch->list, &dev->qdisc_list); > qdisc_unlock_tree(dev); > > #ifdef CONFIG_NET_ESTIMATOR >@@ -812,18 +811,20 @@ > continue; > if (idx > s_idx) > s_q_idx = 0; >- read_lock(&qdisc_tree_lock); >- for (q = dev->qdisc_list, q_idx = 0; q; >- q = q->next, q_idx++) { >- if (q_idx < s_q_idx) >+ >+ rcu_read_lock(); >+ >+ q_idx = 0; >+ list_for_each_entry_rcu(q, &dev->qdisc_list, list) { >+ if (q_idx++ < s_q_idx) > continue; > if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, > cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { >- read_unlock(&qdisc_tree_lock); >+ rcu_read_unlock(); > goto done; > } > } >- read_unlock(&qdisc_tree_lock); >+ rcu_read_unlock(); > } > > done: >@@ -1033,9 +1034,10 @@ > > s_t = cb->args[0]; > >- read_lock(&qdisc_tree_lock); >- for (q=dev->qdisc_list, t=0; q; q = q->next, t++) { >- if (t < s_t) continue; >+ rcu_read_lock(); >+ t = 0; >+ list_for_each_entry_rcu(q, &dev->qdisc_list, list) { >+ if (t++ < s_t) continue; > if (!q->ops->cl_ops) continue; > if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle) > continue; >@@ -1052,7 +1054,7 @@ > if (arg.w.stop) > break; > } >- read_unlock(&qdisc_tree_lock); >+ rcu_read_unlock(); > > cb->args[0] = t; > >diff -Nru a/net/sched/sch_generic.c b/net/sched/sch_generic.c >--- a/net/sched/sch_generic.c 2004-07-28 15:14:27 -07:00 >+++ b/net/sched/sch_generic.c 2004-07-28 15:14:27 -07:00 >@@ -405,6 +405,8 @@ > sch->dev = dev; > sch->stats_lock = &dev->queue_lock; > atomic_set(&sch->refcnt, 1); >+ INIT_LIST_HEAD(&sch->list); >+ > /* enqueue is accessed locklessly - make sure it's visible > * before we set a netdevice's qdisc pointer to sch */ > smp_wmb(); >@@ -450,23 +452,12 @@ > > void qdisc_destroy(struct Qdisc *qdisc) > { >- struct net_device *dev = qdisc->dev; >- > if (!atomic_dec_and_test(&qdisc->refcnt)) > return; > >- if (dev) { >- struct Qdisc *q, **qp; >- for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { >- if (q == qdisc) { >- *qp = q->next; >- break; >- } >- } >- } >- >+ if (qdisc->dev) >+ list_del_rcu(&qdisc->list); > call_rcu(&qdisc->q_rcu, __qdisc_destroy); >- > } > > >@@ -488,8 +479,7 @@ > } > > write_lock(&qdisc_tree_lock); >- qdisc->next = dev->qdisc_list; >- dev->qdisc_list = qdisc; >+ list_add_rcu(&qdisc->list, &dev->qdisc_list); > write_unlock(&qdisc_tree_lock); > > } else { >@@ -533,7 +523,7 @@ > qdisc_lock_tree(dev); > dev->qdisc = &noop_qdisc; > dev->qdisc_sleeping = &noop_qdisc; >- dev->qdisc_list = NULL; >+ INIT_LIST_HEAD(&dev->qdisc_list); > qdisc_unlock_tree(dev); > > dev_watchdog_init(dev); >@@ -554,9 +544,9 @@ > qdisc_destroy(qdisc); > } > #endif >- BUG_TRAP(dev->qdisc_list == NULL); >+ BUG_TRAP(!list_empty(&dev->qdisc_list)); > BUG_TRAP(!timer_pending(&dev->watchdog_timer)); >- dev->qdisc_list = NULL; >+ > qdisc_unlock_tree(dev); > } > > > > From mcr@sandelman.ottawa.on.ca Tue Aug 3 12:35:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 12:36:10 -0700 (PDT) Received: from noxmail.sandelman.ottawa.on.ca (cyphermail.sandelman.ottawa.on.ca [205.150.200.161]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73JZw8i016675 for ; Tue, 3 Aug 2004 12:35:58 -0700 Received: from lox.sandelman.ottawa.on.ca (IDENT:root@lox.sandelman.ottawa.on.ca [205.150.200.178]) by noxmail.sandelman.ottawa.on.ca (8.11.6p3/8.11.6) with ESMTP id i73JZe825542 (using TLSv1/SSLv3 with cipher EDH-RSA-DES-CBC3-SHA (168 bits) verified FAIL); Tue, 3 Aug 2004 15:35:41 -0400 (EDT) Received: from sandelman.ottawa.on.ca (desk.marajade.sandelman.ca [205.150.200.247]) by lox.sandelman.ottawa.on.ca (8.11.6p3/8.11.6) with ESMTP id i73JePs01612 (using TLSv1/SSLv3 with cipher EDH-RSA-DES-CBC3-SHA (168 bits) verified FAIL); Tue, 3 Aug 2004 15:40:31 -0400 (EDT) Received: from sandelman.ottawa.on.ca (marajade [127.0.0.1]) by sandelman.ottawa.on.ca (8.12.3/8.12.3/Debian-6.6) with ESMTP id i73JX74F022098 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO); Tue, 3 Aug 2004 15:33:08 -0400 Received: from marajade.sandelman.ottawa.on.ca (mcr@localhost) by sandelman.ottawa.on.ca (8.12.3/8.12.3/Debian-6.6) with ESMTP id i73JWxZF022094; Tue, 3 Aug 2004 15:33:02 -0400 To: Herbert Xu cc: netdev , dev@lists.openswan.org Subject: CONFIG_XFRM vs udp.c X-Mailer: MH-E 7.4.2; nmh 1.0.4+dev; XEmacs 21.4 (patch 6) Mime-Version: 1.0 (generated by tm-edit 1.8) Content-Type: text/plain; charset=US-ASCII Date: Tue, 03 Aug 2004 15:32:59 -0400 Message-ID: <22093.1091561579@marajade.sandelman.ottawa.on.ca> From: Michael Richardson X-archive-position: 7463 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: mcr@sandelman.ottawa.on.ca Precedence: bulk X-list: netdev Content-Length: 1242 Lines: 33 -----BEGIN PGP SIGNED MESSAGE----- I was examining udp.c to understand how NAT-T (UDP encap of ESP packets) is handled. udp_encap_rcv() clearly bails if CONFIG_XFRM is not defined. but, udp_queue_rcv_skb() seems to call xfrm4_rcv_encap() regardless. It is it intentional that this part of XFRM can not be a module? It seems that one should call xfrm4_rcv_encap() directly only if one is all statically linked, and indirect through some function pointer otherwise. Or am I missing some magic that defines xfrom4_rcv_encap() all the time, and replaces it when XFRM is loaded? - -- ] "Elmo went to the wrong fundraiser" - The Simpson | firewalls [ ] Michael Richardson, Xelerance Corporation, Ottawa, ON |net architect[ ] mcr@xelerance.com http://www.sandelman.ottawa.on.ca/mcr/ |device driver[ ] panic("Just another Debian GNU/Linux using, kernel hacking, security guy"); [ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2 (GNU/Linux) Comment: Finger me for keys iQCVAwUBQQ/oaYqHRg3pndX9AQHtrAQAmO8u1SMq24mtYcq1bT1gFvYXEjZozHmf k6MJFLz/U9OzETMdBwa6V+geIjOhAN/7BUIilONcT0Q9ESzr8SeW1cRpIv2/jQb3 maGAiVE8dqM2wdUKPX5x3nY7t5FHIxz3zUVD6Eyk8McpfzA7z42fYTqyJn4pKiNQ gjcjs/uLdRo= =SWZ1 -----END PGP SIGNATURE----- From shemminger@osdl.org Tue Aug 3 13:11:29 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:11:36 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KBQSZ017778 for ; Tue, 3 Aug 2004 13:11:29 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73KBB125550; Tue, 3 Aug 2004 13:11:11 -0700 Date: Tue, 3 Aug 2004 13:11:11 -0700 From: Stephen Hemminger To: "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] netem limit not returned correctly Message-Id: <20040803131111.6ce2c36c@dell_ss3.pdx.osdl.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7464 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 612 Lines: 20 Minor leftover from earlier code. Netem scheduler is not reporting correct limit (ie for 'tc qdisc ls') because it is returning devices limit not it's own. Should apply to 2.4 as well (with fuzz) Signed-off-by: Stephen Hemminger diff -Nru a/net/sched/sch_netem.c b/net/sched/sch_netem.c --- a/net/sched/sch_netem.c 2004-08-03 13:10:17 -07:00 +++ b/net/sched/sch_netem.c 2004-08-03 13:10:17 -07:00 @@ -825,7 +825,7 @@ qopt.latency = q->latency; qopt.jitter = q->jitter; - qopt.limit = sch->dev->tx_queue_len; + qopt.limit = q->limit; qopt.loss = q->loss; qopt.gap = q->gap; From shemminger@osdl.org Tue Aug 3 13:14:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:14:51 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KEian018480 for ; Tue, 3 Aug 2004 13:14:46 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73KEP126052; Tue, 3 Aug 2004 13:14:25 -0700 Date: Tue, 3 Aug 2004 13:14:25 -0700 From: Stephen Hemminger To: Ben Greear , "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] vlan - device refcount bug. Message-Id: <20040803131425.503f8f45@dell_ss3.pdx.osdl.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7465 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 619 Lines: 17 If you rmmod a network device that is in a vlan, the system hangs waiting for the refcount to go to zero, because it is -1. The problem is that the vlan notifier does an extra dev_put in NETDEV_UNREGISTER case of notifier. Signed-off-by: Stephen Hemminger diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c --- a/net/8021q/vlan.c 2004-08-03 13:13:33 -07:00 +++ b/net/8021q/vlan.c 2004-08-03 13:13:33 -07:00 @@ -645,7 +645,6 @@ ret = unregister_vlan_dev(dev, VLAN_DEV_INFO(vlandev)->vlan_id); - dev_put(vlandev); unregister_netdevice(vlandev); /* Group was destroyed? */ From ptsjohol@cc.jyu.fi Tue Aug 3 13:19:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:20:05 -0700 (PDT) Received: from posti5.jyu.fi (posti5.jyu.fi [130.234.4.34]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KJvT1018895 for ; Tue, 3 Aug 2004 13:19:58 -0700 Received: from silmu.st.jyu.fi (IDENT:zzeTGsDHselP2xnHa6XVvCA77CN0dcuo@silmu.st.jyu.fi [130.234.4.64]) by posti5.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i73KJYcn022592; Tue, 3 Aug 2004 23:19:34 +0300 Date: Tue, 3 Aug 2004 23:19:33 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: <20040803185026.A10580@electric-eye.fr.zoreil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti5.jyu.fi; Tue, 03 Aug 2004 23:19:36 +0300 X-archive-position: 7466 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev Content-Length: 1252 Lines: 35 On Tue, 3 Aug 2004, Francois Romieu wrote: > > The first log file is with both patchs applied and the second one with one > > little change to rx8139_rx() to show if it even goes to through > > > > " while (netif_running(dev) && received < budget > > && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {"-section. > > > > This was the change which I made.. so you can see in the second log file > > that there won't be any of these messages after the driver has crashed. > If you remove the "if (received > 0) {" test in r8139-10.patch and keep > both patches applied, I assume you are back to a crash within 15min (instead > of within 2min as suggested by the log), right ? Hmm, I removed "if (received > 0) {" and tested it something like 3 hours and wasn't able to crash the driver. I will test it for couple more hours tomorrow and if I'm not still able the crash it, we may have find some sort of a solution. I'm not sure yet if it's a good one because of that earlier crash I had. I guess I will also test if - read the interruption status word that the driver will ack before the actual processing is done; has something to do it. We'll see.. I'll get back to you tomorrow with more information. -- Pasi Sjöholm From shemminger@osdl.org Tue Aug 3 13:32:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:32:17 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KW3EI019429 for ; Tue, 3 Aug 2004 13:32:05 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73KVd128792; Tue, 3 Aug 2004 13:31:39 -0700 Date: Tue, 3 Aug 2004 13:31:39 -0700 From: Stephen Hemminger To: Patrick McHardy , "David S. Miller" Cc: netdev@oss.sgi.com Subject: Re: [PATCH 2.6] cache align qdisc data Message-Id: <20040803133139.43107fd3@dell_ss3.pdx.osdl.net> In-Reply-To: <410FE4DD.5000306@trash.net> References: <410FAE42.2050909@trash.net> <20040803083820.711c917c@dell_ss3.pdx.osdl.net> <410FE4DD.5000306@trash.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7467 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 53558 Lines: 1550 On Tue, 03 Aug 2004 21:17:49 +0200 Patrick McHardy wrote: > Stephen Hemminger wrote: > > >This patch has qdisc code use the same interface as the netdevice code > >to cache align the object private data. That was some old messing around, that got in there... Here is the correct patch. diff -urNp -X dontdiff linux-2.6/include/net/pkt_sched.h qdisc-2.6/include/net/pkt_sched.h --- linux-2.6/include/net/pkt_sched.h 2004-07-30 12:17:02.000000000 -0700 +++ qdisc-2.6/include/net/pkt_sched.h 2004-08-03 12:50:52.324952264 -0700 @@ -77,6 +77,7 @@ struct Qdisc #define TCQ_F_BUILTIN 1 #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 + int padded; struct Qdisc_ops *ops; struct Qdisc *next; u32 handle; @@ -93,10 +94,17 @@ struct Qdisc * and it will live until better solution will be invented. */ struct Qdisc *__parent; - - char data[0]; }; +#define QDISC_ALIGN 32 +#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) + +static inline void *qdisc_priv(struct Qdisc *q) +{ + return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); +} + struct qdisc_rate_table { struct tc_ratespec rate; diff -urNp -X dontdiff linux-2.6/net/sched/sch_cbq.c qdisc-2.6/net/sched/sch_cbq.c --- linux-2.6/net/sched/sch_cbq.c 2004-07-07 10:14:26.000000000 -0700 +++ qdisc-2.6/net/sched/sch_cbq.c 2004-07-27 09:17:28.000000000 -0700 @@ -241,7 +241,7 @@ cbq_reclassify(struct sk_buff *skb, stru static struct cbq_class * cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *head = &q->link; struct cbq_class **defmap; struct cbq_class *cl = NULL; @@ -344,7 +344,7 @@ fallback: static __inline__ void cbq_activate_class(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); int prio = cl->cpriority; struct cbq_class *cl_tail; @@ -368,7 +368,7 @@ static __inline__ void cbq_activate_clas static void cbq_deactivate_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); int prio = this->cpriority; struct cbq_class *cl; struct cbq_class *cl_prev = q->active[prio]; @@ -419,7 +419,7 @@ cbq_mark_toplevel(struct cbq_sched_data static int cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); int len = skb->len; int ret = NET_XMIT_SUCCESS; struct cbq_class *cl = cbq_classify(skb, sch,&ret); @@ -466,7 +466,7 @@ cbq_enqueue(struct sk_buff *skb, struct static int cbq_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int ret; @@ -500,7 +500,7 @@ cbq_requeue(struct sk_buff *skb, struct static void cbq_ovl_classic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -554,7 +554,7 @@ static void cbq_ovl_classic(struct cbq_c static void cbq_ovl_rclassic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this = cl; do { @@ -573,7 +573,7 @@ static void cbq_ovl_rclassic(struct cbq_ static void cbq_ovl_delay(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -609,7 +609,7 @@ static void cbq_ovl_delay(struct cbq_cla static void cbq_ovl_lowprio(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); cl->penalized = jiffies + cl->penalty; @@ -678,7 +678,7 @@ static unsigned long cbq_undelay_prio(st static void cbq_undelay(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); long delay = 0; unsigned pmask; @@ -715,7 +715,7 @@ static int cbq_reshape_fail(struct sk_bu { int len = skb->len; struct Qdisc *sch = child->__parent; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = q->rx_class; q->rx_class = NULL; @@ -863,7 +863,7 @@ cbq_update(struct cbq_sched_data *q) static __inline__ struct cbq_class * cbq_under_limit(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this_cl = cl; if (cl->tparent == NULL) @@ -903,7 +903,7 @@ cbq_under_limit(struct cbq_class *cl) static __inline__ struct sk_buff * cbq_dequeue_prio(struct Qdisc *sch, int prio) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl_tail, *cl_prev, *cl; struct sk_buff *skb; int deficit; @@ -1006,7 +1006,7 @@ next_class: static __inline__ struct sk_buff * cbq_dequeue_1(struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; unsigned activemask; @@ -1025,7 +1025,7 @@ static struct sk_buff * cbq_dequeue(struct Qdisc *sch) { struct sk_buff *skb; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); psched_time_t now; psched_tdiff_t incr; @@ -1150,7 +1150,7 @@ static void cbq_normalize_quanta(struct static void cbq_sync_defmap(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *split = cl->split; unsigned h; int i; @@ -1216,7 +1216,7 @@ static void cbq_change_defmap(struct cbq static void cbq_unlink_class(struct cbq_class *this) { struct cbq_class *cl, **clp; - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); for (clp = &q->classes[cbq_hash(this->classid)]; (cl = *clp) != NULL; clp = &cl->next) { if (cl == this) { @@ -1249,7 +1249,7 @@ static void cbq_unlink_class(struct cbq_ static void cbq_link_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); unsigned h = cbq_hash(this->classid); struct cbq_class *parent = this->tparent; @@ -1270,7 +1270,7 @@ static void cbq_link_class(struct cbq_cl static unsigned int cbq_drop(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl, *cl_head; int prio; unsigned int len; @@ -1293,7 +1293,7 @@ static unsigned int cbq_drop(struct Qdis static void cbq_reset(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int prio; unsigned h; @@ -1363,7 +1363,7 @@ static void cbq_addprio(struct cbq_sched static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); if (wrr->allot) cl->allot = wrr->allot; @@ -1432,7 +1432,7 @@ static int cbq_set_fopt(struct cbq_class static int cbq_init(struct Qdisc *sch, struct rtattr *opt) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_CBQ_MAX]; struct tc_ratespec *r; @@ -1623,7 +1623,7 @@ rtattr_failure: static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; @@ -1650,7 +1650,7 @@ static int cbq_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; unsigned char *b = skb->tail; struct rtattr *rta; @@ -1726,7 +1726,7 @@ cbq_leaf(struct Qdisc *sch, unsigned lon static unsigned long cbq_get(struct Qdisc *sch, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = cbq_class_lookup(q, classid); if (cl) { @@ -1760,7 +1760,7 @@ static void cbq_destroy_class(struct cbq static void cbq_destroy(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; unsigned h; @@ -1791,7 +1791,7 @@ static void cbq_put(struct Qdisc *sch, u if (--cl->refcnt == 0) { #ifdef CONFIG_NET_CLS_POLICE - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); spin_lock_bh(&sch->dev->queue_lock); if (q->rx_class == cl) @@ -1808,7 +1808,7 @@ cbq_change_class(struct Qdisc *sch, u32 unsigned long *arg) { int err; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)*arg; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_CBQ_MAX]; @@ -2004,7 +2004,7 @@ failure: static int cbq_delete(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; if (cl->filters || cl->children || cl == &q->link) @@ -2042,7 +2042,7 @@ static int cbq_delete(struct Qdisc *sch, static struct tcf_proto **cbq_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class *)arg; if (cl == NULL) @@ -2054,7 +2054,7 @@ static struct tcf_proto **cbq_find_tcf(s static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *p = (struct cbq_class*)parent; struct cbq_class *cl = cbq_class_lookup(q, classid); @@ -2076,7 +2076,7 @@ static void cbq_unbind_filter(struct Qdi static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned h; if (arg->stop) diff -urNp -X dontdiff linux-2.6/net/sched/sch_dsmark.c qdisc-2.6/net/sched/sch_dsmark.c --- linux-2.6/net/sched/sch_dsmark.c 2004-04-19 10:03:23.000000000 -0700 +++ qdisc-2.6/net/sched/sch_dsmark.c 2004-07-27 09:17:28.000000000 -0700 @@ -30,7 +30,7 @@ #endif -#define PRIV(sch) ((struct dsmark_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* diff -urNp -X dontdiff linux-2.6/net/sched/sch_fifo.c qdisc-2.6/net/sched/sch_fifo.c --- linux-2.6/net/sched/sch_fifo.c 2004-02-19 10:28:27.000000000 -0800 +++ qdisc-2.6/net/sched/sch_fifo.c 2004-07-27 09:17:28.000000000 -0700 @@ -45,7 +45,7 @@ struct fifo_sched_data static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->stats.backlog + skb->len <= q->limit) { __skb_queue_tail(&sch->q, skb); @@ -106,7 +106,7 @@ fifo_reset(struct Qdisc* sch) static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->q.qlen < q->limit) { __skb_queue_tail(&sch->q, skb); @@ -138,7 +138,7 @@ pfifo_dequeue(struct Qdisc* sch) static int fifo_init(struct Qdisc *sch, struct rtattr *opt) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (opt == NULL) { unsigned int limit = sch->dev->tx_queue_len ? : 1; @@ -158,7 +158,7 @@ static int fifo_init(struct Qdisc *sch, static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_fifo_qopt opt; diff -urNp -X dontdiff linux-2.6/net/sched/sch_generic.c qdisc-2.6/net/sched/sch_generic.c --- linux-2.6/net/sched/sch_generic.c 2004-07-30 12:17:03.000000000 -0700 +++ qdisc-2.6/net/sched/sch_generic.c 2004-08-03 12:50:53.071838720 -0700 @@ -283,10 +283,9 @@ static const u8 prio2band[TC_PRIO_MAX+1] static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; if (list->qlen < qdisc->dev->tx_queue_len) { __skb_queue_tail(list, skb); @@ -304,7 +303,7 @@ static struct sk_buff * pfifo_fast_dequeue(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); struct sk_buff *skb; for (prio = 0; prio < 3; prio++, list++) { @@ -320,10 +319,9 @@ pfifo_fast_dequeue(struct Qdisc* qdisc) static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; __skb_queue_head(list, skb); qdisc->q.qlen++; @@ -334,7 +332,7 @@ static void pfifo_fast_reset(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (prio=0; prio < 3; prio++) skb_queue_purge(list+prio); @@ -359,9 +357,7 @@ rtattr_failure: static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt) { int i; - struct sk_buff_head *list; - - list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (i=0; i<3; i++) skb_queue_head_init(list+i); @@ -385,13 +381,22 @@ static struct Qdisc_ops pfifo_fast_ops = struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) { + void *p; struct Qdisc *sch; - int size = sizeof(*sch) + ops->priv_size; + int size; + + /* ensure that the Qdisc and the private data are 32-byte aligned */ + size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); + size += ops->priv_size + QDISC_ALIGN_CONST; - sch = kmalloc(size, GFP_KERNEL); - if (!sch) + p = kmalloc(size, GFP_KERNEL); + if (!p) return NULL; - memset(sch, 0, size); + memset(p, 0, size); + + sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); + sch->padded = (char *)sch - (char *)p; skb_queue_head_init(&sch->q); sch->ops = ops; @@ -406,7 +411,7 @@ struct Qdisc * qdisc_create_dflt(struct if (!ops->init || ops->init(sch, NULL) == 0) return sch; - kfree(sch); + kfree(p); return NULL; } @@ -438,7 +443,7 @@ static void __qdisc_destroy(struct rcu_h module_put(ops->owner); if (!(qdisc->flags&TCQ_F_BUILTIN)) - kfree(qdisc); + kfree((char *) qdisc - qdisc->padded); } /* Under dev->queue_lock and BH! */ diff -urNp -X dontdiff linux-2.6/net/sched/sch_gred.c qdisc-2.6/net/sched/sch_gred.c --- linux-2.6/net/sched/sch_gred.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_gred.c 2004-07-27 09:17:28.000000000 -0700 @@ -106,7 +106,7 @@ gred_enqueue(struct sk_buff *skb, struct { psched_time_t now; struct gred_sched_data *q=NULL; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); unsigned long qave=0; int i=0; @@ -215,7 +215,7 @@ static int gred_requeue(struct sk_buff *skb, struct Qdisc* sch) { struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); q= t->tab[(skb->tc_index&0xf)]; /* error checking here -- probably unnecessary */ PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -231,7 +231,7 @@ gred_dequeue(struct Qdisc* sch) { struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -264,7 +264,7 @@ static unsigned int gred_drop(struct Qdi struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -300,7 +300,7 @@ static void gred_reset(struct Qdisc* sch { int i; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); __skb_queue_purge(&sch->q); @@ -323,7 +323,7 @@ static void gred_reset(struct Qdisc* sch static int gred_change(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; struct tc_gred_qopt *ctl; struct tc_gred_sopt *sopt; @@ -469,7 +469,7 @@ static int gred_change(struct Qdisc *sch static int gred_init(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct tc_gred_sopt *sopt; struct rtattr *tb[TCA_GRED_STAB]; struct rtattr *tb2[TCA_GRED_DPS]; @@ -502,7 +502,7 @@ static int gred_dump(struct Qdisc *sch, struct rtattr *rta; struct tc_gred_qopt *opt = NULL ; struct tc_gred_qopt *dst; - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; int i; unsigned char *b = skb->tail; @@ -593,7 +593,7 @@ rtattr_failure: static void gred_destroy(struct Qdisc *sch) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); int i; for (i = 0;i < table->DPs; i++) { diff -urNp -X dontdiff linux-2.6/net/sched/sch_hfsc.c qdisc-2.6/net/sched/sch_hfsc.c --- linux-2.6/net/sched/sch_hfsc.c 2004-07-26 09:20:38.000000000 -0700 +++ qdisc-2.6/net/sched/sch_hfsc.c 2004-07-27 09:17:28.000000000 -0700 @@ -1016,7 +1016,7 @@ hfsc_hash(u32 h) static inline struct hfsc_class * hfsc_find_class(u32 classid, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; list_for_each_entry(cl, &q->clhash[hfsc_hash(classid)], hlist) { @@ -1061,7 +1061,7 @@ static int hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **tca, unsigned long *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)*arg; struct hfsc_class *parent = NULL; struct rtattr *opt = tca[TCA_OPTIONS-1]; @@ -1204,7 +1204,7 @@ hfsc_destroy_filters(struct tcf_proto ** static void hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); hfsc_destroy_filters(&cl->filter_list); qdisc_destroy(cl->qdisc); @@ -1218,7 +1218,7 @@ hfsc_destroy_class(struct Qdisc *sch, st static int hfsc_delete_class(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl->level > 0 || cl->filter_cnt > 0 || cl == &q->root) @@ -1240,7 +1240,7 @@ hfsc_delete_class(struct Qdisc *sch, uns static struct hfsc_class * hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -1381,7 +1381,7 @@ hfsc_unbind_tcf(struct Qdisc *sch, unsig static struct tcf_proto ** hfsc_tcf_chain(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl == NULL) @@ -1489,7 +1489,7 @@ hfsc_dump_class(struct Qdisc *sch, unsig static void hfsc_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1523,7 +1523,7 @@ hfsc_watchdog(unsigned long arg) static void hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; u64 next_time = 0; long delay; @@ -1545,7 +1545,7 @@ hfsc_schedule_watchdog(struct Qdisc *sch static int hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; unsigned int i; @@ -1554,7 +1554,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struc qopt = RTA_DATA(opt); memset(q, 0, sizeof(struct hfsc_sched)); - sch->stats_lock = &sch->dev->queue_lock; q->defcls = qopt->defcls; for (i = 0; i < HFSC_HSIZE; i++) @@ -1585,7 +1584,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struc static int hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt)) @@ -1632,7 +1631,7 @@ hfsc_reset_class(struct hfsc_class *cl) static void hfsc_reset_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1651,7 +1650,7 @@ hfsc_reset_qdisc(struct Qdisc *sch) static void hfsc_destroy_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl, *next; unsigned int i; @@ -1666,7 +1665,7 @@ hfsc_destroy_qdisc(struct Qdisc *sch) static int hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_hfsc_qopt qopt; @@ -1674,7 +1673,7 @@ hfsc_dump_qdisc(struct Qdisc *sch, struc RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); sch->stats.qlen = sch->q.qlen; - if (qdisc_copy_stats(skb, &sch->stats, sch->stats_lock) < 0) + if (qdisc_copy_stats(skb, &sch->stats, &sch->dev->queue_lock) < 0) goto rtattr_failure; return skb->len; @@ -1730,7 +1729,7 @@ hfsc_enqueue(struct sk_buff *skb, struct static struct sk_buff * hfsc_dequeue(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct sk_buff *skb; u64 cur_time; @@ -1799,7 +1798,7 @@ hfsc_dequeue(struct Qdisc *sch) static int hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); __skb_queue_head(&q->requeue, skb); sch->q.qlen++; @@ -1809,7 +1808,7 @@ hfsc_requeue(struct sk_buff *skb, struct static unsigned int hfsc_drop(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int len; diff -urNp -X dontdiff linux-2.6/net/sched/sch_htb.c qdisc-2.6/net/sched/sch_htb.c --- linux-2.6/net/sched/sch_htb.c 2004-07-26 09:20:38.000000000 -0700 +++ qdisc-2.6/net/sched/sch_htb.c 2004-07-27 09:17:28.000000000 -0700 @@ -267,7 +267,7 @@ static __inline__ int htb_hash(u32 h) /* find class in global hash table using given handle */ static __inline__ struct htb_class *htb_find(u32 handle, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; if (TC_H_MAJ(handle) != sch->handle) return NULL; @@ -300,7 +300,7 @@ static inline u32 htb_classid(struct htb static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -712,7 +712,7 @@ htb_deactivate(struct htb_sched *q,struc static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) { int ret = NET_XMIT_SUCCESS; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_classify(skb,sch,&ret); @@ -759,7 +759,7 @@ static int htb_enqueue(struct sk_buff *s /* TODO: requeuing packet charges it to policers again !! */ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int ret = NET_XMIT_SUCCESS; struct htb_class *cl = htb_classify(skb,sch, &ret); struct sk_buff *tskb; @@ -800,7 +800,7 @@ static void htb_timer(unsigned long arg) static void htb_rate_timer(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; /* lock queue so that we can muck with it */ @@ -1060,7 +1060,7 @@ next: static void htb_delay_by(struct Qdisc *sch,long delay) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); if (delay <= 0) delay = 1; if (unlikely(delay > 5*HZ)) { if (net_ratelimit()) @@ -1077,7 +1077,7 @@ static void htb_delay_by(struct Qdisc *s static struct sk_buff *htb_dequeue(struct Qdisc *sch) { struct sk_buff *skb = NULL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int level; long min_delay; #ifdef HTB_DEBUG @@ -1147,7 +1147,7 @@ fin: /* try to drop from each class (by prio) until one succeed */ static unsigned int htb_drop(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int prio; for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) { @@ -1172,7 +1172,7 @@ static unsigned int htb_drop(struct Qdis /* always caled under BH & queue lock */ static void htb_reset(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; HTB_DBG(0,1,"htb_reset sch=%p, handle=%X\n",sch,sch->handle); @@ -1210,7 +1210,7 @@ static void htb_reset(struct Qdisc* sch) static int htb_init(struct Qdisc *sch, struct rtattr *opt) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct rtattr *tb[TCA_HTB_INIT]; struct tc_htb_glob *gopt; int i; @@ -1265,7 +1265,7 @@ static int htb_init(struct Qdisc *sch, s static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_htb_glob gopt; @@ -1300,7 +1300,7 @@ static int htb_dump_class(struct Qdisc * struct sk_buff *skb, struct tcmsg *tcm) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; unsigned char *b = skb->tail; @@ -1358,7 +1358,7 @@ static int htb_graft(struct Qdisc *sch, sch_tree_lock(sch); if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { if (cl->prio_activity) - htb_deactivate ((struct htb_sched*)sch->data,cl); + htb_deactivate (qdisc_priv(sch),cl); /* TODO: is it correct ? Why CBQ doesn't do it ? */ sch->q.qlen -= (*old)->q.qlen; @@ -1379,7 +1379,7 @@ static struct Qdisc * htb_leaf(struct Qd static unsigned long htb_get(struct Qdisc *sch, u32 classid) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = htb_find(classid,sch); HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0); @@ -1400,7 +1400,7 @@ static void htb_destroy_filters(struct t static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destrycls clid=%X ref=%d\n", cl?cl->classid:0,cl?cl->refcnt:0); if (!cl->level) { BUG_TRAP(cl->un.leaf.q); @@ -1435,7 +1435,7 @@ static void htb_destroy_class(struct Qdi /* always caled under BH & queue lock */ static void htb_destroy(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destroy q=%p\n",q); del_timer_sync (&q->timer); @@ -1457,7 +1457,7 @@ static void htb_destroy(struct Qdisc* sc static int htb_delete(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1484,7 +1484,7 @@ static int htb_delete(struct Qdisc *sch, static void htb_put(struct Qdisc *sch, unsigned long arg) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1497,7 +1497,7 @@ static int htb_change_class(struct Qdisc u32 parentid, struct rtattr **tca, unsigned long *arg) { int err = -EINVAL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)*arg,*parent; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct qdisc_rate_table *rtab = NULL, *ctab = NULL; @@ -1623,7 +1623,7 @@ failure: static struct tcf_proto **htb_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list; HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl); @@ -1633,7 +1633,7 @@ static struct tcf_proto **htb_find_tcf(s static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_find (classid,sch); HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt); /*if (cl && !cl->level) return 0; @@ -1654,7 +1654,7 @@ static unsigned long htb_bind_filter(str static void htb_unbind_filter(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt); if (cl) @@ -1665,7 +1665,7 @@ static void htb_unbind_filter(struct Qdi static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; if (arg->stop) diff -urNp -X dontdiff linux-2.6/net/sched/sch_ingress.c qdisc-2.6/net/sched/sch_ingress.c --- linux-2.6/net/sched/sch_ingress.c 2004-06-24 08:52:58.000000000 -0700 +++ qdisc-2.6/net/sched/sch_ingress.c 2004-07-27 09:17:28.000000000 -0700 @@ -40,7 +40,7 @@ #endif -#define PRIV(sch) ((struct ingress_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* Thanks to Doron Oz for this hack diff -urNp -X dontdiff linux-2.6/net/sched/sch_netem.c qdisc-2.6/net/sched/sch_netem.c --- linux-2.6/net/sched/sch_netem.c 2004-07-23 09:36:18.000000000 -0700 +++ qdisc-2.6/net/sched/sch_netem.c 2004-07-27 09:17:28.000000000 -0700 @@ -603,7 +603,7 @@ static inline int tabledist(int mu, int */ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; psched_time_t now; long delay; @@ -659,7 +659,7 @@ static int netem_enqueue(struct sk_buff /* Requeue packets but don't change time stamp */ static int netem_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -670,7 +670,7 @@ static int netem_requeue(struct sk_buff static unsigned int netem_drop(struct Qdisc* sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -686,7 +686,7 @@ static unsigned int netem_drop(struct Qd */ static struct sk_buff *netem_dequeue(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; psched_time_t now; @@ -726,7 +726,7 @@ static void netem_watchdog(unsigned long static void netem_reset(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); skb_queue_purge(&q->delayed); @@ -754,7 +754,7 @@ static int set_fifo_limit(struct Qdisc * static int netem_change(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct tc_netem_qopt *qopt = RTA_DATA(opt); struct Qdisc *child; int ret; @@ -791,7 +791,7 @@ static int netem_change(struct Qdisc *sc static int netem_init(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (!opt) return -EINVAL; @@ -809,7 +809,7 @@ static int netem_init(struct Qdisc *sch, static void netem_destroy(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); del_timer_sync(&q->timer); @@ -819,7 +819,7 @@ static void netem_destroy(struct Qdisc * static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_netem_qopt qopt; @@ -841,7 +841,7 @@ rtattr_failure: static int netem_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct netem_sched_data *q = (struct netem_sched_data*)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -855,7 +855,7 @@ static int netem_dump_class(struct Qdisc static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -871,7 +871,7 @@ static int netem_graft(struct Qdisc *sch static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -urNp -X dontdiff linux-2.6/net/sched/sch_prio.c qdisc-2.6/net/sched/sch_prio.c --- linux-2.6/net/sched/sch_prio.c 2004-07-07 10:14:26.000000000 -0700 +++ qdisc-2.6/net/sched/sch_prio.c 2004-07-27 09:17:28.000000000 -0700 @@ -49,7 +49,7 @@ struct prio_sched_data struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); u32 band = skb->priority; struct tcf_result res; @@ -151,7 +151,7 @@ static struct sk_buff * prio_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; struct Qdisc *qdisc; @@ -169,7 +169,7 @@ prio_dequeue(struct Qdisc* sch) static unsigned int prio_drop(struct Qdisc* sch) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; unsigned int len; struct Qdisc *qdisc; @@ -189,7 +189,7 @@ static void prio_reset(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); for (prio=0; priobands; prio++) qdisc_reset(q->queues[prio]); @@ -200,7 +200,7 @@ static void prio_destroy(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tcf_proto *tp; while ((tp = q->filter_list) != NULL) { @@ -216,7 +216,7 @@ prio_destroy(struct Qdisc* sch) static int prio_tune(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tc_prio_qopt *qopt = RTA_DATA(opt); int i; @@ -261,7 +261,7 @@ static int prio_tune(struct Qdisc *sch, static int prio_init(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int i; for (i=0; idata; + struct prio_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_prio_qopt opt; @@ -297,7 +297,7 @@ rtattr_failure: static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -319,7 +319,7 @@ static int prio_graft(struct Qdisc *sch, static struct Qdisc * prio_leaf(struct Qdisc *sch, unsigned long arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -330,7 +330,7 @@ prio_leaf(struct Qdisc *sch, unsigned lo static unsigned long prio_get(struct Qdisc *sch, u32 classid) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = TC_H_MIN(classid); if (band - 1 >= q->bands) @@ -352,7 +352,7 @@ static void prio_put(struct Qdisc *q, un static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct rtattr **tca, unsigned long *arg) { unsigned long cl = *arg; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -361,7 +361,7 @@ static int prio_change(struct Qdisc *sch static int prio_delete(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; return 0; @@ -371,7 +371,7 @@ static int prio_delete(struct Qdisc *sch static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -383,7 +383,7 @@ static int prio_dump_class(struct Qdisc static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; if (arg->stop) @@ -404,7 +404,7 @@ static void prio_walk(struct Qdisc *sch, static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl) return NULL; diff -urNp -X dontdiff linux-2.6/net/sched/sch_red.c qdisc-2.6/net/sched/sch_red.c --- linux-2.6/net/sched/sch_red.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_red.c 2004-07-27 09:17:28.000000000 -0700 @@ -180,7 +180,7 @@ static int red_ecn_mark(struct sk_buff * static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); psched_time_t now; @@ -303,7 +303,7 @@ drop: static int red_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -316,7 +316,7 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -330,7 +330,7 @@ red_dequeue(struct Qdisc* sch) static unsigned int red_drop(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -347,7 +347,7 @@ static unsigned int red_drop(struct Qdis static void red_reset(struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); __skb_queue_purge(&sch->q); sch->stats.backlog = 0; @@ -358,7 +358,7 @@ static void red_reset(struct Qdisc* sch) static int red_change(struct Qdisc *sch, struct rtattr *opt) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_RED_STAB]; struct tc_red_qopt *ctl; @@ -407,7 +407,7 @@ rtattr_failure: static int red_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_red_qopt opt; diff -urNp -X dontdiff linux-2.6/net/sched/sch_sfq.c qdisc-2.6/net/sched/sch_sfq.c --- linux-2.6/net/sched/sch_sfq.c 2004-02-23 08:31:40.000000000 -0800 +++ qdisc-2.6/net/sched/sch_sfq.c 2004-07-27 09:17:28.000000000 -0700 @@ -211,7 +211,7 @@ static inline void sfq_inc(struct sfq_sc static unsigned int sfq_drop(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); sfq_index d = q->max_depth; struct sk_buff *skb; unsigned int len; @@ -253,7 +253,7 @@ static unsigned int sfq_drop(struct Qdis static int sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -288,7 +288,7 @@ sfq_enqueue(struct sk_buff *skb, struct static int sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -324,7 +324,7 @@ sfq_requeue(struct sk_buff *skb, struct static struct sk_buff * sfq_dequeue(struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; sfq_index a, old_a; @@ -369,7 +369,7 @@ sfq_reset(struct Qdisc* sch) static void sfq_perturbation(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); q->perturbation = net_random()&0x1F; q->perturb_timer.expires = jiffies + q->perturb_period; @@ -382,7 +382,7 @@ static void sfq_perturbation(unsigned lo static int sfq_change(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct tc_sfq_qopt *ctl = RTA_DATA(opt); if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) @@ -408,7 +408,7 @@ static int sfq_change(struct Qdisc *sch, static int sfq_init(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); int i; init_timer(&q->perturb_timer); @@ -440,13 +440,13 @@ static int sfq_init(struct Qdisc *sch, s static void sfq_destroy(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); del_timer(&q->perturb_timer); } static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_sfq_qopt opt; diff -urNp -X dontdiff linux-2.6/net/sched/sch_tbf.c qdisc-2.6/net/sched/sch_tbf.c --- linux-2.6/net/sched/sch_tbf.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_tbf.c 2004-07-27 09:17:28.000000000 -0700 @@ -137,7 +137,7 @@ struct tbf_sched_data static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if (skb->len > q->max_size) { @@ -163,7 +163,7 @@ static int tbf_enqueue(struct sk_buff *s static int tbf_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -174,7 +174,7 @@ static int tbf_requeue(struct sk_buff *s static unsigned int tbf_drop(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -194,7 +194,7 @@ static void tbf_watchdog(unsigned long a static struct sk_buff *tbf_dequeue(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; skb = q->qdisc->dequeue(q->qdisc); @@ -261,7 +261,7 @@ static struct sk_buff *tbf_dequeue(struc static void tbf_reset(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); sch->q.qlen = 0; @@ -300,7 +300,7 @@ static struct Qdisc *tbf_create_dflt_qdi static int tbf_change(struct Qdisc* sch, struct rtattr *opt) { int err = -EINVAL; - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_TBF_PTAB]; struct tc_tbf_qopt *qopt; struct qdisc_rate_table *rtab = NULL; @@ -366,7 +366,7 @@ done: static int tbf_init(struct Qdisc* sch, struct rtattr *opt) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (opt == NULL) return -EINVAL; @@ -383,7 +383,7 @@ static int tbf_init(struct Qdisc* sch, s static void tbf_destroy(struct Qdisc *sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); del_timer(&q->wd_timer); @@ -398,7 +398,7 @@ static void tbf_destroy(struct Qdisc *sc static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_tbf_qopt opt; @@ -427,7 +427,7 @@ rtattr_failure: static int tbf_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct tbf_sched_data *q = (struct tbf_sched_data*)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -441,7 +441,7 @@ static int tbf_dump_class(struct Qdisc * static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -457,7 +457,7 @@ static int tbf_graft(struct Qdisc *sch, static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -urNp -X dontdiff linux-2.6/net/sched/sch_teql.c qdisc-2.6/net/sched/sch_teql.c --- linux-2.6/net/sched/sch_teql.c 2004-02-23 08:31:40.000000000 -0800 +++ qdisc-2.6/net/sched/sch_teql.c 2004-07-27 09:17:28.000000000 -0700 @@ -81,7 +81,7 @@ struct teql_sched_data struct sk_buff_head q; }; -#define NEXT_SLAVE(q) (((struct teql_sched_data*)((q)->data))->next) +#define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next) #define FMASK (IFF_BROADCAST|IFF_POINTOPOINT|IFF_BROADCAST) @@ -91,7 +91,7 @@ static int teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) { struct net_device *dev = sch->dev; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_tail(&q->q, skb); if (q->q.qlen <= dev->tx_queue_len) { @@ -109,7 +109,7 @@ teql_enqueue(struct sk_buff *skb, struct static int teql_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_head(&q->q, skb); return 0; @@ -118,7 +118,7 @@ teql_requeue(struct sk_buff *skb, struct static struct sk_buff * teql_dequeue(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct sk_buff *skb; skb = __skb_dequeue(&dat->q); @@ -143,7 +143,7 @@ teql_neigh_release(struct neighbour *n) static void teql_reset(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); skb_queue_purge(&dat->q); sch->q.qlen = 0; @@ -154,7 +154,7 @@ static void teql_destroy(struct Qdisc* sch) { struct Qdisc *q, *prev; - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct teql_master *master = dat->m; if ((prev = master->slaves) != NULL) { @@ -184,7 +184,7 @@ static int teql_qdisc_init(struct Qdisc { struct net_device *dev = sch->dev; struct teql_master *m = (struct teql_master*)sch->ops; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); if (dev->hard_header_len > m->dev->hard_header_len) return -EINVAL; @@ -229,7 +229,7 @@ static int teql_qdisc_init(struct Qdisc static int __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) { - struct teql_sched_data *q = (void*)dev->qdisc->data; + struct teql_sched_data *q = qdisc_priv(dev->qdisc); struct neighbour *mn = skb->dst->neighbour; struct neighbour *n = q->ncache; From greearb@candelatech.com Tue Aug 3 13:36:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:36:27 -0700 (PDT) Received: from www.lanforge.com (ns1.lanforge.com [66.165.47.210]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KaLjJ019857 for ; Tue, 3 Aug 2004 13:36:21 -0700 Received: from candelatech.com (evrtwa1-ar2-4-35-049-074.evrtwa1.dsl-verizon.net [4.35.49.74]) (authenticated bits=0) by www.lanforge.com (8.12.8/8.12.8) with ESMTP id i73KorSb014494; Tue, 3 Aug 2004 13:50:53 -0700 Message-ID: <410FF740.5060903@candelatech.com> Date: Tue, 03 Aug 2004 13:36:16 -0700 From: Ben Greear Organization: Candela Technologies User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Stephen Hemminger CC: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] vlan - device refcount bug. References: <20040803131425.503f8f45@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803131425.503f8f45@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7468 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: greearb@candelatech.com Precedence: bulk X-list: netdev Content-Length: 500 Lines: 15 Stephen Hemminger wrote: > If you rmmod a network device that is in a vlan, the system hangs waiting > for the refcount to go to zero, because it is -1. The problem is that the > vlan notifier does an extra dev_put in NETDEV_UNREGISTER case of notifier. Good catch. It would seem to me that it would be good to have a BUG() or similar to catch any instance of the reference count going negative. Ben -- Ben Greear Candela Technologies Inc http://www.candelatech.com From kaber@trash.net Tue Aug 3 13:40:25 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:40:29 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KeOwS020263 for ; Tue, 3 Aug 2004 13:40:25 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 66EF619F355; Tue, 3 Aug 2004 22:40:15 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id A7B6F394133; Tue, 3 Aug 2004 22:40:14 +0200 (CEST) Message-ID: <410FF8C4.7010705@trash.net> Date: Tue, 03 Aug 2004 22:42:44 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Stephen Hemminger Cc: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] cache align qdisc data References: <410FAE42.2050909@trash.net> <20040803083820.711c917c@dell_ss3.pdx.osdl.net> <410FE4DD.5000306@trash.net> <20040803133139.43107fd3@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803133139.43107fd3@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7469 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 732 Lines: 28 Stephen Hemminger wrote: >That was some old messing around, that got in there... >Here is the correct patch. > > The hunks are still there. > >@@ -1554,7 +1554,6 @@ hfsc_init_qdisc(struct Qdisc *sch, struc > qopt = RTA_DATA(opt); > > memset(q, 0, sizeof(struct hfsc_sched)); >- sch->stats_lock = &sch->dev->queue_lock; > > q->defcls = qopt->defcls; > for (i = 0; i < HFSC_HSIZE; i++) >@@ -1674,7 +1673,7 @@ hfsc_dump_qdisc(struct Qdisc *sch, struc > RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt); > > sch->stats.qlen = sch->q.qlen; >- if (qdisc_copy_stats(skb, &sch->stats, sch->stats_lock) < 0) >+ if (qdisc_copy_stats(skb, &sch->stats, &sch->dev->queue_lock) < 0) > goto rtattr_failure; > > return skb->len; > From shemminger@osdl.org Tue Aug 3 13:40:35 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:40:41 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KeYWs020274 for ; Tue, 3 Aug 2004 13:40:35 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73KeE130603; Tue, 3 Aug 2004 13:40:14 -0700 Date: Tue, 3 Aug 2004 13:40:14 -0700 From: Stephen Hemminger To: Ben Greear , "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] (2/3) vlan propogate carrier and hotplug state Message-Id: <20040803134014.7164280c@dell_ss3.pdx.osdl.net> In-Reply-To: <410FD348.9040301@candelatech.com> References: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> <410FD348.9040301@candelatech.com> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7470 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 1561 Lines: 53 The bridge STP code now wants to handle device's getting connected/disconnected and this includes vlan devices. This patch makes the VLAN pseudo device state mirror the state of the real device. Only bothered with carrier and hotplug. Signed-off-by: Stephen Hemminger diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c --- a/net/8021q/vlan.c 2004-08-03 13:35:48 -07:00 +++ b/net/8021q/vlan.c 2004-08-03 13:35:48 -07:00 @@ -69,6 +69,10 @@ .func = vlan_skb_recv, /* VLAN receive method */ }; +/* Bits of netdev state that are propogated from real device to virtual */ +#define VLAN_LINK_STATE_MASK \ + ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)) + /* End of global variables definitions. */ /* @@ -472,6 +476,8 @@ new_dev->flags = real_dev->flags; new_dev->flags &= ~IFF_UP; + new_dev->state = real_dev->state & VLAN_LINK_STATE_MASK; + /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. */ @@ -598,9 +604,20 @@ */ switch (event) { - case NETDEV_CHANGEADDR: - case NETDEV_GOING_DOWN: - /* Ignore for now */ + case NETDEV_CHANGE: + /* Propogate real device state to vlan devices */ + flgs = dev->state & VLAN_LINK_STATE_MASK; + for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + vlandev = grp->vlan_devices[i]; + if (!vlandev) + continue; + + if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) { + vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) + | flgs; + netdev_state_change(vlandev); + } + } break; case NETDEV_DOWN: From shemminger@osdl.org Tue Aug 3 13:44:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:44:11 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Ki3VC020953 for ; Tue, 3 Aug 2004 13:44:04 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73Khl130972; Tue, 3 Aug 2004 13:43:47 -0700 Date: Tue, 3 Aug 2004 13:43:46 -0700 From: Stephen Hemminger To: Ben Greear , "David S. Miller" Cc: netdev@oss.sgi.com Subject: [PATCH 2.6] (3/3) vlan - use RCU Message-Id: <20040803134346.341e5636@dell_ss3.pdx.osdl.net> In-Reply-To: <410FD348.9040301@candelatech.com> References: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> <410FD348.9040301@candelatech.com> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7471 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 8810 Lines: 302 This patch makes VLAN use RCU for the group lookup and removes the group_lock. Since all operations that are done under group_lock already have the rtnetlink semaphore (RTNL), the group_lock is unnecessary. The result is the vlan code becomes basically lock free in the send/receive path. Signed-off-by: Stephen Hemminger diff -Nru a/include/linux/if_vlan.h b/include/linux/if_vlan.h --- a/include/linux/if_vlan.h 2004-08-03 13:38:50 -07:00 +++ b/include/linux/if_vlan.h 2004-08-03 13:38:50 -07:00 @@ -22,6 +22,7 @@ struct packet_type; struct vlan_collection; struct vlan_dev_info; +struct hlist_node; #include /* for proc_dir_entry */ #include @@ -67,9 +68,9 @@ struct vlan_group { int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */ + struct hlist_node hlist; /* linked list */ struct net_device *vlan_devices[VLAN_GROUP_ARRAY_LEN]; - - struct vlan_group *next; /* the next in the list */ + struct rcu_head rcu; }; struct vlan_priority_tci_mapping { diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c --- a/net/8021q/vlan.c 2004-08-03 13:38:50 -07:00 +++ b/net/8021q/vlan.c 2004-08-03 13:38:50 -07:00 @@ -38,8 +38,7 @@ /* Global VLAN variables */ /* Our listing of VLAN group(s) */ -struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE]; -spinlock_t vlan_group_lock = SPIN_LOCK_UNLOCKED; +struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; #define vlan_grp_hashfn(IDX) ((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK) static char vlan_fullname[] = "802.1Q VLAN Support"; @@ -150,8 +149,7 @@ * references left. */ for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) { - if (vlan_group_hash[i] != NULL) - BUG(); + BUG_ON(!hlist_empty(&vlan_group_hash[i])); } vlan_proc_cleanup(); @@ -161,48 +159,24 @@ module_init(vlan_proto_init); module_exit(vlan_cleanup_module); -/* Must be invoked with vlan_group_lock held. */ +/* Must be invoked with RCU read lock (no preempt) */ static struct vlan_group *__vlan_find_group(int real_dev_ifindex) { struct vlan_group *grp; + struct hlist_node *n; + int hash = vlan_grp_hashfn(real_dev_ifindex); - for (grp = vlan_group_hash[vlan_grp_hashfn(real_dev_ifindex)]; - grp != NULL; - grp = grp->next) { + hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { if (grp->real_dev_ifindex == real_dev_ifindex) - break; + return grp; } - return grp; -} - -/* Must hold vlan_group_lock. */ -static void __grp_hash(struct vlan_group *grp) -{ - struct vlan_group **head; - - head = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)]; - grp->next = *head; - *head = grp; -} - -/* Must hold vlan_group_lock. */ -static void __grp_unhash(struct vlan_group *grp) -{ - struct vlan_group *next, **pprev; - - pprev = &vlan_group_hash[vlan_grp_hashfn(grp->real_dev_ifindex)]; - next = *pprev; - while (next != grp) { - pprev = &next->next; - next = *pprev; - } - *pprev = grp->next; + return NULL; } /* Find the protocol handler. Assumes VID < VLAN_VID_MASK. * - * Must be invoked with vlan_group_lock held. + * Must be invoked with RCU read lock (no preempt) */ struct net_device *__find_vlan_dev(struct net_device *real_dev, unsigned short VID) @@ -215,6 +189,12 @@ return NULL; } +static void vlan_rcu_free(struct rcu_head *rcu) +{ + kfree(container_of(rcu, struct vlan_group, rcu)); +} + + /* This returns 0 if everything went fine. * It will return 1 if the group was killed as a result. * A negative return indicates failure. @@ -237,9 +217,8 @@ if (vlan_id >= VLAN_VID_MASK) return -EINVAL; - spin_lock_bh(&vlan_group_lock); + ASSERT_RTNL(); grp = __vlan_find_group(real_dev_ifindex); - spin_unlock_bh(&vlan_group_lock); ret = 0; @@ -279,16 +258,12 @@ if (real_dev->features & NETIF_F_HW_VLAN_RX) real_dev->vlan_rx_register(real_dev, NULL); - spin_lock_bh(&vlan_group_lock); - __grp_unhash(grp); - spin_unlock_bh(&vlan_group_lock); - - /* Free the group, after we have removed it - * from the hash. - */ - kfree(grp); - grp = NULL; + hlist_del_rcu(&grp->hlist); + /* Free the group, after all cpu's are done. */ + call_rcu(&grp->rcu, vlan_rcu_free); + + grp = NULL; ret = 1; } } @@ -375,7 +350,6 @@ struct vlan_group *grp; struct net_device *new_dev; struct net_device *real_dev; /* the ethernet device */ - int r; char name[IFNAMSIZ]; #ifdef VLAN_DEBUG @@ -424,11 +398,7 @@ if (!(real_dev->flags & IFF_UP)) goto out_unlock; - spin_lock_bh(&vlan_group_lock); - r = (__find_vlan_dev(real_dev, VLAN_ID) != NULL); - spin_unlock_bh(&vlan_group_lock); - - if (r) { + if (__find_vlan_dev(real_dev, VLAN_ID) != NULL) { /* was already registered. */ printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__); goto out_unlock; @@ -527,9 +497,7 @@ /* So, got the sucker initialized, now lets place * it into our local structure. */ - spin_lock_bh(&vlan_group_lock); grp = __vlan_find_group(real_dev->ifindex); - spin_unlock_bh(&vlan_group_lock); /* Note, we are running under the RTNL semaphore * so it cannot "appear" on us. @@ -543,9 +511,8 @@ memset(grp, 0, sizeof(struct vlan_group)); grp->real_dev_ifindex = real_dev->ifindex; - spin_lock_bh(&vlan_group_lock); - __grp_hash(grp); - spin_unlock_bh(&vlan_group_lock); + hlist_add_head_rcu(&grp->hlist, + &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]); if (real_dev->features & NETIF_F_HW_VLAN_RX) real_dev->vlan_rx_register(real_dev, grp); @@ -587,14 +554,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { - struct net_device *dev = (struct net_device *)(ptr); - struct vlan_group *grp = NULL; + struct net_device *dev = ptr; + struct vlan_group *grp = __vlan_find_group(dev->ifindex); int i, flgs; - struct net_device *vlandev = NULL; - - spin_lock_bh(&vlan_group_lock); - grp = __vlan_find_group(dev->ifindex); - spin_unlock_bh(&vlan_group_lock); + struct net_device *vlandev; if (!grp) goto out; diff -Nru a/net/8021q/vlan.h b/net/8021q/vlan.h --- a/net/8021q/vlan.h 2004-08-03 13:38:50 -07:00 +++ b/net/8021q/vlan.h 2004-08-03 13:38:50 -07:00 @@ -33,8 +33,7 @@ #define VLAN_GRP_HASH_SHIFT 5 #define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) #define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) -extern struct vlan_group *vlan_group_hash[VLAN_GRP_HASH_SIZE]; -extern spinlock_t vlan_group_lock; +extern struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; /* Find a VLAN device by the MAC address of its Ethernet device, and * it's VLAN ID. The default configuration is to have VLAN's scope @@ -44,10 +43,8 @@ * NOT follow the spec for VLANs, but may be useful for doing very * large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs. * - * Must be invoked with vlan_group_lock held and that lock MUST NOT - * be dropped until a reference is obtained on the returned device. - * You may drop the lock earlier if you are running under the RTNL - * semaphore, however. + * Must be invoked with rcu_read_lock (ie preempt disabled) + * or with RTNL. */ struct net_device *__find_vlan_dev(struct net_device* real_dev, unsigned short VID); /* vlan.c */ diff -Nru a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c --- a/net/8021q/vlan_dev.c 2004-08-03 13:38:50 -07:00 +++ b/net/8021q/vlan_dev.c 2004-08-03 13:38:50 -07:00 @@ -138,15 +138,15 @@ /* We have 12 bits of vlan ID. * - * We must not drop the vlan_group_lock until we hold a + * We must not drop allow preempt until we hold a * reference to the device (netif_rx does that) or we * fail. */ - spin_lock_bh(&vlan_group_lock); + rcu_read_lock(); skb->dev = __find_vlan_dev(dev, vid); if (!skb->dev) { - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: ERROR: No net_device for VID: %i on dev: %s [%i]\n", @@ -170,7 +170,7 @@ */ if (dev != VLAN_DEV_INFO(skb->dev)->real_dev) { - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: dropping skb: %p because came in on wrong device, dev: %s real_dev: %s, skb_dev: %s\n", @@ -244,7 +244,7 @@ /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_lock(); return 0; } @@ -273,7 +273,7 @@ /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); return 0; } @@ -296,7 +296,7 @@ /* TODO: Add a more specific counter here. */ stats->rx_errors++; } - spin_unlock_bh(&vlan_group_lock); + rcu_read_unlock(); return 0; } From greearb@candelatech.com Tue Aug 3 13:53:24 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 13:53:30 -0700 (PDT) Received: from www.lanforge.com (ns1.lanforge.com [66.165.47.210]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73KrOj1021415 for ; Tue, 3 Aug 2004 13:53:24 -0700 Received: from candelatech.com (evrtwa1-ar2-4-35-049-074.evrtwa1.dsl-verizon.net [4.35.49.74]) (authenticated bits=0) by www.lanforge.com (8.12.8/8.12.8) with ESMTP id i73L7tSb014733; Tue, 3 Aug 2004 14:07:55 -0700 Message-ID: <410FFB3D.7070002@candelatech.com> Date: Tue, 03 Aug 2004 13:53:17 -0700 From: Ben Greear Organization: Candela Technologies User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Stephen Hemminger CC: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] (2/3) vlan propogate carrier and hotplug state References: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> <410FD348.9040301@candelatech.com> <20040803134014.7164280c@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803134014.7164280c@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7472 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: greearb@candelatech.com Precedence: bulk X-list: netdev Content-Length: 380 Lines: 13 Stephen Hemminger wrote: > The bridge STP code now wants to handle device's getting connected/disconnected > and this includes vlan devices. This patch makes the VLAN pseudo device state > mirror the state of the real device. Only bothered with carrier and hotplug. Ok by me. Ben -- Ben Greear Candela Technologies Inc http://www.candelatech.com From greearb@candelatech.com Tue Aug 3 14:03:57 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 14:04:02 -0700 (PDT) Received: from www.lanforge.com (ns1.lanforge.com [66.165.47.210]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73L3te4021923 for ; Tue, 3 Aug 2004 14:03:57 -0700 Received: from candelatech.com (evrtwa1-ar2-4-35-049-074.evrtwa1.dsl-verizon.net [4.35.49.74]) (authenticated bits=0) by www.lanforge.com (8.12.8/8.12.8) with ESMTP id i73LIRSb014871; Tue, 3 Aug 2004 14:18:28 -0700 Message-ID: <410FFDB6.8040309@candelatech.com> Date: Tue, 03 Aug 2004 14:03:50 -0700 From: Ben Greear Organization: Candela Technologies User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Stephen Hemminger CC: "David S. Miller" , netdev@oss.sgi.com Subject: Re: [PATCH 2.6] (3/3) vlan - use RCU References: <20040803105017.0774e1db@dell_ss3.pdx.osdl.net> <410FD348.9040301@candelatech.com> <20040803134346.341e5636@dell_ss3.pdx.osdl.net> In-Reply-To: <20040803134346.341e5636@dell_ss3.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7473 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: greearb@candelatech.com Precedence: bulk X-list: netdev Content-Length: 537 Lines: 16 Stephen Hemminger wrote: > This patch makes VLAN use RCU for the group lookup and removes > the group_lock. Since all operations that are done under group_lock > already have the rtnetlink semaphore (RTNL), the group_lock is unnecessary. > The result is the vlan code becomes basically lock free in the send/receive > path. Looks good to me, but I'm fairly ignorant of RCU at this point. Will trust Stephen knows what he is doing :) Ben -- Ben Greear Candela Technologies Inc http://www.candelatech.com From shemminger@osdl.org Tue Aug 3 14:06:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 14:06:11 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73L5wev022289 for ; Tue, 3 Aug 2004 14:05:59 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i73L5c103266; Tue, 3 Aug 2004 14:05:38 -0700 Date: Tue, 3 Aug 2004 14:05:38 -0700 From: Stephen Hemminger To: Patrick McHardy , "David S. Miller" Cc: netdev@oss.sgi.com Subject: Re: [PATCH 2.6] cache align qdisc data Message-Id: <20040803140538.7c40f961@dell_ss3.pdx.osdl.net> In-Reply-To: <410FF8C4.7010705@trash.net> References: <410FAE42.2050909@trash.net> <20040803083820.711c917c@dell_ss3.pdx.osdl.net> <410FE4DD.5000306@trash.net> <20040803133139.43107fd3@dell_ss3.pdx.osdl.net> <410FF8C4.7010705@trash.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7474 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev Content-Length: 47276 Lines: 1523 Ugh, here it is without the hfsc messup. diff -urN -X dontdiff linux-2.6/include/net/pkt_sched.h qdisc-2.6/include/net/pkt_sched.h --- linux-2.6/include/net/pkt_sched.h 2004-07-30 12:17:02.000000000 -0700 +++ qdisc-2.6/include/net/pkt_sched.h 2004-08-03 12:50:52.324952264 -0700 @@ -77,6 +77,7 @@ #define TCQ_F_BUILTIN 1 #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 + int padded; struct Qdisc_ops *ops; struct Qdisc *next; u32 handle; @@ -93,10 +94,17 @@ * and it will live until better solution will be invented. */ struct Qdisc *__parent; - - char data[0]; }; +#define QDISC_ALIGN 32 +#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) + +static inline void *qdisc_priv(struct Qdisc *q) +{ + return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); +} + struct qdisc_rate_table { struct tc_ratespec rate; diff -urN -X dontdiff linux-2.6/net/sched/sch_cbq.c qdisc-2.6/net/sched/sch_cbq.c --- linux-2.6/net/sched/sch_cbq.c 2004-07-07 10:14:26.000000000 -0700 +++ qdisc-2.6/net/sched/sch_cbq.c 2004-07-27 09:17:28.000000000 -0700 @@ -241,7 +241,7 @@ static struct cbq_class * cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *head = &q->link; struct cbq_class **defmap; struct cbq_class *cl = NULL; @@ -344,7 +344,7 @@ static __inline__ void cbq_activate_class(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); int prio = cl->cpriority; struct cbq_class *cl_tail; @@ -368,7 +368,7 @@ static void cbq_deactivate_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); int prio = this->cpriority; struct cbq_class *cl; struct cbq_class *cl_prev = q->active[prio]; @@ -419,7 +419,7 @@ static int cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); int len = skb->len; int ret = NET_XMIT_SUCCESS; struct cbq_class *cl = cbq_classify(skb, sch,&ret); @@ -466,7 +466,7 @@ static int cbq_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int ret; @@ -500,7 +500,7 @@ static void cbq_ovl_classic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -554,7 +554,7 @@ static void cbq_ovl_rclassic(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this = cl; do { @@ -573,7 +573,7 @@ static void cbq_ovl_delay(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); psched_tdiff_t delay = PSCHED_TDIFF(cl->undertime, q->now); if (!cl->delayed) { @@ -609,7 +609,7 @@ static void cbq_ovl_lowprio(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); cl->penalized = jiffies + cl->penalty; @@ -678,7 +678,7 @@ static void cbq_undelay(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); long delay = 0; unsigned pmask; @@ -715,7 +715,7 @@ { int len = skb->len; struct Qdisc *sch = child->__parent; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = q->rx_class; q->rx_class = NULL; @@ -863,7 +863,7 @@ static __inline__ struct cbq_class * cbq_under_limit(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *this_cl = cl; if (cl->tparent == NULL) @@ -903,7 +903,7 @@ static __inline__ struct sk_buff * cbq_dequeue_prio(struct Qdisc *sch, int prio) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl_tail, *cl_prev, *cl; struct sk_buff *skb; int deficit; @@ -1006,7 +1006,7 @@ static __inline__ struct sk_buff * cbq_dequeue_1(struct Qdisc *sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; unsigned activemask; @@ -1025,7 +1025,7 @@ cbq_dequeue(struct Qdisc *sch) { struct sk_buff *skb; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); psched_time_t now; psched_tdiff_t incr; @@ -1150,7 +1150,7 @@ static void cbq_sync_defmap(struct cbq_class *cl) { - struct cbq_sched_data *q = (struct cbq_sched_data*)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); struct cbq_class *split = cl->split; unsigned h; int i; @@ -1216,7 +1216,7 @@ static void cbq_unlink_class(struct cbq_class *this) { struct cbq_class *cl, **clp; - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); for (clp = &q->classes[cbq_hash(this->classid)]; (cl = *clp) != NULL; clp = &cl->next) { if (cl == this) { @@ -1249,7 +1249,7 @@ static void cbq_link_class(struct cbq_class *this) { - struct cbq_sched_data *q = (struct cbq_sched_data*)this->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(this->qdisc); unsigned h = cbq_hash(this->classid); struct cbq_class *parent = this->tparent; @@ -1270,7 +1270,7 @@ static unsigned int cbq_drop(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl, *cl_head; int prio; unsigned int len; @@ -1293,7 +1293,7 @@ static void cbq_reset(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; int prio; unsigned h; @@ -1363,7 +1363,7 @@ static int cbq_set_wrr(struct cbq_class *cl, struct tc_cbq_wrropt *wrr) { - struct cbq_sched_data *q = (struct cbq_sched_data *)cl->qdisc->data; + struct cbq_sched_data *q = qdisc_priv(cl->qdisc); if (wrr->allot) cl->allot = wrr->allot; @@ -1432,7 +1432,7 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_CBQ_MAX]; struct tc_ratespec *r; @@ -1623,7 +1623,7 @@ static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; @@ -1650,7 +1650,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb, struct tcmsg *tcm) { - struct cbq_sched_data *q = (struct cbq_sched_data*)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; unsigned char *b = skb->tail; struct rtattr *rta; @@ -1726,7 +1726,7 @@ static unsigned long cbq_get(struct Qdisc *sch, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = cbq_class_lookup(q, classid); if (cl) { @@ -1760,7 +1760,7 @@ static void cbq_destroy(struct Qdisc* sch) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl; unsigned h; @@ -1791,7 +1791,7 @@ if (--cl->refcnt == 0) { #ifdef CONFIG_NET_CLS_POLICE - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); spin_lock_bh(&sch->dev->queue_lock); if (q->rx_class == cl) @@ -1808,7 +1808,7 @@ unsigned long *arg) { int err; - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)*arg; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_CBQ_MAX]; @@ -2004,7 +2004,7 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class*)arg; if (cl->filters || cl->children || cl == &q->link) @@ -2042,7 +2042,7 @@ static struct tcf_proto **cbq_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *cl = (struct cbq_class *)arg; if (cl == NULL) @@ -2054,7 +2054,7 @@ static unsigned long cbq_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_class *p = (struct cbq_class*)parent; struct cbq_class *cl = cbq_class_lookup(q, classid); @@ -2076,7 +2076,7 @@ static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data; + struct cbq_sched_data *q = qdisc_priv(sch); unsigned h; if (arg->stop) diff -urN -X dontdiff linux-2.6/net/sched/sch_dsmark.c qdisc-2.6/net/sched/sch_dsmark.c --- linux-2.6/net/sched/sch_dsmark.c 2004-04-19 10:03:23.000000000 -0700 +++ qdisc-2.6/net/sched/sch_dsmark.c 2004-07-27 09:17:28.000000000 -0700 @@ -30,7 +30,7 @@ #endif -#define PRIV(sch) ((struct dsmark_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* diff -urN -X dontdiff linux-2.6/net/sched/sch_fifo.c qdisc-2.6/net/sched/sch_fifo.c --- linux-2.6/net/sched/sch_fifo.c 2004-02-19 10:28:27.000000000 -0800 +++ qdisc-2.6/net/sched/sch_fifo.c 2004-07-27 09:17:28.000000000 -0700 @@ -45,7 +45,7 @@ static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->stats.backlog + skb->len <= q->limit) { __skb_queue_tail(&sch->q, skb); @@ -106,7 +106,7 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (sch->q.qlen < q->limit) { __skb_queue_tail(&sch->q, skb); @@ -138,7 +138,7 @@ static int fifo_init(struct Qdisc *sch, struct rtattr *opt) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); if (opt == NULL) { unsigned int limit = sch->dev->tx_queue_len ? : 1; @@ -158,7 +158,7 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct fifo_sched_data *q = (void*)sch->data; + struct fifo_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_fifo_qopt opt; diff -urN -X dontdiff linux-2.6/net/sched/sch_generic.c qdisc-2.6/net/sched/sch_generic.c --- linux-2.6/net/sched/sch_generic.c 2004-07-30 12:17:03.000000000 -0700 +++ qdisc-2.6/net/sched/sch_generic.c 2004-08-03 12:50:53.071838720 -0700 @@ -283,10 +283,9 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; if (list->qlen < qdisc->dev->tx_queue_len) { __skb_queue_tail(list, skb); @@ -304,7 +303,7 @@ pfifo_fast_dequeue(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); struct sk_buff *skb; for (prio = 0; prio < 3; prio++, list++) { @@ -320,10 +319,9 @@ static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) { - struct sk_buff_head *list; + struct sk_buff_head *list = qdisc_priv(qdisc); - list = ((struct sk_buff_head*)qdisc->data) + - prio2band[skb->priority&TC_PRIO_MAX]; + list += prio2band[skb->priority&TC_PRIO_MAX]; __skb_queue_head(list, skb); qdisc->q.qlen++; @@ -334,7 +332,7 @@ pfifo_fast_reset(struct Qdisc* qdisc) { int prio; - struct sk_buff_head *list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (prio=0; prio < 3; prio++) skb_queue_purge(list+prio); @@ -359,9 +357,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt) { int i; - struct sk_buff_head *list; - - list = ((struct sk_buff_head*)qdisc->data); + struct sk_buff_head *list = qdisc_priv(qdisc); for (i=0; i<3; i++) skb_queue_head_init(list+i); @@ -385,13 +381,22 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) { + void *p; struct Qdisc *sch; - int size = sizeof(*sch) + ops->priv_size; + int size; + + /* ensure that the Qdisc and the private data are 32-byte aligned */ + size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); + size += ops->priv_size + QDISC_ALIGN_CONST; - sch = kmalloc(size, GFP_KERNEL); - if (!sch) + p = kmalloc(size, GFP_KERNEL); + if (!p) return NULL; - memset(sch, 0, size); + memset(p, 0, size); + + sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) + & ~QDISC_ALIGN_CONST); + sch->padded = (char *)sch - (char *)p; skb_queue_head_init(&sch->q); sch->ops = ops; @@ -406,7 +411,7 @@ if (!ops->init || ops->init(sch, NULL) == 0) return sch; - kfree(sch); + kfree(p); return NULL; } @@ -438,7 +443,7 @@ module_put(ops->owner); if (!(qdisc->flags&TCQ_F_BUILTIN)) - kfree(qdisc); + kfree((char *) qdisc - qdisc->padded); } /* Under dev->queue_lock and BH! */ diff -urN -X dontdiff linux-2.6/net/sched/sch_gred.c qdisc-2.6/net/sched/sch_gred.c --- linux-2.6/net/sched/sch_gred.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_gred.c 2004-07-27 09:17:28.000000000 -0700 @@ -106,7 +106,7 @@ { psched_time_t now; struct gred_sched_data *q=NULL; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); unsigned long qave=0; int i=0; @@ -215,7 +215,7 @@ gred_requeue(struct sk_buff *skb, struct Qdisc* sch) { struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); q= t->tab[(skb->tc_index&0xf)]; /* error checking here -- probably unnecessary */ PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -231,7 +231,7 @@ { struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -264,7 +264,7 @@ struct sk_buff *skb; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -300,7 +300,7 @@ { int i; struct gred_sched_data *q; - struct gred_sched *t= (struct gred_sched *)sch->data; + struct gred_sched *t= qdisc_priv(sch); __skb_queue_purge(&sch->q); @@ -323,7 +323,7 @@ static int gred_change(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; struct tc_gred_qopt *ctl; struct tc_gred_sopt *sopt; @@ -469,7 +469,7 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct tc_gred_sopt *sopt; struct rtattr *tb[TCA_GRED_STAB]; struct rtattr *tb2[TCA_GRED_DPS]; @@ -502,7 +502,7 @@ struct rtattr *rta; struct tc_gred_qopt *opt = NULL ; struct tc_gred_qopt *dst; - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); struct gred_sched_data *q; int i; unsigned char *b = skb->tail; @@ -593,7 +593,7 @@ static void gred_destroy(struct Qdisc *sch) { - struct gred_sched *table = (struct gred_sched *)sch->data; + struct gred_sched *table = qdisc_priv(sch); int i; for (i = 0;i < table->DPs; i++) { diff -urN -X dontdiff linux-2.6/net/sched/sch_hfsc.c qdisc-2.6/net/sched/sch_hfsc.c --- linux-2.6/net/sched/sch_hfsc.c 2004-07-26 09:20:38.000000000 -0700 +++ qdisc-2.6/net/sched/sch_hfsc.c 2004-08-03 13:58:10.829006328 -0700 @@ -1016,7 +1016,7 @@ static inline struct hfsc_class * hfsc_find_class(u32 classid, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; list_for_each_entry(cl, &q->clhash[hfsc_hash(classid)], hlist) { @@ -1061,7 +1061,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **tca, unsigned long *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)*arg; struct hfsc_class *parent = NULL; struct rtattr *opt = tca[TCA_OPTIONS-1]; @@ -1204,7 +1204,7 @@ static void hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); hfsc_destroy_filters(&cl->filter_list); qdisc_destroy(cl->qdisc); @@ -1218,7 +1218,7 @@ static int hfsc_delete_class(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl->level > 0 || cl->filter_cnt > 0 || cl == &q->root) @@ -1240,7 +1240,7 @@ static struct hfsc_class * hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -1381,7 +1381,7 @@ static struct tcf_proto ** hfsc_tcf_chain(struct Qdisc *sch, unsigned long arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl = (struct hfsc_class *)arg; if (cl == NULL) @@ -1489,7 +1489,7 @@ static void hfsc_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1523,7 +1523,7 @@ static void hfsc_schedule_watchdog(struct Qdisc *sch, u64 cur_time) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; u64 next_time = 0; long delay; @@ -1545,7 +1545,7 @@ static int hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; unsigned int i; @@ -1585,7 +1585,7 @@ static int hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct tc_hfsc_qopt *qopt; if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt)) @@ -1632,7 +1632,7 @@ static void hfsc_reset_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int i; @@ -1651,7 +1651,7 @@ static void hfsc_destroy_qdisc(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl, *next; unsigned int i; @@ -1666,7 +1666,7 @@ static int hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_hfsc_qopt qopt; @@ -1730,7 +1730,7 @@ static struct sk_buff * hfsc_dequeue(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; struct sk_buff *skb; u64 cur_time; @@ -1799,7 +1799,7 @@ static int hfsc_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); __skb_queue_head(&q->requeue, skb); sch->q.qlen++; @@ -1809,7 +1809,7 @@ static unsigned int hfsc_drop(struct Qdisc *sch) { - struct hfsc_sched *q = (struct hfsc_sched *)sch->data; + struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_class *cl; unsigned int len; diff -urN -X dontdiff linux-2.6/net/sched/sch_htb.c qdisc-2.6/net/sched/sch_htb.c --- linux-2.6/net/sched/sch_htb.c 2004-07-26 09:20:38.000000000 -0700 +++ qdisc-2.6/net/sched/sch_htb.c 2004-07-27 09:17:28.000000000 -0700 @@ -267,7 +267,7 @@ /* find class in global hash table using given handle */ static __inline__ struct htb_class *htb_find(u32 handle, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; if (TC_H_MAJ(handle) != sch->handle) return NULL; @@ -300,7 +300,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, int *qres) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl; struct tcf_result res; struct tcf_proto *tcf; @@ -712,7 +712,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) { int ret = NET_XMIT_SUCCESS; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_classify(skb,sch,&ret); @@ -759,7 +759,7 @@ /* TODO: requeuing packet charges it to policers again !! */ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int ret = NET_XMIT_SUCCESS; struct htb_class *cl = htb_classify(skb,sch, &ret); struct sk_buff *tskb; @@ -800,7 +800,7 @@ static void htb_rate_timer(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct list_head *p; /* lock queue so that we can muck with it */ @@ -1060,7 +1060,7 @@ static void htb_delay_by(struct Qdisc *sch,long delay) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); if (delay <= 0) delay = 1; if (unlikely(delay > 5*HZ)) { if (net_ratelimit()) @@ -1077,7 +1077,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) { struct sk_buff *skb = NULL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int level; long min_delay; #ifdef HTB_DEBUG @@ -1147,7 +1147,7 @@ /* try to drop from each class (by prio) until one succeed */ static unsigned int htb_drop(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int prio; for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) { @@ -1172,7 +1172,7 @@ /* always caled under BH & queue lock */ static void htb_reset(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; HTB_DBG(0,1,"htb_reset sch=%p, handle=%X\n",sch,sch->handle); @@ -1210,7 +1210,7 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct rtattr *tb[TCA_HTB_INIT]; struct tc_htb_glob *gopt; int i; @@ -1265,7 +1265,7 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_htb_glob gopt; @@ -1300,7 +1300,7 @@ struct sk_buff *skb, struct tcmsg *tcm) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched*)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; unsigned char *b = skb->tail; @@ -1358,7 +1358,7 @@ sch_tree_lock(sch); if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { if (cl->prio_activity) - htb_deactivate ((struct htb_sched*)sch->data,cl); + htb_deactivate (qdisc_priv(sch),cl); /* TODO: is it correct ? Why CBQ doesn't do it ? */ sch->q.qlen -= (*old)->q.qlen; @@ -1379,7 +1379,7 @@ static unsigned long htb_get(struct Qdisc *sch, u32 classid) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = htb_find(classid,sch); HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0); @@ -1400,7 +1400,7 @@ static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destrycls clid=%X ref=%d\n", cl?cl->classid:0,cl?cl->refcnt:0); if (!cl->level) { BUG_TRAP(cl->un.leaf.q); @@ -1435,7 +1435,7 @@ /* always caled under BH & queue lock */ static void htb_destroy(struct Qdisc* sch) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); HTB_DBG(0,1,"htb_destroy q=%p\n",q); del_timer_sync (&q->timer); @@ -1457,7 +1457,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1484,7 +1484,7 @@ static void htb_put(struct Qdisc *sch, unsigned long arg) { #ifdef HTB_DEBUG - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); #endif struct htb_class *cl = (struct htb_class*)arg; HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0); @@ -1497,7 +1497,7 @@ u32 parentid, struct rtattr **tca, unsigned long *arg) { int err = -EINVAL; - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class*)*arg,*parent; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct qdisc_rate_table *rtab = NULL, *ctab = NULL; @@ -1623,7 +1623,7 @@ static struct tcf_proto **htb_find_tcf(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list; HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl); @@ -1633,7 +1633,7 @@ static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent, u32 classid) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = htb_find (classid,sch); HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt); /*if (cl && !cl->level) return 0; @@ -1654,7 +1654,7 @@ static void htb_unbind_filter(struct Qdisc *sch, unsigned long arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); struct htb_class *cl = (struct htb_class *)arg; HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt); if (cl) @@ -1665,7 +1665,7 @@ static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_sched *q = qdisc_priv(sch); int i; if (arg->stop) diff -urN -X dontdiff linux-2.6/net/sched/sch_ingress.c qdisc-2.6/net/sched/sch_ingress.c --- linux-2.6/net/sched/sch_ingress.c 2004-06-24 08:52:58.000000000 -0700 +++ qdisc-2.6/net/sched/sch_ingress.c 2004-07-27 09:17:28.000000000 -0700 @@ -40,7 +40,7 @@ #endif -#define PRIV(sch) ((struct ingress_qdisc_data *) (sch)->data) +#define PRIV(sch) qdisc_priv(sch) /* Thanks to Doron Oz for this hack diff -urN -X dontdiff linux-2.6/net/sched/sch_netem.c qdisc-2.6/net/sched/sch_netem.c --- linux-2.6/net/sched/sch_netem.c 2004-07-23 09:36:18.000000000 -0700 +++ qdisc-2.6/net/sched/sch_netem.c 2004-07-27 09:17:28.000000000 -0700 @@ -603,7 +603,7 @@ */ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; psched_time_t now; long delay; @@ -659,7 +659,7 @@ /* Requeue packets but don't change time stamp */ static int netem_requeue(struct sk_buff *skb, struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -670,7 +670,7 @@ static unsigned int netem_drop(struct Qdisc* sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -686,7 +686,7 @@ */ static struct sk_buff *netem_dequeue(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; psched_time_t now; @@ -726,7 +726,7 @@ static void netem_reset(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); skb_queue_purge(&q->delayed); @@ -754,7 +754,7 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); struct tc_netem_qopt *qopt = RTA_DATA(opt); struct Qdisc *child; int ret; @@ -791,7 +791,7 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (!opt) return -EINVAL; @@ -809,7 +809,7 @@ static void netem_destroy(struct Qdisc *sch) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); del_timer_sync(&q->timer); @@ -819,7 +819,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_netem_qopt qopt; @@ -841,7 +841,7 @@ static int netem_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct netem_sched_data *q = (struct netem_sched_data*)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -855,7 +855,7 @@ static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -871,7 +871,7 @@ static struct Qdisc *netem_leaf(struct Qdisc *sch, unsigned long arg) { - struct netem_sched_data *q = (struct netem_sched_data *)sch->data; + struct netem_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -urN -X dontdiff linux-2.6/net/sched/sch_prio.c qdisc-2.6/net/sched/sch_prio.c --- linux-2.6/net/sched/sch_prio.c 2004-07-07 10:14:26.000000000 -0700 +++ qdisc-2.6/net/sched/sch_prio.c 2004-07-27 09:17:28.000000000 -0700 @@ -49,7 +49,7 @@ struct Qdisc *prio_classify(struct sk_buff *skb, struct Qdisc *sch,int *r) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); u32 band = skb->priority; struct tcf_result res; @@ -151,7 +151,7 @@ prio_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; struct Qdisc *qdisc; @@ -169,7 +169,7 @@ static unsigned int prio_drop(struct Qdisc* sch) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; unsigned int len; struct Qdisc *qdisc; @@ -189,7 +189,7 @@ prio_reset(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); for (prio=0; priobands; prio++) qdisc_reset(q->queues[prio]); @@ -200,7 +200,7 @@ prio_destroy(struct Qdisc* sch) { int prio; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tcf_proto *tp; while ((tp = q->filter_list) != NULL) { @@ -216,7 +216,7 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); struct tc_prio_qopt *qopt = RTA_DATA(opt); int i; @@ -261,7 +261,7 @@ static int prio_init(struct Qdisc *sch, struct rtattr *opt) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int i; for (i=0; idata; + struct prio_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_prio_qopt opt; @@ -297,7 +297,7 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -319,7 +319,7 @@ static struct Qdisc * prio_leaf(struct Qdisc *sch, unsigned long arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = arg - 1; if (band >= q->bands) @@ -330,7 +330,7 @@ static unsigned long prio_get(struct Qdisc *sch, u32 classid) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); unsigned long band = TC_H_MIN(classid); if (band - 1 >= q->bands) @@ -352,7 +352,7 @@ static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct rtattr **tca, unsigned long *arg) { unsigned long cl = *arg; - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -361,7 +361,7 @@ static int prio_delete(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; return 0; @@ -371,7 +371,7 @@ static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl - 1 > q->bands) return -ENOENT; @@ -383,7 +383,7 @@ static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); int prio; if (arg->stop) @@ -404,7 +404,7 @@ static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl) { - struct prio_sched_data *q = (struct prio_sched_data *)sch->data; + struct prio_sched_data *q = qdisc_priv(sch); if (cl) return NULL; diff -urN -X dontdiff linux-2.6/net/sched/sch_red.c qdisc-2.6/net/sched/sch_red.c --- linux-2.6/net/sched/sch_red.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_red.c 2004-07-27 09:17:28.000000000 -0700 @@ -180,7 +180,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); psched_time_t now; @@ -303,7 +303,7 @@ static int red_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); PSCHED_SET_PASTPERFECT(q->qidlestart); @@ -316,7 +316,7 @@ red_dequeue(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue(&sch->q); if (skb) { @@ -330,7 +330,7 @@ static unsigned int red_drop(struct Qdisc* sch) { struct sk_buff *skb; - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); skb = __skb_dequeue_tail(&sch->q); if (skb) { @@ -347,7 +347,7 @@ static void red_reset(struct Qdisc* sch) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); __skb_queue_purge(&sch->q); sch->stats.backlog = 0; @@ -358,7 +358,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_RED_STAB]; struct tc_red_qopt *ctl; @@ -407,7 +407,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct red_sched_data *q = (struct red_sched_data *)sch->data; + struct red_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_red_qopt opt; diff -urN -X dontdiff linux-2.6/net/sched/sch_sfq.c qdisc-2.6/net/sched/sch_sfq.c --- linux-2.6/net/sched/sch_sfq.c 2004-02-23 08:31:40.000000000 -0800 +++ qdisc-2.6/net/sched/sch_sfq.c 2004-07-27 09:17:28.000000000 -0700 @@ -211,7 +211,7 @@ static unsigned int sfq_drop(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); sfq_index d = q->max_depth; struct sk_buff *skb; unsigned int len; @@ -253,7 +253,7 @@ static int sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -288,7 +288,7 @@ static int sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned hash = sfq_hash(q, skb); sfq_index x; @@ -324,7 +324,7 @@ static struct sk_buff * sfq_dequeue(struct Qdisc* sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; sfq_index a, old_a; @@ -369,7 +369,7 @@ static void sfq_perturbation(unsigned long arg) { struct Qdisc *sch = (struct Qdisc*)arg; - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); q->perturbation = net_random()&0x1F; q->perturb_timer.expires = jiffies + q->perturb_period; @@ -382,7 +382,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); struct tc_sfq_qopt *ctl = RTA_DATA(opt); if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) @@ -408,7 +408,7 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); int i; init_timer(&q->perturb_timer); @@ -440,13 +440,13 @@ static void sfq_destroy(struct Qdisc *sch) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); del_timer(&q->perturb_timer); } static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct sfq_sched_data *q = (struct sfq_sched_data *)sch->data; + struct sfq_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct tc_sfq_qopt opt; diff -urN -X dontdiff linux-2.6/net/sched/sch_tbf.c qdisc-2.6/net/sched/sch_tbf.c --- linux-2.6/net/sched/sch_tbf.c 2004-06-30 13:42:31.000000000 -0700 +++ qdisc-2.6/net/sched/sch_tbf.c 2004-07-27 09:17:28.000000000 -0700 @@ -137,7 +137,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if (skb->len > q->max_size) { @@ -163,7 +163,7 @@ static int tbf_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); int ret; if ((ret = q->qdisc->ops->requeue(skb, q->qdisc)) == 0) @@ -174,7 +174,7 @@ static unsigned int tbf_drop(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned int len; if ((len = q->qdisc->ops->drop(q->qdisc)) != 0) { @@ -194,7 +194,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct sk_buff *skb; skb = q->qdisc->dequeue(q->qdisc); @@ -261,7 +261,7 @@ static void tbf_reset(struct Qdisc* sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); sch->q.qlen = 0; @@ -300,7 +300,7 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt) { int err = -EINVAL; - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); struct rtattr *tb[TCA_TBF_PTAB]; struct tc_tbf_qopt *qopt; struct qdisc_rate_table *rtab = NULL; @@ -366,7 +366,7 @@ static int tbf_init(struct Qdisc* sch, struct rtattr *opt) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (opt == NULL) return -EINVAL; @@ -383,7 +383,7 @@ static void tbf_destroy(struct Qdisc *sch) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); del_timer(&q->wd_timer); @@ -398,7 +398,7 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); unsigned char *b = skb->tail; struct rtattr *rta; struct tc_tbf_qopt opt; @@ -427,7 +427,7 @@ static int tbf_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, struct tcmsg *tcm) { - struct tbf_sched_data *q = (struct tbf_sched_data*)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (cl != 1) /* only one class */ return -ENOENT; @@ -441,7 +441,7 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct Qdisc **old) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); if (new == NULL) new = &noop_qdisc; @@ -457,7 +457,7 @@ static struct Qdisc *tbf_leaf(struct Qdisc *sch, unsigned long arg) { - struct tbf_sched_data *q = (struct tbf_sched_data *)sch->data; + struct tbf_sched_data *q = qdisc_priv(sch); return q->qdisc; } diff -urN -X dontdiff linux-2.6/net/sched/sch_teql.c qdisc-2.6/net/sched/sch_teql.c --- linux-2.6/net/sched/sch_teql.c 2004-02-23 08:31:40.000000000 -0800 +++ qdisc-2.6/net/sched/sch_teql.c 2004-07-27 09:17:28.000000000 -0700 @@ -81,7 +81,7 @@ struct sk_buff_head q; }; -#define NEXT_SLAVE(q) (((struct teql_sched_data*)((q)->data))->next) +#define NEXT_SLAVE(q) (((struct teql_sched_data*)qdisc_priv(q))->next) #define FMASK (IFF_BROADCAST|IFF_POINTOPOINT|IFF_BROADCAST) @@ -91,7 +91,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) { struct net_device *dev = sch->dev; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_tail(&q->q, skb); if (q->q.qlen <= dev->tx_queue_len) { @@ -109,7 +109,7 @@ static int teql_requeue(struct sk_buff *skb, struct Qdisc* sch) { - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); __skb_queue_head(&q->q, skb); return 0; @@ -118,7 +118,7 @@ static struct sk_buff * teql_dequeue(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct sk_buff *skb; skb = __skb_dequeue(&dat->q); @@ -143,7 +143,7 @@ static void teql_reset(struct Qdisc* sch) { - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); skb_queue_purge(&dat->q); sch->q.qlen = 0; @@ -154,7 +154,7 @@ teql_destroy(struct Qdisc* sch) { struct Qdisc *q, *prev; - struct teql_sched_data *dat = (struct teql_sched_data *)sch->data; + struct teql_sched_data *dat = qdisc_priv(sch); struct teql_master *master = dat->m; if ((prev = master->slaves) != NULL) { @@ -184,7 +184,7 @@ { struct net_device *dev = sch->dev; struct teql_master *m = (struct teql_master*)sch->ops; - struct teql_sched_data *q = (struct teql_sched_data *)sch->data; + struct teql_sched_data *q = qdisc_priv(sch); if (dev->hard_header_len > m->dev->hard_header_len) return -EINVAL; @@ -229,7 +229,7 @@ static int __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev) { - struct teql_sched_data *q = (void*)dev->qdisc->data; + struct teql_sched_data *q = qdisc_priv(dev->qdisc); struct neighbour *mn = skb->dst->neighbour; struct neighbour *n = q->ncache; From davem@redhat.com Tue Aug 3 14:23:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 14:23:56 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73LNnZX022936 for ; Tue, 3 Aug 2004 14:23:50 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i73LNZe1015894; Tue, 3 Aug 2004 17:23:35 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i73LNZa02600; Tue, 3 Aug 2004 17:23:35 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i73LMnu5005174; Tue, 3 Aug 2004 17:22:52 -0400 Date: Tue, 3 Aug 2004 14:21:51 -0700 From: "David S. Miller" To: yoshfuji@linux-ipv6.org Cc: shemminger@osdl.org, hadi@znyx.com, netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-Id: <20040803142151.11d130ee.davem@redhat.com> In-Reply-To: <20040803.005542.104434029.yoshfuji@linux-ipv6.org> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> <20040802160445.5ef3b251.davem@redhat.com> <20040803.005542.104434029.yoshfuji@linux-ipv6.org> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by oss.sgi.com id i73LNnZX022936 X-archive-position: 7475 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Content-Length: 470 Lines: 18 On Tue, 03 Aug 2004 00:55:42 -0700 (PDT) YOSHIFUJI Hideaki / $B5HF#1QL@(B wrote: > In article <20040802160445.5ef3b251.davem@redhat.com> (at Mon, 2 Aug 2004 16:04:45 -0700), "David S. Miller" says: > > > > What headers really seem to change a lot? The obvious ones are: > > > > > > linux/pkt_sched.h > > > linux/tcp_diag.h > > > linux/xfrm.h > > > > I would add linux/rtnetlink.h > > Then, linux/snmp.h. Agreed. From davem@redhat.com Tue Aug 3 14:26:29 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 14:26:34 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73LQS5X023300 for ; Tue, 3 Aug 2004 14:26:28 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i73LQDe1016594; Tue, 3 Aug 2004 17:26:14 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i73LQDa03479; Tue, 3 Aug 2004 17:26:13 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i73LPT47007340; Tue, 3 Aug 2004 17:25:30 -0400 Date: Tue, 3 Aug 2004 14:24:31 -0700 From: "David S. Miller" To: Stephen Hemminger Cc: netdev@oss.sgi.com Subject: Re: [PATCH 2.6] netem limit not returned correctly Message-Id: <20040803142431.0d5d669a.davem@redhat.com> In-Reply-To: <20040803131111.6ce2c36c@dell_ss3.pdx.osdl.net> References: <20040803131111.6ce2c36c@dell_ss3.pdx.osdl.net> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7476 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Content-Length: 331 Lines: 11 On Tue, 3 Aug 2004 13:11:11 -0700 Stephen Hemminger wrote: > Minor leftover from earlier code. Netem scheduler is not reporting > correct limit (ie for 'tc qdisc ls') because it is returning devices limit > not it's own. > > Should apply to 2.4 as well (with fuzz) Applied to both trees, thanks Stephen. From herbert@gondor.apana.org.au Tue Aug 3 14:28:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 14:28:21 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73LSAJw023642 for ; Tue, 3 Aug 2004 14:28:11 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1Bs6pD-0002x6-00; Wed, 04 Aug 2004 07:27:59 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1Bs6p7-00005T-00; Wed, 04 Aug 2004 07:27:53 +1000 Date: Wed, 4 Aug 2004 07:27:53 +1000 To: Michael Richardson Cc: netdev , dev@lists.openswan.org Subject: Re: CONFIG_XFRM vs udp.c Message-ID: <20040803212753.GA319@gondor.apana.org.au> References: <22093.1091561579@marajade.sandelman.ottawa.on.ca> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <22093.1091561579@marajade.sandelman.ottawa.on.ca> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7477 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev Content-Length: 482 Lines: 13 On Tue, Aug 03, 2004 at 03:32:59PM -0400, Michael Richardson wrote: > > It is it intentional that this part of XFRM can not be a module? As it is XFRM cannot be built as a module at all. This is only one of the places in the IP stack that calls XFRM directly. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From nakam@linux-ipv6.org Tue Aug 3 16:46:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 16:46:08 -0700 (PDT) Received: from localhost (opene-130-129-129-66.ietf60.ietf.org [130.129.129.66]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Nk1Ui029681 for ; Tue, 3 Aug 2004 16:46:02 -0700 Received: from localhost ([127.0.0.1]) by localhost with smtp (Exim 3.36 #1 (Debian)) id 1Bs8ye-0000Nx-00; Tue, 03 Aug 2004 16:45:52 -0700 Date: Tue, 3 Aug 2004 16:45:52 -0700 From: Masahide Nakamura To: Stephen Hemminger Cc: netdev@oss.sgi.com, nakam@linux-ipv6.org Subject: [IPROUTE2] purging a directory Message-Id: <20040803164552.4b5cea87@localhost> X-Mailer: Sylpheed-Claws 0.9.12 (GTK+ 1.2.10; i386-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7478 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: nakam@linux-ipv6.org Precedence: bulk X-list: netdev Content-Length: 425 Lines: 16 Hi Stephen, I found a ChangeSet which seems to be an erroneous importing in your iproute2 tree. (That is a patch I sent.) It causes directory problem; It creates new sub directory named "iproute2" which should be placed as parent one. It is unnecessary so please remove it or try below (it works fine for me in local testing): bk -r prs -hr+ -nd:ROOTKEY: | grep '|iproute2' | bk csetprune Thanks, -- Masahide NAKAMURA From nakam@linux-ipv6.org Tue Aug 3 16:46:04 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 16:46:17 -0700 (PDT) Received: from localhost (opene-130-129-129-66.ietf60.ietf.org [130.129.129.66]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Nk4n9029686 for ; Tue, 3 Aug 2004 16:46:04 -0700 Received: from localhost ([127.0.0.1]) by localhost with smtp (Exim 3.36 #1 (Debian)) id 1Bs8yS-0000Nu-00; Tue, 03 Aug 2004 16:45:40 -0700 Date: Tue, 3 Aug 2004 16:45:39 -0700 From: Masahide Nakamura To: Stephen Hemminger Cc: Herbert Xu , netdev@oss.sgi.com, nakam@linux-ipv6.org Subject: [PATCH][IPROUTE2] clean xfrm message format Message-Id: <20040803164539.41a0a975@localhost> X-Mailer: Sylpheed-Claws 0.9.12 (GTK+ 1.2.10; i386-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7479 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: nakam@linux-ipv6.org Precedence: bulk X-list: netdev Content-Length: 28185 Lines: 1089 Hello, This is a patch for ip xfrm and against for the latest snapshot(iproute2-2.6.8-ss040730.tar.gz). Please apply it. Here is log: fix xfrm command line option and clean its output message format (commented by Herbert Xu ). * fix to specify algorithm key correctly and its output format. * omit some items when they are zero/default. * fix output can be one line. * use "enc/auth/comp" instead of "E/A/C" for altorithm type. * show SPI in hex. * remove "sel" and "upspec" from command. diff -uNr iproute2-2.6.8.orig/ip/ipxfrm.c iproute2-2.6.8/ip/ipxfrm.c --- iproute2-2.6.8.orig/ip/ipxfrm.c 2004-07-30 15:28:47.000000000 -0700 +++ iproute2-2.6.8/ip/ipxfrm.c 2004-08-02 17:27:43.000000000 -0700 @@ -52,6 +52,48 @@ exit(-1); } +struct typeent { + const char *t_name; + int t_type; +}; + +static const struct typeent algo_types[]= { + { "enc", XFRMA_ALG_CRYPT }, { "auth", XFRMA_ALG_AUTH }, + { "comp", XFRMA_ALG_COMP }, { NULL, -1 } +}; + +int xfrm_algotype_getbyname(char *name) +{ + int i; + + for (i = 0; ; i++) { + const struct typeent *t = &algo_types[i]; + if (!t->t_name || t->t_type == -1) + break; + + if (strcmp(t->t_name, name) == 0) + return t->t_type; + } + + return -1; +} + +const char *strxf_algotype(int type) +{ + int i; + + for (i = 0; ; i++) { + const struct typeent *t = &algo_types[i]; + if (!t->t_name || t->t_type == -1) + break; + + if (t->t_type == type) + return t->t_name; + } + + return NULL; +} + const char *strxf_flags(__u8 flags) { static char str[16]; @@ -84,7 +126,7 @@ strcpy(str, "unique"); break; default: - sprintf(str, "unknown-share(%d)", share); + sprintf(str, "%d", share); break; } @@ -114,9 +156,6 @@ { char abuf[256]; __u32 spi; - struct protoent *pp; - char pbuf[32]; - char *p; if (prefix) fprintf(fp, prefix); @@ -125,26 +164,20 @@ fprintf(fp, "src %s ", rt_addr_n2a(family, sizeof(*saddr), saddr, abuf, sizeof(abuf))); memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "dst %s\n", rt_addr_n2a(family, sizeof(id->daddr), - &id->daddr, abuf, sizeof(abuf))); + fprintf(fp, "dst %s", rt_addr_n2a(family, sizeof(id->daddr), + &id->daddr, abuf, sizeof(abuf))); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); fprintf(fp, "\t"); - pp = getprotobynumber(id->proto); - if (pp) - p = pp->p_name; - else { - sprintf(pbuf, "%d", id->proto); - p = pbuf; - } - fprintf(fp, "proto %s ", p); + fprintf(fp, "proto %s ", strxf_proto(id->proto)); spi = ntohl(id->spi); - fprintf(fp, "spi %u", spi); + fprintf(fp, "spi 0x%08x", spi); if (show_stats > 0) - fprintf(fp, "(0x%08x)", spi); + fprintf(fp, "(%u)", spi); fprintf(fp, " "); fprintf(fp, "reqid %u", reqid); @@ -152,7 +185,19 @@ fprintf(fp, "(0x%08x)", reqid); fprintf(fp, " "); - fprintf(fp, "mode %s\n", (mode ? "tunnel" : "transport")); + fprintf(fp, "mode "); + switch (mode) { + case 0: + fprintf(fp, "transport"); + break; + case 1: + fprintf(fp, "tunnel"); + break; + default: + fprintf(fp, "%u", mode); + break; + } + fprintf(fp, "%s", _SL_); } static const char *strxf_limit(__u64 limit) @@ -170,7 +215,8 @@ { if (prefix) fprintf(fp, prefix); - fprintf(fp, "stats:\n"); + fprintf(fp, "stats:"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); @@ -178,25 +224,26 @@ fprintf(fp, "replay-window %d ", s->replay_window); fprintf(fp, "replay %d ", s->replay); fprintf(fp, "failed %d", s->integrity_failed); - fprintf(fp, "\n"); + fprintf(fp, "%s", _SL_); } static const char *strxf_time(__u64 time) { static char str[32]; - struct tm *tp; - time_t t; - if (time == 0) { - strcpy(str, "(undefined)"); - } else { - /* XXX: treat time in the same manner of xfrm_{user,state}.c */ + if (time == 0) + strcpy(str, "-"); + else { + time_t t; + struct tm *tp; + + /* XXX: treat time in the same manner of kernel's + * net/xfrm/xfrm_{user,state}.c + */ t = (long)time; tp = localtime(&t); - sprintf(str, "%04d/%02d/%02d %02d:%02d:%02d", - tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday, - tp->tm_hour, tp->tm_min, tp->tm_sec); + strftime(str, sizeof(str), "%F %T", tp); } return str; @@ -209,7 +256,8 @@ if (cfg) { if (prefix) fprintf(fp, prefix); - fprintf(fp, "lifetime config:\n"); + fprintf(fp, "lifetime config:"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); @@ -219,7 +267,8 @@ fprintf(fp, strxf_limit(cfg->soft_byte_limit)); fprintf(fp, "(bytes), hard "); fprintf(fp, strxf_limit(cfg->hard_byte_limit)); - fprintf(fp, "(bytes)\n"); + fprintf(fp, "(bytes)"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); @@ -229,7 +278,8 @@ fprintf(fp, strxf_limit(cfg->soft_packet_limit)); fprintf(fp, "(packets), hard "); fprintf(fp, strxf_limit(cfg->hard_packet_limit)); - fprintf(fp, "(packets)\n"); + fprintf(fp, "(packets)"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); @@ -239,7 +289,8 @@ fprintf(fp, "%llu", cfg->soft_add_expires_seconds); fprintf(fp, "(sec), hard "); fprintf(fp, "%llu", cfg->hard_add_expires_seconds); - fprintf(fp, "(sec)\n"); + fprintf(fp, "(sec)"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); @@ -249,24 +300,28 @@ fprintf(fp, "%llu", cfg->soft_use_expires_seconds); fprintf(fp, "(sec), hard "); fprintf(fp, "%llu", cfg->hard_use_expires_seconds); - fprintf(fp, "(sec)\n"); + fprintf(fp, "(sec)"); + fprintf(fp, "%s", _SL_); } if (cur) { if (prefix) fprintf(fp, prefix); - fprintf(fp, "lifetime current:\n"); + fprintf(fp, "lifetime current:"); + fprintf(fp, "%s", _SL_); if (prefix) fprintf(fp, prefix); fprintf(fp, " "); fprintf(fp, "%llu(bytes), ", cur->bytes); - fprintf(fp, "%llu(packets)\n", cur->packets); + fprintf(fp, "%llu(packets)", cur->packets); + fprintf(fp, "%s", _SL_); + if (prefix) fprintf(fp, prefix); fprintf(fp, " "); fprintf(fp, "add %s ", strxf_time(cur->add_time)); fprintf(fp, "use %s", strxf_time(cur->use_time)); - fprintf(fp, "\n"); + fprintf(fp, "%s", _SL_); } } @@ -291,18 +346,16 @@ sel->prefixlen_s); memset(abuf, '\0', sizeof(abuf)); - fprintf(fp, "dst %s/%d", rt_addr_n2a(f, sizeof(sel->daddr), + fprintf(fp, "dst %s/%d ", rt_addr_n2a(f, sizeof(sel->daddr), &sel->daddr, abuf, sizeof(abuf)), sel->prefixlen_d); - fprintf(fp, "\n"); - - if (prefix) - fprintf(fp, prefix); - fprintf(fp, "\t"); - - fprintf(fp, "upspec proto %u ", sel->proto); - fprintf(fp, "sport %u dport %u ", sel->sport, sel->dport); + if (sel->proto) + fprintf(fp, "proto %s ", strxf_proto(sel->proto)); + if (sel->sport) + fprintf(fp, "sport %u ", ntohs(sel->sport)); + if (sel->dport) + fprintf(fp, "dport %u ", ntohs(sel->dport)); if (sel->ifindex > 0) { char buf[IF_NAMESIZE]; @@ -314,10 +367,11 @@ if (show_stats > 0) fprintf(fp, "uid %u", sel->user); - fprintf(fp, "\n"); + + fprintf(fp, "%s", _SL_); } -static void xfrm_algo_print(struct xfrm_algo *algo, FILE *fp, +static void xfrm_algo_print(struct xfrm_algo *algo, int type, FILE *fp, const char *prefix) { int len; @@ -326,16 +380,18 @@ if (prefix) fprintf(fp, prefix); - fprintf(fp, "%s", algo->alg_name); + fprintf(fp, "%s ", strxf_algotype(type)); + fprintf(fp, "%s ", algo->alg_name); + fprintf(fp, "0x"); len = algo->alg_key_len / 8; - for (i = 0; i < len; i ++) { - if (i % 4 == 0) - fprintf(fp, " "); - fprintf(fp, "%x", algo->alg_key[i]); - } + for (i = 0; i < len; i ++) + fprintf(fp, "%.2x", (unsigned char)algo->alg_key[i]); - fprintf(fp, "\n"); + if (show_stats > 0) + fprintf(fp, " (%d bits)", algo->alg_key_len); + + fprintf(fp, "%s", _SL_); } static const char *strxf_mask(__u32 mask) @@ -384,30 +440,36 @@ xfrm_id_info_print(&tmpl->saddr, &tmpl->id, tmpl->mode, tmpl->reqid, family, fp, prefix); - fprintf(fp, prefix); + if (prefix) + fprintf(fp, prefix); fprintf(fp, "\t"); - fprintf(fp, "level "); switch (tmpl->optional) { case 0: - fprintf(fp, "required"); + if (show_stats > 0) + fprintf(fp, "level required "); break; case 1: - fprintf(fp, "use"); + fprintf(fp, "level use "); break; default: - fprintf(fp, "%d", tmpl->optional); + fprintf(fp, "level %d ", tmpl->optional); break; } - fprintf(fp, " "); if (show_stats > 0) { fprintf(fp, "share %s ", strxf_share(tmpl->share)); fprintf(fp, "algo-mask:"); - fprintf(fp, "E=%s, ", strxf_mask(tmpl->ealgos)); - fprintf(fp, "A=%s, ", strxf_mask(tmpl->aalgos)); - fprintf(fp, "C=%s", strxf_mask(tmpl->calgos)); + fprintf(fp, "%s=%s, ", + strxf_algotype(XFRMA_ALG_CRYPT), + strxf_mask(tmpl->ealgos)); + fprintf(fp, "%s=%s, ", + strxf_algotype(XFRMA_ALG_AUTH), + strxf_mask(tmpl->aalgos)); + fprintf(fp, "%s=%s", + strxf_algotype(XFRMA_ALG_COMP), + strxf_mask(tmpl->calgos)); } - fprintf(fp, "\n"); + fprintf(fp, "%s", _SL_); } } @@ -422,25 +484,17 @@ switch (type) { case XFRMA_ALG_CRYPT: - if (prefix) - fprintf(fp, prefix); - xfrm_algo_print((struct xfrm_algo *)data, fp, "algo E "); - break; case XFRMA_ALG_AUTH: - if (prefix) - fprintf(fp, prefix); - xfrm_algo_print((struct xfrm_algo *)data, fp, "algo A "); - break; case XFRMA_ALG_COMP: - if (prefix) - fprintf(fp, prefix); - xfrm_algo_print((struct xfrm_algo *)data, fp, "algo C "); + xfrm_algo_print((struct xfrm_algo *)data, type, fp, + prefix); break; case XFRMA_ENCAP: if (prefix) fprintf(fp, prefix); /* XXX */ - fprintf(fp, "encap: (not implemented yet!)\n"); + fprintf(fp, "encap (not implemented yet!)"); + fprintf(fp, "%s", _SL_); break; case XFRMA_TMPL: { @@ -454,14 +508,15 @@ default: if (prefix) fprintf(fp, prefix); - fprintf(fp, "unknown rta_type: %u\n", type); + fprintf(fp, "%u (unknown rta_type)", type); + fprintf(fp, "%s", _SL_); break; } } } int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, - int *argcp, char ***argvp) + int loose, int *argcp, char ***argvp) { int argc = *argcp; char **argv = *argvp; @@ -509,7 +564,7 @@ proto = pp->p_proto; else { if (get_u8(&proto, *argv, 0)) - invarg("\"PROTO\" is invalid", *argv); + invarg("\"XFRM_PROTO\" is invalid", *argv); } switch (proto) { @@ -519,7 +574,7 @@ id->proto = proto; break; default: - invarg("\"PROTO\" is unsuppored proto", *argv); + invarg("\"XFRM_PROTO\" is unsuppored proto", *argv); } filter.id_proto_mask = XFRM_FILTER_MASK_FULL; @@ -548,9 +603,9 @@ if (src.family && dst.family && (src.family != dst.family)) invarg("the same address family is required between \"SADDR\" and \"DADDR\"", *argv); - if (proto == 0) - missarg("PROTO"); + if (loose == 0 && proto == 0) + missarg("PROTO"); if (argc == *argcp) missarg("ID"); @@ -598,10 +653,11 @@ { int argc = *argcp; char **argv = *argvp; - __u8 upspec; while (1) { if (strcmp(*argv, "proto") == 0) { + __u8 upspec; + NEXT_ARG(); if (strcmp(*argv, "any") == 0) @@ -613,7 +669,7 @@ upspec = pp->p_proto; else { if (get_u8(&upspec, *argv, 0)) - invarg("\"UPSPEC\" is invalid", *argv); + invarg("\"PROTO\" is invalid", *argv); } } sel->proto = upspec; @@ -666,6 +722,7 @@ char **argv = *argvp; inet_prefix dst; inet_prefix src; + char *upspecp = NULL; memset(&dst, 0, sizeof(dst)); memset(&src, 0, sizeof(src)); @@ -697,11 +754,6 @@ filter.sel_dst_mask = dst.bitlen; - } else if (strcmp(*argv, "upspec") == 0) { - NEXT_ARG(); - - xfrm_selector_upspec_parse(sel, &argc, &argv); - } else if (strcmp(*argv, "dev") == 0) { int ifindex; @@ -719,8 +771,13 @@ filter.sel_dev_mask = XFRM_FILTER_MASK_FULL; } else { - PREV_ARG(); /* back track */ - break; + if (upspecp) { + PREV_ARG(); /* back track */ + break; + } else { + upspecp = *argv; + xfrm_selector_upspec_parse(sel, &argc, &argv); + } } if (!NEXT_ARG_OK()) diff -uNr iproute2-2.6.8.orig/ip/xfrm.h iproute2-2.6.8/ip/xfrm.h --- iproute2-2.6.8.orig/ip/xfrm.h 2004-07-30 15:28:47.000000000 -0700 +++ iproute2-2.6.8/ip/xfrm.h 2004-08-02 17:27:43.000000000 -0700 @@ -78,6 +78,8 @@ int do_xfrm_state(int argc, char **argv); int do_xfrm_policy(int argc, char **argv); +int xfrm_algotype_getbyname(char *name); +const char *strxf_algotype(int type); const char *strxf_flags(__u8 flags); const char *strxf_share(__u8 share); const char *strxf_proto(__u8 proto); @@ -93,7 +95,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], int ntb, __u16 family, FILE *fp, const char *prefix); int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family, - int *argcp, char ***argvp); + int loose, int *argcp, char ***argvp); int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp); int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp); int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp); diff -uNr iproute2-2.6.8.orig/ip/xfrm_policy.c iproute2-2.6.8/ip/xfrm_policy.c --- iproute2-2.6.8.orig/ip/xfrm_policy.c 2004-07-30 15:28:47.000000000 -0700 +++ iproute2-2.6.8/ip/xfrm_policy.c 2004-08-02 17:27:43.000000000 -0700 @@ -53,14 +53,14 @@ static void usage(void) { - fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR sel SELECTOR [ index INDEX ] \n"); + fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] \n"); fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ LIMIT-LIST ] [ TMPL-LIST ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ sel SELECTOR | index INDEX ]\n"); - fprintf(stderr, "Usage: ip xfrm policy { flush | list } [ dir DIR ] [ sel SELECTOR ]\n"); + fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ]\n"); + fprintf(stderr, "Usage: ip xfrm policy { flush | list } [ dir DIR ] [ SELECTOR ]\n"); fprintf(stderr, " [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]\n"); fprintf(stderr, "DIR := [ in | out | fwd ]\n"); - fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ upspec UPSPEC ] [ dev DEV ]\n"); + fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n"); fprintf(stderr, "UPSPEC := proto PROTO [ sport PORT ] [ dport PORT ]\n"); @@ -134,7 +134,7 @@ else if (strcmp(*argv, "use") == 0) tmpl->optional = 1; else - invarg("\"level\" value is invalid\n", *argv); + invarg("\"LEVEL\" is invalid\n", *argv); } else { if (idp) { @@ -143,7 +143,7 @@ } idp = *argv; xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family, - &argc, &argv); + 0, &argc, &argv); if (preferred_family == AF_UNSPEC) preferred_family = tmpl->family; } @@ -171,6 +171,7 @@ char buf[RTA_BUF_SIZE]; } req; char *dirp = NULL; + char *selp = NULL; char tmpls_buf[XFRM_TMPLS_BUF_SIZE]; int tmpls_len = 0; @@ -198,12 +199,6 @@ filter.dir_mask = XFRM_FILTER_MASK_FULL; - } else if (strcmp(*argv, "sel") == 0) { - NEXT_ARG(); - xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xpinfo.sel.family; - } else if (strcmp(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&req.xpinfo.index, *argv, 0)) @@ -250,8 +245,15 @@ xfrm_tmpl_parse(tmpl, &argc, &argv); tmpls_len += sizeof(*tmpl); - } else - invarg("unknown", *argv); + } else { + if (selp) + duparg("unknown", *argv); + selp = *argv; + + xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv); + if (preferred_family == AF_UNSPEC) + preferred_family = req.xpinfo.sel.family; + } argc--; argv++; } @@ -362,7 +364,6 @@ if (n->nlmsg_type == XFRM_MSG_DELPOLICY) fprintf(fp, "Deleted "); - fprintf(fp, "sel "); xfrm_selector_print(&xpinfo->sel, preferred_family, fp, NULL); fprintf(fp, "\t"); @@ -383,33 +384,36 @@ } fprintf(fp, " "); - fprintf(fp, "action "); switch (xpinfo->action) { case XFRM_POLICY_ALLOW: - fprintf(fp, "allow"); + if (show_stats > 0) + fprintf(fp, "action allow "); break; case XFRM_POLICY_BLOCK: - fprintf(fp, "block"); + fprintf(fp, "action block "); break; default: - fprintf(fp, "%d", xpinfo->action); + fprintf(fp, "action %d ", xpinfo->action); break; } - fprintf(fp, " "); - fprintf(fp, "index %u ", xpinfo->index); + if (show_stats) + fprintf(fp, "index %u ", xpinfo->index); fprintf(fp, "priority %u ", xpinfo->priority); if (show_stats > 0) { fprintf(fp, "share %s ", strxf_share(xpinfo->share)); fprintf(fp, "flags 0x%s", strxf_flags(xpinfo->flags)); } - fprintf(fp, "\n"); + fprintf(fp, "%s", _SL_); if (show_stats > 0) xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, "\t"); xfrm_xfrma_print(tb, ntb, xpinfo->sel.family, fp, "\t"); + if (oneline) + fprintf(fp, "\n"); + return 0; } @@ -440,16 +444,6 @@ NEXT_ARG(); xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv); - } else if (strcmp(*argv, "sel") == 0) { - if (selp) - duparg("sel", *argv); - selp = *argv; - - NEXT_ARG(); - xfrm_selector_parse(&req.xpid.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xpid.sel.family; - } else if (strcmp(*argv, "index") == 0) { if (indexp) duparg("index", *argv); @@ -459,8 +453,16 @@ if (get_u32(&req.xpid.index, *argv, 0)) invarg("\"INDEX\" is invalid", *argv); - } else - invarg("unknown", *argv); + } else { + if (selp) + invarg("unknown", *argv); + selp = *argv; + + xfrm_selector_parse(&req.xpid.sel, &argc, &argv); + if (preferred_family == AF_UNSPEC) + preferred_family = req.xpid.sel.family; + + } argc--; argv++; } @@ -564,6 +566,7 @@ static int xfrm_policy_list_or_flush(int argc, char **argv, int flush) { + char *selp = NULL; struct rtnl_handle rth; if (argc > 0) @@ -577,12 +580,6 @@ filter.dir_mask = XFRM_FILTER_MASK_FULL; - } else if (strcmp(*argv, "sel") == 0) { - NEXT_ARG(); - xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = filter.xpinfo.sel.family; - } else if (strcmp(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&filter.xpinfo.index, *argv, 0)) @@ -597,7 +594,7 @@ else if (strcmp(*argv, "block") == 0) filter.xpinfo.action = XFRM_POLICY_BLOCK; else - invarg("\"action\" value is invalid\n", *argv); + invarg("\"ACTION\" is invalid\n", *argv); filter.action_mask = XFRM_FILTER_MASK_FULL; @@ -608,8 +605,16 @@ filter.priority_mask = XFRM_FILTER_MASK_FULL; - } else - invarg("unknown", *argv); + } else { + if (selp) + invarg("unknown", *argv); + selp = *argv; + + xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv); + if (preferred_family == AF_UNSPEC) + preferred_family = filter.xpinfo.sel.family; + + } argc--; argv++; } diff -uNr iproute2-2.6.8.orig/ip/xfrm_state.c iproute2-2.6.8/ip/xfrm_state.c --- iproute2-2.6.8.orig/ip/xfrm_state.c 2004-07-30 15:28:47.000000000 -0700 +++ iproute2-2.6.8/ip/xfrm_state.c 2004-08-02 17:27:43.000000000 -0700 @@ -67,8 +67,8 @@ fprintf(stderr, "XFRM_PROTO := [ "); fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ESP)); fprintf(stderr, "%s | ", strxf_proto(IPPROTO_AH)); - fprintf(stderr, "%s", strxf_proto(IPPROTO_COMP)); - fprintf(stderr, " ]\n"); + fprintf(stderr, "%s ", strxf_proto(IPPROTO_COMP)); + fprintf(stderr, "]\n"); //fprintf(stderr, "SPI - security parameter index(default=0)\n"); @@ -78,9 +78,14 @@ fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] [ flag FLAG ]\n"); fprintf(stderr, "FLAG := [ noecn ]\n"); - fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ algo ALGO ]\n"); + fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ ALGO ]\n"); fprintf(stderr, "ALGO := ALGO_TYPE ALGO_NAME ALGO_KEY\n"); - fprintf(stderr, "ALGO_TYPE := [ E | A | C ]\n"); + fprintf(stderr, "ALGO_TYPE := [ "); + fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT)); + fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_AUTH)); + fprintf(stderr, "%s ", strxf_algotype(XFRMA_ALG_COMP)); + fprintf(stderr, "]\n"); + //fprintf(stderr, "ALGO_NAME - algorithm name\n"); //fprintf(stderr, "ALGO_KEY - algorithm key\n"); @@ -99,6 +104,7 @@ char *name, char *key, int max) { int len; + int slen = strlen(key); #if 1 /* XXX: verifying both name and key is required! */ @@ -107,30 +113,37 @@ strncpy(alg->alg_name, name, sizeof(alg->alg_name)); - if (strncmp(key, "0x", 2) == 0) { + if (slen > 2 && strncmp(key, "0x", 2) == 0) { /* * XXX: fix me!! */ - __u64 val = 0; - char *p = (char *)&val; + union { + __u64 x; + unsigned char p[8]; + } val; + + memset(&val, 0, sizeof(val)); - if (get_u64(&val, key, 16)) + if (get_u64(&val.x, key, 16)) invarg("\"ALGOKEY\" is invalid", key); - len = (strlen(key) - 2) / 2; + len = (slen - 2) / 2; if (len > sizeof(val)) invarg("\"ALGOKEY\" is invalid: too large", key); if (len > 0) { - int index = sizeof(val) - len; + int i; + if (len > max) invarg("\"ALGOKEY\" makes buffer overflow\n", key); - - memcpy(alg->alg_key, &p[index], len); + for (i = sizeof(val.p) - 1; i >= 0; i--) { + int j = sizeof(val.p) - 1 - i; + alg->alg_key[j] = val.p[i]; + } } } else { - len = strlen(key); + len = slen; if (len > 0) { if (len > max) invarg("\"ALGOKEY\" makes buffer overflow\n", key); @@ -197,56 +210,7 @@ req.xsinfo.lft.hard_packet_limit = XFRM_INF; while (argc > 0) { - if (strcmp(*argv, "algo") == 0) { - struct { - struct xfrm_algo alg; - char buf[XFRM_ALGO_KEY_BUF_SIZE]; - } alg; - int len; - enum xfrm_attr_type_t type; - char *name; - char *key; - - NEXT_ARG(); - - if (strcmp(*argv, "E") == 0) { - if (ealgop) - duparg("ALGOTYPE", *argv); - ealgop = *argv; - type = XFRMA_ALG_CRYPT; - } else if (strcmp(*argv, "A") == 0) { - if (aalgop) - duparg("ALGOTYPE", *argv); - aalgop = *argv; - type = XFRMA_ALG_AUTH; - - } else if (strcmp(*argv, "C") == 0) { - if (calgop) - duparg("ALGOTYPE", *argv); - calgop = *argv; - type = XFRMA_ALG_COMP; - } else - invarg("\"ALGOTYPE\" is invalid\n", *argv); - - if (!NEXT_ARG_OK()) - missarg("ALGONAME"); - NEXT_ARG(); - name = *argv; - - if (!NEXT_ARG_OK()) - missarg("ALGOKEY"); - NEXT_ARG(); - key = *argv; - - memset(&alg, 0, sizeof(alg)); - - xfrm_algo_parse((void *)&alg, type, name, key, sizeof(alg.buf)); - len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len; - - addattr_l(&req.n, sizeof(req.buf), type, - (void *)&alg, len); - - } else if (strcmp(*argv, "mode") == 0) { + if (strcmp(*argv, "mode") == 0) { NEXT_ARG(); xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv); } else if (strcmp(*argv, "reqid") == 0) { @@ -258,20 +222,79 @@ } else if (strcmp(*argv, "sel") == 0) { NEXT_ARG(); xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv); - } else if (strcmp(*argv, "limit") == 0) { NEXT_ARG(); xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv); } else { - if (idp) - invarg("unknown", *argv); - idp = *argv; + /* try to assume ALGO */ + int type = xfrm_algotype_getbyname(*argv); + switch (type) { + case XFRMA_ALG_CRYPT: + case XFRMA_ALG_AUTH: + case XFRMA_ALG_COMP: + { + /* ALGO */ + struct { + struct xfrm_algo alg; + char buf[XFRM_ALGO_KEY_BUF_SIZE]; + } alg; + int len; + char *name; + char *key; + + switch (type) { + case XFRMA_ALG_CRYPT: + if (ealgop) + duparg("ALGOTYPE", *argv); + ealgop = *argv; + break; + case XFRMA_ALG_AUTH: + if (aalgop) + duparg("ALGOTYPE", *argv); + aalgop = *argv; + break; + case XFRMA_ALG_COMP: + if (calgop) + duparg("ALGOTYPE", *argv); + calgop = *argv; + break; + default: + /* not reached */ + invarg("\"ALGOTYPE\" is invalid\n", *argv); + } + + if (!NEXT_ARG_OK()) + missarg("ALGONAME"); + NEXT_ARG(); + name = *argv; + + if (!NEXT_ARG_OK()) + missarg("ALGOKEY"); + NEXT_ARG(); + key = *argv; + + memset(&alg, 0, sizeof(alg)); + + xfrm_algo_parse((void *)&alg, type, name, key, + sizeof(alg.buf)); + len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len; - /* ID */ - xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id, - &req.xsinfo.family, &argc, &argv); - if (preferred_family == AF_UNSPEC) - preferred_family = req.xsinfo.family; + addattr_l(&req.n, sizeof(req.buf), type, + (void *)&alg, len); + break; + } + default: + /* try to assume ID */ + if (idp) + invarg("unknown", *argv); + idp = *argv; + + /* ID */ + xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id, + &req.xsinfo.family, 0, &argc, &argv); + if (preferred_family == AF_UNSPEC) + preferred_family = req.xsinfo.family; + } } argc--; argv++; } @@ -285,14 +308,14 @@ if (req.xsinfo.id.proto != IPPROTO_ESP && req.xsinfo.id.proto != IPPROTO_AH && req.xsinfo.id.proto != IPPROTO_COMP) { - fprintf(stderr, "\"ALGO\" is invalid with proto=%d\n", req.xsinfo.id.proto); + fprintf(stderr, "\"ALGO\" is invalid with proto=%s\n", strxf_proto(req.xsinfo.id.proto)); exit(1); } } else { if (req.xsinfo.id.proto == IPPROTO_ESP || req.xsinfo.id.proto == IPPROTO_AH || req.xsinfo.id.proto == IPPROTO_COMP) { - fprintf(stderr, "\"ALGO\" is required with proto=%d\n", req.xsinfo.id.proto); + fprintf(stderr, "\"ALGO\" is required with proto=%s\n", strxf_proto(req.xsinfo.id.proto)); exit (1); } } @@ -339,6 +362,15 @@ return 1; } +static int xfrm_selector_iszero(struct xfrm_selector *s) +{ + struct xfrm_selector s0; + + memset(&s0, 0, sizeof(s0)); + + return (memcmp(&s0, s, sizeof(s0)) == 0); +} + int xfrm_state_print(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { FILE *fp = (FILE*)arg; @@ -373,33 +405,35 @@ xsinfo->reqid, xsinfo->family, fp, NULL); fprintf(fp, "\t"); - if (show_stats > 0) { + fprintf(fp, "replay-window %d ", xsinfo->replay_window); + if (show_stats > 0) fprintf(fp, "seq 0x%08u ", xsinfo->seq); - fprintf(fp, "replay-window %d ", xsinfo->replay_window); - } - fprintf(fp, "flag 0x%s", strxf_flags(xsinfo->flags)); - if (show_stats > 0) { - if (xsinfo->flags) { - fprintf(fp, "("); - if (xsinfo->flags & XFRM_STATE_NOECN) - fprintf(fp, "noecn"); - fprintf(fp, ")"); + if (xsinfo->flags) { + fprintf(fp, "flag 0x%s", strxf_flags(xsinfo->flags)); + if (show_stats > 0) { + if (xsinfo->flags) { + fprintf(fp, "("); + if (xsinfo->flags & XFRM_STATE_NOECN) + fprintf(fp, "noecn"); + fprintf(fp, ")"); + } } } - fprintf(fp, "\n"); + fprintf(fp, "%s", _SL_); xfrm_xfrma_print(tb, ntb, xsinfo->family, fp, "\t"); - if (show_stats > 0) { - fprintf(fp, "\tsel\n"); - xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, "\t "); - } + if (!xfrm_selector_iszero(&xsinfo->sel)) + xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, "\tsel "); if (show_stats > 0) { xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, "\t"); xfrm_stats_print(&xsinfo->stats, fp, "\t"); } + if (oneline) + fprintf(fp, "\n"); + return 0; } @@ -434,7 +468,7 @@ /* ID */ memset(&id, 0, sizeof(id)); - xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family, + xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family, 0, &argc, &argv); memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr)); @@ -557,9 +591,8 @@ idp = *argv; /* ID */ - xfrm_id_parse(&filter.xsinfo.saddr, - &filter.xsinfo.id, - &filter.xsinfo.family, &argc, &argv); + xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id, + &filter.xsinfo.family, 1, &argc, &argv); if (preferred_family == AF_UNSPEC) preferred_family = filter.xsinfo.family; } -- Masahide NAKAMURA From pp@ee.oulu.fi Tue Aug 3 17:31:20 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 17:31:26 -0700 (PDT) Received: from ee.oulu.fi (ee.oulu.fi [130.231.61.23]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i740VIDW030935 for ; Tue, 3 Aug 2004 17:31:19 -0700 Received: from tk28.oulu.fi (tk28 [130.231.48.68]) by ee.oulu.fi (8.12.11/8.12.11) with ESMTP id i740VEkq006790; Wed, 4 Aug 2004 03:31:14 +0300 (EEST) Received: (from pp@localhost) by tk28.oulu.fi (8.13.0/8.13.0/Submit) id i740V8uc011237; Wed, 4 Aug 2004 03:31:08 +0300 (EEST) Date: Wed, 4 Aug 2004 03:31:08 +0300 From: Pekka Pietikainen To: jgarzik@pobox.com Cc: Florian Schirmer , linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: [PATCH] b44 1GB DMA workaround (was: b44: add 47xx support) Message-ID: <20040804003108.GA10445@ee.oulu.fi> References: <200407232335.37809.jolt@tuxbox.org> <20040726141128.GA5435@ee.oulu.fi> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: <20040726141128.GA5435@ee.oulu.fi> User-Agent: Mutt/1.4.2i X-archive-position: 7480 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: pp@ee.oulu.fi Precedence: bulk X-list: netdev Content-Length: 5022 Lines: 154 On Mon, Jul 26, 2004 at 05:11:28PM +0300, Pekka Pietikainen wrote: > Looks good (well, won't be able to test that it doesn't break 4401 until > next week :-) ). The 47xx patch didn't break anything for 4401 so I'm all for merging. > As for the 1GB patch going in, I sure hope they would (perhaps in a cleaned > up state, it might be more pretty if I just unconditionally enabled the > workaround and had a b44_alloc_skb() that tries a normal dev_alloc_skb and if > that gives something over 1GB retry with GFP_DMA... I just did that, apart from possibly reducing the default ring sizes to reduce GFP_DMA usage from the ~= 1.6MB worst-case it is now, it's just about as good as it'll ever get. Would be nice to get this merged, it seems to be hitting quite a few people out there. Signed-off-by: Pekka Pietikainen --- linux-2.6.7-1.503/drivers/net/b44.h.bb 2004-08-04 00:34:37.850485784 +0300 +++ linux-2.6.7-1.503/drivers/net/b44.h 2004-08-04 00:34:48.711834608 +0300 @@ -493,6 +493,7 @@ struct ring_info *rx_buffers; struct ring_info *tx_buffers; + unsigned char *tx_bufs; u32 dma_offset; u32 flags; @@ -525,7 +526,7 @@ struct pci_dev *pdev; struct net_device *dev; - dma_addr_t rx_ring_dma, tx_ring_dma; + dma_addr_t rx_ring_dma, tx_ring_dma,tx_bufs_dma; u32 rx_pending; u32 tx_pending; --- linux-2.6.7-1.503/drivers/net/b44.c.bb 2004-08-04 00:34:30.653579880 +0300 +++ linux-2.6.7-1.503/drivers/net/b44.c 2004-08-04 02:54:12.756306576 +0300 @@ -27,8 +27,8 @@ #define DRV_MODULE_NAME "b44" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "0.94" -#define DRV_MODULE_RELDATE "May 4, 2004" +#define DRV_MODULE_VERSION "0.95" +#define DRV_MODULE_RELDATE "Aug 3, 2004" #define B44_DEF_MSG_ENABLE \ (NETIF_MSG_DRV | \ @@ -57,6 +57,7 @@ #define B44_DEF_TX_RING_PENDING (B44_TX_RING_SIZE - 1) #define B44_TX_RING_BYTES (sizeof(struct dma_desc) * \ B44_TX_RING_SIZE) +#define B44_DMA_MASK 0x3fffffff #define TX_RING_GAP(BP) \ (B44_TX_RING_SIZE - (BP)->tx_pending) @@ -67,6 +68,7 @@ #define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) #define RX_PKT_BUF_SZ (1536 + bp->rx_offset + 64) +#define TX_PKT_BUF_SZ (B44_MAX_MTU + ETH_HLEN + 8) /* minimum number of free TX descriptors required to wake up TX process */ #define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) @@ -631,10 +633,30 @@ if (skb == NULL) return -ENOMEM; - skb->dev = bp->dev; mapping = pci_map_single(bp->pdev, skb->data, RX_PKT_BUF_SZ, PCI_DMA_FROMDEVICE); + + /* Hardware bug work-around, the chip is unable to do PCI DMA + to/from anything above 1GB :-( */ + if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { + /* Sigh... */ + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + dev_kfree_skb_any(skb); + skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); + if (skb == NULL) + return -ENOMEM; + mapping = pci_map_single(bp->pdev, skb->data, + RX_PKT_BUF_SZ, + PCI_DMA_FROMDEVICE); + if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { + pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); + dev_kfree_skb_any(skb); + return -ENOMEM; + } + } + + skb->dev = bp->dev; skb_reserve(skb, bp->rx_offset); rh = (struct rx_header *) @@ -912,6 +934,13 @@ entry = bp->tx_prod; mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); + if(mapping+len > B44_DMA_MASK) { + /* Chip can't handle DMA to/from >1GB, use bounce buffer */ + pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE); + memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len); + skb->data=bp->tx_bufs+entry*TX_PKT_BUF_SZ; + mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); + } bp->tx_buffers[entry].skb = skb; pci_unmap_addr_set(&bp->tx_buffers[entry], mapping, mapping); @@ -1059,6 +1088,11 @@ bp->tx_ring, bp->tx_ring_dma); bp->tx_ring = NULL; } + if (bp->tx_bufs) { + pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ, + bp->tx_bufs, bp->tx_bufs_dma); + bp->tx_bufs = NULL; + } } /* @@ -1081,6 +1115,12 @@ goto out_err; memset(bp->tx_buffers, 0, size); + size = B44_TX_RING_SIZE * TX_PKT_BUF_SZ; + bp->tx_bufs = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma); + if (!bp->tx_bufs) + goto out_err; + memset(bp->tx_bufs, 0, size); + size = DMA_TABLE_BYTES; bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); if (!bp->rx_ring) @@ -1746,12 +1786,19 @@ pci_set_master(pdev); - err = pci_set_dma_mask(pdev, (u64) 0xffffffff); + err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK); if (err) { printk(KERN_ERR PFX "No usable DMA configuration, " "aborting.\n"); goto err_out_free_res; } + + err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); + if (err) { + printk(KERN_ERR PFX "No usable DMA configuration, " + "aborting.\n"); + goto err_out_free_res; + } b44reg_base = pci_resource_start(pdev, 0); b44reg_len = pci_resource_len(pdev, 0); From jt@bougret.hpl.hp.com Tue Aug 3 17:40:43 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 17:40:53 -0700 (PDT) Received: from palrel13.hp.com (palrel13.hp.com [156.153.255.238]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i740ehZx031365 for ; Tue, 3 Aug 2004 17:40:43 -0700 Received: from tomil.hpl.hp.com (tomil.hpl.hp.com [15.0.152.100]) by palrel13.hp.com (Postfix) with ESMTP id E05161C004CB; Tue, 3 Aug 2004 17:40:35 -0700 (PDT) Received: from bougret.hpl.hp.com (bougret.hpl.hp.com [15.4.92.227]) by tomil.hpl.hp.com (8.9.3 (PHNE_29774)/8.9.3 HPLabs Timeshare Server) with ESMTP id RAA09864; Tue, 3 Aug 2004 17:42:05 -0700 (PDT) Received: from jt by bougret.hpl.hp.com with local (Exim 3.35 #1 (Debian)) id 1Bs9pb-00073u-00; Tue, 03 Aug 2004 17:40:35 -0700 Date: Tue, 3 Aug 2004 17:40:35 -0700 To: Jeff Garzik , netdev@oss.sgi.com, Linux kernel mailing list Subject: [PATCH 2.6] Wireless drivers update for WE-17 Message-ID: <20040804004035.GA26633@bougret.hpl.hp.com> Reply-To: jt@hpl.hp.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.28i Organisation: HP Labs Palo Alto Address: HP Labs, 1U-17, 1501 Page Mill road, Palo Alto, CA 94304, USA. E-mail: jt@hpl.hp.com From: Jean Tourrilhes X-archive-position: 7481 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jt@bougret.hpl.hp.com Precedence: bulk X-list: netdev Content-Length: 10936 Lines: 283 Hi Jeff, This patch complement the main WE-17 patch I just sent you. It updates a few driver to take advantage of WE-17. You should queue it along with the other patch. o Aironet driver : o iwspy data can be shared between eth0 and wifi0 if needed o allow arbitrarily large scan results (no longer limited) o export wireless event capabilities o Wavelan drivers : o export wireless event capabilities Have fun... Jean ------------------------------------------------------------- diff -u -p -r linux/drivers/net/wireless.we16/airo.c linux/drivers/net/wireless/airo.c --- linux/drivers/net/wireless.we16/airo.c Mon Aug 2 14:35:54 2004 +++ linux/drivers/net/wireless/airo.c Tue Aug 3 11:33:26 2004 @@ -1188,6 +1188,7 @@ struct airo_info { struct iw_statistics wstats; // wireless stats unsigned long scan_timestamp; /* Time started to scan */ struct iw_spy_data spy_data; + struct iw_public_data wireless_data; #endif /* WIRELESS_EXT */ #ifdef MICSUPPORT /* MIC stuff */ @@ -2626,8 +2627,7 @@ static void wifi_setup(struct net_device dev->set_mac_address = &airo_set_mac_address; dev->do_ioctl = &airo_ioctl; #ifdef WIRELESS_EXT - dev->get_wireless_stats = airo_get_wireless_stats; - dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def; + dev->wireless_handlers = &airo_handler_def; #endif /* WIRELESS_EXT */ dev->change_mtu = &airo_change_mtu; dev->open = &airo_open; @@ -2654,6 +2654,9 @@ static struct net_device *init_wifidev(s dev->priv = ethdev->priv; dev->irq = ethdev->irq; dev->base_addr = ethdev->base_addr; +#ifdef WIRELESS_EXT + dev->wireless_data = ethdev->wireless_data; +#endif /* WIRELESS_EXT */ memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len); err = register_netdev(dev); if (err<0) { @@ -2733,8 +2736,9 @@ struct net_device *_init_airo_card( unsi dev->set_mac_address = &airo_set_mac_address; dev->do_ioctl = &airo_ioctl; #ifdef WIRELESS_EXT - dev->get_wireless_stats = airo_get_wireless_stats; - dev->wireless_handlers = (struct iw_handler_def *)&airo_handler_def; + dev->wireless_handlers = &airo_handler_def; + ai->wireless_data.spy_data = &ai->spy_data; + dev->wireless_data = &ai->wireless_data; #endif /* WIRELESS_EXT */ dev->change_mtu = &airo_change_mtu; dev->open = &airo_open; @@ -3217,7 +3221,7 @@ badrx: goto exitrx; } } -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ +#ifdef WIRELESS_SPY if (apriv->spy_data.spy_number > 0) { char *sa; struct iw_quality wstats; @@ -3237,7 +3241,7 @@ badrx: /* Update spy records */ wireless_spy_update(dev, sa, &wstats); } -#endif /* IW_WIRELESS_SPY */ +#endif /* WIRELESS_SPY */ OUT4500( apriv, EVACK, EV_RX); if (test_bit(FLAG_802_11, &apriv->flags)) { @@ -3467,7 +3471,7 @@ badmic: #else memcpy(buffer, ai->rxfids[0].virtual_host_addr, len); #endif -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ +#ifdef WIRELESS_SPY if (ai->spy_data.spy_number > 0) { char *sa; struct iw_quality wstats; @@ -3479,7 +3483,7 @@ badmic: /* Update spy records */ wireless_spy_update(ai->dev, sa, &wstats); } -#endif /* IW_WIRELESS_SPY */ +#endif /* WIRELESS_SPY */ skb->dev = ai->dev; skb->ip_summed = CHECKSUM_NONE; @@ -6505,6 +6509,13 @@ static int airo_get_range(struct net_dev range->avg_qual.level = 176; /* -80 dBm */ range->avg_qual.noise = 0; + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP); return 0; } @@ -6872,9 +6883,15 @@ static int airo_get_scan(struct net_devi while((!rc) && (BSSList.index != 0xffff)) { /* Translate to WE format this entry */ current_ev = airo_translate_scan(dev, current_ev, - extra + IW_SCAN_MAX_DATA, + extra + dwrq->length, &BSSList); + /* Check if there is space for one more entry */ + if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) { + /* Ask user space to try again with a bigger buffer */ + return -E2BIG; + } + /* Read next entry */ rc = PC4500_readrid(ai, RID_BSSLISTNEXT, &BSSList, sizeof(BSSList), 1); @@ -7010,12 +7027,10 @@ static const struct iw_handler_def airo_ .num_standard = sizeof(airo_handler)/sizeof(iw_handler), .num_private = sizeof(airo_private_handler)/sizeof(iw_handler), .num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args), - .standard = (iw_handler *) airo_handler, - .private = (iw_handler *) airo_private_handler, - .private_args = (struct iw_priv_args *) airo_private_args, - .spy_offset = ((void *) (&((struct airo_info *) NULL)->spy_data) - - (void *) NULL), - + .standard = airo_handler, + .private = airo_private_handler, + .private_args = airo_private_args, + .get_wireless_stats = airo_get_wireless_stats, }; #endif /* WIRELESS_EXT */ diff -u -p -r linux/drivers/net/wireless.we16/wavelan.c linux/drivers/net/wireless/wavelan.c --- linux/drivers/net/wireless.we16/wavelan.c Mon Aug 2 14:23:02 2004 +++ linux/drivers/net/wireless/wavelan.c Tue Aug 3 11:35:52 2004 @@ -2172,6 +2172,11 @@ static int wavelan_get_range(struct net_ range->num_bitrates = 1; range->bitrate[0] = 2000000; /* 2 Mb/s */ + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) | + IW_EVENT_CAPA_MASK(0x8B04)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); @@ -2403,11 +2408,10 @@ static const struct iw_handler_def wavel .num_standard = sizeof(wavelan_handler)/sizeof(iw_handler), .num_private = sizeof(wavelan_private_handler)/sizeof(iw_handler), .num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args), - .standard = (iw_handler *) wavelan_handler, - .private = (iw_handler *) wavelan_private_handler, - .private_args = (struct iw_priv_args *) wavelan_private_args, - .spy_offset = ((void *) (&((net_local *) NULL)->spy_data) - - (void *) NULL), + .standard = wavelan_handler, + .private = wavelan_private_handler, + .private_args = wavelan_private_args, + .get_wireless_stats = wavelan_get_wireless_stats, }; /*------------------------------------------------------------------*/ @@ -4190,8 +4194,9 @@ static int __init wavelan_config(struct #endif /* SET_MAC_ADDRESS */ #ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */ - dev->get_wireless_stats = wavelan_get_wireless_stats; - dev->wireless_handlers = (struct iw_handler_def *)&wavelan_handler_def; + dev->wireless_handlers = &wavelan_handler_def; + lp->wireless_data.spy_data = &lp->spy_data; + dev->wireless_data = &lp->wireless_data; #endif dev->mtu = WAVELAN_MTU; diff -u -p -r linux/drivers/net/wireless.we16/wavelan.p.h linux/drivers/net/wireless/wavelan.p.h --- linux/drivers/net/wireless.we16/wavelan.p.h Mon Aug 2 14:23:02 2004 +++ linux/drivers/net/wireless/wavelan.p.h Tue Aug 3 11:32:06 2004 @@ -510,6 +510,7 @@ struct net_local iw_stats wstats; /* Wireless-specific statistics */ struct iw_spy_data spy_data; + struct iw_public_data wireless_data; #endif #ifdef HISTOGRAM @@ -614,6 +615,8 @@ static inline void /* ------------------- IOCTL, STATS & RECONFIG ------------------- */ static en_stats * wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */ +static iw_stats * + wavelan_get_wireless_stats(struct net_device *); static void wavelan_set_multicast_list(struct net_device *); /* ----------------------- PACKET RECEPTION ----------------------- */ diff -u -p -r linux/drivers/net/wireless.we16/wavelan_cs.c linux/drivers/net/wireless/wavelan_cs.c --- linux/drivers/net/wireless.we16/wavelan_cs.c Mon Aug 2 14:28:32 2004 +++ linux/drivers/net/wireless/wavelan_cs.c Tue Aug 3 11:37:31 2004 @@ -1550,7 +1550,6 @@ wavelan_set_mac_address(struct net_devic /* * Frequency setting (for hardware able of it) * It's a bit complicated and you don't really want to look into it... - * (called in wavelan_ioctl) */ static inline int wv_set_frequency(u_long base, /* i/o port of the card */ @@ -2438,6 +2437,12 @@ static int wavelan_get_range(struct net_ range->num_bitrates = 1; range->bitrate[0] = 2000000; /* 2 Mb/s */ + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) | + IW_EVENT_CAPA_MASK(0x8B04) | + IW_EVENT_CAPA_MASK(0x8B06)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + /* Disable interrupts and save flags. */ spin_lock_irqsave(&lp->spinlock, flags); @@ -2737,11 +2742,10 @@ static const struct iw_handler_def wavel .num_standard = sizeof(wavelan_handler)/sizeof(iw_handler), .num_private = sizeof(wavelan_private_handler)/sizeof(iw_handler), .num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args), - .standard = (iw_handler *) wavelan_handler, - .private = (iw_handler *) wavelan_private_handler, - .private_args = (struct iw_priv_args *) wavelan_private_args, - .spy_offset = ((void *) (&((net_local *) NULL)->spy_data) - - (void *) NULL), + .standard = wavelan_handler, + .private = wavelan_private_handler, + .private_args = wavelan_private_args, + .get_wireless_stats = wavelan_get_wireless_stats, }; /*------------------------------------------------------------------*/ @@ -4720,9 +4724,10 @@ wavelan_attach(void) dev->watchdog_timeo = WATCHDOG_JIFFIES; #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ - dev->wireless_handlers = (struct iw_handler_def *)&wavelan_handler_def; - dev->do_ioctl = wavelan_ioctl; /* old wireless extensions */ - dev->get_wireless_stats = wavelan_get_wireless_stats; + dev->wireless_handlers = &wavelan_handler_def; + dev->do_ioctl = wavelan_ioctl; /* ethtool */ + lp->wireless_data.spy_data = &lp->spy_data; + dev->wireless_data = &lp->wireless_data; #endif /* Other specific data */ diff -u -p -r linux/drivers/net/wireless.we16/wavelan_cs.p.h linux/drivers/net/wireless/wavelan_cs.p.h --- linux/drivers/net/wireless.we16/wavelan_cs.p.h Mon Aug 2 14:23:02 2004 +++ linux/drivers/net/wireless/wavelan_cs.p.h Tue Aug 3 11:32:06 2004 @@ -629,6 +629,7 @@ struct net_local iw_stats wstats; /* Wireless specific stats */ struct iw_spy_data spy_data; + struct iw_public_data wireless_data; #endif #ifdef HISTOGRAM @@ -725,6 +726,8 @@ static inline void /* ------------------- IOCTL, STATS & RECONFIG ------------------- */ static en_stats * wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */ +static iw_stats * + wavelan_get_wireless_stats(struct net_device *); /* ----------------------- PACKET RECEPTION ----------------------- */ static inline int wv_start_of_frame(struct net_device *, /* Seek beggining of current frame */ From jt@bougret.hpl.hp.com Tue Aug 3 17:40:43 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 17:40:55 -0700 (PDT) Received: from palrel13.hp.com (palrel13.hp.com [156.153.255.238]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i740ehvo031364 for ; Tue, 3 Aug 2004 17:40:43 -0700 Received: from tomil.hpl.hp.com (tomil.hpl.hp.com [15.0.152.100]) by palrel13.hp.com (Postfix) with ESMTP id 8C4631C002F8; Tue, 3 Aug 2004 17:40:33 -0700 (PDT) Received: from bougret.hpl.hp.com (bougret.hpl.hp.com [15.4.92.227]) by tomil.hpl.hp.com (8.9.3 (PHNE_29774)/8.9.3 HPLabs Timeshare Server) with ESMTP id RAA09860; Tue, 3 Aug 2004 17:42:02 -0700 (PDT) Received: from jt by bougret.hpl.hp.com with local (Exim 3.35 #1 (Debian)) id 1Bs9pY-00073k-00; Tue, 03 Aug 2004 17:40:32 -0700 Date: Tue, 3 Aug 2004 17:40:32 -0700 To: Jeff Garzik , netdev@oss.sgi.com, Linux kernel mailing list Subject: [PATCH 2.6] Wireless Extension v17 for Linus Message-ID: <20040804004032.GA26091@bougret.hpl.hp.com> Reply-To: jt@hpl.hp.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.28i Organisation: HP Labs Palo Alto Address: HP Labs, 1U-17, 1501 Page Mill road, Palo Alto, CA 94304, USA. E-mail: jt@hpl.hp.com From: Jean Tourrilhes X-archive-position: 7482 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jt@bougret.hpl.hp.com Precedence: bulk X-list: netdev Content-Length: 30353 Lines: 840 Hi Jeff, This is the patch to migrate Wireless Extension from WE-16 to WE-17 for kernel 2.6.X. I would like you to queue that patch and submit it to Linus as soon as 2.6.8 is released (so it can be fully tested during 2.6.9). If you want, I can resend that as soon as 2.6.8 is released. The patch is basically unchanged compared to the version posted to the netdev list and my web page one month ago, I just re-diff to the latest kernel (2.6.8-rc2-bk12). The patch already included feedback from various driver maintainers, and nobody else complained, so I guess it's ready. The patch for some drivers inside the kernel will follow (airo.c, wavelan.c, wavelan_cs). Patch for various other drivers (orinoco, hostap, prism54) have been sent already to their maintainers (one month ago) and basically waiting for this patch. Changelog : * - Add flags to frequency -> auto/fixed * - Document (struct iw_quality *)->updated, add new flags (INVALID) * - Wireless Event capability in struct iw_range * - Add support for relative TxPower (yick !) * - Change the way we get to spy_data method for added safety and hostap * - Remove spy #ifdef, they are always on -> cleaner code * - Allow any size GET request if user specifies length > max * - Start migrating get_wireless_stats to struct iw_handler_def * Based on patch from Pavel Roskin : * - Fix kernel data leak to user space in private handler handling I also added on my page a version of Wireless Tools that use RtNetlink instead of ioctls. This is not as clean as I would like, but is fully functional (if you have WE-19). I know that you were interested, so feel free to send feedback on that... Have fun... Jean -------------------------------------------------------------------- diff -u -p linux/include/linux/netdevice.we16.h linux/include/linux/netdevice.h --- linux/include/linux/netdevice.we16.h Tue Aug 3 11:13:59 2004 +++ linux/include/linux/netdevice.h Tue Aug 3 11:16:30 2004 @@ -304,7 +304,9 @@ struct net_device /* List of functions to handle Wireless Extensions (instead of ioctl). * See for details. Jean II */ - struct iw_handler_def * wireless_handlers; + const struct iw_handler_def * wireless_handlers; + /* Instance data managed by the core of Wireless Extensions. */ + struct iw_public_data * wireless_data; struct ethtool_ops *ethtool_ops; diff -u -p linux/include/linux/wireless.we16.h linux/include/linux/wireless.h --- linux/include/linux/wireless.we16.h Tue Aug 3 11:14:07 2004 +++ linux/include/linux/wireless.h Tue Aug 3 11:23:15 2004 @@ -1,10 +1,10 @@ /* * This file define a set of standard wireless extensions * - * Version : 16 2.4.03 + * Version : 17 21.6.04 * * Authors : Jean Tourrilhes - HPL - - * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved. + * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved. */ #ifndef _LINUX_WIRELESS_H @@ -47,12 +47,12 @@ * # include/net/iw_handler.h * * Note as well that /proc/net/wireless implementation has now moved in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Wireless Events (2002 -> onward) : * -------------------------------- * Events are defined at the end of this file, and implemented in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Other comments : * -------------- @@ -82,7 +82,7 @@ * (there is some stuff that will be added in the future...) * I just plan to increment with each new version. */ -#define WIRELESS_EXT 16 +#define WIRELESS_EXT 17 /* * Changes : @@ -175,6 +175,13 @@ * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index + * + * V16 to V17 + * ---------- + * - Add flags to frequency -> auto/fixed + * - Document (struct iw_quality *)->updated, add new flags (INVALID) + * - Wireless Event capability in struct iw_range + * - Add support for relative TxPower (yick !) */ /**************************** CONSTANTS ****************************/ @@ -251,7 +258,7 @@ /* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ -/* These 16 ioctl are wireless device private. +/* These 32 ioctl are wireless device private, for 16 commands. * Each driver is free to use them for whatever purpose it chooses, * however the driver *must* export the description of those ioctls * with SIOCGIWPRIV and *must* use arguments as defined below. @@ -266,8 +273,8 @@ * We now have 32 commands, so a bit more space ;-). * Also, all 'odd' commands are only usable by root and don't return the * content of ifr/iwr to user (but you are not obliged to use the set/get - * convention, just use every other two command). - * And I repeat : you are not obliged to use them with iwspy, but you + * convention, just use every other two command). More details in iwpriv.c. + * And I repeat : you are not forced to use them with iwpriv, but you * must be compliant with it. */ @@ -352,6 +359,18 @@ #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ #define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ +/* Statistics flags (bitmask in updated) */ +#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 + +/* Frequency flags */ +#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ +#define IW_FREQ_FIXED 0x01 /* Force a specific value */ + /* Maximum number of size of encoding token available * they are listed in the range structure */ #define IW_MAX_ENCODING_SIZES 8 @@ -390,6 +409,7 @@ #define IW_TXPOW_TYPE 0x00FF /* Type of value */ #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ +#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ #define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ /* Retry limits and lifetime flags available */ @@ -418,6 +438,25 @@ /* Max number of char in custom event - use multiple of them if needed */ #define IW_CUSTOM_MAX 256 /* In bytes */ +/* Event capability macros - in (struct iw_range *)->event_capa + * Because we have more than 32 possible events, we use an array of + * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ +#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ + (cmd - SIOCIWFIRSTPRIV + 0x60) : \ + (cmd - SIOCSIWCOMMIT)) +#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) +#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) +/* Event capability constants - event autogenerated by the kernel + * This list is valid for most 802.11 devices, customise as needed... */ +#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ + IW_EVENT_CAPA_MASK(0x8B06) | \ + IW_EVENT_CAPA_MASK(0x8B1A)) +#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) +/* "Easy" macro to set events in iw_range (less efficient) */ +#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) +#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } + + /****************************** TYPES ******************************/ /* --------------------------- SUBTYPES --------------------------- */ @@ -456,7 +495,7 @@ struct iw_freq __s32 m; /* Mantissa */ __s16 e; /* Exponent */ __u8 i; /* List index (when in range struct) */ - __u8 pad; /* Unused - just for alignement */ + __u8 flags; /* Flags (fixed/auto) */ }; /* @@ -610,11 +649,12 @@ struct iw_range /* Old Frequency (backward compat - moved lower ) */ __u16 old_num_channels; __u8 old_num_frequency; - /* Filler to keep "version" at the same offset */ - __s32 old_freq[6]; + + /* Wireless event capability bitmasks */ + __u32 event_capa[6]; /* signal level threshold range */ - __s32 sensitivity; + __s32 sensitivity; /* Quality of link & SNR stuff */ /* Quality range (link, level, noise) diff -u -p linux/include/net/iw_handler.we16.h linux/include/net/iw_handler.h --- linux/include/net/iw_handler.we16.h Tue Aug 3 11:14:22 2004 +++ linux/include/net/iw_handler.h Tue Aug 3 11:18:46 2004 @@ -1,10 +1,10 @@ /* * This file define the new driver API for Wireless Extensions * - * Version : 5 4.12.02 + * Version : 6 21.6.04 * * Authors : Jean Tourrilhes - HPL - - * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved. + * Copyright (c) 2001-2004 Jean Tourrilhes, All Rights Reserved. */ #ifndef _IW_HANDLER_H @@ -206,7 +206,7 @@ * will be needed... * I just plan to increment with each new version. */ -#define IW_HANDLER_VERSION 5 +#define IW_HANDLER_VERSION 6 /* * Changes : @@ -224,11 +224,18 @@ * V4 to V5 * -------- * - Add new spy support : struct iw_spy_data & prototypes + * + * V5 to V6 + * -------- + * - Change the way we get to spy_data method for added safety + * - Remove spy #ifdef, they are always on -> cleaner code + * - Add IW_DESCR_FLAG_NOMAX flag for very large requests + * - Start migrating get_wireless_stats to struct iw_handler_def */ /**************************** CONSTANTS ****************************/ -/* Enable enhanced spy support. Disable to reduce footprint */ +/* Enhanced spy support available */ #define IW_WIRELESS_SPY #define IW_WIRELESS_THRSPY @@ -258,6 +265,7 @@ #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */ #define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ /* SET : Omit payload from generated iwevent */ +#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */ /* Driver level flags */ #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ @@ -303,31 +311,33 @@ struct iw_handler_def { /* Number of handlers defined (more precisely, index of the * last defined handler + 1) */ - __u16 num_standard; - __u16 num_private; + const __u16 num_standard; + const __u16 num_private; /* Number of private arg description */ - __u16 num_private_args; + const __u16 num_private_args; /* Array of handlers for standard ioctls * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME] */ - iw_handler * standard; + const iw_handler * standard; /* Array of handlers for private ioctls * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV] */ - iw_handler * private; + const iw_handler * private; /* Arguments of private handler. This one is just a list, so you * can put it in any order you want and should not leave holes... * We will automatically export that to user space... */ - struct iw_priv_args * private_args; + const struct iw_priv_args * private_args; - /* Driver enhanced spy support */ - long spy_offset; /* Spy data offset */ + /* This field will be *removed* in the next version of WE */ + const long spy_offset; /* DO NOT USE */ - /* In the long term, get_wireless_stats will move from - * 'struct net_device' to here, to minimise bloat. */ + /* New location of get_wireless_stats, to de-bloat struct net_device. + * The old pointer in struct net_device will be gradually phased + * out, and drivers are encouraged to use this one... */ + struct iw_statistics* (*get_wireless_stats)(struct net_device *dev); }; /* ---------------------- IOCTL DESCRIPTION ---------------------- */ @@ -374,18 +384,29 @@ struct iw_ioctl_description */ struct iw_spy_data { -#ifdef IW_WIRELESS_SPY /* --- Standard spy support --- */ int spy_number; u_char spy_address[IW_MAX_SPY][ETH_ALEN]; struct iw_quality spy_stat[IW_MAX_SPY]; -#ifdef IW_WIRELESS_THRSPY /* --- Enhanced spy support (event) */ struct iw_quality spy_thr_low; /* Low threshold */ struct iw_quality spy_thr_high; /* High threshold */ u_char spy_thr_under[IW_MAX_SPY]; -#endif /* IW_WIRELESS_THRSPY */ -#endif /* IW_WIRELESS_SPY */ +}; + +/* --------------------- DEVICE WIRELESS DATA --------------------- */ +/* + * This is all the wireless data specific to a device instance that + * is managed by the core of Wireless Extensions. + * We only keep pointer to those structures, so that a driver is free + * to share them between instances. + * This structure should be initialised before registering the device. + * Access to this data follow the same rules as any other struct net_device + * data (i.e. valid as long as struct net_device exist, same locking rules). + */ +struct iw_public_data { + /* Driver enhanced spy support */ + struct iw_spy_data * spy_data; }; /**************************** PROTOTYPES ****************************/ @@ -393,6 +414,9 @@ struct iw_spy_data * Functions part of the Wireless Extensions (defined in net/core/wireless.c). * Those may be called only within the kernel. */ + +/* Data needed by fs/compat_ioctl.c for 32->64 bit conversion */ +extern const char iw_priv_type_size[]; /* First : function strictly used inside the kernel */ diff -u -p linux/net/core/dev.we16.c linux/net/core/dev.c --- linux/net/core/dev.we16.c Tue Aug 3 11:14:45 2004 +++ linux/net/core/dev.c Tue Aug 3 11:15:09 2004 @@ -2787,7 +2787,7 @@ int dev_ioctl(unsigned int cmd, void __u /* Follow me in net/core/wireless.c */ ret = wireless_process_ioctl(&ifr, cmd); rtnl_unlock(); - if (!ret && IW_IS_GET(cmd) && + if (IW_IS_GET(cmd) && copy_to_user(arg, &ifr, sizeof(struct ifreq))) ret = -EFAULT; diff -u -p linux/net/core/wireless.we16.c linux/net/core/wireless.c --- linux/net/core/wireless.we16.c Tue Aug 3 11:14:54 2004 +++ linux/net/core/wireless.c Tue Aug 3 11:20:39 2004 @@ -2,7 +2,7 @@ * This file implement the Wireless Extensions APIs. * * Authors : Jean Tourrilhes - HPL - - * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved. + * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved. * * (As all part of the Linux kernel, this file is GPL) */ @@ -48,6 +48,15 @@ * o Add common spy support : iw_handler_set_spy(), wireless_spy_update() * o Add enhanced spy support : iw_handler_set_thrspy() and event. * o Add WIRELESS_EXT version display in /proc/net/wireless + * + * v6 - 18.06.04 - Jean II + * o Change get_spydata() method for added safety + * o Remove spy #ifdef, they are always on -> cleaner code + * o Allow any size GET request is user specifies length > max + * o Start migrating get_wireless_stats to struct iw_handler_def + * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus + * Based on patch from Pavel Roskin : + * o Fix kernel data leak to user space in private handler handling */ /***************************** INCLUDES *****************************/ @@ -69,10 +78,6 @@ /**************************** CONSTANTS ****************************/ -/* Enough lenience, let's make sure things are proper... */ -#define WE_STRICT_WRITE /* Check write buffer size */ -/* I'll probably drop both the define and kernel message in the next version */ - /* Debugging stuff */ #undef WE_IOCTL_DEBUG /* Debug IOCTL API */ #undef WE_EVENT_DEBUG /* Debug Event dispatcher */ @@ -186,6 +191,7 @@ static const struct iw_ioctl_description .token_size = sizeof(struct sockaddr) + sizeof(struct iw_quality), .max_tokens = IW_MAX_AP, + .flags = IW_DESCR_FLAG_NOMAX, }, [SIOCSIWSCAN - SIOCIWFIRST] = { .header_type = IW_HEADER_TYPE_PARAM, @@ -194,6 +200,7 @@ static const struct iw_ioctl_description .header_type = IW_HEADER_TYPE_POINT, .token_size = 1, .max_tokens = IW_SCAN_MAX_DATA, + .flags = IW_DESCR_FLAG_NOMAX, }, [SIOCSIWESSID - SIOCIWFIRST] = { .header_type = IW_HEADER_TYPE_POINT, @@ -296,7 +303,7 @@ static const int standard_event_num = (s sizeof(struct iw_ioctl_description)); /* Size (in bytes) of the various private data types */ -static const char priv_type_size[] = { +const char iw_priv_type_size[] = { 0, /* IW_PRIV_TYPE_NONE */ 1, /* IW_PRIV_TYPE_BYTE */ 1, /* IW_PRIV_TYPE_CHAR */ @@ -363,12 +370,15 @@ static inline iw_handler get_handler(str */ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev) { + /* New location */ + if((dev->wireless_handlers != NULL) && + (dev->wireless_handlers->get_wireless_stats != NULL)) + return dev->wireless_handlers->get_wireless_stats(dev); + + /* Old location, will be phased out in next WE */ return (dev->get_wireless_stats ? dev->get_wireless_stats(dev) : (struct iw_statistics *) NULL); - /* In the future, get_wireless_stats may move from 'struct net_device' - * to 'struct iw_handler_def', to de-bloat struct net_device. - * Definitely worse a thought... */ } /* ---------------------------------------------------------------- */ @@ -403,14 +413,32 @@ static inline int call_commit_handler(st /* ---------------------------------------------------------------- */ /* - * Number of private arguments + * Calculate size of private arguments */ static inline int get_priv_size(__u16 args) { int num = args & IW_PRIV_SIZE_MASK; int type = (args & IW_PRIV_TYPE_MASK) >> 12; - return num * priv_type_size[type]; + return num * iw_priv_type_size[type]; +} + +/* ---------------------------------------------------------------- */ +/* + * Re-calculate the size of private arguments + */ +static inline int adjust_priv_size(__u16 args, + union iwreq_data * wrqu) +{ + int num = wrqu->data.length; + int max = args & IW_PRIV_SIZE_MASK; + int type = (args & IW_PRIV_TYPE_MASK) >> 12; + + /* Make sure the driver doesn't goof up */ + if (max < num) + num = max; + + return num * iw_priv_type_size[type]; } @@ -440,11 +468,14 @@ static __inline__ void wireless_seq_prin seq_printf(seq, "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d " "%6d %6d %6d\n", dev->name, stats->status, stats->qual.qual, - stats->qual.updated & 1 ? '.' : ' ', + stats->qual.updated & IW_QUAL_QUAL_UPDATED + ? '.' : ' ', ((__u8) stats->qual.level), - stats->qual.updated & 2 ? '.' : ' ', + stats->qual.updated & IW_QUAL_LEVEL_UPDATED + ? '.' : ' ', ((__u8) stats->qual.noise), - stats->qual.updated & 4 ? '.' : ' ', + stats->qual.updated & IW_QUAL_NOISE_UPDATED + ? '.' : ' ', stats->discard.nwid, stats->discard.code, stats->discard.fragment, stats->discard.retries, stats->discard.misc, stats->miss.beacon); @@ -555,13 +586,15 @@ static inline int ioctl_export_private(s /* Check NULL pointer */ if(iwr->u.data.pointer == NULL) return -EFAULT; -#ifdef WE_STRICT_WRITE + /* Check if there is enough buffer up there */ if(iwr->u.data.length < dev->wireless_handlers->num_private_args) { - printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args); + /* User space can't know in advance how large the buffer + * needs to be. Give it a hint, so that we can support + * any size buffer we want somewhat efficiently... */ + iwr->u.data.length = dev->wireless_handlers->num_private_args; return -E2BIG; } -#endif /* WE_STRICT_WRITE */ /* Set the number of available ioctls. */ iwr->u.data.length = dev->wireless_handlers->num_private_args; @@ -590,7 +623,6 @@ static inline int ioctl_standard_call(st const struct iw_ioctl_description * descr; struct iw_request_info info; int ret = -EINVAL; - int user_size = 0; /* Get the description of the IOCTL */ if((cmd - SIOCIWFIRST) >= standard_ioctl_num) @@ -621,8 +653,14 @@ static inline int ioctl_standard_call(st #endif /* WE_SET_EVENT */ } else { char * extra; + int extra_size; + int user_length = 0; int err; + /* Calculate space needed by arguments. Always allocate + * for max space. Easier, and won't last long... */ + extra_size = descr->max_tokens * descr->token_size; + /* Check what user space is giving us */ if(IW_IS_SET(cmd)) { /* Check NULL pointer */ @@ -639,18 +677,29 @@ static inline int ioctl_standard_call(st if(iwr->u.data.pointer == NULL) return -EFAULT; /* Save user space buffer size for checking */ - user_size = iwr->u.data.length; + user_length = iwr->u.data.length; + + /* Don't check if user_length > max to allow forward + * compatibility. The test user_length < min is + * implied by the test at the end. */ + + /* Support for very large requests */ + if((descr->flags & IW_DESCR_FLAG_NOMAX) && + (user_length > descr->max_tokens)) { + /* Allow userspace to GET more than max so + * we can support any size GET requests. + * There is still a limit : -ENOMEM. */ + extra_size = user_length * descr->token_size; + } } #ifdef WE_IOCTL_DEBUG printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n", - dev->name, descr->max_tokens * descr->token_size); + dev->name, extra_size); #endif /* WE_IOCTL_DEBUG */ - /* Always allocate for max space. Easier, and won't last - * long... */ - extra = kmalloc(descr->max_tokens * descr->token_size, - GFP_KERNEL); + /* Create the kernel buffer */ + extra = kmalloc(extra_size, GFP_KERNEL); if (extra == NULL) { return -ENOMEM; } @@ -676,14 +725,11 @@ static inline int ioctl_standard_call(st /* If we have something to return to the user */ if (!ret && IW_IS_GET(cmd)) { -#ifdef WE_STRICT_WRITE /* Check if there is enough buffer up there */ - if(user_size < iwr->u.data.length) { - printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length); + if(user_length < iwr->u.data.length) { kfree(extra); return -E2BIG; } -#endif /* WE_STRICT_WRITE */ err = copy_to_user(iwr->u.data.pointer, extra, iwr->u.data.length * @@ -746,7 +792,7 @@ static inline int ioctl_private_call(str iw_handler handler) { struct iwreq * iwr = (struct iwreq *) ifr; - struct iw_priv_args * descr = NULL; + const struct iw_priv_args * descr = NULL; struct iw_request_info info; int extra_size = 0; int i; @@ -786,7 +832,7 @@ static inline int ioctl_private_call(str ((extra_size + offset) <= IFNAMSIZ)) extra_size = 0; } else { - /* Size of set arguments */ + /* Size of get arguments */ extra_size = get_priv_size(descr->get_args); /* Does it fits in iwr ? */ @@ -816,7 +862,7 @@ static inline int ioctl_private_call(str return -EFAULT; /* Does it fits within bounds ? */ - if(iwr->u.data.length > (descr->set_args & + if(iwr->u.data.length > (descr->get_args & IW_PRIV_SIZE_MASK)) return -E2BIG; } else { @@ -856,6 +902,14 @@ static inline int ioctl_private_call(str /* If we have something to return to the user */ if (!ret && IW_IS_GET(cmd)) { + + /* Adjust for the actual length if it's variable, + * avoid leaking kernel bits outside. */ + if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) { + extra_size = adjust_priv_size(descr->get_args, + &(iwr->u)); + } + err = copy_to_user(iwr->u.data.pointer, extra, extra_size); if (err) @@ -1127,9 +1181,25 @@ void wireless_send_event(struct net_devi * One of the main advantage of centralising spy support here is that * it becomes much easier to improve and extend it without having to touch * the drivers. One example is the addition of the Spy-Threshold events. - * Note : IW_WIRELESS_SPY is defined in iw_handler.h */ +/* ---------------------------------------------------------------- */ +/* + * Return the pointer to the spy data in the driver. + * Because this is called on the Rx path via wireless_spy_update(), + * we want it to be efficient... + */ +static inline struct iw_spy_data * get_spydata(struct net_device *dev) +{ + /* This is the new way */ + if(dev->wireless_data) + return(dev->wireless_data->spy_data); + + /* This is the old way. Doesn't work for multi-headed drivers. + * It will be removed in the next version of WE. */ + return (dev->priv + dev->wireless_handlers->spy_offset); +} + /*------------------------------------------------------------------*/ /* * Standard Wireless Handler : set Spy List @@ -1139,16 +1209,30 @@ int iw_handler_set_spy(struct net_device union iwreq_data * wrqu, char * extra) { -#ifdef IW_WIRELESS_SPY - struct iw_spy_data * spydata = (dev->priv + - dev->wireless_handlers->spy_offset); + struct iw_spy_data * spydata = get_spydata(dev); struct sockaddr * address = (struct sockaddr *) extra; + if(!dev->wireless_data) + /* Help user know that driver needs updating */ + printk(KERN_DEBUG "%s (WE) : Driver using old/buggy spy support, please fix driver !\n", + dev->name); + /* Make sure driver is not buggy or using the old API */ + if(!spydata) + return -EOPNOTSUPP; + /* Disable spy collection while we copy the addresses. - * As we don't disable interrupts, we need to do this to avoid races. - * As we are the only writer, this is good enough. */ + * While we copy addresses, any call to wireless_spy_update() + * will NOP. This is OK, as anyway the addresses are changing. */ spydata->spy_number = 0; + /* We want to operate without locking, because wireless_spy_update() + * most likely will happen in the interrupt handler, and therefore + * have it own locking constraints and needs performance. + * The rtnl_lock() make sure we don't race with the other iw_handlers. + * This make sure wireless_spy_update() "see" that the spy list + * is temporarily disabled. */ + wmb(); + /* Are there are addresses to copy? */ if(wrqu->data.length > 0) { int i; @@ -1174,13 +1258,14 @@ int iw_handler_set_spy(struct net_device spydata->spy_address[i][5]); #endif /* WE_SPY_DEBUG */ } + + /* Make sure above is updated before re-enabling */ + wmb(); + /* Enable addresses */ spydata->spy_number = wrqu->data.length; return 0; -#else /* IW_WIRELESS_SPY */ - return -EOPNOTSUPP; -#endif /* IW_WIRELESS_SPY */ } /*------------------------------------------------------------------*/ @@ -1192,12 +1277,14 @@ int iw_handler_get_spy(struct net_device union iwreq_data * wrqu, char * extra) { -#ifdef IW_WIRELESS_SPY - struct iw_spy_data * spydata = (dev->priv + - dev->wireless_handlers->spy_offset); + struct iw_spy_data * spydata = get_spydata(dev); struct sockaddr * address = (struct sockaddr *) extra; int i; + /* Make sure driver is not buggy or using the old API */ + if(!spydata) + return -EOPNOTSUPP; + wrqu->data.length = spydata->spy_number; /* Copy addresses. */ @@ -1214,9 +1301,6 @@ int iw_handler_get_spy(struct net_device for(i = 0; i < spydata->spy_number; i++) spydata->spy_stat[i].updated = 0; return 0; -#else /* IW_WIRELESS_SPY */ - return -EOPNOTSUPP; -#endif /* IW_WIRELESS_SPY */ } /*------------------------------------------------------------------*/ @@ -1228,11 +1312,13 @@ int iw_handler_set_thrspy(struct net_dev union iwreq_data * wrqu, char * extra) { -#ifdef IW_WIRELESS_THRSPY - struct iw_spy_data * spydata = (dev->priv + - dev->wireless_handlers->spy_offset); + struct iw_spy_data * spydata = get_spydata(dev); struct iw_thrspy * threshold = (struct iw_thrspy *) extra; + /* Make sure driver is not buggy or using the old API */ + if(!spydata) + return -EOPNOTSUPP; + /* Just do it */ memcpy(&(spydata->spy_thr_low), &(threshold->low), 2 * sizeof(struct iw_quality)); @@ -1245,9 +1331,6 @@ int iw_handler_set_thrspy(struct net_dev #endif /* WE_SPY_DEBUG */ return 0; -#else /* IW_WIRELESS_THRSPY */ - return -EOPNOTSUPP; -#endif /* IW_WIRELESS_THRSPY */ } /*------------------------------------------------------------------*/ @@ -1259,22 +1342,20 @@ int iw_handler_get_thrspy(struct net_dev union iwreq_data * wrqu, char * extra) { -#ifdef IW_WIRELESS_THRSPY - struct iw_spy_data * spydata = (dev->priv + - dev->wireless_handlers->spy_offset); + struct iw_spy_data * spydata = get_spydata(dev); struct iw_thrspy * threshold = (struct iw_thrspy *) extra; + /* Make sure driver is not buggy or using the old API */ + if(!spydata) + return -EOPNOTSUPP; + /* Just do it */ memcpy(&(threshold->low), &(spydata->spy_thr_low), 2 * sizeof(struct iw_quality)); return 0; -#else /* IW_WIRELESS_THRSPY */ - return -EOPNOTSUPP; -#endif /* IW_WIRELESS_THRSPY */ } -#ifdef IW_WIRELESS_THRSPY /*------------------------------------------------------------------*/ /* * Prepare and send a Spy Threshold event @@ -1312,7 +1393,6 @@ static void iw_send_thrspy_event(struct /* Send event to user space */ wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold); } -#endif /* IW_WIRELESS_THRSPY */ /* ---------------------------------------------------------------- */ /* @@ -1325,12 +1405,14 @@ void wireless_spy_update(struct net_devi unsigned char * address, struct iw_quality * wstats) { -#ifdef IW_WIRELESS_SPY - struct iw_spy_data * spydata = (dev->priv + - dev->wireless_handlers->spy_offset); + struct iw_spy_data * spydata = get_spydata(dev); int i; int match = -1; + /* Make sure driver is not buggy or using the old API */ + if(!spydata) + return; + #ifdef WE_SPY_DEBUG printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]); #endif /* WE_SPY_DEBUG */ @@ -1342,7 +1424,7 @@ void wireless_spy_update(struct net_devi sizeof(struct iw_quality)); match = i; } -#ifdef IW_WIRELESS_THRSPY + /* Generate an event if we cross the spy threshold. * To avoid event storms, we have a simple hysteresis : we generate * event only when we go under the low threshold or above the @@ -1362,8 +1444,6 @@ void wireless_spy_update(struct net_devi } } } -#endif /* IW_WIRELESS_THRSPY */ -#endif /* IW_WIRELESS_SPY */ } EXPORT_SYMBOL(iw_handler_get_spy); From davem@redhat.com Tue Aug 3 18:41:18 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 18:41:25 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i741fITG000699 for ; Tue, 3 Aug 2004 18:41:18 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i741f7e1001987; Tue, 3 Aug 2004 21:41:07 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i741f7a31657; Tue, 3 Aug 2004 21:41:07 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i741eMxm021793; Tue, 3 Aug 2004 21:40:22 -0400 Date: Tue, 3 Aug 2004 18:39:19 -0700 From: "David S. Miller" To: Pekka Pietikainen Cc: jgarzik@pobox.com, jolt@tuxbox.org, linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: Re: [PATCH] b44 1GB DMA workaround (was: b44: add 47xx support) Message-Id: <20040803183919.2990d045.davem@redhat.com> In-Reply-To: <20040804003108.GA10445@ee.oulu.fi> References: <200407232335.37809.jolt@tuxbox.org> <20040726141128.GA5435@ee.oulu.fi> <20040804003108.GA10445@ee.oulu.fi> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7483 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Content-Length: 867 Lines: 20 On Wed, 4 Aug 2004 03:31:08 +0300 Pekka Pietikainen wrote: > + if(mapping+len > B44_DMA_MASK) { > + /* Chip can't handle DMA to/from >1GB, use bounce buffer */ > + pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE); > + memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len); > + skb->data=bp->tx_bufs+entry*TX_PKT_BUF_SZ; > + mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); > + } Changing skb->data is not legal. Please implement this in such a way that skb->data does not get modified. By modifying skb->data you will break things such as packet sniffers and netfilter, and that's just the tip of the iceberg. :-) I would suggest merely freeing up this TX skb, and marking the entry in the b44 software state with some dummy skb pointer such as (void *) 0x1UL or something like that to indicate this case. From herbert@gondor.apana.org.au Tue Aug 3 20:28:12 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 20:28:20 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i743SA4t006658 for ; Tue, 3 Aug 2004 20:28:11 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BsCRc-0005aK-00; Wed, 04 Aug 2004 13:28:00 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BsCRY-0000di-00; Wed, 04 Aug 2004 13:27:56 +1000 Date: Wed, 4 Aug 2004 13:27:56 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: Transparent Proxying Message-ID: <20040804032756.GA2388@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7484 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev Content-Length: 1359 Lines: 31 Hi Dave: I need to implement a semi-transparent TCP proxy for work. The requirement is that it'll intercept all TCP connections passing through and redirect them to a local port. Once there the connection will be forwarded through a non-TCP protocol (that's why it's only semi-transparent, in fact it's only a half-TCP proxy :) Redirecting is easy through the REDIRECT netfilter target. But the tricky bit is getting the original destination address so that we can forward this information to our peer who will turn the connection back into TCP. Since this proxy has to be completely generic it cannot rely on ULP-specific information to deduce the destination address. I looked around and found the TPROXY patch which is part of pom-ng. It is capable of providing the information I need via a getsockopt() call. The only catch is that you seem to have some objections to it :) So I'd like to know your objections against the patch and how they might be overcome. If you know another way of getting the destination information then that would be good to (apart from the obvious one of parsing /proc/net/ip_conntrack :) Thanks in advance, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From herbert@gondor.apana.org.au Tue Aug 3 22:07:51 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 22:07:59 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7457lkS009081 for ; Tue, 3 Aug 2004 22:07:50 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BsDzw-000611-00; Wed, 04 Aug 2004 15:07:32 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BsDzs-0000m6-00; Wed, 04 Aug 2004 15:07:28 +1000 Date: Wed, 4 Aug 2004 15:07:28 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: Re: Transparent Proxying Message-ID: <20040804050728.GA2968@gondor.apana.org.au> References: <20040804032756.GA2388@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040804032756.GA2388@gondor.apana.org.au> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7485 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev Content-Length: 555 Lines: 15 On Wed, Aug 04, 2004 at 01:27:56PM +1000, herbert wrote: > > might be overcome. If you know another way of getting the destination > information then that would be good to (apart from the obvious one > of parsing /proc/net/ip_conntrack :) Never mind, I somehow missed getorigdst in ip_conntrack_core.c which does exactly what I want. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From akpm@osdl.org Tue Aug 3 22:45:03 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 22:45:13 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i745iwhK010025 for ; Tue, 3 Aug 2004 22:45:01 -0700 Received: from bix (build.pdx.osdl.net [172.20.1.2]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i745im116293 for ; Tue, 3 Aug 2004 22:44:49 -0700 Date: Tue, 3 Aug 2004 22:43:19 -0700 From: Andrew Morton To: netdev@oss.sgi.com Subject: Fw: [Bugme-new] [Bug 3151] New: IPSEC triggers "bad: scheduling while atomic!" errors. Message-Id: <20040803224319.50363100.akpm@osdl.org> X-Mailer: Sylpheed version 0.9.7 (GTK+ 1.2.10; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7486 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: akpm@osdl.org Precedence: bulk X-list: netdev Content-Length: 57768 Lines: 1066 Looks like a lock/unlock imbalance somewhere in the 2.6.7 ipsec code. Begin forwarded message: Date: Tue, 3 Aug 2004 13:43:57 -0700 From: bugme-daemon@osdl.org To: bugme-new@lists.osdl.org Subject: [Bugme-new] [Bug 3151] New: IPSEC triggers "bad: scheduling while atomic!" errors. http://bugme.osdl.org/show_bug.cgi?id=3151 Summary: IPSEC triggers "bad: scheduling while atomic!" errors. Kernel Version: 2.6.6 & 2.6.7, earlier kernels untested. Status: NEW Severity: normal Owner: niv@us.ibm.com Submitter: johan.karlberg@gmail.com Distribution: Debian unstable and testing. Hardware Environment: K6-2 400, K6 233 Linux version 2.6.7 (root@scooby) (gcc version 3.3.4 (Debian 1:3.3.4-6)) #2 Sun Aug 1 21:13:50 CEST 2004 BIOS-provided physical RAM map: BIOS-e820: 0000000000000000 - 00000000000a0000 (usable) BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved) BIOS-e820: 0000000000100000 - 000000000fffc000 (usable) BIOS-e820: 000000000fffc000 - 000000000ffff000 (ACPI data) BIOS-e820: 000000000ffff000 - 0000000010000000 (ACPI NVS) BIOS-e820: 00000000ffff0000 - 0000000100000000 (reserved) 255MB LOWMEM available. On node 0 totalpages: 65532 DMA zone: 4096 pages, LIFO batch:1 Normal zone: 61436 pages, LIFO batch:14 HighMem zone: 0 pages, LIFO batch:1 DMI 2.0 present. Built 1 zonelists Kernel command line: auto BOOT_IMAGE=Linux ro root=302 acpi=off No local APIC present or hardware disabled Initializing CPU#0 PID hash table entries: 1024 (order 10: 8192 bytes) Detected 400.859 MHz processor. Using tsc for high-res timesource Console: colour VGA+ 80x25 Memory: 256672k/262128k available (1446k kernel code, 4732k reserved, 757k data, 208k init, 0k highmem) Checking if this processor honours the WP bit even in supervisor mode... Ok. Calibrating delay loop... 792.57 BogoMIPS Security Scaffold v1.0.0 initialized Dentry cache hash table entries: 32768 (order: 5, 131072 bytes) Inode-cache hash table entries: 16384 (order: 4, 65536 bytes) Mount-cache hash table entries: 512 (order: 0, 4096 bytes) CPU: After generic identify, caps: 008021bf 808029bf 00000000 00000000 CPU: After vendor identify, caps: 008021bf 808029bf 00000000 00000000 CPU: L1 I Cache: 32K (32 bytes/line), D cache 32K (32 bytes/line) CPU: After all inits, caps: 008021bf 808029bf 00000000 00000002 CPU: AMD-K6(tm) 3D processor stepping 0c Checking 'hlt' instruction... OK. Checking for popad bug... OK. NET: Registered protocol family 16 EISA bus registered PCI: PCI BIOS revision 2.10 entry at 0xf0720, last bus=1 PCI: Using configuration type 1 mtrr: v2.0 (20020519) ACPI: Subsystem revision 20040326 ACPI: Interpreter disabled. Linux Plug and Play Support v0.97 (c) Adam Belay PnPBIOS: Scanning system for PnP BIOS support... PnPBIOS: Found PnP BIOS installation structure at 0xc00fd220 PnPBIOS: PnP BIOS version 1.0, entry 0xf0000:0xd250, dseg 0xf0000 PnPBIOS: Resource structure does not contain an end tag. PnPBIOS: build_devlist: Node number 0x0 is out of sequence following node 0x0. Aborting. PnPBIOS: 1 node reported by PnP BIOS; 1 recorded by driver PCI: Probing PCI hardware PCI: Probing PCI hardware (bus 00) PCI: Using ALI IRQ Router PCI: Using IRQ router ALI [10b9/1533] at 0000:00:07.0 VFS: Disk quotas dquot_6.5.1 Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) devfs: 2004-01-31 Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x0 Initializing Cryptographic API Activating ISA DMA hang workarounds. isapnp: Scanning for PnP cards... isapnp: No Plug & Play device found Serial: 8250/16550 driver $Revision: 1.90 $ 54 ports, IRQ sharing enabled RAMDISK driver initialized: 16 RAM disks of 8192K size 1024 blocksize Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2 ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx ALI15X3: IDE controller at PCI slot 0000:00:0f.0 ALI15X3: chipset revision 193 ALI15X3: not 100% native mode: will probe irqs later ide0: BM-DMA at 0xd400-0xd407, BIOS settings: hda:DMA, hdb:pio ide1: BM-DMA at 0xd408-0xd40f, BIOS settings: hdc:pio, hdd:pio hda: ST360021A, ATA DISK drive hdb: ST380021A, ATA DISK drive Using anticipatory io scheduler ide0 at 0x1f0-0x1f7,0x3f6 on irq 14 hdc: ST3120023A, ATA DISK drive hdd: ST3120024A, ATA DISK drive ide1 at 0x170-0x177,0x376 on irq 15 hda: max request size: 128KiB hda: 117231408 sectors (60022 MB) w/2048KiB Cache, CHS=65535/16/63, UDMA(33) /dev/ide/host0/bus0/target0/lun0: p1 p2 p3 p4 hdb: max request size: 128KiB hdb: 156301488 sectors (80026 MB) w/2048KiB Cache, CHS=65535/16/63, UDMA(33) /dev/ide/host0/bus0/target1/lun0: p1 hdc: max request size: 128KiB hdc: 234441648 sectors (120034 MB) w/2048KiB Cache, CHS=65535/16/63, UDMA(33) /dev/ide/host0/bus1/target0/lun0: p1 hdd: max request size: 128KiB hdd: 234441648 sectors (120034 MB) w/8192KiB Cache, CHS=65535/16/63, UDMA(33) /dev/ide/host0/bus1/target1/lun0: p1 serio: i8042 AUX port at 0x60,0x64 irq 12 serio: i8042 KBD port at 0x60,0x64 irq 1 input: AT Translated Set 2 keyboard on isa0060/serio0 EISA: Probing bus 0 at eisa0 NET: Registered protocol family 2 IP: routing cache hash table of 2048 buckets, 16Kbytes TCP: Hash tables configured (established 16384 bind 32768) NET: Registered protocol family 8 NET: Registered protocol family 20 kjournald starting. Commit interval 5 seconds EXT3-fs: mounted filesystem with ordered data mode. VFS: Mounted root (ext3 filesystem) readonly. Freeing unused kernel memory: 208k freed NET: Registered protocol family 1 Adding 996020k swap on /dev/hda4. Priority:-1 extents:1 EXT3 FS on hda2, internal journal Real Time Clock Driver v1.12 device-mapper: 4.1.0-ioctl (2003-12-10) initialised: dm@uk.sistina.com kjournald starting. Commit interval 5 seconds EXT3 FS on hda1, internal journal EXT3-fs: mounted filesystem with ordered data mode. kjournald starting. Commit interval 5 seconds EXT3 FS on hda3, internal journal EXT3-fs: mounted filesystem with ordered data mode. kjournald starting. Commit interval 5 seconds EXT3 FS on hdb1, internal journal EXT3-fs: mounted filesystem with ordered data mode. kjournald starting. Commit interval 5 seconds EXT3 FS on hdc1, internal journal EXT3-fs: mounted filesystem with ordered data mode. kjournald starting. Commit interval 5 seconds EXT3 FS on hdd1, internal journal EXT3-fs: mounted filesystem with ordered data mode. Linux agpgart interface v0.100 (c) Dave Jones agpgart: Detected ALi M1541 chipset agpgart: Maximum main memory to use for agp memory: 203M agpgart: AGP aperture is 64M @ 0xe0000000 cpci_hotplug: CompactPCI Hot Plug Core version: 0.2 pci_hotplug: PCI Hot Plug PCI Core version: 0.5 pciehp: acpi_pciehprm:get_device PCI ROOT HID fail=0x1001 shpchp: acpi_shpchprm:get_device PCI ROOT HID fail=0x1001 PCI: Found IRQ 10 for device 0000:00:0d.0 3c59x: Donald Becker and others. www.scyld.com/network/vortex.html 0000:00:0d.0: 3Com PCI 3c905 Boomerang 100baseTx at 0xd800. Vers LK1.1.19 PCI: Setting latency timer of device 0000:00:0d.0 to 64 eth0: Dropping NETIF_F_SG since no checksum feature. usbcore: registered new driver usbfs usbcore: registered new driver hub ohci_hcd: 2004 Feb 02 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI) ohci_hcd: block sizes: ed 64 td 64 USB Universal Host Controller Interface driver v2.2 ttyS0: LSR safety check engaged! ttyS0: LSR safety check engaged! ttyS1: LSR safety check engaged! ttyS1: LSR safety check engaged! NET: Registered protocol family 10 Disabled Privacy Extensions on device c02f0580(lo) IPv6 over IPv4 tunneling driver processor : 0 vendor_id : AuthenticAMD cpu family : 5 model : 8 model name : AMD-K6(tm) 3D processor stepping : 12 cpu MHz : 400.859 cache size : 64 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr mce cx8 pge mmx syscall 3dnow k6_mtrr bogomips : 792.57 Software Environment: options.l2tp.lns: ipcp-accept-local ipcp-accept-remote ms-dns 192.168.0.1 #ms-wins 10.1.96.3 auth crtscts idle 1800 mtu 1400 mru 1400 defaultroute nodetach debug lock proxyarp connect-delay 5000 racoon.conf: # # Simple racoon.conf # # # Please look in /usr/share/doc/racoon/examples for # the example that comes with the source. # # Please read racoon.conf(5) for details, and also # read setkey(8). # # Also read the Linux IPSEC Howto up at # http://www.ipsec-howto.org/t1.html # path pre_shared_key "/etc/racoon/psk.txt"; path certificate "/etc/racoon/certs"; log debug2; listen { isakmp 192.168.0.2; strict_address; } remote anonymous { exchange_mode main; doi ipsec_doi; situation identity_only; generate_policy on; verify_cert off; my_identifier asn1dn; peers_identifier asn1dn; verify_identifier on; certificate_type x509 "scooby_cert.pem" "scooby_key.pem"; proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method rsasig; dh_group modp1024; } } sainfo anonymous { lifetime time 28800 sec; encryption_algorithm 3des ; authentication_algorithm hmac_md5; compression_algorithm deflate ; } portion of syslog preceeding the problem, and including the first of the error message. messages and trace seems to be identical and repeating indefinitly.: Aug 3 21:55:43 scooby pppd[3975]: sent [LCP EchoReq id=0x70 magic=0x3e763ee9] Aug 3 21:55:43 scooby pppd[3975]: rcvd [LCP EchoRep id=0x70 magic=0x8da75c9] Aug 3 21:56:13 scooby pppd[3975]: sent [LCP EchoReq id=0x71 magic=0x3e763ee9] Aug 3 21:56:13 scooby pppd[3975]: rcvd [LCP EchoRep id=0x71 magic=0x8da75c9] Aug 3 21:56:41 scooby l2tpd[1194]: check_control: control, cid = 0, Ns = 4, Nr = 59 Aug 3 21:56:43 scooby pppd[3975]: sent [LCP EchoReq id=0x72 magic=0x3e763ee9] Aug 3 21:56:43 scooby pppd[3975]: rcvd [LCP EchoRep id=0x72 magic=0x8da75c9] Aug 3 21:57:13 scooby pppd[3975]: sent [LCP EchoReq id=0x73 magic=0x3e763ee9] Aug 3 21:57:13 scooby pppd[3975]: rcvd [LCP EchoRep id=0x73 magic=0x8da75c9] Aug 3 21:57:41 scooby l2tpd[1194]: check_control: control, cid = 0, Ns = 4, Nr = 60 Aug 3 21:57:43 scooby pppd[3975]: sent [LCP EchoReq id=0x74 magic=0x3e763ee9] Aug 3 21:57:43 scooby pppd[3975]: rcvd [LCP EchoRep id=0x74 magic=0x8da75c9] Aug 3 21:58:13 scooby pppd[3975]: sent [LCP EchoReq id=0x75 magic=0x3e763ee9] Aug 3 21:58:13 scooby pppd[3975]: rcvd [LCP EchoRep id=0x75 magic=0x8da75c9] Aug 3 21:58:41 scooby l2tpd[1194]: check_control: control, cid = 0, Ns = 4, Nr = 61 Aug 3 21:58:43 scooby pppd[3975]: sent [LCP EchoReq id=0x76 magic=0x3e763ee9] Aug 3 21:58:43 scooby pppd[3975]: rcvd [LCP EchoRep id=0x76 magic=0x8da75c9] Aug 3 21:59:13 scooby pppd[3975]: sent [LCP EchoReq id=0x77 magic=0x3e763ee9] Aug 3 21:59:13 scooby racoon: DEBUG: === Aug 3 21:59:13 scooby racoon: DEBUG: 1116 bytes message received from 192.168.0.100[500] to 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08102001 d48272e2 0000045c 7bbec0a2 280a7f91 c7d45818 29e7efa1 f5edb562 25e2d94d 035809d3 531a5dc4 a5788256 1fa9bd30 4caa0e06 4da593f9 b8cfa9f4 571ee579 40682f9c fd676bbf 694c63a1 16e55cb6 64d6d491 1080f6fd 7ac0103f ce9dd9c1 27838b58 4a77ee04 e1ebd209 b386c792 9f5a405c 324ade2f ea9361b5 5e59c63b 7a835a2a 3e43860d 905d6c7e f59bbb9b 3926967b d153ffc2 e8f44a48 60dc16fa f1082e22 2f8f1e84 027a387d 16657978 147f3e76 e3c7cf5e 23265899 d7f7d43b 8f44ca43 7e451d4c 4f7f81fe 26aa518f 7f60b88f 2aecd19a 24fd9724 1a88c259 0497c0a7 bbf50cd5 1608ae47 fcdfe38e eb80c706 271664fc 07e43e47 2efde0d2 231359bf 7a924935 c0022be9 90824d55 fea279bc 14957031 db26a92e bfe71395 59ce5d44 37c13bbb dbec384d 06cb9741 3eed1116 ce582060 48360835 5ff9b961 a1db5978 bbc0649a 62241d36 f53ba9b9 23217d0f 6f4aea50 b4fccec2 da4da175 b75dbd8f f5dd5ba3 700869be a8c49a5d dc7452c6 9952c1d4 7605a19b 940ecd50 d217d398 4673a9af 7e70f403 90c743bc ee2754b2 2a6cc5b4 fd809cb1 ab569fce 14fe1 Aug 3 21:59:13 scooby racoon: DEBUG: compute IV for phase2 Aug 3 21:59:13 scooby racoon: DEBUG: phase1 last IV: Aug 3 21:59:13 scooby racoon: DEBUG: d589b86f 956f2b07 d48272e2 Aug 3 21:59:13 scooby racoon: DEBUG: hash(sha1) Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: phase2 IV computed: Aug 3 21:59:13 scooby racoon: DEBUG: c975fe48 1f39bbb6 Aug 3 21:59:13 scooby racoon: DEBUG: === Aug 3 21:59:13 scooby racoon: INFO: respond new phase 2 negotiation: 192.168.0.2[0]<=>192.168.0.100[0] Aug 3 21:59:13 scooby racoon: DEBUG: begin decryption. Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: IV was saved for next processing: Aug 3 21:59:13 scooby racoon: DEBUG: fb5332b8 6d9c5cbf Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: with key: Aug 3 21:59:13 scooby racoon: DEBUG: e0814bd6 704b9d63 54bf6496 64f8abdb b5e41d57 e08d61d9 Aug 3 21:59:13 scooby racoon: DEBUG: decrypted payload by IV: Aug 3 21:59:13 scooby racoon: DEBUG: fb5332b8 6d9c5cbf Aug 3 21:59:13 scooby racoon: DEBUG: decrypted payload, but not trimed. Aug 3 21:59:13 scooby racoon: DEBUG: 01000018 416fc129 f6e56e35 38696b7f 077c02b3 99fb3621 0a0003f4 00000001 00000001 0200005c 01030402 c072ec18 03000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 00000028 02030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 02020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000030 02030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 03020401 c072ec18 00000028 01020000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 02000030 03030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 04020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 04030401 7fc0da59 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 05020 Aug 3 21:59:13 scooby racoon: DEBUG: padding len=1 Aug 3 21:59:13 scooby racoon: DEBUG: skip to trim padding. Aug 3 21:59:13 scooby racoon: DEBUG: decrypted. Aug 3 21:59:13 scooby pppd[3975]: rcvd [LCP EchoRep id=0x77 magic=0x8da75c9] Aug 3 21:59:13 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08102001 d48272e2 0000045c 01000018 416fc129 f6e56e35 38696b7f 077c02b3 99fb3621 0a0003f4 00000001 00000001 0200005c 01030402 c072ec18 03000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 00000028 02030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 02020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000030 02030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 03020401 c072ec18 00000028 01020000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 02000030 03030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 04020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 04030401 7fc0da59 00000028 01030000 80010001 00020004 00000 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=8(hash) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=1(sa) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=10(nonce) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=5(id) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=5(id) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: received IDci2: Aug 3 21:59:13 scooby racoon: DEBUG: 011106a5 c0a80064 Aug 3 21:59:13 scooby racoon: DEBUG: received IDcr2: Aug 3 21:59:13 scooby racoon: DEBUG: 01110000 c0a80002 Aug 3 21:59:13 scooby racoon: DEBUG: HASH(1) validate: Aug 3 21:59:13 scooby racoon: DEBUG: 416fc129 f6e56e35 38696b7f 077c02b3 99fb3621 Aug 3 21:59:13 scooby racoon: DEBUG: HASH with: Aug 3 21:59:13 scooby racoon: DEBUG: d48272e2 0a0003f4 00000001 00000001 0200005c 01030402 c072ec18 03000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 00000028 02030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 02020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000030 02030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 03020401 c072ec18 00000028 01020000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 02000030 03030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 04020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 04030401 7fc0da59 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 05020401 c072ec18 00000028 01020000 80010001 00020 Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby racoon: DEBUG: HASH computed: Aug 3 21:59:13 scooby racoon: DEBUG: 416fc129 f6e56e35 38696b7f 077c02b3 99fb3621 Aug 3 21:59:13 scooby racoon: DEBUG: anonymous sainfo selected. Aug 3 21:59:13 scooby racoon: DEBUG: get sa info: anonymous Aug 3 21:59:13 scooby racoon: DEBUG: get a src address from ID payload 192.168.0.100[1701] prefixlen=32 ul_proto=17 Aug 3 21:59:13 scooby racoon: DEBUG: get dst address from ID payload 192.168.0.2[0] prefixlen=32 ul_proto=17 Aug 3 21:59:13 scooby racoon: DEBUG: sub:0xbffff8e0: 192.168.0.100/32[1701] 192.168.0.2/32[0] proto=udp dir=in Aug 3 21:59:13 scooby racoon: DEBUG: db: 0x80aa020: 192.168.0.100/32[1701] 192.168.0.2/32[0] proto=udp dir=in Aug 3 21:59:13 scooby racoon: DEBUG: 0xbffff8e0 masked with /32: 192.168.0.100[1701] Aug 3 21:59:13 scooby racoon: DEBUG: 0x80aa020 masked with /32: 192.168.0.100[1701] Aug 3 21:59:13 scooby racoon: DEBUG: 0xbffff8e0 masked with /32: 192.168.0.2[0] Aug 3 21:59:13 scooby racoon: DEBUG: 0x80aa020 masked with /32: 192.168.0.2[0] Aug 3 21:59:13 scooby racoon: DEBUG: sub:0xbffff8e0: 192.168.0.2/32[0] 192.168.0.100/32[1701] proto=udp dir=out Aug 3 21:59:13 scooby racoon: DEBUG: db: 0x80aa020: 192.168.0.100/32[1701] 192.168.0.2/32[0] proto=udp dir=in Aug 3 21:59:13 scooby racoon: DEBUG: sub:0xbffff8e0: 192.168.0.2/32[0] 192.168.0.100/32[1701] proto=udp dir=out Aug 3 21:59:13 scooby racoon: DEBUG: db: 0x80aa258: 192.168.0.2/32[0] 192.168.0.100/32[1701] proto=udp dir=out Aug 3 21:59:13 scooby racoon: DEBUG: 0xbffff8e0 masked with /32: 192.168.0.2[0] Aug 3 21:59:13 scooby racoon: DEBUG: 0x80aa258 masked with /32: 192.168.0.2[0] Aug 3 21:59:13 scooby racoon: DEBUG: 0xbffff8e0 masked with /32: 192.168.0.100[1701] Aug 3 21:59:13 scooby racoon: DEBUG: 0x80aa258 masked with /32: 192.168.0.100[1701] Aug 3 21:59:13 scooby racoon: DEBUG: suitable SP found:192.168.0.2/32[0] 192.168.0.100/32[1701] proto=udp dir=out Aug 3 21:59:13 scooby racoon: DEBUG: (proto_id=ESP spisize=4 spi=00000000 spi_p=00000000 encmode=Transport reqid=0:0) Aug 3 21:59:13 scooby racoon: DEBUG: (trns_id=3DES encklen=0 authtype=hmac-md5) Aug 3 21:59:13 scooby racoon: DEBUG: total SA len=1008 Aug 3 21:59:13 scooby racoon: DEBUG: 00000001 00000001 0200005c 01030402 c072ec18 03000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 00000028 02030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 02020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000030 02030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 03020401 c072ec18 00000028 01020000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 02000030 03030401 7fc0da59 00000024 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 02000034 04020401 c072ec18 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 04030401 7fc0da59 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050002 02000034 05020401 c072ec18 00000028 01020000 80010001 00020004 00000e10 80010 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=2(prop) Aug 3 21:59:13 scooby last message repeated 17 times Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: proposal #1 len=92 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: transform #2 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #2 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #2 len=48 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=36 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: proposal #3 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: proposal #3 len=48 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=36 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: proposal #4 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #4 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #5 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: proposal #5 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: proposal #6 len=92 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: transform #2 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #7 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #7 len=48 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=36 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: proposal #8 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: proposal #8 len=48 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=36 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: proposal #9 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #9 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: proposal #10 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: proposal #10 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: pair 1: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80abf18: next=(nil) tnext=0x80a9858 Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a9858: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #1: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 2: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a77e0: next=0x80a5bd0 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a5bd0: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #2: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 3: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a8688: next=0x80a8478 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a8478: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #3: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 4: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a8490: next=0x80a63d0 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a63d0: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #4: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 5: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a63e8: next=0x80a8f50 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a8f50: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #5: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 6: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a8f68: next=(nil) tnext=0x80a9890 Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a9890: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #6: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 7: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a98a8: next=0x80a98c0 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a98c0: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #7: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 8: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80ac080: next=0x80ac098 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80ac098: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #8: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 9: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80ac0b0: next=0x80abf70 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80abf70: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #9: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: pair 10: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80abf88: next=0x80abfa0 tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: 0x80abfa0: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #10: 2 transform Aug 3 21:59:13 scooby racoon: DEBUG: begin compare proposals. Aug 3 21:59:13 scooby racoon: DEBUG: pair[1]: 0x80abf18 Aug 3 21:59:13 scooby racoon: DEBUG: 0x80abf18: next=(nil) tnext=0x80a9858 Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a9858: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: prop#=1 prot-id=ESP spi-size=4 #trns=2 trns#=1 trns-id=3DES Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: prop#=1 prot-id=ESP spi-size=4 #trns=2 trns#=2 trns-id=3DES Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-sha Aug 3 21:59:13 scooby racoon: DEBUG: peer's single bundle: Aug 3 21:59:13 scooby racoon: DEBUG: (proto_id=ESP spisize=4 spi=c072ec18 spi_p=00000000 encmode=Transport reqid=0:0) Aug 3 21:59:13 scooby racoon: DEBUG: (trns_id=3DES encklen=0 authtype=hmac-md5) Aug 3 21:59:13 scooby racoon: DEBUG: (trns_id=3DES encklen=0 authtype=hmac-sha) Aug 3 21:59:13 scooby racoon: DEBUG: my single bundle: Aug 3 21:59:13 scooby racoon: DEBUG: (proto_id=ESP spisize=4 spi=00000000 spi_p=00000000 encmode=Transport reqid=0:0) Aug 3 21:59:13 scooby racoon: DEBUG: (trns_id=3DES encklen=0 authtype=hmac-md5) Aug 3 21:59:13 scooby racoon: DEBUG: matched Aug 3 21:59:13 scooby racoon: DEBUG: === Aug 3 21:59:13 scooby racoon: DEBUG: call pfkey_send_getspi Aug 3 21:59:13 scooby racoon: DEBUG: pfkey GETSPI sent: ESP/Transport 192.168.0.100->192.168.0.2 Aug 3 21:59:13 scooby racoon: DEBUG: pfkey getspi sent. Aug 3 21:59:13 scooby racoon: DEBUG: get pfkey GETSPI message Aug 3 21:59:13 scooby racoon: DEBUG2: 02010003 18000000 57032238 6e0f0000 02000100 0e66db7c 00000000 00000000 04000300 00000000 00000000 00000000 1e000000 00000000 00000000 00000000 04000400 00000000 00000000 00000000 00000000 00000000 00000000 00000000 04000200 00000000 00000000 00000000 91ee0f41 00000000 00000000 00000000 03000500 00200000 02000000 c0a80064 00000000 00000000 03000600 00200000 02000000 c0a80002 00000000 00000000 02001300 01000000 00000000 00000000 Aug 3 21:59:13 scooby racoon: DEBUG: pfkey GETSPI succeeded: ESP/Transport 192.168.0.100->192.168.0.2 spi=241621884(0xe66db7c) Aug 3 21:59:13 scooby racoon: DEBUG: total SA len=60 Aug 3 21:59:13 scooby racoon: DEBUG: 00000001 00000001 00000034 01030401 00000000 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=2(prop) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: proposal #1 len=52 Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=3(trns) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: transform #1 len=40 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=seconds Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Type, flag=0x8000, lorv=kilobytes Aug 3 21:59:13 scooby racoon: DEBUG: type=SA Life Duration, flag=0x0000, lorv=4 Aug 3 21:59:13 scooby racoon: DEBUG: type=Encryption Mode, flag=0x8000, lorv=Transport Aug 3 21:59:13 scooby racoon: DEBUG: type=Authentication Algorithm, flag=0x8000, lorv=hmac-md5 Aug 3 21:59:13 scooby racoon: DEBUG: pair 1: Aug 3 21:59:13 scooby racoon: DEBUG: 0x80a77e0: next=(nil) tnext=(nil) Aug 3 21:59:13 scooby racoon: DEBUG: proposal #1: 1 transform Aug 3 21:59:13 scooby racoon: DEBUG: add payload of len 60, next type 10 Aug 3 21:59:13 scooby racoon: DEBUG: add payload of len 16, next type 5 Aug 3 21:59:13 scooby racoon: DEBUG: add payload of len 8, next type 5 Aug 3 21:59:13 scooby racoon: DEBUG: add payload of len 8, next type 0 Aug 3 21:59:13 scooby racoon: DEBUG: HASH with: Aug 3 21:59:13 scooby racoon: DEBUG: d48272e2 3ea5d7bf 02b62d71 b37efd97 30013a15 020cfc8c 0a000040 00000001 00000001 00000034 01030401 0e66db7c 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 05000014 d26aff15 3d0b02f5 67c81d7f a4fc003e 0500000c 011106a5 c0a80064 0000000c 01110000 c0a80002 Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby racoon: DEBUG: HASH computed: Aug 3 21:59:13 scooby racoon: DEBUG: 05a385f9 7d0d36c4 e5b74449 7fed7dfa 70415905 Aug 3 21:59:13 scooby racoon: DEBUG: add payload of len 20, next type 1 Aug 3 21:59:13 scooby racoon: DEBUG: begin encryption. Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: pad length = 4 Aug 3 21:59:13 scooby racoon: DEBUG: 01000018 05a385f9 7d0d36c4 e5b74449 7fed7dfa 70415905 0a000040 00000001 00000001 00000034 01030401 0e66db7c 00000028 01030000 80010001 00020004 00000e10 80010002 00020004 0003d090 80040002 80050001 05000014 d26aff15 3d0b02f5 67c81d7f a4fc003e 0500000c 011106a5 c0a80064 0000000c 01110000 c0a80002 62c4d403 Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: with key: Aug 3 21:59:13 scooby racoon: DEBUG: e0814bd6 704b9d63 54bf6496 64f8abdb b5e41d57 e08d61d9 Aug 3 21:59:13 scooby racoon: DEBUG: encrypted payload by IV: Aug 3 21:59:13 scooby racoon: DEBUG: 02132a91 a14258ce Aug 3 21:59:13 scooby racoon: DEBUG: save IV for next: Aug 3 21:59:13 scooby racoon: DEBUG: 02132a91 a14258ce Aug 3 21:59:13 scooby racoon: DEBUG: encrypted. Aug 3 21:59:13 scooby racoon: DEBUG: 164 bytes from 192.168.0.2[500] to 192.168.0.100[500] Aug 3 21:59:13 scooby racoon: DEBUG: sockname 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: send packet from 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: send packet to 192.168.0.100[500] Aug 3 21:59:13 scooby racoon: DEBUG: src4 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: dst4 192.168.0.100[500] Aug 3 21:59:13 scooby racoon: DEBUG: 1 times of 164 bytes message will be sent to 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08102001 d48272e2 000000a4 bb97981a 572e0599 8d18a65f 8436564b 4288fad8 c46126d3 f31eae1f f152d8d4 99b888cb c4bc1cdb 0601e679 cb4c5007 949b0461 106b3000 1b64661f cb7fd72f 8e1c6628 4b79ab0e 2dc7f80f 8ac126b4 4af20066 fcd13a14 29461c26 757feb7d 0c4712ee f45d2415 4d4b870b 5f22cd4c 11badbb0 0250889e b0cdb938 9517caad 02132a91 a14258ce Aug 3 21:59:13 scooby racoon: DEBUG: resend phase2 packet e439faa2df4fcd2d:6f7069be243c45c7:0000d482 Aug 3 21:59:13 scooby racoon: DEBUG: === Aug 3 21:59:13 scooby racoon: DEBUG: 52 bytes message received from 192.168.0.100[500] to 192.168.0.2[500] Aug 3 21:59:13 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08102001 d48272e2 00000034 b1c1d0ee 3169ba37 fbfbaed2 6f47f81a a507e835 fb9bffb6 Aug 3 21:59:13 scooby racoon: DEBUG: begin decryption. Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: IV was saved for next processing: Aug 3 21:59:13 scooby racoon: DEBUG: a507e835 fb9bffb6 Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: with key: Aug 3 21:59:13 scooby racoon: DEBUG: e0814bd6 704b9d63 54bf6496 64f8abdb b5e41d57 e08d61d9 Aug 3 21:59:13 scooby racoon: DEBUG: decrypted payload by IV: Aug 3 21:59:13 scooby racoon: DEBUG: a507e835 fb9bffb6 Aug 3 21:59:13 scooby racoon: DEBUG: decrypted payload, but not trimed. Aug 3 21:59:13 scooby racoon: DEBUG: 00000018 b33064f9 a01ad7f1 d06a8614 7b1f4381 95af180f Aug 3 21:59:13 scooby racoon: DEBUG: padding len=16 Aug 3 21:59:13 scooby racoon: DEBUG: skip to trim padding. Aug 3 21:59:13 scooby racoon: DEBUG: decrypted. Aug 3 21:59:13 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08102001 d48272e2 00000034 00000018 b33064f9 a01ad7f1 d06a8614 7b1f4381 95af180f Aug 3 21:59:13 scooby racoon: DEBUG: begin. Aug 3 21:59:13 scooby racoon: DEBUG: seen nptype=8(hash) Aug 3 21:59:13 scooby racoon: DEBUG: succeed. Aug 3 21:59:13 scooby racoon: DEBUG: HASH(3) validate: Aug 3 21:59:13 scooby racoon: DEBUG: b33064f9 a01ad7f1 d06a8614 7b1f4381 95af180f Aug 3 21:59:13 scooby racoon: DEBUG: HASH with: Aug 3 21:59:13 scooby racoon: DEBUG: 00d48272 e23ea5d7 bf02b62d 71b37efd 9730013a 15020cfc 8cd26aff 153d0b02 f567c81d 7fa4fc00 3e Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby racoon: DEBUG: HASH computed: Aug 3 21:59:13 scooby racoon: DEBUG: b33064f9 a01ad7f1 d06a8614 7b1f4381 95af180f Aug 3 21:59:13 scooby racoon: DEBUG: === Aug 3 21:59:13 scooby racoon: DEBUG: KEYMAT compute with Aug 3 21:59:13 scooby racoon: DEBUG: 030e66db 7c3ea5d7 bf02b62d 71b37efd 9730013a 15020cfc 8cd26aff 153d0b02 f567c81d 7fa4fc00 3e Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_md5) Aug 3 21:59:13 scooby racoon: DEBUG: encklen=192 authklen=128 Aug 3 21:59:13 scooby racoon: DEBUG: generating 640 bits of key (dupkeymat=4) Aug 3 21:59:13 scooby racoon: DEBUG: generating K1...K4 for KEYMAT. Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby last message repeated 2 times Aug 3 21:59:13 scooby racoon: DEBUG: 44fe759a 613f2253 f07f473f b69bd9a0 636e32e3 7bab6b95 05d2e75c 32fc8f2a 079f2ee2 7dfd1a97 409c333b 53295a34 2b0cfb11 d987fbac caddcd52 9025d3b5 3fe17e0c 8b3218ff 19e83f37 a10feb81 Aug 3 21:59:13 scooby racoon: DEBUG: KEYMAT compute with Aug 3 21:59:13 scooby racoon: DEBUG: 03c072ec 183ea5d7 bf02b62d 71b37efd 9730013a 15020cfc 8cd26aff 153d0b02 f567c81d 7fa4fc00 3e Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_md5) Aug 3 21:59:13 scooby racoon: DEBUG: encklen=192 authklen=128 Aug 3 21:59:13 scooby racoon: DEBUG: generating 640 bits of key (dupkeymat=4) Aug 3 21:59:13 scooby racoon: DEBUG: generating K1...K4 for KEYMAT. Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:13 scooby last message repeated 2 times Aug 3 21:59:13 scooby racoon: DEBUG: 0c152d12 073ffb51 cad0263b b1153c91 37785e6a c2284721 f1f131d7 b2623e0e 779628b7 cef91303 e384cded 03335cce 8d198749 07acb210 d98810ed 7266b191 4dbbe9aa f5be72f1 6e5f6e3b 10cd8f41 Aug 3 21:59:13 scooby racoon: DEBUG: KEYMAT computed. Aug 3 21:59:13 scooby racoon: DEBUG: call pk_sendupdate Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_md5) Aug 3 21:59:13 scooby racoon: DEBUG: call pfkey_send_update_nat Aug 3 21:59:13 scooby racoon: DEBUG: pfkey update sent. Aug 3 21:59:13 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:13 scooby racoon: DEBUG: hmac(hmac_md5) Aug 3 21:59:13 scooby racoon: DEBUG: call pfkey_send_add_nat Aug 3 21:59:14 scooby racoon: DEBUG: pfkey add sent. Aug 3 21:59:14 scooby racoon: DEBUG: === Aug 3 21:59:14 scooby racoon: DEBUG: 68 bytes message received from 192.168.0.100[500] to 192.168.0.2[500] Aug 3 21:59:14 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08100501 524480bd 00000044 204abdb1 76d81c76 cef865ed e4062372 2b7a6678 76e6a3e7 5f1db06a 5605f5e8 4d0baf02 1c67fefc Aug 3 21:59:14 scooby racoon: DEBUG: receive Information. Aug 3 21:59:14 scooby racoon: DEBUG: compute IV for phase2 Aug 3 21:59:14 scooby racoon: DEBUG: phase1 last IV: Aug 3 21:59:14 scooby racoon: DEBUG: d589b86f 956f2b07 524480bd Aug 3 21:59:14 scooby racoon: DEBUG: hash(sha1) Aug 3 21:59:14 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:14 scooby racoon: DEBUG: phase2 IV computed: Aug 3 21:59:14 scooby racoon: DEBUG: e26970dd b85e38d4 Aug 3 21:59:14 scooby racoon: DEBUG: begin decryption. Aug 3 21:59:14 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:14 scooby racoon: DEBUG: IV was saved for next processing: Aug 3 21:59:14 scooby racoon: DEBUG: 4d0baf02 1c67fefc Aug 3 21:59:14 scooby racoon: DEBUG: encription(3des) Aug 3 21:59:14 scooby racoon: DEBUG: with key: Aug 3 21:59:14 scooby racoon: DEBUG: e0814bd6 704b9d63 54bf6496 64f8abdb b5e41d57 e08d61d9 Aug 3 21:59:14 scooby racoon: DEBUG: decrypted payload by IV: Aug 3 21:59:14 scooby racoon: DEBUG: 4d0baf02 1c67fefc Aug 3 21:59:14 scooby racoon: DEBUG: decrypted payload, but not trimed. Aug 3 21:59:14 scooby racoon: DEBUG: 0c000018 25e0d47f 66545c70 ef1396c8 a53f2dbd 79b5364b 00000010 00000001 03040001 55b1fcde Aug 3 21:59:14 scooby racoon: DEBUG: padding len=223 Aug 3 21:59:14 scooby racoon: DEBUG: skip to trim padding. Aug 3 21:59:14 scooby racoon: DEBUG: decrypted. Aug 3 21:59:14 scooby racoon: DEBUG: e439faa2 df4fcd2d 6f7069be 243c45c7 08100501 524480bd 00000044 0c000018 25e0d47f 66545c70 ef1396c8 a53f2dbd 79b5364b 00000010 00000001 03040001 55b1fcde Aug 3 21:59:14 scooby racoon: DEBUG: HASH with: Aug 3 21:59:14 scooby racoon: DEBUG: 524480bd 00000010 00000001 03040001 55b1fcde Aug 3 21:59:14 scooby racoon: DEBUG: hmac(hmac_sha1) Aug 3 21:59:14 scooby racoon: DEBUG: HASH computed: Aug 3 21:59:14 scooby racoon: DEBUG: 25e0d47f 66545c70 ef1396c8 a53f2dbd 79b5364b Aug 3 21:59:14 scooby racoon: DEBUG: hash validated. Aug 3 21:59:14 scooby racoon: DEBUG: begin. Aug 3 21:59:14 scooby racoon: DEBUG: seen nptype=8(hash) Aug 3 21:59:14 scooby racoon: DEBUG: seen nptype=12(delete) Aug 3 21:59:14 scooby racoon: DEBUG: succeed. Aug 3 21:59:14 scooby racoon: DEBUG: call pfkey_send_dump Aug 3 21:59:14 scooby racoon: DEBUG: check spi(packet)=1437727966 spi(db)=3228757016. Aug 3 21:59:14 scooby racoon: DEBUG: check spi(packet)=1437727966 spi(db)=1437727966. Aug 3 21:59:14 scooby racoon: INFO: purged IPsec-SA proto_id=ESP spi=1437727966. Aug 3 21:59:14 scooby racoon: DEBUG: purged SAs. Aug 3 21:59:14 scooby racoon: DEBUG: get pfkey UPDATE message Aug 3 21:59:14 scooby racoon: DEBUG2: 02020003 1b000000 57032238 6e0f0000 02000100 0e66db7c 04010203 00000000 04000300 00000000 00000000 00000000 100e0000 00000000 00000000 00000000 04000400 00000000 00000000 00000000 400b0000 00000000 00000000 00000000 04000200 00000000 00000000 00000000 91ee0f41 00000000 00000000 00000000 03000500 00200000 02000000 c0a80064 00000000 00000000 03000600 00200000 02000000 c0a80002 00000000 00000000 03000700 ff000000 02000000 00000000 00000000 00000000 02001300 01000000 00000000 00000000 Aug 3 21:59:14 scooby racoon: DEBUG: pfkey UPDATE succeeded: ESP/Transport 192.168.0.100->192.168.0.2 spi=241621884(0xe66db7c) Aug 3 21:59:14 scooby racoon: INFO: IPsec-SA established: ESP/Transport 192.168.0.100->192.168.0.2 spi=241621884(0xe66db7c) Aug 3 21:59:14 scooby racoon: DEBUG: === Aug 3 21:59:14 scooby racoon: DEBUG: get pfkey ADD message Aug 3 21:59:14 scooby racoon: DEBUG2: 02030003 1b000000 57032238 6e0f0000 02000100 c072ec18 04010203 00000000 04000300 00000000 00000000 00000000 100e0000 00000000 00000000 00000000 04000400 00000000 00000000 00000000 400b0000 00000000 00000000 00000000 04000200 00000000 00000000 00000000 92ee0f41 00000000 00000000 00000000 03000500 00200000 02000000 c0a80002 00000000 00000000 03000600 00200000 02000000 c0a80064 00000000 00000000 03000700 ff000000 02000000 00000000 00000000 00000000 02001300 01000000 00000000 00000000 Aug 3 21:59:14 scooby racoon: INFO: IPsec-SA established: ESP/Transport 192.168.0.2->192.168.0.100 spi=3228757016(0xc072ec18) Aug 3 21:59:14 scooby racoon: DEBUG: === Aug 3 21:59:14 scooby racoon: DEBUG: get pfkey DELETE message Aug 3 21:59:14 scooby racoon: DEBUG2: 02040003 0a000000 00000000 6e0f0000 02000100 55b1fcde 00000000 00000000 03000500 ff200000 02000000 c0a80002 00000000 00000000 03000600 ff200000 02000000 c0a80064 00000000 00000000 Aug 3 21:59:14 scooby racoon: DEBUG: DELETE message is not interesting because the message was originated by me. Aug 3 21:59:40 scooby racoon: DEBUG: get pfkey EXPIRE message Aug 3 21:59:40 scooby racoon: DEBUG2: 02080003 17000000 00000000 00000000 02000100 081bb4e6 04030203 00000000 04000300 00000000 00000000 00000000 100e0000 00000000 00000000 00000000 04000200 e9010000 2a880100 00000000 9ce00f41 00000000 9de00f41 00000000 03000500 00200000 02000000 c0a80064 00000000 00000000 03000600 00200000 02000000 c0a80002 00000000 00000000 03000700 ff000000 02000000 00000000 00000000 00000000 02001300 01000000 00000000 00000000 Aug 3 21:59:40 scooby racoon: INFO: IPsec-SA expired: ESP/Transport 192.168.0.100->192.168.0.2 spi=136033510(0x81bb4e6) Aug 3 21:59:40 scooby racoon: DEBUG: no such a SA found: ESP/Transport 192.168.0.100->192.168.0.2 spi=136033510(0x81bb4e6) Aug 3 21:59:41 scooby l2tpd[1194]: check_control: control, cid = 0, Ns = 4, Nr = 62 Aug 3 21:59:41 scooby kernel: bad: scheduling while atomic! Aug 3 21:59:41 scooby kernel: [schedule+60/1002] schedule+0x3c/0x3ea Aug 3 21:59:41 scooby kernel: [default_idle+0/38] default_idle+0x0/0x26 Aug 3 21:59:41 scooby kernel: [cpu_idle+48/50] cpu_idle+0x30/0x32 Aug 3 21:59:41 scooby kernel: [start_kernel+388/392] start_kernel+0x184/0x188 Aug 3 21:59:41 scooby kernel: Aug 3 21:59:41 scooby kernel: bad: scheduling while atomic! Aug 3 21:59:41 scooby kernel: [schedule+60/1002] schedule+0x3c/0x3ea Aug 3 21:59:41 scooby kernel: [default_idle+0/38] default_idle+0x0/0x26 Aug 3 21:59:41 scooby kernel: [cpu_idle+48/50] cpu_idle+0x30/0x32 Aug 3 21:59:41 scooby kernel: [start_kernel+388/392] start_kernel+0x184/0x188 Aug 3 21:59:41 scooby kernel: Problem Description: If I connect one of my l2tp over ipsec (ipsec in transport mode) clients (Up to date Windows XP, using x509 auth), connection works, but after some time passes (anything from minutes to hours, doesn't appear to be affected by traffic amount through the tunnel) Steps to reproduce: Simply start the XP vpn connection and wait. Feel free to contact me for additional information. ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. From acid@krezus.e-wro.net Wed Aug 4 02:14:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 02:14:26 -0700 (PDT) Received: from krezus.e-wro.net (krezus.e-wro.net [82.143.159.250]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i749EKWA019030 for ; Wed, 4 Aug 2004 02:14:21 -0700 Received: from krezus.e-wro.net (localhost [127.0.0.1]) by krezus.e-wro.net (8.12.10/8.12.10) with ESMTP id i749E4OC000414; Wed, 4 Aug 2004 11:14:04 +0200 Received: (from acid@localhost) by krezus.e-wro.net (8.12.10/8.12.10/Submit) id i749E261000413; Wed, 4 Aug 2004 11:14:02 +0200 Date: Wed, 4 Aug 2004 11:14:02 +0200 From: Tomasz Paszkowski To: Patrick McHardy Cc: "David S. Miller" , hadi@cyberus.ca, devik@cdi.cz, netdev@oss.sgi.com Subject: Re: Fw: hfsc and huge set of rules Message-ID: <20040804091402.GB30364@krezus.e-wro.net> References: <20040729211844.61e8d328.davem@redhat.com> <410A2449.3020701@trash.net> <20040730110815.GA7812@krezus.e-wro.net> <410D2E30.2050104@trash.net> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="xXmbgvnjoT4axfJE" Content-Disposition: inline In-Reply-To: <410D2E30.2050104@trash.net> User-Agent: Mutt/1.4i X-NCC-RegID: pl.e-wro X-Scanned-By: MIMEDefang 2.42 X-archive-position: 7487 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: tomasz.paszkowski@e-wro.pl Precedence: bulk X-list: netdev Content-Length: 1063 Lines: 43 --xXmbgvnjoT4axfJE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sun, Aug 01, 2004 at 07:53:52PM +0200, Patrick McHardy wrote: > I've done some profiles with your script (on an old kernel without > the lockless loopback patch), qdisc_destroy takes up 89% of the time > when destroying the qdiscs. >=20 > These are the exact results: >=20 > - execute the script on kernel using double-linked lists for=20 > dev->qdisc_list: >=20 > time: > real 0m51.804s > user 0m2.286s > sys 0m48.795s The results are great ! Thanks ! I'am using hfsc with 2.4.x kernel so there= will be no problem with lockless loopback patch ;] So could you please send me a patch ? --=20 Tomasz Paszkowski --xXmbgvnjoT4axfJE Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQFBEKjacNXOL98XeysRAsD+AJ9N8kuFRVVGPhwcmOX3zzoIc7PcBwCePN4Y KtoRRqExgx+zRZrwtwcD51o= =0LUN -----END PGP SIGNATURE----- --xXmbgvnjoT4axfJE-- From herbert@gondor.apana.org.au Wed Aug 4 02:56:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 02:56:29 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i749uK0M026268 for ; Wed, 4 Aug 2004 02:56:21 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BsIV1-0007it-00; Wed, 04 Aug 2004 19:55:55 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BsIUx-0001As-00; Wed, 04 Aug 2004 19:55:51 +1000 From: Herbert Xu To: akpm@osdl.org (Andrew Morton) Subject: Re: Fw: [Bugme-new] [Bug 3151] New: IPSEC triggers "bad: scheduling while atomic!" errors. Cc: netdev@oss.sgi.com Organization: Core In-Reply-To: <20040803224319.50363100.akpm@osdl.org> X-Newsgroups: apana.lists.os.linux.netdev User-Agent: tin/1.7.4-20040225 ("Benbecula") (UNIX) (Linux/2.4.26-1-686-smp (i686)) Message-Id: Date: Wed, 04 Aug 2004 19:55:51 +1000 X-archive-position: 7488 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev Content-Length: 639 Lines: 18 Andrew Morton wrote: > > Looks like a lock/unlock imbalance somewhere in the 2.6.7 ipsec code. Yes this is most likely the missing unlock in xfrm_policy_timer() that was fixed not so long ago. However, that bug was only introduced in 2.6.7 and the submitter says that he saw this with 2.6.6. So this might be something else. So the submitter should test 2.6.8-rc3 to see if it's still there or not. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From herbert@gondor.apana.org.au Wed Aug 4 03:12:14 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 03:12:23 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74ACDZK027392 for ; Wed, 4 Aug 2004 03:12:14 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BsIkV-0007uF-00; Wed, 04 Aug 2004 20:11:55 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BsIkR-0001Hu-00; Wed, 04 Aug 2004 20:11:51 +1000 Date: Wed, 4 Aug 2004 20:11:51 +1000 To: Masahide Nakamura Cc: Stephen Hemminger , netdev@oss.sgi.com Subject: Re: [PATCH][IPROUTE2] clean xfrm message format Message-ID: <20040804101151.GA4940@gondor.apana.org.au> References: <20040803164539.41a0a975@localhost> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040803164539.41a0a975@localhost> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7489 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev Content-Length: 459 Lines: 15 On Tue, Aug 03, 2004 at 04:45:39PM -0700, Masahide Nakamura wrote: > > This is a patch for ip xfrm and against for the latest > snapshot(iproute2-2.6.8-ss040730.tar.gz). Please apply it. Yes this looks great. Thanks a lot for your work. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From jmorris@redhat.com Wed Aug 4 06:00:19 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 06:00:25 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74D0ILW005973 for ; Wed, 4 Aug 2004 06:00:19 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i74D0Ae1014906; Wed, 4 Aug 2004 09:00:10 -0400 Received: from mail.boston.redhat.com (mail.boston.redhat.com [172.16.76.12]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i74D0Aa20598; Wed, 4 Aug 2004 09:00:10 -0400 Received: from thoron.boston.redhat.com (thoron.boston.redhat.com [172.16.80.63]) by mail.boston.redhat.com (8.12.8/8.12.8) with ESMTP id i74D0BtM018547; Wed, 4 Aug 2004 09:00:11 -0400 Date: Wed, 4 Aug 2004 09:00:09 -0400 (EDT) From: James Morris X-X-Sender: jmorris@dhcp83-76.boston.redhat.com To: Andrew Morton cc: netdev@oss.sgi.com Subject: Re: Fw: [Bugme-new] [Bug 3151] New: IPSEC triggers "bad: scheduling while atomic!" errors. In-Reply-To: <20040803224319.50363100.akpm@osdl.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-archive-position: 7491 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jmorris@redhat.com Precedence: bulk X-list: netdev Content-Length: 258 Lines: 15 On Tue, 3 Aug 2004, Andrew Morton wrote: > > Looks like a lock/unlock imbalance somewhere in the 2.6.7 ipsec code. This could also be ppp related, oops related to this code seem to be reported regularly. - James -- James Morris From acid@krezus.e-wro.net Wed Aug 4 05:59:36 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 05:59:41 -0700 (PDT) Received: from krezus.e-wro.net (krezus.e-wro.net [82.143.159.250]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74CxZjG005879 for ; Wed, 4 Aug 2004 05:59:36 -0700 Received: from krezus.e-wro.net (localhost [127.0.0.1]) by krezus.e-wro.net (8.12.10/8.12.10) with ESMTP id i74CxQOC015450; Wed, 4 Aug 2004 14:59:26 +0200 Received: (from acid@localhost) by krezus.e-wro.net (8.12.10/8.12.10/Submit) id i74CxQHD015449; Wed, 4 Aug 2004 14:59:26 +0200 Date: Wed, 4 Aug 2004 14:59:26 +0200 From: Tomasz Paszkowski To: davem@redhat.com Cc: kaber@trash.net, netdev@oss.sgi.com Subject: [PATCH 2.4] Use double-linked list for dev->qdisc_list Message-ID: <20040804125926.GA15324@krezus.e-wro.net> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ftEhullJWpWg/VHq" Content-Disposition: inline User-Agent: Mutt/1.4i X-NCC-RegID: pl.e-wro X-Scanned-By: MIMEDefang 2.42 X-archive-position: 7490 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: tomasz.paszkowski@e-wro.pl Precedence: bulk X-list: netdev Content-Length: 6582 Lines: 248 --ftEhullJWpWg/VHq Content-Type: multipart/mixed; boundary="KsGdsel6WgEHnImy" Content-Disposition: inline --KsGdsel6WgEHnImy Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable This patch changes dev->qdisc_list to a double-linked list. This solves the performance problems when destroying qdiscs with large number of inner qdiscs. This is backported version of Patrick McHardy patch (03-qdisc_list-list_h.d= iff) for 2.6 kernels. --=20 Tomasz Paszkowski --KsGdsel6WgEHnImy Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="03-qdisc_list-list_h_2.4.27-rc5.diff" Content-Transfer-Encoding: quoted-printable diff -Nru linux-2.4.27-rc5_van/include/linux/netdevice.h linux-2.4.27-rc5/i= nclude/linux/netdevice.h --- linux-2.4.27-rc5_van/include/linux/netdevice.h 2004-08-04 16:37:39.0000= 00000 +0200 +++ linux-2.4.27-rc5/include/linux/netdevice.h 2004-08-04 16:22:08.00000000= 0 +0200 @@ -352,8 +352,8 @@ =20 struct Qdisc *qdisc; struct Qdisc *qdisc_sleeping; - struct Qdisc *qdisc_list; struct Qdisc *qdisc_ingress; + struct list_head qdisc_list; unsigned long tx_queue_len; /* Max frames per queue allowed */ =20 /* hard_start_xmit synchronizer */ diff -Nru linux-2.4.27-rc5_van/include/net/pkt_sched.h linux-2.4.27-rc5/inc= lude/net/pkt_sched.h --- linux-2.4.27-rc5_van/include/net/pkt_sched.h 2004-02-18 14:36:32.000000= 000 +0100 +++ linux-2.4.27-rc5/include/net/pkt_sched.h 2004-08-04 16:22:08.000000000 = +0200 @@ -80,11 +80,11 @@ #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 struct Qdisc_ops *ops; - struct Qdisc *next; u32 handle; atomic_t refcnt; struct sk_buff_head q; struct net_device *dev; + struct list_head list; =20 struct tc_stats stats; int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q); diff -Nru linux-2.4.27-rc5_van/net/sched/sch_api.c linux-2.4.27-rc5/net/sch= ed/sch_api.c --- linux-2.4.27-rc5_van/net/sched/sch_api.c 2002-11-29 00:53:16.000000000 = +0100 +++ linux-2.4.27-rc5/net/sched/sch_api.c 2004-08-04 16:26:55.000000000 +0200 @@ -32,6 +32,7 @@ #include #include #include +#include =20 #include #include @@ -193,7 +194,7 @@ { struct Qdisc *q; =20 - for (q =3D dev->qdisc_list; q; q =3D q->next) { + list_for_each_entry(q, &dev->qdisc_list, list) { if (q->handle =3D=3D handle) return q; } @@ -424,6 +425,7 @@ =20 memset(sch, 0, size); =20 + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); =20 if (handle =3D=3D TC_H_INGRESS) @@ -449,8 +451,7 @@ =20 if (!ops->init || (err =3D ops->init(sch, tca[TCA_OPTIONS-1])) =3D=3D 0) { write_lock(&qdisc_tree_lock); - sch->next =3D dev->qdisc_list; - dev->qdisc_list =3D sch; + list_add_tail(&sch->list, &dev->qdisc_list); write_unlock(&qdisc_tree_lock); #ifdef CONFIG_NET_ESTIMATOR if (tca[TCA_RATE-1]) @@ -805,9 +806,9 @@ if (idx > s_idx) s_q_idx =3D 0; read_lock(&qdisc_tree_lock); - for (q =3D dev->qdisc_list, q_idx =3D 0; q; - q =3D q->next, q_idx++) { - if (q_idx < s_q_idx) + q_idx =3D 0; + list_for_each_entry(q, &dev->qdisc_list, list) { + if (q_idx++ < s_q_idx) continue; if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <=3D 0) { @@ -822,7 +823,7 @@ read_unlock(&dev_base_lock); =20 cb->args[0] =3D idx; - cb->args[1] =3D q_idx; + cb->args[1] =3D q_idx - 1; =20 return skb->len; } @@ -1024,13 +1025,16 @@ return 0; =20 s_t =3D cb->args[0]; + t =3D 0; =20 read_lock(&qdisc_tree_lock); - for (q=3Ddev->qdisc_list, t=3D0; q; q =3D q->next, t++) { - if (t < s_t) continue; - if (!q->ops->cl_ops) continue; - if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) !=3D q->handle) + list_for_each_entry(q, &dev->qdisc_list, list) { + if (t < s_t || !q->ops->cl_ops || + (tcm->tcm_parent && + TC_H_MAJ(tcm->tcm_parent) !=3D q->handle)) { + t++; continue; + } if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); arg.w.fn =3D qdisc_class_dump; @@ -1043,6 +1047,7 @@ cb->args[1] =3D arg.w.count; if (arg.w.stop) break; + t++; } read_unlock(&qdisc_tree_lock); =20 diff -Nru linux-2.4.27-rc5_van/net/sched/sch_generic.c linux-2.4.27-rc5/net= /sched/sch_generic.c --- linux-2.4.27-rc5_van/net/sched/sch_generic.c 2004-02-18 14:36:32.000000= 000 +0100 +++ linux-2.4.27-rc5/net/sched/sch_generic.c 2004-08-04 16:30:16.000000000 = +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include =20 @@ -391,6 +392,7 @@ return NULL; memset(sch, 0, size); =20 + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); sch->ops =3D ops; sch->enqueue =3D ops->enqueue; @@ -420,22 +422,10 @@ void qdisc_destroy(struct Qdisc *qdisc) { struct Qdisc_ops *ops =3D qdisc->ops; - struct net_device *dev; =20 if (!atomic_dec_and_test(&qdisc->refcnt)) return; - - dev =3D qdisc->dev; - - if (dev) { - struct Qdisc *q, **qp; - for (qp =3D &qdisc->dev->qdisc_list; (q=3D*qp) !=3D NULL; qp =3D &q->nex= t) { - if (q =3D=3D qdisc) { - *qp =3D q->next; - break; - } - } - } + list_del(&qdisc->list); #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif @@ -464,10 +454,8 @@ printk(KERN_INFO "%s: activation failed\n", dev->name); return; } - write_lock(&qdisc_tree_lock); - qdisc->next =3D dev->qdisc_list; - dev->qdisc_list =3D qdisc; + list_add_tail(&qdisc->list, &dev->qdisc_list); write_unlock(&qdisc_tree_lock); =20 } else { @@ -513,7 +501,7 @@ dev->qdisc =3D &noop_qdisc; spin_unlock_bh(&dev->queue_lock); dev->qdisc_sleeping =3D &noop_qdisc; - dev->qdisc_list =3D NULL; + INIT_LIST_HEAD(&dev->qdisc_list); write_unlock(&qdisc_tree_lock); =20 dev_watchdog_init(dev); @@ -535,9 +523,7 @@ qdisc_destroy(qdisc); } #endif - BUG_TRAP(dev->qdisc_list =3D=3D NULL); BUG_TRAP(!timer_pending(&dev->watchdog_timer)); - dev->qdisc_list =3D NULL; spin_unlock_bh(&dev->queue_lock); write_unlock(&qdisc_tree_lock); } --KsGdsel6WgEHnImy-- --ftEhullJWpWg/VHq Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQFBEN2tcNXOL98XeysRAh8RAJwNnKyt6wC/GhimrDWBDlPSnJzBvACfQ4Uk c2lzDxLg6/T9Ecx61r4SSWo= =JCaa -----END PGP SIGNATURE----- --ftEhullJWpWg/VHq-- From mtk-lists@gmx.net Wed Aug 4 06:22:38 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 06:22:44 -0700 (PDT) Received: from mail.gmx.net (pop.gmx.de [213.165.64.20]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i74DMaTd007506 for ; Wed, 4 Aug 2004 06:22:37 -0700 Received: (qmail 13980 invoked by uid 0); 4 Aug 2004 13:22:27 -0000 Received: from 62.245.207.82 by www2.gmx.net with HTTP; Wed, 4 Aug 2004 15:22:27 +0200 (MEST) Date: Wed, 4 Aug 2004 15:22:27 +0200 (MEST) From: "Michael T Kerrisk" To: netdev@oss.sgi.com MIME-Version: 1.0 Subject: Assassination of TIME_WAIT state (RESEND) X-Priority: 3 (Normal) X-Authenticated: #18454895 Message-ID: <16217.1091625747@www2.gmx.net> X-Mailer: WWW-Mail 1.6 (Global Message Exchange) X-Flags: 0001 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-archive-position: 7492 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: mtk-lists@gmx.net Precedence: bulk X-list: netdev Content-Length: 2667 Lines: 80 Gidday, I did try posting this many weeks back, but got response. I'll take another shot -- does anyone have thoughts on the questions below? == In the scenario below, one achieves assassination of the TIME_WAIT state on Linux 2.6.5 and 2.4.x. From a conversation I had a while ago with Andi Kleen (see below), it appears that this is expected behavior. I have two (closely linked) questions: -- what is the rationale for this behavior (i.e., why assassinate in this scenario)? -- why does Linux behave differently from FreeBSD and Solaris in this scenario? Assume in the following scenario that SO_RESUSEADDR is set on the server socket(s): Server Client 1. Create listening socket bound to INADDR_ANY/port=9999 2. Accept a connection on the listening socket 3. Create a socket bound to INADDR_ANY/port=50000 4. Connect to server socket (on port 9999) 5. Close listening and connected sockets 6. Close the socket At this point, there is TCP on the server side in the TIME_WAIT state: { local=localhost:9999, peer=XXX:50000 } (re-run server) 7. Create listening socket bound to INADDR_ANY/port=9999 8. Accept a connection on the listening socket (re-run client while TIME_WAIT TCP still exists) 9. Create a socket bound to INADDR_ANY/port=50000 10.Connect to server socket (on port 9999) On Linux the connect() in step 10 succeeds; the reason that it does is that the TIME_WAIT TCP is immediately assassinated. A while back I asked Andi Kleen about this scenario, and he commented that this behavious was: > a (dubious) BSD extension, also implemented > in linux (after all sockets is about being bug to bug coompatible). > the kernel sees the TIME-WAIT and choses a sequence number with > a large offset to avoid conflicts. When you don't have PAWS > but still had a big window it is rather risky though. However, when I try the above on FreeBSD 5.1 and Solaris 8, we see different behavior: the TIME_WAIT TCP is NOT assassinated and the connect() at step 10 fails with EADDRINUSE (which makes sense because we can't create a duplicate 4-tuple...). Cheers, Michael -- Michael Kerrisk mtk-lists@gmx.net NEU: WLAN-Router für 0,- EUR* - auch für DSL-Wechsler! GMX DSL = supergünstig & kabellos http://www.gmx.net/de/go/dsl From kaber@trash.net Wed Aug 4 06:28:30 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 06:28:35 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74DSOXS008179 for ; Wed, 4 Aug 2004 06:28:30 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 74D3519F356; Wed, 4 Aug 2004 15:28:15 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id B2488394133; Wed, 4 Aug 2004 15:28:14 +0200 (CEST) Message-ID: <4110E505.1010205@trash.net> Date: Wed, 04 Aug 2004 15:30:45 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Tomasz Paszkowski Cc: davem@redhat.com, netdev@oss.sgi.com Subject: Re: [PATCH 2.4] Use double-linked list for dev->qdisc_list References: <20040804125926.GA15324@krezus.e-wro.net> In-Reply-To: <20040804125926.GA15324@krezus.e-wro.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7493 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Content-Length: 729 Lines: 27 Tomasz Paszkowski wrote: >This patch changes dev->qdisc_list to a double-linked list. This solves >the performance problems when destroying qdiscs with large number of inner >qdiscs. > >This is backported version of Patrick McHardy patch (03-qdisc_list-list_h.diff) >or 2.6 kernels. > > Looks good, except for the last hunk, the BUG_TRAP is valid in 2.4 because it doesn't use RCU. Change it to BUG_TRAP(list_empty(&dev->qdisc_list)). > > >------------------------------------------------------------------------ > > #endif >- BUG_TRAP(dev->qdisc_list == NULL); > BUG_TRAP(!timer_pending(&dev->watchdog_timer)); >- dev->qdisc_list = NULL; > spin_unlock_bh(&dev->queue_lock); > write_unlock(&qdisc_tree_lock); > } > > From mtk-lists@gmx.net Wed Aug 4 07:25:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 07:25:43 -0700 (PDT) Received: from mail.gmx.net (pop.gmx.de [213.165.64.20]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i74EPagd010795 for ; Wed, 4 Aug 2004 07:25:37 -0700 Received: (qmail 24367 invoked by uid 0); 4 Aug 2004 14:25:27 -0000 Received: from 62.245.207.82 by www2.gmx.net with HTTP; Wed, 4 Aug 2004 16:25:27 +0200 (MEST) Date: Wed, 4 Aug 2004 16:25:27 +0200 (MEST) From: "Michael T Kerrisk" To: netdev@oss.sgi.com MIME-Version: 1.0 Subject: SO_REUSEADDR behavior different from BSD X-Priority: 3 (Normal) X-Authenticated: #18454895 Message-ID: <16224.1091629527@www2.gmx.net> X-Mailer: WWW-Mail 1.6 (Global Message Exchange) X-Flags: 0001 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit X-archive-position: 7494 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: mtk-lists@gmx.net Precedence: bulk X-list: netdev Content-Length: 2123 Lines: 70 Gidday, In the classical BSD sockets implementation, the SO_REUSEADDR socket option serves two purposes: (a) to permit a socket to be bound to a port that currently has a bound endpoint in the TIME_WAIT state, and (b) to allow a terminated server to be restarted (and once again be bound to it's well-known port), even if there is a child of the previous server still serving a connection. On Linux SO_REUSEADDR does serve this purpose. However, other second scenario is mot permitted by SO_REUSEADDR. To make it clear what I mean, I’ll detail the scenario. Suppose we have the following: Server (host Y) Create listening socket -- fd 4 bind() to INADDR_ANY:9999 listen() accept() Client (host X) Create socket connect() to Y:9999 server forks --------+ \ server terminates closes fd 4 At this point, netstat on host Y shows the tuple [local=Y-IP-addr:9999, remote=X-IP-addr:ephem-port] ESTABLISHED New Server started Create listening socket -- fd 4 set SO_REUSEADDR to 1 for fd 4 bind() fd 4 to port INADDR_ANY:9999 WHAT HAPPENS? On FreeBSD, the bind() succeeds, and then using "netstat –an" on host Y shows: [local=Y-IP-addr:9999, remote=X-IP-addr:ephem-port] ESTABLISHED and [local=*:9999, remote=*.*] CLOSED But on Linux (2.6), the bind() fails with EADDRINUSE. Why does Linux behave differently in this scenario? Cheers, Michael -- Michael Kerrisk mtk-lists@gmx.net NEU: WLAN-Router für 0,- EUR* - auch für DSL-Wechsler! GMX DSL = supergünstig & kabellos http://www.gmx.net/de/go/dsl From acid@krezus.e-wro.net Wed Aug 4 07:56:22 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 07:56:29 -0700 (PDT) Received: from krezus.e-wro.net (krezus.e-wro.net [82.143.159.250]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74EuLZ4012208 for ; Wed, 4 Aug 2004 07:56:22 -0700 Received: from krezus.e-wro.net (localhost [127.0.0.1]) by krezus.e-wro.net (8.12.10/8.12.10) with ESMTP id i74EuCOC023699; Wed, 4 Aug 2004 16:56:12 +0200 Received: (from acid@localhost) by krezus.e-wro.net (8.12.10/8.12.10/Submit) id i74EuA9f023698; Wed, 4 Aug 2004 16:56:10 +0200 Date: Wed, 4 Aug 2004 16:56:10 +0200 From: Tomasz Paszkowski To: Patrick McHardy Cc: davem@redhat.com, netdev@oss.sgi.com Subject: Re: [PATCH 2.4] Use double-linked list for dev->qdisc_list Message-ID: <20040804145610.GA21339@krezus.e-wro.net> References: <20040804125926.GA15324@krezus.e-wro.net> <4110E505.1010205@trash.net> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="zx4FCpZtqtKETZ7O" Content-Disposition: inline In-Reply-To: <4110E505.1010205@trash.net> User-Agent: Mutt/1.4i X-NCC-RegID: pl.e-wro X-Scanned-By: MIMEDefang 2.42 X-archive-position: 7495 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: tomasz.paszkowski@e-wro.pl Precedence: bulk X-list: netdev Content-Length: 6720 Lines: 249 --zx4FCpZtqtKETZ7O Content-Type: multipart/mixed; boundary="ew6BAiZeqk4r7MaW" Content-Disposition: inline --ew6BAiZeqk4r7MaW Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Aug 04, 2004 at 03:30:45PM +0200, Patrick McHardy wrote: > Looks good, except for the last hunk, the BUG_TRAP is valid in 2.4 because > it doesn't use RCU. Change it to BUG_TRAP(list_empty(&dev->qdisc_list)). Thanks. In attachment there's a corrected version of this patch. --=20 Tomasz Paszkowski Administrator Miejskie Sieci Informatyczne e-wro http://www.e-wro.pl --ew6BAiZeqk4r7MaW Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="03-qdisc_list-list_h_2.4.27-rc5.diff" Content-Transfer-Encoding: quoted-printable diff -Nru linux-2.4.27-rc5_van/include/linux/netdevice.h linux-2.4.27-rc5/i= nclude/linux/netdevice.h --- linux-2.4.27-rc5_van/include/linux/netdevice.h 2004-08-04 17:34:49.0000= 00000 +0200 +++ linux-2.4.27-rc5/include/linux/netdevice.h 2004-08-04 17:36:28.00000000= 0 +0200 @@ -352,8 +352,8 @@ =20 struct Qdisc *qdisc; struct Qdisc *qdisc_sleeping; - struct Qdisc *qdisc_list; struct Qdisc *qdisc_ingress; + struct list_head qdisc_list; unsigned long tx_queue_len; /* Max frames per queue allowed */ =20 /* hard_start_xmit synchronizer */ diff -Nru linux-2.4.27-rc5_van/include/net/pkt_sched.h linux-2.4.27-rc5/inc= lude/net/pkt_sched.h --- linux-2.4.27-rc5_van/include/net/pkt_sched.h 2004-02-18 14:36:32.000000= 000 +0100 +++ linux-2.4.27-rc5/include/net/pkt_sched.h 2004-08-04 17:36:28.000000000 = +0200 @@ -80,11 +80,11 @@ #define TCQ_F_THROTTLED 2 #define TCQ_F_INGRES 4 struct Qdisc_ops *ops; - struct Qdisc *next; u32 handle; atomic_t refcnt; struct sk_buff_head q; struct net_device *dev; + struct list_head list; =20 struct tc_stats stats; int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q); diff -Nru linux-2.4.27-rc5_van/net/sched/sch_api.c linux-2.4.27-rc5/net/sch= ed/sch_api.c --- linux-2.4.27-rc5_van/net/sched/sch_api.c 2002-11-29 00:53:16.000000000 = +0100 +++ linux-2.4.27-rc5/net/sched/sch_api.c 2004-08-04 17:36:28.000000000 +0200 @@ -32,6 +32,7 @@ #include #include #include +#include =20 #include #include @@ -193,7 +194,7 @@ { struct Qdisc *q; =20 - for (q =3D dev->qdisc_list; q; q =3D q->next) { + list_for_each_entry(q, &dev->qdisc_list, list) { if (q->handle =3D=3D handle) return q; } @@ -424,6 +425,7 @@ =20 memset(sch, 0, size); =20 + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); =20 if (handle =3D=3D TC_H_INGRESS) @@ -449,8 +451,7 @@ =20 if (!ops->init || (err =3D ops->init(sch, tca[TCA_OPTIONS-1])) =3D=3D 0) { write_lock(&qdisc_tree_lock); - sch->next =3D dev->qdisc_list; - dev->qdisc_list =3D sch; + list_add_tail(&sch->list, &dev->qdisc_list); write_unlock(&qdisc_tree_lock); #ifdef CONFIG_NET_ESTIMATOR if (tca[TCA_RATE-1]) @@ -805,9 +806,9 @@ if (idx > s_idx) s_q_idx =3D 0; read_lock(&qdisc_tree_lock); - for (q =3D dev->qdisc_list, q_idx =3D 0; q; - q =3D q->next, q_idx++) { - if (q_idx < s_q_idx) + q_idx =3D 0; + list_for_each_entry(q, &dev->qdisc_list, list) { + if (q_idx++ < s_q_idx) continue; if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <=3D 0) { @@ -822,7 +823,7 @@ read_unlock(&dev_base_lock); =20 cb->args[0] =3D idx; - cb->args[1] =3D q_idx; + cb->args[1] =3D q_idx - 1; =20 return skb->len; } @@ -1024,13 +1025,16 @@ return 0; =20 s_t =3D cb->args[0]; + t =3D 0; =20 read_lock(&qdisc_tree_lock); - for (q=3Ddev->qdisc_list, t=3D0; q; q =3D q->next, t++) { - if (t < s_t) continue; - if (!q->ops->cl_ops) continue; - if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) !=3D q->handle) + list_for_each_entry(q, &dev->qdisc_list, list) { + if (t < s_t || !q->ops->cl_ops || + (tcm->tcm_parent && + TC_H_MAJ(tcm->tcm_parent) !=3D q->handle)) { + t++; continue; + } if (t > s_t) memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); arg.w.fn =3D qdisc_class_dump; @@ -1043,6 +1047,7 @@ cb->args[1] =3D arg.w.count; if (arg.w.stop) break; + t++; } read_unlock(&qdisc_tree_lock); =20 diff -Nru linux-2.4.27-rc5_van/net/sched/sch_generic.c linux-2.4.27-rc5/net= /sched/sch_generic.c --- linux-2.4.27-rc5_van/net/sched/sch_generic.c 2004-02-18 14:36:32.000000= 000 +0100 +++ linux-2.4.27-rc5/net/sched/sch_generic.c 2004-08-04 17:38:43.000000000 = +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include =20 @@ -391,6 +392,7 @@ return NULL; memset(sch, 0, size); =20 + INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); sch->ops =3D ops; sch->enqueue =3D ops->enqueue; @@ -420,22 +422,10 @@ void qdisc_destroy(struct Qdisc *qdisc) { struct Qdisc_ops *ops =3D qdisc->ops; - struct net_device *dev; =20 if (!atomic_dec_and_test(&qdisc->refcnt)) return; - - dev =3D qdisc->dev; - - if (dev) { - struct Qdisc *q, **qp; - for (qp =3D &qdisc->dev->qdisc_list; (q=3D*qp) !=3D NULL; qp =3D &q->nex= t) { - if (q =3D=3D qdisc) { - *qp =3D q->next; - break; - } - } - } + list_del(&qdisc->list); #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif @@ -464,10 +454,8 @@ printk(KERN_INFO "%s: activation failed\n", dev->name); return; } - write_lock(&qdisc_tree_lock); - qdisc->next =3D dev->qdisc_list; - dev->qdisc_list =3D qdisc; + list_add_tail(&qdisc->list, &dev->qdisc_list); write_unlock(&qdisc_tree_lock); =20 } else { @@ -513,7 +501,7 @@ dev->qdisc =3D &noop_qdisc; spin_unlock_bh(&dev->queue_lock); dev->qdisc_sleeping =3D &noop_qdisc; - dev->qdisc_list =3D NULL; + INIT_LIST_HEAD(&dev->qdisc_list); write_unlock(&qdisc_tree_lock); =20 dev_watchdog_init(dev); @@ -535,9 +523,8 @@ qdisc_destroy(qdisc); } #endif - BUG_TRAP(dev->qdisc_list =3D=3D NULL); + BUG_TRAP(list_empty(&dev->qdisc_list)); BUG_TRAP(!timer_pending(&dev->watchdog_timer)); - dev->qdisc_list =3D NULL; spin_unlock_bh(&dev->queue_lock); write_unlock(&qdisc_tree_lock); } --ew6BAiZeqk4r7MaW-- --zx4FCpZtqtKETZ7O Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQFBEPkKcNXOL98XeysRApODAJ9NIX5kEocbs7qXUwu72NcvzP2xsgCfQ7tP qMZ1efoKSELfZHlJh3nvFrQ= =icYm -----END PGP SIGNATURE----- --zx4FCpZtqtKETZ7O-- From ptsjohol@cc.jyu.fi Wed Aug 4 09:26:32 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 09:26:37 -0700 (PDT) Received: from posti6.jyu.fi (posti6.jyu.fi [130.234.4.43]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74GQVCn029702 for ; Wed, 4 Aug 2004 09:26:32 -0700 Received: from silmu.st.jyu.fi (IDENT:YpIl8zWwJy8GidOHbDMXOhURX0rORj6S@silmu.st.jyu.fi [130.234.4.64]) by posti6.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i74GQ6ob024861; Wed, 4 Aug 2004 19:26:07 +0300 Date: Wed, 4 Aug 2004 19:26:03 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti6.jyu.fi; Wed, 04 Aug 2004 19:26:08 +0300 X-archive-position: 7496 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev Content-Length: 1377 Lines: 33 On Tue, 3 Aug 2004, Pasi Sjoholm wrote: > > If you remove the "if (received > 0) {" test in r8139-10.patch and keep > > both patches applied, I assume you are back to a crash within 15min (instead > > of within 2min as suggested by the log), right ? > I removed "if (received > 0) {" and tested it something like 3 hours and > wasn't able to crash the driver. I will test it for couple more hours > tomorrow and if I'm not still able the crash it, we may have find some > sort of a solution. > I'm not sure yet if it's a good one because of that earlier crash I had. > I guess I will also test if > "- read the interruption status word that the driver will ack before the > actual processing is done;" has something to do with it. Ok, now I have tested it for 6 hours without crashing the driver. The system's load has been something like 5-6 the whole time. I also made some network load with ~90Mbps-incoming and ~90Mbps-outgoing traffic. I haven't had time to test anything else but I'm quite sure that there is no need for that anymore because the stability we have reached. I'll let you know if there's any problems within next few days but I would recommend that those patches would be included in 2.6.8. (without that "if (received > 0) {"). Many thanks for your help to resolve this problem. Hector, have you tested these patches? -- Pasi Sjöholm From davem@redhat.com Wed Aug 4 09:35:32 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 09:35:38 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74GZV0l030355 for ; Wed, 4 Aug 2004 09:35:31 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i74GZRe1009186; Wed, 4 Aug 2004 12:35:27 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i74GZRa02227; Wed, 4 Aug 2004 12:35:27 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i74GYglC001927; Wed, 4 Aug 2004 12:34:43 -0400 Date: Wed, 4 Aug 2004 09:33:28 -0700 From: "David S. Miller" To: Patrick McHardy Cc: netdev@oss.sgi.com Subject: Re: [PATCH 2.6 1/5]: Fix locking in __qdisc_destroy rcu-callback Message-Id: <20040804093328.4ee56d30.davem@redhat.com> In-Reply-To: <410FAD44.7020503@trash.net> References: <410FAD44.7020503@trash.net> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7497 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Content-Length: 766 Lines: 17 On Tue, 03 Aug 2004 17:20:36 +0200 Patrick McHardy wrote: > The __qdisc_destroy rcu-callback doesn't do any locking when calling > ops->reset and ops->destroy. qdisc_destroy is often called from both > of these functions and it changes dev->qdisc_list. This patch adds proper > locking to __qdisc_destroy. Unfortunately when using qdisc_tree_lock in > process context we now also need to disable local bh's to avoid beeing > interrupted by the rcu-callback. I'm not sure if RCU callback can be > scheduled while the kernel is running in process context, so this may > be unneccessary. RCU callbacks run via tasklets, and thus in softirq context, thus your locking changes to _bh() are indeed necessary. I will apply this patch, thanks Patrick. From davem@redhat.com Wed Aug 4 09:38:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Wed, 04 Aug 2004 09:38:18 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i74GcCwl030836 for ; Wed, 4 Aug 2004 09:38:13 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i74Gc8e1009900; Wed, 4 Aug 2004 12:38:08 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i74Gc3a03160; Wed, 4 Aug 2004 12:38:03 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i74GbJAm003807; Wed, 4 Aug 2004 12:37:19 -0400 Date: Wed, 4 Aug 2004 09:36:04 -0700 From: "David S. Miller" To: Patrick McHardy Cc: netdev@oss.sgi.com Subject: Re: [PATCH 2.6 2/5]: ref