]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 Aug 2010 22:42:44 +0000 (15:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 Aug 2010 22:42:44 +0000 (15:42 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  net/ipv4: Eliminate kstrdup memory leak
  net/caif/cfrfml.c: use asm/unaligned.h
  ax25: missplaced sock_put(sk)
  qlge: reset the chip before freeing the buffers
  l2tp: test for ethernet header in l2tp_eth_dev_recv()
  tcp: select(writefds) don't hang up when a peer close connection
  tcp: fix three tcp sysctls tuning
  tcp: Combat per-cpu skew in orphan tests.
  pxa168_eth: silence gcc warnings
  pxa168_eth: update call to phy_mii_ioctl()
  pxa168_eth: fix error handling in prope
  pxa168_eth: remove unneeded null check
  phylib: Fix race between returning phydev and calling adjust_link
  caif-driver: add HAS_DMA dependency
  3c59x: Fix deadlock between boomerang_interrupt and boomerang_start_tx
  qlcnic: fix poll implementation
  netxen: fix poll implementation
  bridge: netfilter: fix a memory leak

15 files changed:
drivers/net/3c59x.c
drivers/net/caif/Kconfig
drivers/net/netxen/netxen_nic_main.c
drivers/net/phy/phy_device.c
drivers/net/pxa168_eth.c
drivers/net/qlcnic/qlcnic_main.c
drivers/net/qlge/qlge_main.c
include/net/tcp.h
net/ax25/ax25_ds_timer.c
net/bridge/br_netfilter.c
net/caif/cfrfml.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_timer.c
net/l2tp/l2tp_eth.c

index c754d88e5ec92d0af82d80094a4576256a50dc61..c685a55fc2f415a7cf376344753366098603c78b 100644 (file)
@@ -633,7 +633,8 @@ struct vortex_private {
                open:1,
                medialock:1,
                must_free_region:1,                             /* Flag: if zero, Cardbus owns the I/O region */
-               large_frames:1;                 /* accept large frames */
+               large_frames:1,                 /* accept large frames */
+               handling_irq:1;                 /* private in_irq indicator */
        int drv_flags;
        u16 status_enable;
        u16 intr_enable;
@@ -2133,6 +2134,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
                           dev->name, vp->cur_tx);
        }
 
+       /*
+        * We can't allow a recursion from our interrupt handler back into the
+        * tx routine, as they take the same spin lock, and that causes
+        * deadlock.  Just return NETDEV_TX_BUSY and let the stack try again in
+        * a bit
+        */
+       if (vp->handling_irq)
+               return NETDEV_TX_BUSY;
+
        if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
                if (vortex_debug > 0)
                        pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
@@ -2335,11 +2345,13 @@ boomerang_interrupt(int irq, void *dev_id)
 
        ioaddr = vp->ioaddr;
 
+
        /*
         * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
         * and boomerang_start_xmit
         */
        spin_lock(&vp->lock);
+       vp->handling_irq = 1;
 
        status = ioread16(ioaddr + EL3_STATUS);
 
@@ -2447,6 +2459,7 @@ boomerang_interrupt(int irq, void *dev_id)
                pr_debug("%s: exiting interrupt, status %4.4x.\n",
                           dev->name, status);
 handler_exit:
+       vp->handling_irq = 0;
        spin_unlock(&vp->lock);
        return IRQ_HANDLED;
 }
index 631a6242b0112aec566b9df0916eb9b1d1552be5..75bfc3a9d95f3f118e6eae1cdc649fd0a442baeb 100644 (file)
@@ -15,7 +15,7 @@ config CAIF_TTY
 
 config CAIF_SPI_SLAVE
        tristate "CAIF SPI transport driver for slave interface"
-       depends on CAIF
+       depends on CAIF && HAS_DMA
        default n
        ---help---
        The CAIF Link layer SPI Protocol driver for Slave SPI interface.
index cb30df106a2c3d7981d74c085a49194e790c86b9..73d31459223098c8e3727a0565ed12805d58e388 100644 (file)
@@ -2131,9 +2131,16 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void netxen_nic_poll_controller(struct net_device *netdev)
 {
+       int ring;
+       struct nx_host_sds_ring *sds_ring;
        struct netxen_adapter *adapter = netdev_priv(netdev);
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
        disable_irq(adapter->irq);
-       netxen_intr(adapter->irq, adapter);
+       for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+               sds_ring = &recv_ctx->sds_rings[ring];
+               netxen_intr(adapter->irq, sds_ring);
+       }
        enable_irq(adapter->irq);
 }
 #endif
