From 8b7c1664405a1262bb78e80011ec10aa6b79df81 Mon Sep 17 00:00:00 2001 From: frederic Rodo Date: Wed, 27 Feb 2008 12:58:37 +0100 Subject: [PATCH 01/47] dm9161: add configuration for MII/RMII Signed-off-by: Frederic Rodo Signed-off-by: Jeff Garzik --- drivers/net/phy/davicom.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index 7ed632db00d7..d926168bc780 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -37,6 +37,7 @@ #define MII_DM9161_SCR 0x10 #define MII_DM9161_SCR_INIT 0x0610 +#define MII_DM9161_SCR_RMII 0x0100 /* DM9161 Interrupt Register */ #define MII_DM9161_INTR 0x15 @@ -103,7 +104,7 @@ static int dm9161_config_aneg(struct phy_device *phydev) static int dm9161_config_init(struct phy_device *phydev) { - int err; + int err, temp; /* Isolate the PHY */ err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); @@ -111,9 +112,19 @@ static int dm9161_config_init(struct phy_device *phydev) if (err < 0) return err; - /* Do not bypass the scrambler/descrambler */ - err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT); + switch (phydev->interface) { + case PHY_INTERFACE_MODE_MII: + temp = MII_DM9161_SCR_INIT; + break; + case PHY_INTERFACE_MODE_RMII: + temp = MII_DM9161_SCR_INIT | MII_DM9161_SCR_RMII; + break; + default: + return -EINVAL; + } + /* Do not bypass the scrambler/descrambler */ + err = phy_write(phydev, MII_DM9161_SCR, temp); if (err < 0) return err; From f25f0f8dcd99e954dc0acf2fcb556cbcd7394549 Mon Sep 17 00:00:00 2001 From: Ondrej Zary Date: Mon, 25 Feb 2008 18:45:46 +0100 Subject: [PATCH 02/47] de2104x: remove BUG_ON() when changing media type When the chip dies (probably because of a bug somewhere in the driver), de_stop_rxtx() fails and changing the media type crashes the whole machine. Replace BUG_ON() in de_set_media() with a warning. Signed-off-by: Ondrej Zary Signed-off-by: Jeff Garzik --- drivers/net/tulip/de2104x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 77d9dd7ea34f..567c62757e9d 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -910,7 +910,8 @@ static void de_set_media (struct de_private *de) unsigned media = de->media_type; u32 macmode = dr32(MacMode); - BUG_ON(de_is_running(de)); + if (de_is_running(de)) + printk(KERN_WARNING "%s: chip is running while changing media!\n", de->dev->name); if (de->de21040) dw32(CSR11, FULL_DUPLEX_MAGIC); From 27c8bc2cc1a520a6c77b225bb7dc53f7dea32f6f Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Thu, 28 Feb 2008 21:11:48 +0100 Subject: [PATCH 03/47] mv643xx_eth: Define module alias for platform device The mv643xx_eth driver can be loaded as a platform device, as is done by various Orion (ARM) based devices. The driver needs to define a module alias for the platform driver so udev will load it automatically. Tested with Debian on a QNAP TS-209. Signed-off-by: Martin Michlmayr Signed-off-by: Jeff Garzik --- drivers/net/mv643xx_eth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b528ce77c406..771139e283af 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2104,6 +2104,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani" " and Dale Farnsworth"); MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); +MODULE_ALIAS("platform:mv643xx_eth"); /* * The second part is the low level driver of the gigE ethernet ports. From 36c86bd27185939b7bb22252e47e133a08dcead6 Mon Sep 17 00:00:00 2001 From: Komuro Date: Sat, 1 Mar 2008 10:52:03 +0900 Subject: [PATCH 04/47] axnet_cs: change debugging level for "Too much work at interrupt" message. This message is frequently displayed even if normal file-transfer. Signed-off-by: Komuro Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/axnet_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index e8a63e483a2b..ce95c5d168fe 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1268,7 +1268,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) } } - if (interrupts && ei_debug) + if (interrupts && ei_debug > 3) { handled = 1; if (nr_serviced >= MAX_SERVICE) From af856bbfc498c3c8c79cb07be84e958962c711c3 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Mon, 3 Mar 2008 13:52:06 +0100 Subject: [PATCH 05/47] ehea: Fix missing Kconfig dependency Fixed Kconfig: ehea driver requires sparse mem Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a0f0e605d630..a64bb415f10c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2519,7 +2519,7 @@ config CHELSIO_T3 config EHEA tristate "eHEA Ethernet support" - depends on IBMEBUS && INET + depends on IBMEBUS && INET && SPARSEMEM select INET_LRO ---help--- This driver supports the IBM pSeries eHEA ethernet adapter. From f902283bbe68639142a00dd23d80ee31e1b00759 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 3 Mar 2008 14:37:31 -0800 Subject: [PATCH 06/47] e100: Do suspend/shutdown like e1000 This fixes a "trying to free already free IRQ" message and simplifies the shutdown/suspend code by re-using already existing code when going to suspend. The code is now symmetric with e100_resume. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/e100.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 36ba6dc96acc..cdf3090a1885 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2782,16 +2782,13 @@ static void __devexit e100_remove(struct pci_dev *pdev) } } -#ifdef CONFIG_PM static int e100_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); if (netif_running(netdev)) - napi_disable(&nic->napi); - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); + e100_down(nic); netif_device_detach(netdev); pci_save_state(pdev); @@ -2804,14 +2801,13 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - free_irq(pdev->irq, netdev); - pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; } +#ifdef CONFIG_PM static int e100_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); @@ -2832,26 +2828,7 @@ static int e100_resume(struct pci_dev *pdev) static void e100_shutdown(struct pci_dev *pdev) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct nic *nic = netdev_priv(netdev); - - if (netif_running(netdev)) - napi_disable(&nic->napi); - del_timer_sync(&nic->watchdog); - netif_carrier_off(nic->netdev); - - if ((nic->flags & wol_magic) | e100_asf(nic)) { - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } else { - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - } - - free_irq(pdev->irq, netdev); - - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + e100_suspend(pdev, PMSG_SUSPEND); } /* ------------------ PCI Error Recovery infrastructure -------------- */ From 5a059e9d49936fd2069d1777210b06b31ce50ee4 Mon Sep 17 00:00:00 2001 From: Emil Tantilov Date: Mon, 3 Mar 2008 14:37:42 -0800 Subject: [PATCH 07/47] ixgbe: fix typo in speed mesage Signed-off-by: Emil Tantilov Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- drivers/net/ixgbe/ixgbe_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 23d0a4afe0e1..c2095ce531c9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2133,7 +2133,7 @@ static void ixgbe_watchdog(unsigned long data) (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? "10 Gbps" : (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? - "1 Gpbs" : "unknown speed")), + "1 Gbps" : "unknown speed")), ((FLOW_RX && FLOW_TX) ? "RX/TX" : (FLOW_RX ? "RX" : (FLOW_TX ? "TX" : "None")))); From d94e6fed6edb365debf44d884a7e626f06a0eb28 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Mon, 3 Mar 2008 14:37:47 -0800 Subject: [PATCH 08/47] Intel ethernet adapter: Update MAINTAINERS Another team member unfortunately left: update MAINTAINERS. Condense the 3 lists down to a single list for all our drivers. Point to our new sourceforge index page which is slightly better navigateable than the sf.net project page. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik --- MAINTAINERS | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 33d99dcac691..93e0de955b4b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2039,43 +2039,19 @@ M: kernel@wantstofly.org L: netdev@vger.kernel.org S: Maintained -INTEL PRO/100 ETHERNET SUPPORT +INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/ixgb/ixgbe) P: Auke Kok M: auke-jan.h.kok@intel.com P: Jesse Brandeburg M: jesse.brandeburg@intel.com P: Jeff Kirsher M: jeffrey.t.kirsher@intel.com +P: Bruce Allan +M: bruce.w.allan@intel.com P: John Ronciak M: john.ronciak@intel.com L: e1000-devel@lists.sourceforge.net -W: http://sourceforge.net/projects/e1000/ -S: Supported - -INTEL PRO/1000 GIGABIT ETHERNET SUPPORT -P: Auke Kok -M: auke-jan.h.kok@intel.com -P: Jesse Brandeburg -M: jesse.brandeburg@intel.com -P: Jeff Kirsher -M: jeffrey.t.kirsher@intel.com -P: John Ronciak -M: john.ronciak@intel.com -L: e1000-devel@lists.sourceforge.net -W: http://sourceforge.net/projects/e1000/ -S: Supported - -INTEL PRO/10GbE SUPPORT -P: Ayyappan Veeraiyan -M: ayyappan.veeraiyan@intel.com -P: Auke Kok -M: auke-jan.h.kok@intel.com -P: Jesse Brandeburg -M: jesse.brandeburg@intel.com -P: John Ronciak -M: john.ronciak@intel.com -L: e1000-devel@lists.sourceforge.net -W: http://sourceforge.net/projects/e1000/ +W: http://e1000.sourceforge.net/ S: Supported INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT From f37c768c39e3aeb8a508e1a45e461a506771445e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 3 Mar 2008 23:34:13 +0200 Subject: [PATCH 09/47] fix drivers/net/atarilance.c compilation This patch fixes the following build error: <-- snip --> ... CC [M] drivers/net/atarilance.o {standard input}: Assembler messages: {standard input}:406: Error: symbol `Lberr' is already defined {standard input}:460: Error: symbol `Lberr' is already defined make[3]: *** [drivers/net/atarilance.o] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/atarilance.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index b74dbeef8050..13c293b286de 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -336,8 +336,6 @@ struct lance_addr { /***************************** Prototypes *****************************/ -static int addr_accessible( volatile void *regp, int wordflag, int - writeflag ); static unsigned long lance_probe1( struct net_device *dev, struct lance_addr *init_rec ); static int lance_open( struct net_device *dev ); @@ -406,7 +404,8 @@ struct net_device * __init atarilance_probe(int unit) /* Derived from hwreg_present() in atari/config.c: */ -static int __init addr_accessible( volatile void *regp, int wordflag, int writeflag ) +static noinline int __init addr_accessible(volatile void *regp, int wordflag, + int writeflag) { int ret; long flags; From f9e7d100ddea5cdcea7a02230566f36b0a648c2e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 27 Feb 2008 17:07:54 +0200 Subject: [PATCH 10/47] FIXED_PHY must depend on PHYLIB=y This patch fixes the following build error introduced by commit a79d8e93d300adb84cccc38ac396cfb118c238ad and reported by Olaf Hering: <-- snip --> ... LD .tmp_vmlinux1 arch/powerpc/sysdev/built-in.o: In function `of_add_fixed_phys': fsl_soc.c:(.init.text+0xd34): undefined reference to `fixed_phy_add' make: *** [.tmp_vmlinux1] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/phy/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index f4ca0591231d..3ac8529bb92c 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -67,6 +67,7 @@ config REALTEK_PHY config FIXED_PHY bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" + depends on PHYLIB=y ---help--- Adds the platform "fixed" MDIO Bus to cover the boards that use PHYs that are not connected to the real MDIO bus. From 0d66afe7805b169b6bf3c7a88cf8163298b8ef05 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 4 Mar 2008 15:19:22 -0800 Subject: [PATCH 11/47] make s2io.c:init_tti() static Make the needlessly global init_tti() static. Signed-off-by: Adrian Bunk Acked-by: "Ramkrishna Vepa" Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/s2io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 6179a0a2032c..c72787adeba3 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -1088,7 +1088,7 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) * '-1' on failure */ -int init_tti(struct s2io_nic *nic, int link) +static int init_tti(struct s2io_nic *nic, int link) { struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 val64 = 0; From 140ee9603c753ce11fc3088c1988a77e92183f9b Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Wed, 5 Mar 2008 13:43:32 -0800 Subject: [PATCH 12/47] SCTP: Fix chunk parameter processing bug If an address family is not listed in "Supported Address Types" parameter(INIT Chunk), but the packet is sent by that family, this address family should be considered as supported by peer. Otherwise, an error condition will occur. For instance, if kernel receives an IPV6 SCTP INIT chunk with "Support Address Types" parameter which indicates just supporting IPV4 Address family. Kernel will reply an IPV6 SCTP INIT ACK packet, but the source ipv6 address in ipv6 header will be vacant. This is not correct. refer to RFC4460 as following: IMPLEMENTATION NOTE: If an SCTP endpoint lists in the 'Supported Address Types' parameter either IPv4 or IPv6, but uses the other family for sending the packet containing the INIT chunk, or if it also lists addresses of the other family in the INIT chunk, then the address family that is not listed in the 'Supported Address Types' parameter SHOULD also be considered as supported by the receiver of the INIT chunk. The receiver of the INIT chunk SHOULD NOT respond with any kind of error indication. Here is a fix to comply to RFC. Signed-off-by: Gui Jianfeng Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/sm_make_chunk.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index e45be4e3f80d..578630e8e00d 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2375,6 +2375,14 @@ static int sctp_process_param(struct sctp_association *asoc, asoc->peer.ipv4_address = 0; asoc->peer.ipv6_address = 0; + /* Assume that peer supports the address family + * by which it sends a packet. + */ + if (peer_addr->sa.sa_family == AF_INET6) + asoc->peer.ipv6_address = 1; + else if (peer_addr->sa.sa_family == AF_INET) + asoc->peer.ipv4_address = 1; + /* Cycle through address types; avoid divide by 0. */ sat = ntohs(param.p->length) - sizeof(sctp_paramhdr_t); if (sat) From 219b99a9edab4fdc478c819acb38f4a592dffd7d Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 5 Mar 2008 13:44:46 -0800 Subject: [PATCH 13/47] [SCTP]: Bring MAX_BURST socket option into ietf API extension compliance Brings max_burst socket option set/get into line with the latest ietf socket extensions api draft, while maintaining backwards compatibility. Signed-off-by: Neil Horman Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/socket.c | 77 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 939892691a26..d994d822900d 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2933,17 +2933,39 @@ static int sctp_setsockopt_maxburst(struct sock *sk, char __user *optval, int optlen) { + struct sctp_assoc_value params; + struct sctp_sock *sp; + struct sctp_association *asoc; int val; + int assoc_id = 0; - if (optlen != sizeof(int)) - return -EINVAL; - if (get_user(val, (int __user *)optval)) - return -EFAULT; - - if (val < 0) + if (optlen < sizeof(int)) return -EINVAL; - sctp_sk(sk)->max_burst = val; + if (optlen == sizeof(int)) { + printk(KERN_WARNING + "SCTP: Use of int in max_burst socket option deprecated\n"); + printk(KERN_WARNING + "SCTP: Use struct sctp_assoc_value instead\n"); + if (copy_from_user(&val, optval, optlen)) + return -EFAULT; + } else if (optlen == sizeof(struct sctp_assoc_value)) { + if (copy_from_user(¶ms, optval, optlen)) + return -EFAULT; + val = params.assoc_value; + assoc_id = params.assoc_id; + } else + return -EINVAL; + + sp = sctp_sk(sk); + + if (assoc_id != 0) { + asoc = sctp_id2assoc(sk, assoc_id); + if (!asoc) + return -EINVAL; + asoc->max_burst = val; + } else + sp->max_burst = val; return 0; } @@ -5005,20 +5027,45 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, char __user *optval, int __user *optlen) { - int val; + struct sctp_assoc_value params; + struct sctp_sock *sp; + struct sctp_association *asoc; if (len < sizeof(int)) return -EINVAL; - len = sizeof(int); + if (len == sizeof(int)) { + printk(KERN_WARNING + "SCTP: Use of int in max_burst socket option deprecated\n"); + printk(KERN_WARNING + "SCTP: Use struct sctp_assoc_value instead\n"); + params.assoc_id = 0; + } else if (len == sizeof (struct sctp_assoc_value)) { + if (copy_from_user(¶ms, optval, len)) + return -EFAULT; + } else + return -EINVAL; - val = sctp_sk(sk)->max_burst; - if (put_user(len, optlen)) - return -EFAULT; - if (copy_to_user(optval, &val, len)) - return -EFAULT; + sp = sctp_sk(sk); + + if (params.assoc_id != 0) { + asoc = sctp_id2assoc(sk, params.assoc_id); + if (!asoc) + return -EINVAL; + params.assoc_value = asoc->max_burst; + } else + params.assoc_value = sp->max_burst; + + if (len == sizeof(int)) { + if (copy_to_user(optval, ¶ms.assoc_value, len)) + return -EFAULT; + } else { + if (copy_to_user(optval, ¶ms, len)) + return -EFAULT; + } + + return 0; - return -ENOTSUPP; } static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, From dfec72285ef50f1a5ff342ed122652ccd3d0fb96 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 5 Mar 2008 18:36:28 -0800 Subject: [PATCH 14/47] net: replace __inline with inline Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/wan/sbni.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 15d5c58e57bc..e59255a155a9 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -751,7 +751,7 @@ upload_data( struct net_device *dev, unsigned framelen, unsigned frameno, } -static __inline void +static inline void send_complete( struct net_local *nl ) { #ifdef CONFIG_SBNI_MULTILINE From 4eb329a5aa113048ec9dbe2bd81ca27adab04e2d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 5 Mar 2008 18:37:16 -0800 Subject: [PATCH 15/47] irda: replace __inline with inline Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/net/irda/irttp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 32c385dd9e06..0788c23d2828 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -169,17 +169,17 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *skb, void irttp_flow_request(struct tsap_cb *self, LOCAL_FLOW flow); struct tsap_cb *irttp_dup(struct tsap_cb *self, void *instance); -static __inline __u32 irttp_get_saddr(struct tsap_cb *self) +static inline __u32 irttp_get_saddr(struct tsap_cb *self) { return irlmp_get_saddr(self->lsap); } -static __inline __u32 irttp_get_daddr(struct tsap_cb *self) +static inline __u32 irttp_get_daddr(struct tsap_cb *self) { return irlmp_get_daddr(self->lsap); } -static __inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) +static inline __u32 irttp_get_max_seg_size(struct tsap_cb *self) { return self->max_seg_size; } From d4f7751495747b0e857b2c302e37fe515cd03ef5 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 5 Mar 2008 18:37:39 -0800 Subject: [PATCH 16/47] isdn: replace __inline with inline Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_common.c | 4 ++-- drivers/isdn/i4l/isdn_v110.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 9cef6fcf587b..d4ad6992f776 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -981,13 +981,13 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) } -static __inline int +static inline int isdn_minor2drv(int minor) { return (dev->drvmap[minor]); } -static __inline int +static inline int isdn_minor2chan(int minor) { return (dev->chanmap[minor]); diff --git a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c index 5484d3c38a57..c5d02b6aafab 100644 --- a/drivers/isdn/i4l/isdn_v110.c +++ b/drivers/isdn/i4l/isdn_v110.c @@ -62,7 +62,7 @@ static unsigned char V110_OffMatrix_38400[] = * and to 67452301 when keylen = 2. This is necessary because ordering on * the isdn line is the other way. */ -static __inline unsigned char +static inline unsigned char FlipBits(unsigned char c, int keylen) { unsigned char b = c; From 5a346a10c0b1192e7eae52f0f3a332f1d3f11226 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 5 Mar 2008 18:38:07 -0800 Subject: [PATCH 17/47] atm: replace remaining __FUNCTION__ occurrences __FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison Signed-off-by: David S. Miller --- drivers/atm/firestream.c | 4 ++-- drivers/atm/fore200e.c | 4 ++-- drivers/atm/idt77252.c | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index c662d686154a..47c57a4294b7 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -331,8 +331,8 @@ module_param(fs_keystream, int, 0); #define FS_DEBUG_QSIZE 0x00001000 -#define func_enter() fs_dprintk (FS_DEBUG_FLOW, "fs: enter %s\n", __FUNCTION__) -#define func_exit() fs_dprintk (FS_DEBUG_FLOW, "fs: exit %s\n", __FUNCTION__) +#define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__) +#define func_exit() fs_dprintk(FS_DEBUG_FLOW, "fs: exit %s\n", __func__) static struct fs_dev *fs_boards = NULL; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f97e050338f0..9427a61f62b0 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -95,8 +95,8 @@ #if 1 #define ASSERT(expr) if (!(expr)) { \ printk(FORE200E "assertion failed! %s[%d]: %s\n", \ - __FUNCTION__, __LINE__, #expr); \ - panic(FORE200E "%s", __FUNCTION__); \ + __func__, __LINE__, #expr); \ + panic(FORE200E "%s", __func__); \ } #else #define ASSERT(expr) do {} while (0) diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index eee54c0cde68..b967919fb7e2 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -555,7 +555,7 @@ idt77252_tx_dump(struct idt77252_dev *card) struct vc_map *vc; int i; - printk("%s\n", __FUNCTION__); + printk("%s\n", __func__); for (i = 0; i < card->tct_size; i++) { vc = card->vcs[i]; if (!vc) @@ -1035,7 +1035,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2)); if (skb == NULL) { printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n", - card->name, __FUNCTION__, + card->name, __func__, le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2), le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4)); return; @@ -1873,7 +1873,7 @@ add_rx_skb(struct idt77252_dev *card, int queue, return; if (sb_pool_add(card, skb, queue)) { - printk("%s: SB POOL full\n", __FUNCTION__); + printk("%s: SB POOL full\n", __func__); goto outfree; } @@ -1883,7 +1883,7 @@ add_rx_skb(struct idt77252_dev *card, int queue, IDT77252_PRV_PADDR(skb) = paddr; if (push_rx_skb(card, skb, queue)) { - printk("%s: FB QUEUE full\n", __FUNCTION__); + printk("%s: FB QUEUE full\n", __func__); goto outunmap; } } @@ -3821,12 +3821,12 @@ static int __init idt77252_init(void) { struct sk_buff *skb; - printk("%s: at %p\n", __FUNCTION__, idt77252_init); + printk("%s: at %p\n", __func__, idt77252_init); if (sizeof(skb->cb) < sizeof(struct atm_skb_data) + sizeof(struct idt77252_skb_prv)) { printk(KERN_ERR "%s: skb->cb is too small (%lu < %lu)\n", - __FUNCTION__, (unsigned long) sizeof(skb->cb), + __func__, (unsigned long) sizeof(skb->cb), (unsigned long) sizeof(struct atm_skb_data) + sizeof(struct idt77252_skb_prv)); return -EIO; From cf3752e2d203bbbfc88d29e362e6938cef4339b3 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 5 Mar 2008 18:39:08 -0800 Subject: [PATCH 18/47] [PPPOL2TP]: Make locking calls softirq-safe Fix locking issues in the pppol2tp driver which can cause a kernel crash on SMP boxes. There were two problems:- 1. The driver was violating read_lock() and write_lock() scheduling rules because it wasn't using softirq-safe locks in softirq contexts. So we now consistently use the _bh variants of the lock functions. 2. The driver was calling sk_dst_get() in pppol2tp_xmit() which was taking sk_dst_lock in softirq context. We now call __sk_dst_get(). Signed-off-by: James Chapman Signed-off-by: David S. Miller --- drivers/net/pppol2tp.c | 58 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 86e5dba079fe..9a90cede0ecc 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -302,14 +302,14 @@ pppol2tp_session_find(struct pppol2tp_tunnel *tunnel, u16 session_id) struct pppol2tp_session *session; struct hlist_node *walk; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); hlist_for_each_entry(session, walk, session_list, hlist) { if (session->tunnel_addr.s_session == session_id) { - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return session; } } - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); return NULL; } @@ -320,14 +320,14 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); list_for_each_entry(tunnel, &pppol2tp_tunnel_list, list) { if (tunnel->stats.tunnel_id == tunnel_id) { - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } } - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return NULL; } @@ -344,7 +344,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_ struct sk_buff *skbp; u16 ns = PPPOL2TP_SKB_CB(skb)->ns; - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); skb_queue_walk(&session->reorder_q, skbp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); @@ -360,7 +360,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_ __skb_queue_tail(&session->reorder_q, skb); out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Dequeue a single skb. @@ -442,7 +442,7 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) * expect to send up next, dequeue it and any other * in-sequence packets behind it. */ - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); skb_queue_walk_safe(&session->reorder_q, skb, tmp) { if (time_after(jiffies, PPPOL2TP_SKB_CB(skb)->expires)) { session->stats.rx_seq_discards++; @@ -470,13 +470,13 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) goto out; } } - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); pppol2tp_recv_dequeue_skb(session, skb); - spin_lock(&session->reorder_q.lock); + spin_lock_bh(&session->reorder_q.lock); } out: - spin_unlock(&session->reorder_q.lock); + spin_unlock_bh(&session->reorder_q.lock); } /* Internal receive frame. Do the real work of receiving an L2TP data frame @@ -1059,7 +1059,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb) /* Get routing info from the tunnel socket */ dst_release(skb->dst); - skb->dst = sk_dst_get(sk_tun); + skb->dst = dst_clone(__sk_dst_get(sk_tun)); skb_orphan(skb); skb->sk = sk_tun; @@ -1107,7 +1107,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel) PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO, "%s: closing all sessions...\n", tunnel->name); - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); for (hash = 0; hash < PPPOL2TP_HASH_SIZE; hash++) { again: hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) { @@ -1129,7 +1129,7 @@ again: * disappear as we're jumping between locks. */ sock_hold(sk); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); lock_sock(sk); if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) { @@ -1154,11 +1154,11 @@ again: * list so we are guaranteed to make forward * progress. */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); goto again; } } - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); } /* Really kill the tunnel. @@ -1167,9 +1167,9 @@ again: static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel) { /* Remove from socket list */ - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_del_init(&tunnel->list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_dec(&pppol2tp_tunnel_count); kfree(tunnel); @@ -1245,9 +1245,9 @@ static void pppol2tp_session_destruct(struct sock *sk) /* Delete the session socket from the * hash */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_del_init(&session->hlist); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_dec(&pppol2tp_session_count); } @@ -1392,9 +1392,9 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id, /* Add tunnel to our list */ INIT_LIST_HEAD(&tunnel->list); - write_lock(&pppol2tp_tunnel_list_lock); + write_lock_bh(&pppol2tp_tunnel_list_lock); list_add(&tunnel->list, &pppol2tp_tunnel_list); - write_unlock(&pppol2tp_tunnel_list_lock); + write_unlock_bh(&pppol2tp_tunnel_list_lock); atomic_inc(&pppol2tp_tunnel_count); /* Bump the reference count. The tunnel context is deleted @@ -1599,11 +1599,11 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, sk->sk_user_data = session; /* Add session to the tunnel's hash list */ - write_lock(&tunnel->hlist_lock); + write_lock_bh(&tunnel->hlist_lock); hlist_add_head(&session->hlist, pppol2tp_session_id_hash(tunnel, session->tunnel_addr.s_session)); - write_unlock(&tunnel->hlist_lock); + write_unlock_bh(&tunnel->hlist_lock); atomic_inc(&pppol2tp_session_count); @@ -2205,7 +2205,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str int next = 0; int i; - read_lock(&tunnel->hlist_lock); + read_lock_bh(&tunnel->hlist_lock); for (i = 0; i < PPPOL2TP_HASH_SIZE; i++) { hlist_for_each_entry(session, walk, &tunnel->session_hlist[i], hlist) { if (curr == NULL) { @@ -2223,7 +2223,7 @@ static struct pppol2tp_session *next_session(struct pppol2tp_tunnel *tunnel, str } } out: - read_unlock(&tunnel->hlist_lock); + read_unlock_bh(&tunnel->hlist_lock); if (!found) session = NULL; @@ -2234,13 +2234,13 @@ static struct pppol2tp_tunnel *next_tunnel(struct pppol2tp_tunnel *curr) { struct pppol2tp_tunnel *tunnel = NULL; - read_lock(&pppol2tp_tunnel_list_lock); + read_lock_bh(&pppol2tp_tunnel_list_lock); if (list_is_last(&curr->list, &pppol2tp_tunnel_list)) { goto out; } tunnel = list_entry(curr->list.next, struct pppol2tp_tunnel, list); out: - read_unlock(&pppol2tp_tunnel_list_lock); + read_unlock_bh(&pppol2tp_tunnel_list_lock); return tunnel; } From e653181dd6b3ad38ce14904351b03a5388f4b0f7 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 5 Mar 2008 18:40:01 -0800 Subject: [PATCH 19/47] [PPPOL2TP]: Fix SMP issues in skb reorder queue handling When walking a session's packet reorder queue, use skb_queue_walk_safe() since the list could be modified inside the loop. Rearrange the unlinking skbs from the reorder queue such that it is done while the queue lock is held in pppol2tp_recv_dequeue() when walking the skb list. A version of this patch was suggested by Jarek Poplawski. Signed-off-by: James Chapman Signed-off-by: David S. Miller --- drivers/net/pppol2tp.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index 9a90cede0ecc..3d10ca050b79 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -342,10 +342,11 @@ static struct pppol2tp_tunnel *pppol2tp_tunnel_find(u16 tunnel_id) static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_buff *skb) { struct sk_buff *skbp; + struct sk_buff *tmp; u16 ns = PPPOL2TP_SKB_CB(skb)->ns; spin_lock_bh(&session->reorder_q.lock); - skb_queue_walk(&session->reorder_q, skbp) { + skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, @@ -371,10 +372,9 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s int length = PPPOL2TP_SKB_CB(skb)->length; struct sock *session_sock = NULL; - /* We're about to requeue the skb, so unlink it and return resources + /* We're about to requeue the skb, so return resources * to its current owner (a socket receive buffer). */ - skb_unlink(skb, &session->reorder_q); skb_orphan(skb); tunnel->stats.rx_packets++; @@ -470,6 +470,11 @@ static void pppol2tp_recv_dequeue(struct pppol2tp_session *session) goto out; } } + __skb_unlink(skb, &session->reorder_q); + + /* Process the skb. We release the queue lock while we + * do so to let other contexts process the queue. + */ spin_unlock_bh(&session->reorder_q.lock); pppol2tp_recv_dequeue_skb(session, skb); spin_lock_bh(&session->reorder_q.lock); From 09a76031f19bc77beb081e8ff7bfde731af93f50 Mon Sep 17 00:00:00 2001 From: SDiZ Date: Wed, 5 Mar 2008 18:43:50 -0800 Subject: [PATCH 20/47] bluetooth: CONWISE Technology based adapters with buggy SCO support (bugzilla #9027) From: SDiZ Fix the CONWISE Technology based adapters with buggy SCO support issue (bugzilla #9027) Signed-off-by: Andrew Morton Acked-by: Marcel Holtmann Signed-off-by: David S. Miller --- drivers/bluetooth/hci_usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index 372c7ef633da..4f8a744c90b7 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -148,6 +148,9 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, + /* CONWISE Technology based adapters with buggy SCO support */ + { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC }, + /* Belkin F8T012 and F8T013 devices */ { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, From 147e2d59833e994cc99341806a88b9e59be41391 Mon Sep 17 00:00:00 2001 From: Dave Young Date: Wed, 5 Mar 2008 18:45:59 -0800 Subject: [PATCH 21/47] bluetooth: hci_core: defer hci_unregister_sysfs() Alon Bar-Lev reports: Feb 16 23:41:33 alon1 usb 3-1: configuration #1 chosen from 1 choice Feb 16 23:41:33 alon1 BUG: unable to handle kernel NULL pointer dereference at virtual address 00000008 Feb 16 23:41:33 alon1 printing eip: c01b2db6 *pde = 00000000 Feb 16 23:41:33 alon1 Oops: 0000 [#1] PREEMPT Feb 16 23:41:33 alon1 Modules linked in: ppp_deflate zlib_deflate zlib_inflate bsd_comp ppp_async rfcomm l2cap hci_usb vmnet(P) vmmon(P) tun radeon drm autofs4 ipv6 aes_generic crypto_algapi ieee80211_crypt_ccmp nf_nat_irc nf_nat_ftp nf_conntrack_irc nf_conntrack_ftp ipt_MASQUERADE iptable_nat nf_nat ipt_REJECT xt_tcpudp ipt_LOG xt_limit xt_state nf_conntrack_ipv4 nf_conntrack iptable_filter ip_tables x_tables snd_pcm_oss snd_mixer_oss snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device bluetooth ppp_generic slhc ioatdma dca cfq_iosched cpufreq_powersave cpufreq_ondemand cpufreq_conservative acpi_cpufreq freq_table uinput fan af_packet nls_cp1255 nls_iso8859_1 nls_utf8 nls_base pcmcia snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm nsc_ircc snd_timer ipw2200 thinkpad_acpi irda snd ehci_hcd yenta_socket uhci_hcd psmouse ieee80211 soundcore intel_agp hwmon rsrc_nonstatic pcspkr e1000 crc_ccitt snd_page_alloc i2c_i801 ieee80211_crypt pcmcia_core agpgart thermal bat! tery nvram rtc sr_mod ac sg firmware_class button processor cdrom unix usbcore evdev ext3 jbd ext2 mbcache loop ata_piix libata sd_mod scsi_mod Feb 16 23:41:33 alon1 Feb 16 23:41:33 alon1 Pid: 4, comm: events/0 Tainted: P (2.6.24-gentoo-r2 #1) Feb 16 23:41:33 alon1 EIP: 0060:[] EFLAGS: 00010282 CPU: 0 Feb 16 23:41:33 alon1 EIP is at sysfs_get_dentry+0x26/0x80 Feb 16 23:41:33 alon1 EAX: 00000000 EBX: 00000000 ECX: 00000000 EDX: f48a2210 Feb 16 23:41:33 alon1 ESI: f72eb900 EDI: f4803ae0 EBP: f4803ae0 ESP: f7c49efc Feb 16 23:41:33 alon1 hcid[7004]: HCI dev 0 registered Feb 16 23:41:33 alon1 DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 Feb 16 23:41:33 alon1 Process events/0 (pid: 4, ti=f7c48000 task=f7c3efc0 task.ti=f7c48000) Feb 16 23:41:33 alon1 Stack: f7cb6140 f4822668 f7e71e10 c01b304d ffffffff ffffffff fffffffe c030ba9c Feb 16 23:41:33 alon1 f7cb6140 f4822668 f6da6720 f7cb6140 f4822668 f6da6720 c030ba8e c01ce20b Feb 16 23:41:33 alon1 f6e9dd00 c030ba8e f6da6720 f6e9dd00 f6e9dd00 00000000 f4822600 00000000 Feb 16 23:41:33 alon1 Call Trace: Feb 16 23:41:33 alon1 [] sysfs_move_dir+0x3d/0x1f0 Feb 16 23:41:33 alon1 [] kobject_move+0x9b/0x120 Feb 16 23:41:33 alon1 [] device_move+0x51/0x110 Feb 16 23:41:33 alon1 [] del_conn+0x0/0x70 [bluetooth] Feb 16 23:41:33 alon1 [] del_conn+0x19/0x70 [bluetooth] Feb 16 23:41:33 alon1 [] run_workqueue+0x81/0x140 Feb 16 23:41:33 alon1 [] schedule+0x168/0x2e0 Feb 16 23:41:33 alon1 [] autoremove_wake_function+0x0/0x50 Feb 16 23:41:33 alon1 [] worker_thread+0x9b/0xf0 Feb 16 23:41:33 alon1 [] autoremove_wake_function+0x0/0x50 Feb 16 23:41:33 alon1 [] worker_thread+0x0/0xf0 Feb 16 23:41:33 alon1 [] kthread+0x42/0x70 Feb 16 23:41:33 alon1 [] kthread+0x0/0x70 Feb 16 23:41:33 alon1 [] kernel_thread_helper+0x7/0x18 Feb 16 23:41:33 alon1 ======================= Feb 16 23:41:33 alon1 Code: 26 00 00 00 00 57 89 c7 a1 50 1b 3a c0 56 53 8b 70 38 85 f6 74 08 8b 0e 85 c9 74 58 ff 06 8b 56 50 39 fa 74 47 89 fb eb 02 89 c3 <8b> 43 08 39 c2 75 f7 8b 46 08 83 c0 68 e8 98 e7 10 00 8b 43 10 Feb 16 23:41:33 alon1 EIP: [] sysfs_get_dentry+0x26/0x80 SS:ESP 0068:f7c49efc Feb 16 23:41:33 alon1 ---[ end trace aae864e9592acc1d ]--- Defer hci_unregister_sysfs because hci device could be destructed while hci conn devices still there. Signed-off-by: Dave Young Tested-by: Stefan Seyfried Acked-by: Alon Bar-Lev Signed-off-by: Andrew Morton Acked-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 930b58e7149a..aec6929f5c16 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -902,8 +902,6 @@ int hci_unregister_dev(struct hci_dev *hdev) BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); - hci_unregister_sysfs(hdev); - write_lock_bh(&hci_dev_list_lock); list_del(&hdev->list); write_unlock_bh(&hci_dev_list_lock); @@ -915,6 +913,8 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UNREG); + hci_unregister_sysfs(hdev); + __hci_dev_put(hdev); return 0; From 04005dd9ae7bf1031408869c33df96149ebb1086 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 5 Mar 2008 18:47:03 -0800 Subject: [PATCH 22/47] bluetooth: Make hci_sock_cleanup() return void hci_sock_cleanup() always returns 0 and its return value isn't used anywhere in the code. Compile-tested with 'make allyesconfig && make net/bluetooth/bluetooth.ko' Signed-off-by: Tobias Klauser Signed-off-by: Andrew Morton Acked-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 2 +- net/bluetooth/hci_sock.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 771d17783c18..750648df13f4 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -170,7 +170,7 @@ static inline int skb_frags_no(struct sk_buff *skb) int bt_err(__u16 code); extern int hci_sock_init(void); -extern int hci_sock_cleanup(void); +extern void hci_sock_cleanup(void); extern int bt_sysfs_init(void); extern void bt_sysfs_cleanup(void); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 14991323c273..b5d4019d3572 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -734,7 +734,7 @@ error: return err; } -int __exit hci_sock_cleanup(void) +void __exit hci_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_HCI) < 0) BT_ERR("HCI socket unregistration failed"); @@ -742,6 +742,4 @@ int __exit hci_sock_cleanup(void) hci_unregister_notifier(&hci_sock_nblock); proto_unregister(&hci_sk_proto); - - return 0; } From a4e2acf01a7e5fcd960fc332335ca10313641f4b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 5 Mar 2008 18:47:40 -0800 Subject: [PATCH 23/47] bluetooth: make bnep_sock_cleanup() return void bnep_sock_cleanup() always returns 0 and its return value isn't used anywhere in the code. Signed-off-by: Tobias Klauser Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/bluetooth/bnep/bnep.h | 2 +- net/bluetooth/bnep/sock.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h index a2992280c3d1..e69244dd8de8 100644 --- a/net/bluetooth/bnep/bnep.h +++ b/net/bluetooth/bnep/bnep.h @@ -174,7 +174,7 @@ struct bnep_session { void bnep_net_setup(struct net_device *dev); int bnep_sock_init(void); -int bnep_sock_cleanup(void); +void bnep_sock_cleanup(void); static inline int bnep_mc_hash(__u8 *addr) { diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 81065e548a1f..201e5b1ce473 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c @@ -257,12 +257,10 @@ error: return err; } -int __exit bnep_sock_cleanup(void) +void __exit bnep_sock_cleanup(void) { if (bt_sock_unregister(BTPROTO_BNEP) < 0) BT_ERR("Can't unregister BNEP socket"); proto_unregister(&bnep_proto); - - return 0; } From 32c9874759651b69e496f89ec9e5e6702f67ffca Mon Sep 17 00:00:00 2001 From: Jon Schindler Date: Wed, 5 Mar 2008 18:49:21 -0800 Subject: [PATCH 24/47] drivers/net/appletalk/ltpc.c: replace init_module&cleanup_module with module_init&module_exit Replaced init_module and cleanup_module with static functions and module_init/module_exit. Signed-off-by: Jon Schindler Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/appletalk/ltpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 6ab2c2d4d673..fef5560bc7a2 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -1252,7 +1252,7 @@ module_param(irq, int, 0); module_param(dma, int, 0); -int __init init_module(void) +static int __init ltpc_module_init(void) { if(io == 0) printk(KERN_NOTICE @@ -1263,6 +1263,7 @@ int __init init_module(void) return PTR_ERR(dev_ltpc); return 0; } +module_init(ltpc_module_init); #endif static void __exit ltpc_cleanup(void) From 7249d4c3985454ee5cd150198bb21cb15dee242e Mon Sep 17 00:00:00 2001 From: Jon Schindler Date: Wed, 5 Mar 2008 18:49:51 -0800 Subject: [PATCH 25/47] drivers/net/arcnet/capmode.c: replace init_module&cleanup_module with module_init&module_exit Replaced init_module and cleanup_module with static functions and module_init/module_exit. Signed-off-by: Jon Schindler Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/arcnet/capmode.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index cc4610db6395..02cb8f1c1148 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c @@ -80,17 +80,19 @@ void arcnet_cap_init(void) #ifdef MODULE -int __init init_module(void) +static int __init capmode_module_init(void) { printk(VERSION); arcnet_cap_init(); return 0; } -void cleanup_module(void) +static void __exit capmode_module_exit(void) { arcnet_unregister_proto(&capmode_proto); } +module_init(capmode_module_init); +module_exit(capmode_module_exit); MODULE_LICENSE("GPL"); #endif /* MODULE */ From 3cfbb6771b11c161aaee0cc839f923fc208868b8 Mon Sep 17 00:00:00 2001 From: Jon Schindler Date: Wed, 5 Mar 2008 18:50:16 -0800 Subject: [PATCH 26/47] drivers/net/apne.c: replace init_module&cleanup_module with module_init&module_exit Replaced init_module and cleanup_module with static functions and module_init/module_exit. Signed-off-by: Jon Schindler Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/apne.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/apne.c b/drivers/net/apne.c index c12cbdf368b1..47a8275d3962 100644 --- a/drivers/net/apne.c +++ b/drivers/net/apne.c @@ -569,7 +569,7 @@ static irqreturn_t apne_interrupt(int irq, void *dev_id) #ifdef MODULE static struct net_device *apne_dev; -int __init init_module(void) +static int __init apne_module_init(void) { apne_dev = apne_probe(-1); if (IS_ERR(apne_dev)) @@ -577,7 +577,7 @@ int __init init_module(void) return 0; } -void __exit cleanup_module(void) +static void __exit apne_module_exit(void) { unregister_netdev(apne_dev); @@ -591,7 +591,8 @@ void __exit cleanup_module(void) free_netdev(apne_dev); } - +module_init(apne_module_init); +module_exit(apne_module_exit); #endif static int init_pcmcia(void) From e8a1d919d16abaccc4564bd913cac9a0c1aaf078 Mon Sep 17 00:00:00 2001 From: Jon Schindler Date: Wed, 5 Mar 2008 18:50:41 -0800 Subject: [PATCH 27/47] drivers/net/ac3200.c: replace init_module&cleanup_module with module_init&module_exit Replace init_module and cleanup_module with static functions and module_init/module_exit. Signed-off-by: Jon Schindler Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/ac3200.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c index 5136d94923aa..b1448637107f 100644 --- a/drivers/net/ac3200.c +++ b/drivers/net/ac3200.c @@ -369,7 +369,7 @@ MODULE_PARM_DESC(mem, "Memory base address(es)"); MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); MODULE_LICENSE("GPL"); -int __init init_module(void) +static int __init ac3200_module_init(void) { struct net_device *dev; int this_dev, found = 0; @@ -404,8 +404,7 @@ static void cleanup_card(struct net_device *dev) iounmap(ei_status.mem); } -void __exit -cleanup_module(void) +static void __exit ac3200_module_exit(void) { int this_dev; @@ -418,4 +417,6 @@ cleanup_module(void) } } } +module_init(ac3200_module_init); +module_exit(ac3200_module_exit); #endif /* MODULE */ From 02ff05c49d7804f2574f358a937b43a41d15e36e Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 5 Mar 2008 18:51:19 -0800 Subject: [PATCH 28/47] net/enc28j60: oops fix Prevent oops on enc28j60 packet RX: make sure buffers are aligned. Not all architectures support unaligned accesses in kernel space. Signed-off-by: David Brownell Acked-by: Claudio Lanconelli Signed-off-by: David S. Miller --- drivers/net/enc28j60.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 0809a6a5a286..46a90e9ec563 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -900,7 +900,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (RSV_GETBIT(rxstat, RSV_LENCHECKERR)) ndev->stats.rx_frame_errors++; } else { - skb = dev_alloc_skb(len); + skb = dev_alloc_skb(len + NET_IP_ALIGN); if (!skb) { if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, @@ -908,6 +908,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) ndev->stats.rx_dropped++; } else { skb->dev = ndev; + skb_reserve(skb, NET_IP_ALIGN); /* copy the packet from the receive buffer */ enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv), len, skb_put(skb, len)); From 1ff82fe0024e8070c38346b8abc1ff09612dea4c Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 5 Mar 2008 18:53:55 -0800 Subject: [PATCH 29/47] RxRPC: fix rxrpc_recvmsg()'s returning of msg_name Fix rxrpc_recvmsg() to return msg_name correctly. We shouldn't overwrite the *msg struct, but should rather write into msg->msg_name (there's a '&' unary operator that shouldn't be there). Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/rxrpc/ar-recvmsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index f19121d4795b..a39bf97f8830 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c @@ -143,7 +143,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, /* copy the peer address and timestamp */ if (!continue_call) { if (msg->msg_name && msg->msg_namelen > 0) - memcpy(&msg->msg_name, &call->conn->trans->peer->srx, + memcpy(msg->msg_name, + &call->conn->trans->peer->srx, sizeof(call->conn->trans->peer->srx)); sock_recv_timestamp(msg, &rx->sk, skb); } From e9720acd728a46cb40daa52c99a979f7c4ff195c Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 7 Mar 2008 11:08:40 -0800 Subject: [PATCH 30/47] [NET]: Make /proc/net a symlink on /proc/self/net (v3) Current /proc/net is done with so called "shadows", but current implementation is broken and has little chances to get fixed. The problem is that dentries subtree of /proc/net directory has fancy revalidation rules to make processes living in different net namespaces see different entries in /proc/net subtree, but currently, tasks see in the /proc/net subdir the contents of any other namespace, depending on who opened the file first. The proposed fix is to turn /proc/net into a symlink, which points to /proc/self/net, which in turn shows what previously was in /proc/net - the network-related info, from the net namespace the appropriate task lives in. # ls -l /proc/net lrwxrwxrwx 1 root root 8 Mar 5 15:17 /proc/net -> self/net In other words - this behaves like /proc/mounts, but unlike "mounts", "net" is not a file, but a directory. Changes from v2: * Fixed discrepancy of /proc/net nlink count and selinux labeling screwup pointed out by Stephen. To get the correct nlink count the ->getattr callback for /proc/net is overridden to read one from the net->proc_net entry. To make selinux still work the net->proc_net entry is initialized properly, i.e. with the "net" name and the proc_net parent. Selinux fixes are Acked-by: Stephen Smalley Changes from v1: * Fixed a task_struct leak in get_proc_task_net, pointed out by Paul. Signed-off-by: Pavel Emelyanov Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- fs/proc/base.c | 1 + fs/proc/generic.c | 26 +++++--- fs/proc/internal.h | 7 +++ fs/proc/proc_net.c | 117 +++++++++++++++++++++++++++--------- include/linux/proc_fs.h | 3 - include/net/net_namespace.h | 1 - 6 files changed, 114 insertions(+), 41 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 96ee899d6502..cc43cf0c1fa5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2274,6 +2274,7 @@ static const struct pid_entry tgid_base_stuff[] = { DIR("task", S_IRUGO|S_IXUGO, task), DIR("fd", S_IRUSR|S_IXUSR, fd), DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), + DIR("net", S_IRUGO|S_IXUSR, net), REG("environ", S_IRUSR, environ), INF("auxv", S_IRUSR, pid_auxv), ONE("status", S_IRUGO, pid_status), diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 68971e66cd41..a36ad3c75cf4 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -377,15 +377,14 @@ static struct dentry_operations proc_dentry_operations = * Don't create negative dentries here, return -ENOENT by hand * instead. */ -struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) +struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, + struct dentry *dentry) { struct inode *inode = NULL; - struct proc_dir_entry * de; int error = -ENOENT; lock_kernel(); spin_lock(&proc_subdir_lock); - de = PDE(dir); if (de) { for (de = de->subdir; de ; de = de->next) { if (de->namelen != dentry->d_name.len) @@ -393,8 +392,6 @@ struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry, struct nam if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { unsigned int ino; - if (de->shadow_proc) - de = de->shadow_proc(current, de); ino = de->low_ino; de_get(de); spin_unlock(&proc_subdir_lock); @@ -417,6 +414,12 @@ out_unlock: return ERR_PTR(error); } +struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + return proc_lookup_de(PDE(dir), dir, dentry); +} + /* * This returns non-zero if at EOF, so that the /proc * root directory can use this and check if it should @@ -426,10 +429,9 @@ out_unlock: * value of the readdir() call, as long as it's non-negative * for success.. */ -int proc_readdir(struct file * filp, - void * dirent, filldir_t filldir) +int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, + filldir_t filldir) { - struct proc_dir_entry * de; unsigned int ino; int i; struct inode *inode = filp->f_path.dentry->d_inode; @@ -438,7 +440,6 @@ int proc_readdir(struct file * filp, lock_kernel(); ino = inode->i_ino; - de = PDE(inode); if (!de) { ret = -EINVAL; goto out; @@ -499,6 +500,13 @@ out: unlock_kernel(); return ret; } +int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + + return proc_readdir_de(PDE(inode), filp, dirent, filldir); +} + /* * These are the generic /proc directory operations. They * use the in-memory "struct proc_dir_entry" tree to parse diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 1c81c8f1aeed..bc72f5c8c47d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -64,6 +64,8 @@ extern const struct file_operations proc_numa_maps_operations; extern const struct file_operations proc_smaps_operations; extern const struct file_operations proc_clear_refs_operations; extern const struct file_operations proc_pagemap_operations; +extern const struct file_operations proc_net_operations; +extern const struct inode_operations proc_net_inode_operations; void free_proc_entry(struct proc_dir_entry *de); @@ -83,3 +85,8 @@ static inline int proc_fd(struct inode *inode) { return PROC_I(inode)->fd; } + +struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *ino, + struct dentry *dentry); +int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, + filldir_t filldir); diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 14e9b5aaf863..4caa5f774fb7 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -63,6 +63,82 @@ int seq_release_net(struct inode *ino, struct file *f) } EXPORT_SYMBOL_GPL(seq_release_net); +static struct net *get_proc_task_net(struct inode *dir) +{ + struct task_struct *task; + struct nsproxy *ns; + struct net *net = NULL; + + rcu_read_lock(); + task = pid_task(proc_pid(dir), PIDTYPE_PID); + if (task != NULL) { + ns = task_nsproxy(task); + if (ns != NULL) + net = get_net(ns->net_ns); + } + rcu_read_unlock(); + + return net; +} + +static struct dentry *proc_tgid_net_lookup(struct inode *dir, + struct dentry *dentry, struct nameidata *nd) +{ + struct dentry *de; + struct net *net; + + de = ERR_PTR(-ENOENT); + net = get_proc_task_net(dir); + if (net != NULL) { + de = proc_lookup_de(net->proc_net, dir, dentry); + put_net(net); + } + return de; +} + +static int proc_tgid_net_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + struct net *net; + + net = get_proc_task_net(inode); + + generic_fillattr(inode, stat); + + if (net != NULL) { + stat->nlink = net->proc_net->nlink; + put_net(net); + } + + return 0; +} + +const struct inode_operations proc_net_inode_operations = { + .lookup = proc_tgid_net_lookup, + .getattr = proc_tgid_net_getattr, +}; + +static int proc_tgid_net_readdir(struct file *filp, void *dirent, + filldir_t filldir) +{ + int ret; + struct net *net; + + ret = -EINVAL; + net = get_proc_task_net(filp->f_path.dentry->d_inode); + if (net != NULL) { + ret = proc_readdir_de(net->proc_net, filp, dirent, filldir); + put_net(net); + } + return ret; +} + +const struct file_operations proc_net_operations = { + .read = generic_read_dir, + .readdir = proc_tgid_net_readdir, +}; + struct proc_dir_entry *proc_net_fops_create(struct net *net, const char *name, mode_t mode, const struct file_operations *fops) @@ -83,14 +159,6 @@ struct net *get_proc_net(const struct inode *inode) } EXPORT_SYMBOL_GPL(get_proc_net); -static struct proc_dir_entry *shadow_pde; - -static struct proc_dir_entry *proc_net_shadow(struct task_struct *task, - struct proc_dir_entry *de) -{ - return task->nsproxy->net_ns->proc_net; -} - struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, struct proc_dir_entry *parent) { @@ -104,45 +172,39 @@ EXPORT_SYMBOL_GPL(proc_net_mkdir); static __net_init int proc_net_ns_init(struct net *net) { - struct proc_dir_entry *root, *netd, *net_statd; + struct proc_dir_entry *netd, *net_statd; int err; err = -ENOMEM; - root = kzalloc(sizeof(*root), GFP_KERNEL); - if (!root) + netd = kzalloc(sizeof(*netd), GFP_KERNEL); + if (!netd) goto out; - err = -EEXIST; - netd = proc_net_mkdir(net, "net", root); - if (!netd) - goto free_root; + netd->data = net; + netd->nlink = 2; + netd->name = "net"; + netd->namelen = 3; + netd->parent = &proc_root; err = -EEXIST; net_statd = proc_net_mkdir(net, "stat", netd); if (!net_statd) goto free_net; - root->data = net; - - net->proc_net_root = root; net->proc_net = netd; net->proc_net_stat = net_statd; - err = 0; + return 0; +free_net: + kfree(netd); out: return err; -free_net: - remove_proc_entry("net", root); -free_root: - kfree(root); - goto out; } static __net_exit void proc_net_ns_exit(struct net *net) { remove_proc_entry("stat", net->proc_net); - remove_proc_entry("net", net->proc_net_root); - kfree(net->proc_net_root); + kfree(net->proc_net); } static struct pernet_operations __net_initdata proc_net_ns_ops = { @@ -152,8 +214,7 @@ static struct pernet_operations __net_initdata proc_net_ns_ops = { int __init proc_net_init(void) { - shadow_pde = proc_mkdir("net", NULL); - shadow_pde->shadow_proc = proc_net_shadow; + proc_symlink("net", NULL, "self/net"); return register_pernet_subsys(&proc_net_ns_ops); } diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index d9a9e718ad19..9b6c935f69cf 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -50,8 +50,6 @@ typedef int (read_proc_t)(char *page, char **start, off_t off, typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data); typedef int (get_info_t)(char *, char **, off_t, int); -typedef struct proc_dir_entry *(shadow_proc_t)(struct task_struct *task, - struct proc_dir_entry *pde); struct proc_dir_entry { unsigned int low_ino; @@ -82,7 +80,6 @@ struct proc_dir_entry { int pde_users; /* number of callers into module in progress */ spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ struct completion *pde_unload_completion; - shadow_proc_t *shadow_proc; }; struct kcore_list { diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 28738b7d53eb..923f2b8b9096 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -31,7 +31,6 @@ struct net { struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; - struct proc_dir_entry *proc_net_root; struct list_head sysctl_table_headers; From e621e69137b24fdbbe7ad28214e8d81e614c25b7 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 7 Mar 2008 11:11:13 -0800 Subject: [PATCH 31/47] [NET]: include into linux/ethtool.h for __u* typedef Signed-off-by: Kirill A. Shutemov Signed-off-by: David S. Miller --- include/linux/ethtool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index fcbe8b640ffb..c8d216357865 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -12,6 +12,7 @@ #ifndef _LINUX_ETHTOOL_H #define _LINUX_ETHTOOL_H +#include /* This should work for both 32 and 64 bit userland. */ struct ethtool_cmd { From b5e85dee2a5433246d5b7488918a1a0ad22c046a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 10 Mar 2008 16:41:06 -0700 Subject: [PATCH 32/47] [NETFILTER]: nfnetlink: fix ifdef in nfnetlink_compat.h Use __KERNEL__ instead of __KERNEL to make sure the headers are not usable by the kernel. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink_compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h index 02a42d875cf7..e1451760c9cd 100644 --- a/include/linux/netfilter/nfnetlink_compat.h +++ b/include/linux/netfilter/nfnetlink_compat.h @@ -1,6 +1,6 @@ #ifndef _NFNETLINK_COMPAT_H #define _NFNETLINK_COMPAT_H -#ifndef __KERNEL +#ifndef __KERNEL__ /* Old nfnetlink macros for userspace */ /* nfnetlink groups: Up to 32 maximum */ From cabaa9bfb01eb4cee97ffb8a18405f4c5175d3d9 Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Mon, 10 Mar 2008 16:41:43 -0700 Subject: [PATCH 33/47] [NETFILTER]: nfnetlink_queue: fix computation of allocated size for netlink skb. Size of the netlink skb was wrongly computed because the formula was using NLMSG_ALIGN instead of NLMSG_SPACE. NLMSG_ALIGN does not add the room for netlink header as NLMSG_SPACE does. This was causing a failure of message building in some cases. On my test system, all messages for packets in range [8*k+41, 8*k+48] where k is an integer were invalid and the corresponding packets were dropped. Signed-off-by: Eric Leblond Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 0043d3a9f87e..c0cc3d3618a3 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -224,7 +224,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, struct net_device *indev; struct net_device *outdev; - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ From 7000d38d6126d6ef928605bdacebc9f12279c5aa Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Mon, 10 Mar 2008 16:42:04 -0700 Subject: [PATCH 34/47] [NETFILTER]: nfnetlink_log: fix computation of netlink skb size This patch is similar to nfnetlink_queue fixes. It fixes the computation of skb size by using NLMSG_SPACE instead of NLMSG_ALIGN. Signed-off-by: Eric Leblond Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 7efa40d47393..c6802c0d6ed8 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -556,7 +556,7 @@ nfulnl_log_packet(unsigned int pf, /* FIXME: do we want to make the size calculation conditional based on * what is actually present? way more branches and checks, but more * memory efficient... */ - size = NLMSG_ALIGN(sizeof(struct nfgenmsg)) + size = NLMSG_SPACE(sizeof(struct nfgenmsg)) + nla_total_size(sizeof(struct nfulnl_msg_packet_hdr)) + nla_total_size(sizeof(u_int32_t)) /* ifindex */ + nla_total_size(sizeof(u_int32_t)) /* ifindex */ From 4f4c9430cf5ee1ca3567bc88faf8b4c18ed0bd13 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Mon, 10 Mar 2008 16:42:40 -0700 Subject: [PATCH 35/47] [NETFILTER]: xt_time: fix failure to match on Sundays From: Andrew Schulman xt_time_match() in net/netfilter/xt_time.c in kernel 2.6.24 never matches on Sundays. On my host I have a rule like iptables -A OUTPUT -m time --weekdays Sun -j REJECT and it never matches. The problem is in localtime_2(), which uses r->weekday = (4 + r->dse) % 7; to map the epoch day onto a weekday in {0,...,6}. In particular this gives 0 for Sundays. But 0 has to be wrong; a weekday of 0 can never match. xt_time_match() has if (!(info->weekdays_match & (1 << current_time.weekday))) return false; and when current_time.weekday = 0, the result of the & is always zero, even when info->weekdays_match = XT_TIME_ALL_WEEKDAYS = 0xFE. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/xt_time.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c index e9a8794bc3ab..9fa2e0824708 100644 --- a/net/netfilter/xt_time.c +++ b/net/netfilter/xt_time.c @@ -95,8 +95,11 @@ static inline void localtime_2(struct xtm *r, time_t time) */ r->dse = time / 86400; - /* 1970-01-01 (w=0) was a Thursday (4). */ - r->weekday = (4 + r->dse) % 7; + /* + * 1970-01-01 (w=0) was a Thursday (4). + * -1 and +1 map Sunday properly onto 7. + */ + r->weekday = (4 + r->dse - 1) % 7 + 1; } static void localtime_3(struct xtm *r, time_t time) From 3d89e9cf3690b4645ce73b86c219c8188f8fa50a Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 10 Mar 2008 16:43:10 -0700 Subject: [PATCH 36/47] [NETFILTER]: nf_conntrack: add \n to "expectation table full" message Signed-off-by: Alexey Dobriyan Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_expect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index e06bf0028bb1..684ec9c1ad38 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -381,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect) if (nf_ct_expect_count >= nf_ct_expect_max) { if (net_ratelimit()) printk(KERN_WARNING - "nf_conntrack: expectation table full"); + "nf_conntrack: expectation table full\n"); ret = -EMFILE; goto out; } From 019f692ea719a2da17606511d2648b8cc1762268 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 10 Mar 2008 16:43:41 -0700 Subject: [PATCH 37/47] [NETFILTER]: nf_conntrack: replace horrible hack with ksize() There's a horrible slab abuse in net/netfilter/nf_conntrack_extend.c that can be replaced with a call to ksize(). Cc: Christoph Lameter Signed-off-by: Pekka Enberg Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/netfilter/nf_conntrack_extend.h | 1 - net/netfilter/nf_conntrack_extend.c | 19 +++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index 49aac6323fbe..f736e842977f 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -17,7 +17,6 @@ enum nf_ct_ext_id struct nf_ct_ext { u8 offset[NF_CT_EXT_NUM]; u8 len; - u8 real_len; char data[0]; }; diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 8b9be1e978cd..2bd9963b5b3e 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c @@ -19,14 +19,6 @@ static struct nf_ct_ext_type *nf_ct_ext_types[NF_CT_EXT_NUM]; static DEFINE_MUTEX(nf_ct_ext_type_mutex); -/* Horrible trick to figure out smallest amount worth kmallocing. */ -#define CACHE(x) (x) + 0 * -enum { - NF_CT_EXT_MIN_SIZE = -#include - 1 }; -#undef CACHE - void __nf_ct_ext_destroy(struct nf_conn *ct) { unsigned int i; @@ -53,7 +45,7 @@ EXPORT_SYMBOL(__nf_ct_ext_destroy); static void * nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) { - unsigned int off, len, real_len; + unsigned int off, len; struct nf_ct_ext_type *t; rcu_read_lock(); @@ -61,16 +53,14 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) BUG_ON(t == NULL); off = ALIGN(sizeof(struct nf_ct_ext), t->align); len = off + t->len; - real_len = t->alloc_size; rcu_read_unlock(); - *ext = kzalloc(real_len, gfp); + *ext = kzalloc(t->alloc_size, gfp); if (!*ext) return NULL; (*ext)->offset[id] = off; (*ext)->len = len; - (*ext)->real_len = real_len; return (void *)(*ext) + off; } @@ -95,7 +85,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) newlen = newoff + t->len; rcu_read_unlock(); - if (newlen >= ct->ext->real_len) { + if (newlen >= ksize(ct->ext)) { new = kmalloc(newlen, gfp); if (!new) return NULL; @@ -114,7 +104,6 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) rcu_read_unlock(); } kfree(ct->ext); - new->real_len = newlen; ct->ext = new; } @@ -156,8 +145,6 @@ static void update_alloc_size(struct nf_ct_ext_type *type) t1->alloc_size = ALIGN(t1->alloc_size, t2->align) + t2->len; } - if (t1->alloc_size < NF_CT_EXT_MIN_SIZE) - t1->alloc_size = NF_CT_EXT_MIN_SIZE; } } From b7047a1c886386b10a103b4fea26678db8b57832 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 10 Mar 2008 16:44:13 -0700 Subject: [PATCH 38/47] [NETFILTER]: nfnetlink_log: fix EPERM when binding/unbinding and instance 0 exists When binding or unbinding to an address family, the res_id is usually set to zero. When logging instance 0 already exists and is owned by a different process, this makes nfunl_recv_config return -EPERM without performing the bind operation. Since no operation on the foreign logging instance itself was requested, this is incorrect. Move bind/unbind commands before the queue instance permissions checks. Also remove an incorrect comment. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_log.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index c6802c0d6ed8..bf3f19b21fe4 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -702,20 +702,30 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); u_int16_t group_num = ntohs(nfmsg->res_id); struct nfulnl_instance *inst; + struct nfulnl_msg_config_cmd *cmd = NULL; int ret = 0; + if (nfula[NFULA_CFG_CMD]) { + u_int8_t pf = nfmsg->nfgen_family; + cmd = nla_data(nfula[NFULA_CFG_CMD]); + + /* Commands without queue context */ + switch (cmd->command) { + case NFULNL_CFG_CMD_PF_BIND: + return nf_log_register(pf, &nfulnl_logger); + case NFULNL_CFG_CMD_PF_UNBIND: + nf_log_unregister_pf(pf); + return 0; + } + } + inst = instance_lookup_get(group_num); if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { ret = -EPERM; goto out_put; } - if (nfula[NFULA_CFG_CMD]) { - u_int8_t pf = nfmsg->nfgen_family; - struct nfulnl_msg_config_cmd *cmd; - - cmd = nla_data(nfula[NFULA_CFG_CMD]); - + if (cmd != NULL) { switch (cmd->command) { case NFULNL_CFG_CMD_BIND: if (inst) { @@ -738,14 +748,6 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, instance_destroy(inst); goto out; - case NFULNL_CFG_CMD_PF_BIND: - ret = nf_log_register(pf, &nfulnl_logger); - break; - case NFULNL_CFG_CMD_PF_UNBIND: - /* This is a bug and a feature. We cannot unregister - * other handlers, like nfnetlink_inst can */ - nf_log_unregister_pf(pf); - break; default: ret = -ENOTSUPP; break; From 914afea84e3e20cdbcd040f8387a0e6ef20ffc97 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 10 Mar 2008 16:44:36 -0700 Subject: [PATCH 39/47] [NETFILTER]: nfnetlink_queue: fix EPERM when binding/unbinding and instance 0 exists Similar to the nfnetlink_log problem, nfnetlink_queue incorrectly returns -EPERM when binding or unbinding to an address family and queueing instance 0 exists and is owned by a different process. Unlike nfnetlink_log it previously completes the operation, but it is still incorrect. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_queue.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index c0cc3d3618a3..012cb6910820 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -703,19 +703,12 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, /* Commands without queue context - might sleep */ switch (cmd->command) { case NFQNL_CFG_CMD_PF_BIND: - ret = nf_register_queue_handler(ntohs(cmd->pf), - &nfqh); - break; + return nf_register_queue_handler(ntohs(cmd->pf), + &nfqh); case NFQNL_CFG_CMD_PF_UNBIND: - ret = nf_unregister_queue_handler(ntohs(cmd->pf), - &nfqh); - break; - default: - break; + return nf_unregister_queue_handler(ntohs(cmd->pf), + &nfqh); } - - if (ret < 0) - return ret; } rcu_read_lock(); From 94be1a3f365e2b9f2615575d7fef16a0bad106a3 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 10 Mar 2008 16:45:05 -0700 Subject: [PATCH 40/47] [NETFILTER]: nf_queue: don't return error when unregistering a non-existant handler Commit ce7663d84: [NETFILTER]: nfnetlink_queue: don't unregister handler of other subsystem changed nf_unregister_queue_handler to return an error when attempting to unregister a queue handler that is not identical to the one passed in. This is correct in case we really do have a different queue handler already registered, but some existing userspace code always does an unbind before bind and aborts if that fails, so try to be nice and return success in that case. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index bfc2928c1912..ddc80ea114cd 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -51,7 +51,7 @@ int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh) return -EINVAL; mutex_lock(&queue_handler_mutex); - if (queue_handler[pf] != qh) { + if (queue_handler[pf] && queue_handler[pf] != qh) { mutex_unlock(&queue_handler_mutex); return -EINVAL; } From 97ed83905e5f8547a94a8066441351c6920728a1 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 6 Mar 2008 13:08:09 -0500 Subject: [PATCH 41/47] drivers/net/Kconfig: fix whitespace for GELIC_WIRELESS entry Signed-off-by: John W. Linville --- drivers/net/Kconfig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a64bb415f10c..fe7b5ec09708 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2366,15 +2366,15 @@ config GELIC_NET module will be called ps3_gelic. config GELIC_WIRELESS - bool "PS3 Wireless support" - depends on GELIC_NET - select WIRELESS_EXT - help - This option adds the support for the wireless feature of PS3. - If you have the wireless-less model of PS3 or have no plan to - use wireless feature, disabling this option saves memory. As - the driver automatically distinguishes the models, you can - safely enable this option even if you have a wireless-less model. + bool "PS3 Wireless support" + depends on GELIC_NET + select WIRELESS_EXT + help + This option adds the support for the wireless feature of PS3. + If you have the wireless-less model of PS3 or have no plan to + use wireless feature, disabling this option saves memory. As + the driver automatically distinguishes the models, you can + safely enable this option even if you have a wireless-less model. config GIANFAR tristate "Gianfar Ethernet" From 5f0547c2813d4677908fa6de02f9911d25996515 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Thu, 6 Mar 2008 10:30:21 +0100 Subject: [PATCH 42/47] libertas: fix the 'compare command with itself' properly |libertas: Invalid CMD_RESP 8012 to command 50! The special case got mixed up in 8a96df80b3. Signed-off-by: Sebastian Siewior Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmdresp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index bdc6a1cc2103..f0ef7081bdeb 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -578,7 +578,7 @@ int lbs_process_rx_command(struct lbs_private *priv) goto done; } if (respcmd != CMD_RET(curcmd) && - respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) { + respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) { lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd); spin_unlock_irqrestore(&priv->driver_lock, flags); ret = -1; From fbb0a27a8ad56f822f479ee85446d9c29483a3d1 Mon Sep 17 00:00:00 2001 From: Adam Baker Date: Sun, 9 Mar 2008 22:40:40 +0100 Subject: [PATCH 43/47] rt2x00: never disable multicast because it disables broadcast too On rt73 and rt61 disabling reception of multicast packets also disables broadcast traffic which we never want to do. Therefore we should never disable multicast. Signed-off-by: Adam Baker Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt61pci.c | 4 ++-- drivers/net/wireless/rt2x00/rt73usb.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e808db98f2f5..93ea212fedd5 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2302,9 +2302,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4fac2d414d84..2917700a2549 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1869,9 +1869,9 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, * Apply some rules to the filters: * - Some filters imply different filters to be set. * - Some things we can't filter out at all. + * - Multicast filter seems to kill broadcast traffic so never use it. */ - if (mc_count) - *total_flags |= FIF_ALLMULTI; + *total_flags |= FIF_ALLMULTI; if (*total_flags & FIF_OTHER_BSS || *total_flags & FIF_PROMISC_IN_BSS) *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; From 445815d7ea4f59baf103f28b45f7dd45f21ff75d Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sun, 9 Mar 2008 22:42:32 +0100 Subject: [PATCH 44/47] rt2x00: Add new D-Link USB ID Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 2917700a2549..8103d41a1543 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2098,6 +2098,7 @@ static struct usb_device_id rt73usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gigabyte */ From 5ea3a7480606cef06321cd85bc5113c72d2c7c68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Tue, 11 Mar 2008 17:55:27 -0700 Subject: [PATCH 45/47] [TCP]: Prevent sending past receiver window with TSO (at last skb) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With TSO it was possible to send past the receiver window when the skb to be sent was the last in the write queue while the receiver window is the limiting factor. One can notice that there's a loophole in the tcp_mss_split_point that lacked a receiver window check for the tcp_write_queue_tail() if also cwnd was smaller than the full skb. Noticed by Thomas Gleixner in form of "Treason uncloaked! Peer ... shrinks window .... Repaired." messages (the peer didn't actually shrink its window as the message suggests, we had just sent something past it without a permission to do so). Signed-off-by: Ilpo Järvinen Tested-by: Thomas Gleixner Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ed750f9ceb07..01578f544ad6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1035,6 +1035,13 @@ static void tcp_cwnd_validate(struct sock *sk) * introducing MSS oddities to segment boundaries. In rare cases where * mss_now != mss_cache, we will request caller to create a small skb * per input skb which could be mostly avoided here (if desired). + * + * We explicitly want to create a request for splitting write queue tail + * to a small skb for Nagle purposes while avoiding unnecessary modulos, + * thus all the complexity (cwnd_len is always MSS multiple which we + * return whenever allowed by the other factors). Basically we need the + * modulo only when the receiver window alone is the limiting factor or + * when we would be allowed to send the split-due-to-Nagle skb fully. */ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd) @@ -1048,10 +1055,11 @@ static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb, if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk))) return cwnd_len; - if (skb == tcp_write_queue_tail(sk) && cwnd_len <= skb->len) + needed = min(skb->len, window); + + if (skb == tcp_write_queue_tail(sk) && cwnd_len <= needed) return cwnd_len; - needed = min(skb->len, window); return needed - needed % mss_now; } From b2211a361a4289c83971f89da53fe2eb9e72769d Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 11 Mar 2008 18:03:35 -0700 Subject: [PATCH 46/47] net: fix build with CONFIG_NET=n fs/built-in.o:(.rodata+0x1134): undefined reference to `proc_net_inode_operations' fs/built-in.o:(.rodata+0x1138): undefined reference to `proc_net_operations' Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- fs/proc/base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index cc43cf0c1fa5..3217774d269f 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2274,7 +2274,9 @@ static const struct pid_entry tgid_base_stuff[] = { DIR("task", S_IRUGO|S_IXUGO, task), DIR("fd", S_IRUSR|S_IXUSR, fd), DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), +#ifdef CONFIG_NET DIR("net", S_IRUGO|S_IXUSR, net), +#endif REG("environ", S_IRUSR, environ), INF("auxv", S_IRUSR, pid_auxv), ONE("status", S_IRUGO, pid_status), From 22626216c46f2ec86287e75ea86dd9ac3df54265 Mon Sep 17 00:00:00 2001 From: Chidambar 'ilLogict' Zinnoury Date: Tue, 11 Mar 2008 18:05:02 -0700 Subject: [PATCH 47/47] [SCTP]: Fix local_addr deletions during list traversals. Since the lists are circular, we need to explicitely tag the address to be deleted since we might end up freeing the list head instead. This fixes some interesting SCTP crashes. Signed-off-by: Chidambar 'ilLogict' Zinnoury Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/bind_addr.c | 4 +++- net/sctp/ipv6.c | 4 +++- net/sctp/protocol.c | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index a27511ebc4cb..ceefda025e2d 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -209,6 +209,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) { struct sctp_sockaddr_entry *addr, *temp; + int found = 0; /* We hold the socket lock when calling this function, * and that acts as a writer synchronizing lock. @@ -216,13 +217,14 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) list_for_each_entry_safe(addr, temp, &bp->address_list, list) { if (sctp_cmp_addr_exact(&addr->a, del_addr)) { /* Found the exact match. */ + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } - if (addr && !addr->valid) { + if (found) { call_rcu(&addr->rcu, sctp_local_addr_free); SCTP_DBG_OBJCNT_DEC(addr); return 0; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 87f940587d5f..9aa0733aee87 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -89,6 +89,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; switch (ev) { case NETDEV_UP: @@ -111,13 +112,14 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, &sctp_local_addr_list, list) { if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; } diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 688546dccd82..ad0a4069b95b 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -628,6 +628,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; struct sctp_sockaddr_entry *addr = NULL; struct sctp_sockaddr_entry *temp; + int found = 0; switch (ev) { case NETDEV_UP: @@ -647,13 +648,14 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, list_for_each_entry_safe(addr, temp, &sctp_local_addr_list, list) { if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) { + found = 1; addr->valid = 0; list_del_rcu(&addr->list); break; } } spin_unlock_bh(&sctp_local_addr_lock); - if (addr && !addr->valid) + if (found) call_rcu(&addr->rcu, sctp_local_addr_free); break; }