From 9a3de25544dadab1971847f28f33b1cd0d1770a6 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Tue, 16 Dec 2008 15:42:20 -0800 Subject: drivers/net: starfire: Fix napi ->poll() weight handling starfire napi ->poll() handler can return work == weight after calling netif_rx_complete() (if there is no more work). It is illegal and this patch fixes it. Reported-by: Alexander Huemer Tested-by: Alexander Huemer Signed-off-by: Jarek Poplawski Signed-off-by: David S. Miller --- drivers/net/starfire.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 1d2ef8f..5a40f2d 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1509,6 +1509,11 @@ static int __netdev_rx(struct net_device *dev, int *quota) desc->status = 0; np->rx_done = (np->rx_done + 1) % DONE_Q_SIZE; } + + if (*quota == 0) { /* out of rx quota */ + retcode = 1; + goto out; + } writew(np->rx_done, np->base + CompletionQConsumerIdx); out: -- cgit v1.1 From e8e5752dc0a56a01527055b0c37510b1d6b6b861 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Wed, 17 Dec 2008 00:24:13 -0800 Subject: net: kernel BUG at drivers/net/phy/mdio_bus.c:165! kernel BUG at drivers/net/phy/mdio_bus.c:165! Unable to handle kernel NULL pointer dereference at virtual address 00000000 How? mdiobus_alloc() sets bus->state = MDIOBUS_ALLOCATED. mdiobus_register() sets bus->state = MDIOBUS_REGISTERED but then can fail (mdiobus_scan()) returning an error to the caller. The caller aborts correctly with mdiobus_free() which does: if (bus->state == MDIOBUS_ALLOCATED) { kfree(bus); return; } BUG_ON(bus->state != MDIOBUS_UNREGISTERED); Signed-off-by: Krzysztof Halasa Signed-off-by: David S. Miller --- drivers/net/phy/mdio_bus.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 536bda1..289fc26 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -105,8 +105,6 @@ int mdiobus_register(struct mii_bus *bus) return -EINVAL; } - bus->state = MDIOBUS_REGISTERED; - mutex_init(&bus->mdio_lock); if (bus->reset) @@ -123,6 +121,9 @@ int mdiobus_register(struct mii_bus *bus) } } + if (!err) + bus->state = MDIOBUS_REGISTERED; + pr_info("%s: probed\n", bus->name); return err; -- cgit v1.1 From 2fccd2814f8ebc8f1bd325dc46e11c333fc76ab3 Mon Sep 17 00:00:00 2001 From: cwm97m Date: Tue, 16 Dec 2008 20:28:44 +0000 Subject: jme: Fixed a typo Found a typo. Signed-off-by: Wei-Min Chen Signed-off-by: David S. Miller --- drivers/net/jme.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/jme.h b/drivers/net/jme.h index f863aee..3f5d915 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -22,7 +22,7 @@ */ #ifndef __JME_H_INCLUDED__ -#define __JME_H_INCLUDEE__ +#define __JME_H_INCLUDED__ #define DRV_NAME "jme" #define DRV_VERSION "1.0.3" -- cgit v1.1 From 69c30e1e7492192f882a3fc11888b320fde5206a Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 17 Dec 2008 15:44:58 -0800 Subject: irda: Add irda_skb_cb qdisc related padding We need to pad irda_skb_cb in order to keep it safe accross dev_queue_xmit() calls. This is some ugly and temporary hack triggered by recent qisc code changes. Even though it fixes bugzilla.kernel.org bug #11795, it will be replaced by a proper fix before 2.6.29 is released. Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- include/net/irda/irda_device.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h index 3025ae1..94c852d 100644 --- a/include/net/irda/irda_device.h +++ b/include/net/irda/irda_device.h @@ -135,9 +135,11 @@ struct dongle_reg { /* * Per-packet information we need to hide inside sk_buff - * (must not exceed 48 bytes, check with struct sk_buff) + * (must not exceed 48 bytes, check with struct sk_buff) + * The default_qdisc_pad field is a temporary hack. */ struct irda_skb_cb { + unsigned int default_qdisc_pad; magic_t magic; /* Be sure that we can trust the information */ __u32 next_speed; /* The Speed to be set *after* this frame */ __u16 mtt; /* Minimum turn around time */ -- cgit v1.1 From 3298a7388c00227e736d1037328788073c80c7b4 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 17 Dec 2008 19:06:08 -0800 Subject: bnx2: Fix bug in bnx2_free_rx_mem(). DMA memory for the jumbo rx page rings was freed incorrectly using the wrong local variable as the array index. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index a1a3d0e..9e8222f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -543,9 +543,9 @@ bnx2_free_rx_mem(struct bnx2 *bp) for (j = 0; j < bp->rx_max_pg_ring; j++) { if (rxr->rx_pg_desc_ring[j]) pci_free_consistent(bp->pdev, RXBD_RING_SIZE, - rxr->rx_pg_desc_ring[i], - rxr->rx_pg_desc_mapping[i]); - rxr->rx_pg_desc_ring[i] = NULL; + rxr->rx_pg_desc_ring[j], + rxr->rx_pg_desc_mapping[j]); + rxr->rx_pg_desc_ring[j] = NULL; } if (rxr->rx_pg_ring) vfree(rxr->rx_pg_ring); -- cgit v1.1 From 1b08534e562dae7b084326f8aa8cc12a4c1b6593 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Dec 2008 19:35:10 -0800 Subject: net: Fix module refcount leak in kernel_accept() The kernel_accept() does not hold the module refcount of newsock->ops->owner, so we need __module_get(newsock->ops->owner) code after call kernel_accept() by hand. In sunrpc, the module refcount is missing to hold. So this cause kernel panic. Used following script to reproduct: while [ 1 ]; do mount -t nfs4 192.168.0.19:/ /mnt touch /mnt/file umount /mnt lsmod | grep ipv6 done This patch fixed the problem by add __module_get(newsock->ops->owner) to kernel_accept(). So we do not need to used __module_get(newsock->ops->owner) in every place when used kernel_accept(). Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- net/bluetooth/rfcomm/core.c | 2 -- net/socket.c | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index ba537fa..ce68e04 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1786,8 +1786,6 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) if (err < 0) return; - __module_get(nsock->ops->owner); - /* Set our callbacks */ nsock->sk->sk_data_ready = rfcomm_l2data_ready; nsock->sk->sk_state_change = rfcomm_l2state_change; diff --git a/net/socket.c b/net/socket.c index 92764d8..76ba80a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -2307,6 +2307,7 @@ int kernel_accept(struct socket *sock, struct socket **newsock, int flags) } (*newsock)->ops = sock->ops; + __module_get((*newsock)->ops->owner); done: return err; -- cgit v1.1 From 739840d529eb7505d3cbfe9d468bf1440c9a8e27 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 17 Dec 2008 12:02:16 +0000 Subject: ppp: fix segfaults introduced by netdev_priv changes This patch fixes a segfault in ppp_shutdown_interface() and ppp_destroy_interface() when a PPP connection is closed. I bisected the problem to the following commit: commit c8019bf3aff653cceb64f66489fc299ee5957b57 Author: Wang Chen Date: Thu Nov 20 04:24:17 2008 -0800 netdevice ppp: Convert directly reference of netdev->priv 1. Use netdev_priv(dev) to replace dev->priv. 2. Alloc netdev's private data by alloc_netdev(). Signed-off-by: Wang Chen Signed-off-by: David S. Miller The original ppp_generic code treated the netdev and struct ppp as independent data structures which were freed separately. In moving the ppp struct into the netdev, it is now possible for the private data to be freed before the call to ppp_shutdown_interface(), which is bad. The kfree(ppp) in ppp_destroy_interface() is also wrong; presumably ppp hasn't worked since the above commit. The following patch fixes both problems. Signed-off-by: James Chapman Reviewed-by: Wang Chen Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 7e857e9..714a230 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -116,6 +116,7 @@ struct ppp { unsigned long last_xmit; /* jiffies when last pkt sent 9c */ unsigned long last_recv; /* jiffies when last pkt rcvd a0 */ struct net_device *dev; /* network interface device a4 */ + int closing; /* is device closing down? a8 */ #ifdef CONFIG_PPP_MULTILINK int nxchan; /* next channel to send something on */ u32 nxseq; /* next sequence number to send */ @@ -995,7 +996,7 @@ ppp_xmit_process(struct ppp *ppp) struct sk_buff *skb; ppp_xmit_lock(ppp); - if (ppp->dev) { + if (!ppp->closing) { ppp_push(ppp); while (!ppp->xmit_pending && (skb = skb_dequeue(&ppp->file.xq))) @@ -1463,8 +1464,7 @@ static inline void ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) { ppp_recv_lock(ppp); - /* ppp->dev == 0 means interface is closing down */ - if (ppp->dev) + if (!ppp->closing) ppp_receive_frame(ppp, skb, pch); else kfree_skb(skb); @@ -2498,18 +2498,16 @@ init_ppp_file(struct ppp_file *pf, int kind) */ static void ppp_shutdown_interface(struct ppp *ppp) { - struct net_device *dev; - mutex_lock(&all_ppp_mutex); - ppp_lock(ppp); - dev = ppp->dev; - ppp->dev = NULL; - ppp_unlock(ppp); /* This will call dev_close() for us. */ - if (dev) { - unregister_netdev(dev); - free_netdev(dev); - } + ppp_lock(ppp); + if (!ppp->closing) { + ppp->closing = 1; + ppp_unlock(ppp); + unregister_netdev(ppp->dev); + } else + ppp_unlock(ppp); + cardmap_set(&all_ppp_units, ppp->file.index, NULL); ppp->file.dead = 1; ppp->owner = NULL; @@ -2554,7 +2552,7 @@ static void ppp_destroy_interface(struct ppp *ppp) if (ppp->xmit_pending) kfree_skb(ppp->xmit_pending); - kfree(ppp); + free_netdev(ppp->dev); } /* @@ -2616,7 +2614,7 @@ ppp_connect_channel(struct channel *pch, int unit) if (pch->file.hdrlen > ppp->file.hdrlen) ppp->file.hdrlen = pch->file.hdrlen; hdrlen = pch->file.hdrlen + 2; /* for protocol bytes */ - if (ppp->dev && hdrlen > ppp->dev->hard_header_len) + if (hdrlen > ppp->dev->hard_header_len) ppp->dev->hard_header_len = hdrlen; list_add_tail(&pch->clist, &ppp->channels); ++ppp->n_channels; -- cgit v1.1