index c0761197c07e6a94e67e3d0d4f417d888e2ec68f..16ddc77313cb08348b3cdbdb7016bd5c56fb9304 100644 (file)
@@ -466,6 +466,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
        phydev->interface = interface;
 
+       phydev->state = PHY_READY;
+
        /* Do initial configuration here, now that
         * we have certain key parameters
         * (dev_flags and interface) */
index ecc64d750cce0535103aa9d22ca0232043a628b1..410ea0a613718af8c42ac02fdbd3def788757ee4 100644 (file)
@@ -654,15 +654,15 @@ static void eth_port_start(struct net_device *dev)
        /* Assignment of Tx CTRP of given queue */
        tx_curr_desc = pep->tx_curr_desc_q;
        wrl(pep, ETH_C_TX_DESC_1,
-           (u32) ((struct tx_desc *)pep->tx_desc_dma + tx_curr_desc));
+           (u32) (pep->tx_desc_dma + tx_curr_desc * sizeof(struct tx_desc)));
 
        /* Assignment of Rx CRDP of given queue */
        rx_curr_desc = pep->rx_curr_desc_q;
        wrl(pep, ETH_C_RX_DESC_0,
-           (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
+           (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc)));
 
        wrl(pep, ETH_F_RX_DESC_0,
-           (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
+           (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc)));
 
        /* Clear all interrupts */
        wrl(pep, INT_CAUSE, 0);
@@ -1350,7 +1350,7 @@ static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr,
 {
        struct pxa168_eth_private *pep = netdev_priv(dev);
        if (pep->phy != NULL)
-               return phy_mii_ioctl(pep->phy, if_mii(ifr), cmd);
+               return phy_mii_ioctl(pep->phy, ifr, cmd);
 
        return -EOPNOTSUPP;
 }
@@ -1414,10 +1414,8 @@ static int ethernet_phy_setup(struct net_device *dev)
 {
        struct pxa168_eth_private *pep = netdev_priv(dev);
 
-       if (pep->pd != NULL) {
-               if (pep->pd->init)
-                       pep->pd->init();
-       }
+       if (pep->pd->init)
+               pep->pd->init();
        pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f);
        if (pep->phy != NULL)
                phy_init(pep, pep->pd->speed, pep->pd->duplex);
@@ -1499,7 +1497,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
        dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
        if (!dev) {
                err = -ENOMEM;
-               goto out;
+               goto err_clk;
        }
 
        platform_set_drvdata(pdev, dev);
@@ -1509,12 +1507,12 @@ static int pxa168_eth_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (res == NULL) {
                err = -ENODEV;
-               goto out;
+               goto err_netdev;
        }
        pep->base = ioremap(res->start, res->end - res->start + 1);
        if (pep->base == NULL) {
                err = -ENOMEM;
-               goto out;
+               goto err_netdev;
        }
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        BUG_ON(!res);
@@ -1551,7 +1549,7 @@ static int pxa168_eth_probe(struct platform_device *pdev)
        pep->smi_bus = mdiobus_alloc();
        if (pep->smi_bus == NULL) {
                err = -ENOMEM;
-               goto out;
+               goto err_base;
        }
        pep->smi_bus->priv = pep;
        pep->smi_bus->name = "pxa168_eth smi";
@@ -1560,31 +1558,31 @@ static int pxa168_eth_probe(struct platform_device *pdev)
        snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id);
        pep->smi_bus->parent = &pdev->dev;
        pep->smi_bus->phy_mask = 0xffffffff;
-       if (mdiobus_register(pep->smi_bus) < 0) {
-               err = -ENOMEM;
-               goto out;
-       }
+       err = mdiobus_register(pep->smi_bus);
+       if (err)
+               goto err_free_mdio;
+
        pxa168_init_hw(pep);
        err = ethernet_phy_setup(dev);
        if (err)
-               goto out;
+               goto err_mdiobus;
        SET_NETDEV_DEV(dev, &pdev->dev);
        err = register_netdev(dev);
        if (err)
-               goto out;
+               goto err_mdiobus;
        return 0;
-out:
-       if (pep->clk) {
-               clk_disable(pep->clk);
-               clk_put(pep->clk);
-               pep->clk = NULL;
-       }
-       if (pep->base) {
-               iounmap(pep->base);
-               pep->base = NULL;
-       }
-       if (dev)
-               free_netdev(dev);
+
+err_mdiobus:
+       mdiobus_unregister(pep->smi_bus);
+err_free_mdio:
+       mdiobus_free(pep->smi_bus);
+err_base:
+       iounmap(pep->base);
+err_netdev:
+       free_netdev(dev);
+err_clk:
+       clk_disable(clk);
+       clk_put(clk);
        return err;
 }
 
index 213e3656d953be316732ec22e82dbaf8552b0555..66eea59720209f85278cf223b6d723f879337aac 100644 (file)
@@ -2188,9 +2188,16 @@ static int qlcnic_rx_poll(struct napi_struct *napi, int budget)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void qlcnic_poll_controller(struct net_device *netdev)
 {
+       int ring;
+       struct qlcnic_host_sds_ring *sds_ring;
        struct qlcnic_adapter *adapter = netdev_priv(netdev);
+       struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+
        disable_irq(adapter->irq);
-       qlcnic_intr(adapter->irq, adapter);
+       for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+               sds_ring = &recv_ctx->sds_rings[ring];
+               qlcnic_intr(adapter->irq, sds_ring);
+       }
        enable_irq(adapter->irq);
 }
 #endif
index 8d63f69b27d912de7dca94d980276963f25c7fe7..5f89e83501f4f5c1892ac15a84681a76ade08c19 100644 (file)
@@ -3919,12 +3919,12 @@ static int ql_adapter_down(struct ql_adapter *qdev)
        for (i = 0; i < qdev->rss_ring_count; i++)
                netif_napi_del(&qdev->rx_ring[i].napi);
 
-       ql_free_rx_buffers(qdev);
-
        status = ql_adapter_reset(qdev);
        if (status)
                netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n",
                          qdev->func);
+       ql_free_rx_buffers(qdev);
+
        return status;
 }
 
index df6a2eb20193f935bc72204ca22c7f2f21b5070f..eaa9582779d029a9362c32b3816fed8c157e4d3e 100644 (file)
@@ -268,11 +268,21 @@ static inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
        return seq3 - seq2 >= seq1 - seq2;
 }
 
-static inline int tcp_too_many_orphans(struct sock *sk, int num)
+static inline bool tcp_too_many_orphans(struct sock *sk, int shift)
 {
-       return (num > sysctl_tcp_max_orphans) ||
-               (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
-                atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
+       struct percpu_counter *ocp = sk->sk_prot->orphan_count;
+       int orphans = percpu_counter_read_positive(ocp);
+
+       if (orphans << shift > sysctl_tcp_max_orphans) {
+               orphans = percpu_counter_sum_positive(ocp);
+               if (orphans << shift > sysctl_tcp_max_orphans)
+                       return true;
+       }
+
+       if (sk->sk_wmem_queued > SOCK_MIN_SNDBUF &&
+           atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])
+               return true;
+       return false;
 }
 
 /* syncookies: remember time of last synqueue overflow */
index 2ce79df00680eee3d9d290fd1156ac1d2ab74557..c7d81436213d13e24e67edf2630930e5c4ed08c0 100644 (file)
@@ -112,8 +112,8 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
                        if (sk) {
                                sock_hold(sk);
                                ax25_destroy_socket(ax25);
-                               sock_put(sk);
                                bh_unlock_sock(sk);
+                               sock_put(sk);
                        } else
                                ax25_destroy_socket(ax25);
                        return;
index 2c911c0759c27bb6e4867b3bce9af0af3946d288..5ed00bd7009f55d1bdb5b8697889594442848e3f 100644 (file)
@@ -162,8 +162,8 @@ static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
                if (tmp) {
                        memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
                        atomic_set(&tmp->use, 1);
-                       nf_bridge_put(nf_bridge);
                }
+               nf_bridge_put(nf_bridge);
                nf_bridge = tmp;
        }
        return nf_bridge;
index eb1602022ac0643af4e4ad655c3de4ae42a200f4..9a699242d104be7fbef70ed4560d6ca3a63ebda3 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/unaligned/le_byteshift.h>
+#include <asm/unaligned.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/cfsrvl.h>
 #include <net/caif/cfpkt.h>
index 176e11aaea771795b21c0be6b1453b46c6349f0c..3fb1428e526eedb521057a49624fa28dde8b41cd 100644 (file)
@@ -451,7 +451,8 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
                                if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
                                        mask |= POLLOUT | POLLWRNORM;
                        }
-               }
+               } else
+                       mask |= POLLOUT | POLLWRNORM;
 
                if (tp->urg_data & TCP_URG_VALID)
                        mask |= POLLPRI;
@@ -2011,11 +2012,8 @@ adjudge_to_death:
                }
        }
        if (sk->sk_state != TCP_CLOSE) {
-               int orphan_count = percpu_counter_read_positive(
-                                               sk->sk_prot->orphan_count);
-
                sk_mem_reclaim(sk);
-               if (tcp_too_many_orphans(sk, orphan_count)) {
+               if (tcp_too_many_orphans(sk, 0)) {
                        if (net_ratelimit())
                                printk(KERN_INFO "TCP: too many of orphaned "
                                       "sockets\n");
@@ -3212,7 +3210,7 @@ void __init tcp_init(void)
 {
        struct sk_buff *skb = NULL;
        unsigned long nr_pages, limit;
-       int order, i, max_share;
+       int i, max_share, cnt;
        unsigned long jiffy = jiffies;
 
        BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -3261,22 +3259,12 @@ void __init tcp_init(void)
                INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
        }
 
-       /* Try to be a bit smarter and adjust defaults depending
-        * on available memory.
-        */
-       for (order = 0; ((1 << order) << PAGE_SHIFT) <
-                       (tcp_hashinfo.bhash_size * sizeof(struct inet_bind_hashbucket));
-                       order++)
-               ;
-       if (order >= 4) {
-               tcp_death_row.sysctl_max_tw_buckets = 180000;
-               sysctl_tcp_max_orphans = 4096 << (order - 4);
-               sysctl_max_syn_backlog = 1024;
-       } else if (order < 3) {
-               tcp_death_row.sysctl_max_tw_buckets >>= (3 - order);
-               sysctl_tcp_max_orphans >>= (3 - order);
-               sysctl_max_syn_backlog = 128;
-       }
+
+       cnt = tcp_hashinfo.ehash_mask + 1;
+
+       tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
+       sysctl_tcp_max_orphans = cnt / 2;
+       sysctl_max_syn_backlog = max(128, cnt / 256);
 
        /* Set the pressure threshold to be a fraction of global memory that
         * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
index 0ec9bd0ae94f2ef37024ac11c5e411f0179c816a..850c737e08e2a4a9185c64c8776711d83b8c7b08 100644 (file)
@@ -196,10 +196,10 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
 int tcp_set_allowed_congestion_control(char *val)
 {
        struct tcp_congestion_ops *ca;
-       char *clone, *name;
+       char *saved_clone, *clone, *name;
        int ret = 0;
 
-       clone = kstrdup(val, GFP_USER);
+       saved_clone = clone = kstrdup(val, GFP_USER);
        if (!clone)
                return -ENOMEM;
 
@@ -226,6 +226,7 @@ int tcp_set_allowed_congestion_control(char *val)
        }
 out:
        spin_unlock(&tcp_cong_list_lock);
+       kfree(saved_clone);
 
        return ret;
 }
index 808bb920c9f5e67249f6747c90cdeb7dddd9ddea..c35b469e851c298814d69583bd593ec1c580dde5 100644 (file)
@@ -66,18 +66,18 @@ static void tcp_write_err(struct sock *sk)
 static int tcp_out_of_resources(struct sock *sk, int do_reset)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       int orphans = percpu_counter_read_positive(&tcp_orphan_count);
+       int shift = 0;
 
        /* If peer does not open window for long time, or did not transmit
         * anything for long time, penalize it. */
        if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset)
-               orphans <<= 1;
+               shift++;
 
        /* If some dubious ICMP arrived, penalize even more. */
        if (sk->sk_err_soft)
-               orphans <<= 1;
+               shift++;
 
-       if (tcp_too_many_orphans(sk, orphans)) {
+       if (tcp_too_many_orphans(sk, shift)) {
                if (net_ratelimit())
                        printk(KERN_INFO "Out of socket memory\n");
 
index 58c6c4cda73b576cd65d3121a9abdf67bc6f7668..1ae697681bc735f3f4ed8cf98f9f63745157be36 100644 (file)
@@ -132,7 +132,7 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb,
                printk("\n");
        }
 
-       if (data_len < ETH_HLEN)
+       if (!pskb_may_pull(skb, sizeof(ETH_HLEN)))
                goto error;
 
        secpath_reset(skb);