--- /dev/null
+From 01a3b2650e2c0e7fbd84e974d90c550a87f1554c Mon Sep 17 00:00:00 2001
+From: Patrick McHardy <kaber@trash.net>
+Date: Sat, 27 Feb 2010 02:52:05 -0800
+Subject: bonding: fix device leak on error in bond_create()
+
+From: Patrick McHardy <kaber@trash.net>
+
+[ Upstream commit 8d6184e4881b423522136aeb3ec1cbd9c35e8813 ]
+
+When the register_netdevice() call fails, the newly allocated device is
+not freed.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/bonding/bond_main.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4935,6 +4935,8 @@ int bond_create(struct net *net, const c
+ }
+
+ res = register_netdevice(bond_dev);
++ if (res < 0)
++ goto out_netdev;
+
+ out:
+ rtnl_unlock();
--- /dev/null
+From 9ce366a41de84db6b1267857b079b0005a017d2d Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 15 Mar 2010 15:23:30 -0700
+Subject: e100: Fix ring parameter change handling regression.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 211a0d941b1924e667483f822a55e2cc694cd212 ]
+
+When the PCI pool changes were added to fix resume failures:
+
+commit 98468efddb101f8a29af974101c17ba513b07be1
+e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failu
+
+and
+
+commit 70abc8cb90e679d8519721e2761d8366a18212a6
+e100: Fix broken cbs accounting due to missing memset.
+
+This introduced a problem that can happen if the TX ring size
+is increased. We need to size the PCI pool using cbs->max
+instead of the default cbs->count value.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/e100.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/e100.c
++++ b/drivers/net/e100.c
+@@ -2854,7 +2854,7 @@ static int __devinit e100_probe(struct p
+ }
+ nic->cbs_pool = pci_pool_create(netdev->name,
+ nic->pdev,
+- nic->params.cbs.count * sizeof(struct cb),
++ nic->params.cbs.max * sizeof(struct cb),
+ sizeof(u32),
+ 0);
+ DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
--- /dev/null
+From 39c0fe2347e5b19352542eefb4cae9b6073b8312 Mon Sep 17 00:00:00 2001
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Date: Tue, 5 Jan 2010 07:07:27 +0000
+Subject: icside: bring back ->maskproc method
+
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+
+[ Upstream commit f75d4a238770d83d3a0475ce7f34e3fa37de161e ]
+
+Bring back ->maskproc method since it is still needed for proper operation,
+as noticed by Russell King:
+
+> This change is bogus.
+>
+> writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+> readb(base + ICS_ARCIN_V6_INTROFFSET_2);
+>
+> writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+> readb(base + ICS_ARCIN_V6_INTROFFSET_1);
+>
+> This sequence of code does:
+>
+> 1. enable interrupt 1
+> 2. disable interrupt 2
+> 3. enable interrupt 2
+> 4. disable interrupt 1
+>
+> which results in the interrupt for the second channel being enabled -
+> leaving channel 1 blocked.
+>
+> Firstly, icside shares its two IDE channels with one DMA engine - so it's
+> a simplex interface. IDE supports those (or did when the code was written)
+> serializing requests between the two interfaces. libata does not.
+>
+> Secondly, the interrupt lines on icside float when there's no drive connected
+> or when the drive has its NIEN bit set, which means that you get spurious
+> screaming interrupts which can kill off all expansion card interrupts on
+> the machine unless you disable the channel interrupt on the card.
+>
+> Since libata can not serialize the operation of the two channels like IDE
+> can, the libata version of the icside driver does not contain the interrupt
+> stearing logic. Instead, it looks at the status after reset, and if
+> nothing was found on that channel, it masks the interrupt from that
+> channel.
+
+This patch reverts changes done in commit dff8817 (I became confused due to
+non-standard & undocumented ->maskproc method, anyway sorry about that).
+
+Noticed-by: Russell King <rmk@arm.linux.org.uk>
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/icside.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 60 insertions(+), 4 deletions(-)
+
+--- a/drivers/ide/icside.c
++++ b/drivers/ide/icside.c
+@@ -65,6 +65,8 @@ static struct cardinfo icside_cardinfo_v
+ };
+
+ struct icside_state {
++ unsigned int channel;
++ unsigned int enabled;
+ void __iomem *irq_port;
+ void __iomem *ioc_base;
+ unsigned int sel;
+@@ -114,11 +116,18 @@ static void icside_irqenable_arcin_v6 (s
+ struct icside_state *state = ec->irq_data;
+ void __iomem *base = state->irq_port;
+
+- writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+- readb(base + ICS_ARCIN_V6_INTROFFSET_2);
++ state->enabled = 1;
+
+- writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+- readb(base + ICS_ARCIN_V6_INTROFFSET_1);
++ switch (state->channel) {
++ case 0:
++ writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
++ readb(base + ICS_ARCIN_V6_INTROFFSET_2);
++ break;
++ case 1:
++ writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
++ readb(base + ICS_ARCIN_V6_INTROFFSET_1);
++ break;
++ }
+ }
+
+ /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
+@@ -128,6 +137,8 @@ static void icside_irqdisable_arcin_v6 (
+ {
+ struct icside_state *state = ec->irq_data;
+
++ state->enabled = 0;
++
+ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+ }
+@@ -149,6 +160,44 @@ static const expansioncard_ops_t icside_
+ .irqpending = icside_irqpending_arcin_v6,
+ };
+
++/*
++ * Handle routing of interrupts. This is called before
++ * we write the command to the drive.
++ */
++static void icside_maskproc(ide_drive_t *drive, int mask)
++{
++ ide_hwif_t *hwif = drive->hwif;
++ struct expansion_card *ec = ECARD_DEV(hwif->dev);
++ struct icside_state *state = ecard_get_drvdata(ec);
++ unsigned long flags;
++
++ local_irq_save(flags);
++
++ state->channel = hwif->channel;
++
++ if (state->enabled && !mask) {
++ switch (hwif->channel) {
++ case 0:
++ writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
++ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
++ break;
++ case 1:
++ writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
++ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
++ break;
++ }
++ } else {
++ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
++ readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
++ }
++
++ local_irq_restore(flags);
++}
++
++static const struct ide_port_ops icside_v6_no_dma_port_ops = {
++ .maskproc = icside_maskproc,
++};
++
+ #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
+ /*
+ * SG-DMA support.
+@@ -228,6 +277,7 @@ static void icside_set_dma_mode(ide_driv
+
+ static const struct ide_port_ops icside_v6_port_ops = {
+ .set_dma_mode = icside_set_dma_mode,
++ .maskproc = icside_maskproc,
+ };
+
+ static void icside_dma_host_set(ide_drive_t *drive, int on)
+@@ -272,6 +322,11 @@ static int icside_dma_setup(ide_drive_t
+ BUG_ON(dma_channel_active(ec->dma));
+
+ /*
++ * Ensure that we have the right interrupt routed.
++ */
++ icside_maskproc(drive, 0);
++
++ /*
+ * Route the DMA signals to the correct interface.
+ */
+ writeb(state->sel | hwif->channel, state->ioc_base);
+@@ -399,6 +454,7 @@ err_free:
+
+ static const struct ide_port_info icside_v6_port_info __initdata = {
+ .init_dma = icside_dma_off_init,
++ .port_ops = &icside_v6_no_dma_port_ops,
+ .dma_ops = &icside_v6_dma_ops,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
+ .mwdma_mask = ATA_MWDMA2,
--- /dev/null
+From 5e249f8401d4955d7a5f18e36d9b2654a1ed4da3 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk@arm.linux.org.uk>
+Date: Sun, 3 Jan 2010 12:35:42 +0000
+Subject: ide: Fix Promise UDMA33 IDE driver (pdc202xx_old)
+
+From: Russell King <rmk@arm.linux.org.uk>
+
+[ Upstream commit c3be57b6f35ef96a980ce84e59d6a5a8ca6184ad ]
+
+On Sun, Jan 03, 2010 at 12:23:14AM +0000, Russell King wrote:
+> - with IDE
+> - locks the interrupt line, and makes the machine extremely painful -
+> about an hour to get to the point of being able to unload the
+> pdc202xx_old module.
+
+Having manually bisected kernel versions, I've narrowed it down to some
+change between 2.6.30 and 2.6.31. There's not much which has changed
+between the two kernels, but one change stands out like a sore thumb:
+
++static int pdc202xx_test_irq(ide_hwif_t *hwif)
++{
++ struct pci_dev *dev = to_pci_dev(hwif->dev);
++ unsigned long high_16 = pci_resource_start(dev, 4);
++ u8 sc1d = inb(high_16 + 0x1d);
++
++ if (hwif->channel) {
++ /*
++ * bit 7: error, bit 6: interrupting,
++ * bit 5: FIFO full, bit 4: FIFO empty
++ */
++ return ((sc1d & 0x50) == 0x40) ? 1 : 0;
++ } else {
++ /*
++ * bit 3: error, bit 2: interrupting,
++ * bit 1: FIFO full, bit 0: FIFO empty
++ */
++ return ((sc1d & 0x05) == 0x04) ? 1 : 0;
++ }
++}
+
+Reading the (documented as a 32-bit) system control register when the
+interface is idle gives: 0x01da110c
+
+So, the byte at 0x1d is 0x11, which is documented as meaning that the
+primary and secondary FIFOs are empty.
+
+The code above, which is trying to see whether an IRQ is pending, checks
+for the IRQ bit to be one, and the FIFO bit to be zero - or in English,
+to be non-empty.
+
+Since during a BM-DMA read, the FIFOs will naturally be drained to the
+PCI bus, the chance of us getting to the interface before this happens
+are extremely small - and if we don't, it means we decide not to service
+the interrupt. Hence, the screaming interrupt problem with drivers/ide.
+
+Fix this by only indicating an interrupt is ready if both the interrupt
+and FIFO empty bits are at '1'.
+
+This bug only affects PDC20246/PDC20247 (Promise Ultra33) based cards,
+and has been tested on 2.6.31 and 2.6.33-rc2.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/pdc202xx_old.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/ide/pdc202xx_old.c
++++ b/drivers/ide/pdc202xx_old.c
+@@ -100,13 +100,13 @@ static int pdc202xx_test_irq(ide_hwif_t
+ * bit 7: error, bit 6: interrupting,
+ * bit 5: FIFO full, bit 4: FIFO empty
+ */
+- return ((sc1d & 0x50) == 0x40) ? 1 : 0;
++ return ((sc1d & 0x50) == 0x50) ? 1 : 0;
+ } else {
+ /*
+ * bit 3: error, bit 2: interrupting,
+ * bit 1: FIFO full, bit 0: FIFO empty
+ */
+- return ((sc1d & 0x05) == 0x04) ? 1 : 0;
++ return ((sc1d & 0x05) == 0x05) ? 1 : 0;
+ }
+ }
+
--- /dev/null
+From b11caf2be6cb62345ac657313adc1b34d44848ef Mon Sep 17 00:00:00 2001
+From: Timo Teräs <timo.teras@iki.fi>
+Date: Sat, 20 Mar 2010 02:27:58 +0000
+Subject: ip_gre: include route header_len in max_headroom calculation
+
+From: Timo Teräs <timo.teras@iki.fi>
+
+[ Upstream commit 243aad830e8a4cdda261626fbaeddde16b08d04a ]
+
+Taking route's header_len into account, and updating gre device
+needed_headroom will give better hints on upper bound of required
+headroom. This is useful if the gre traffic is xfrm'ed.
+
+Signed-off-by: Timo Teras <timo.teras@iki.fi>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/ip_gre.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_gre.c
++++ b/net/ipv4/ip_gre.c
+@@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(str
+ tunnel->err_count = 0;
+ }
+
+- max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen;
++ max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len;
+
+ if (skb_headroom(skb) < max_headroom || skb_shared(skb)||
+ (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
++ if (max_headroom > dev->needed_headroom)
++ dev->needed_headroom = max_headroom;
+ if (!new_skb) {
+ ip_rt_put(rt);
+ txq->tx_dropped++;
--- /dev/null
+From 5701123473ef64bae0519d22f756383b55d5bb04 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 2 Mar 2010 02:51:56 +0000
+Subject: ipsec: Fix bogus bundle flowi
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9 ]
+
+When I merged the bundle creation code, I introduced a bogus
+flowi value in the bundle. Instead of getting from the caller,
+it was instead set to the flow in the route object, which is
+totally different.
+
+The end result is that the bundles we created never match, and
+we instead end up with an ever growing bundle list.
+
+Thanks to Jamal for find this problem.
+
+Reported-by: Jamal Hadi Salim <hadi@cyberus.ca>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Acked-by: Steffen Klassert <steffen.klassert@secunet.com>
+Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ include/net/xfrm.h | 3 ++-
+ net/ipv4/xfrm4_policy.c | 5 +++--
+ net/ipv6/xfrm6_policy.c | 3 ++-
+ net/xfrm/xfrm_policy.c | 7 ++++---
+ 4 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/include/net/xfrm.h
++++ b/include/net/xfrm.h
+@@ -274,7 +274,8 @@ struct xfrm_policy_afinfo {
+ struct dst_entry *dst,
+ int nfheader_len);
+ int (*fill_dst)(struct xfrm_dst *xdst,
+- struct net_device *dev);
++ struct net_device *dev,
++ struct flowi *fl);
+ };
+
+ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
+--- a/net/ipv4/xfrm4_policy.c
++++ b/net/ipv4/xfrm4_policy.c
+@@ -91,11 +91,12 @@ static int xfrm4_init_path(struct xfrm_d
+ return 0;
+ }
+
+-static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
++static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
++ struct flowi *fl)
+ {
+ struct rtable *rt = (struct rtable *)xdst->route;
+
+- xdst->u.rt.fl = rt->fl;
++ xdst->u.rt.fl = *fl;
+
+ xdst->u.dst.dev = dev;
+ dev_hold(dev);
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -116,7 +116,8 @@ static int xfrm6_init_path(struct xfrm_d
+ return 0;
+ }
+
+-static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
++static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
++ struct flowi *fl)
+ {
+ struct rt6_info *rt = (struct rt6_info*)xdst->route;
+
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1354,7 +1354,8 @@ static inline int xfrm_init_path(struct
+ return err;
+ }
+
+-static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
++static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
++ struct flowi *fl)
+ {
+ struct xfrm_policy_afinfo *afinfo =
+ xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
+@@ -1363,7 +1364,7 @@ static inline int xfrm_fill_dst(struct x
+ if (!afinfo)
+ return -EINVAL;
+
+- err = afinfo->fill_dst(xdst, dev);
++ err = afinfo->fill_dst(xdst, dev, fl);
+
+ xfrm_policy_put_afinfo(afinfo);
+
+@@ -1468,7 +1469,7 @@ static struct dst_entry *xfrm_bundle_cre
+ for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
+ struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
+
+- err = xfrm_fill_dst(xdst, dev);
++ err = xfrm_fill_dst(xdst, dev, fl);
+ if (err)
+ goto free_dst;
+
--- /dev/null
+From 2638ae735ff6e317f0527b940764ed3000c9fe54 Mon Sep 17 00:00:00 2001
+From: Timo Teräs <timo.teras@iki.fi>
+Date: Thu, 18 Mar 2010 23:20:20 +0000
+Subject: ipv4: check rt_genid in dst_check
+
+From: Timo Teräs <timo.teras@iki.fi>
+
+[ Upstream commit d11a4dc18bf41719c9f0d7ed494d295dd2973b92 ]
+
+Xfrm_dst keeps a reference to ipv4 rtable entries on each
+cached bundle. The only way to renew xfrm_dst when the underlying
+route has changed, is to implement dst_check for this. This is
+what ipv6 side does too.
+
+The problems started after 87c1e12b5eeb7b30b4b41291bef8e0b41fc3dde9
+("ipsec: Fix bogus bundle flowi") which fixed a bug causing xfrm_dst
+to not get reused, until that all lookups always generated new
+xfrm_dst with new route reference and path mtu worked. But after the
+fix, the old routes started to get reused even after they were expired
+causing pmtu to break (well it would occationally work if the rtable
+gc had run recently and marked the route obsolete causing dst_check to
+get called).
+
+Signed-off-by: Timo Teras <timo.teras@iki.fi>
+Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/route.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1415,7 +1415,7 @@ void ip_rt_redirect(__be32 old_gw, __be3
+ dev_hold(rt->u.dst.dev);
+ if (rt->idev)
+ in_dev_hold(rt->idev);
+- rt->u.dst.obsolete = 0;
++ rt->u.dst.obsolete = -1;
+ rt->u.dst.lastuse = jiffies;
+ rt->u.dst.path = &rt->u.dst;
+ rt->u.dst.neighbour = NULL;
+@@ -1480,7 +1480,7 @@ static struct dst_entry *ipv4_negative_a
+ struct dst_entry *ret = dst;
+
+ if (rt) {
+- if (dst->obsolete) {
++ if (dst->obsolete > 0) {
+ ip_rt_put(rt);
+ ret = NULL;
+ } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
+@@ -1700,7 +1700,9 @@ static void ip_rt_update_pmtu(struct dst
+
+ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+ {
+- return NULL;
++ if (rt_is_expired((struct rtable *)dst))
++ return NULL;
++ return dst;
+ }
+
+ static void ipv4_dst_destroy(struct dst_entry *dst)
+@@ -1862,7 +1864,8 @@ static int ip_route_input_mc(struct sk_b
+ if (!rth)
+ goto e_nobufs;
+
+- rth->u.dst.output= ip_rt_bug;
++ rth->u.dst.output = ip_rt_bug;
++ rth->u.dst.obsolete = -1;
+
+ atomic_set(&rth->u.dst.__refcnt, 1);
+ rth->u.dst.flags= DST_HOST;
+@@ -2023,6 +2026,7 @@ static int __mkroute_input(struct sk_buf
+ rth->fl.oif = 0;
+ rth->rt_spec_dst= spec_dst;
+
++ rth->u.dst.obsolete = -1;
+ rth->u.dst.input = ip_forward;
+ rth->u.dst.output = ip_output;
+ rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
+@@ -2187,6 +2191,7 @@ local_input:
+ goto e_nobufs;
+
+ rth->u.dst.output= ip_rt_bug;
++ rth->u.dst.obsolete = -1;
+ rth->rt_genid = rt_genid(net);
+
+ atomic_set(&rth->u.dst.__refcnt, 1);
+@@ -2413,6 +2418,7 @@ static int __mkroute_output(struct rtabl
+ rth->rt_spec_dst= fl->fl4_src;
+
+ rth->u.dst.output=ip_output;
++ rth->u.dst.obsolete = -1;
+ rth->rt_genid = rt_genid(dev_net(dev_out));
+
+ RT_CACHE_STAT_INC(out_slow_tot);
--- /dev/null
+From f5668ec496d8d4c03cd775257fe7dc2528dfdeb6 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <guenter.roeck@ericsson.com>
+Date: Sun, 21 Mar 2010 20:55:13 -0700
+Subject: ipv4: Don't drop redirected route cache entry unless PTMU actually expired
+
+From: Guenter Roeck <guenter.roeck@ericsson.com>
+
+[ Upstream commit 5e016cbf6cffd4a53b7922e0c91b775399d7fe47 ]
+
+TCP sessions over IPv4 can get stuck if routers between endpoints
+do not fragment packets but implement PMTU instead, and we are using
+those routers because of an ICMP redirect.
+
+Setup is as follows
+
+ MTU1 MTU2 MTU1
+ A--------B------C------D
+
+with MTU1 > MTU2. A and D are endpoints, B and C are routers. B and C
+implement PMTU and drop packets larger than MTU2 (for example because
+DF is set on all packets). TCP sessions are initiated between A and D.
+There is packet loss between A and D, causing frequent TCP
+retransmits.
+
+After the number of retransmits on a TCP session reaches tcp_retries1,
+tcp calls dst_negative_advice() prior to each retransmit. This results
+in route cache entries for the peer to be deleted in
+ipv4_negative_advice() if the Path MTU is set.
+
+If the outstanding data on an affected TCP session is larger than
+MTU2, packets sent from the endpoints will be dropped by B or C, and
+ICMP NEEDFRAG will be returned. A and D receive NEEDFRAG messages and
+update PMTU.
+
+Before the next retransmit, tcp will again call dst_negative_advice(),
+causing the route cache entry (with correct PMTU) to be deleted. The
+retransmitted packet will be larger than MTU2, causing it to be
+dropped again.
+
+This sequence repeats until the TCP session aborts or is terminated.
+
+Problem is fixed by removing redirected route cache entries in
+ipv4_negative_advice() only if the PMTU is expired.
+
+Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/route.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1484,7 +1484,8 @@ static struct dst_entry *ipv4_negative_a
+ ip_rt_put(rt);
+ ret = NULL;
+ } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
+- rt->u.dst.expires) {
++ (rt->u.dst.expires &&
++ time_after_eq(jiffies, rt->u.dst.expires))) {
+ unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
+ rt->fl.oif,
+ rt_genid(dev_net(dst->dev)));
--- /dev/null
+From ff9d7bef4e7bf1bd674d2335e1d705a9545bb0a1 Mon Sep 17 00:00:00 2001
+From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
+Date: Sun, 28 Mar 2010 07:15:45 +0000
+Subject: ipv6: Don't drop cache route entry unless timer actually expired.
+
+From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
+
+[ Upstream commit 54c1a859efd9fd6cda05bc700315ba2519c14eba ]
+
+This is ipv6 variant of the commit 5e016cbf6.. ("ipv4: Don't drop
+redirected route cache entry unless PTMU actually expired")
+by Guenter Roeck <guenter.roeck@ericsson.com>.
+
+Remove cache route entry in ipv6_negative_advice() only if
+the timer is expired.
+
+Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv6/route.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -897,12 +897,17 @@ static struct dst_entry *ip6_negative_ad
+ struct rt6_info *rt = (struct rt6_info *) dst;
+
+ if (rt) {
+- if (rt->rt6i_flags & RTF_CACHE)
+- ip6_del_rt(rt);
+- else
++ if (rt->rt6i_flags & RTF_CACHE) {
++ if (rt6_check_expired(rt)) {
++ ip6_del_rt(rt);
++ dst = NULL;
++ }
++ } else {
+ dst_release(dst);
++ dst = NULL;
++ }
+ }
+- return NULL;
++ return dst;
+ }
+
+ static void ip6_link_failure(struct sk_buff *skb)
--- /dev/null
+From 7db2c466705125aaa141420bccbd4ffc98796994 Mon Sep 17 00:00:00 2001
+From: James Chapman <jchapman@katalix.com>
+Date: Tue, 16 Mar 2010 06:46:31 +0000
+Subject: l2tp: Fix oops in pppol2tp_xmit
+
+From: James Chapman <jchapman@katalix.com>
+
+[ Upstream commit 3feec9095d12e311b7d4eb7fe7e5dfa75d4a72a5 ]
+
+When transmitting L2TP frames, we derive the outgoing interface's UDP
+checksum hardware assist capabilities from the tunnel dst dev. This
+can sometimes be NULL, especially when routing protocols are used and
+routing changes occur. This patch just checks for NULL dst or dev
+pointers when checking for netdev hardware assist features.
+
+BUG: unable to handle kernel NULL pointer dereference at 0000000c
+IP: [<f89d074c>] pppol2tp_xmit+0x341/0x4da [pppol2tp]
+*pde = 00000000
+Oops: 0000 [#1] SMP
+last sysfs file: /sys/class/net/lo/operstate
+Modules linked in: pppol2tp pppox ppp_generic slhc ipv6 dummy loop snd_hda_codec_atihdmi snd_hda_intel snd_hda_codec snd_pcm snd_timer snd soundcore snd_page_alloc evdev psmouse serio_raw processor button i2c_piix4 i2c_core ati_agp agpgart pcspkr ext3 jbd mbcache sd_mod ide_pci_generic atiixp ide_core ahci ata_generic floppy ehci_hcd ohci_hcd libata e1000e scsi_mod usbcore nls_base thermal fan thermal_sys [last unloaded: scsi_wait_scan]
+
+Pid: 0, comm: swapper Not tainted (2.6.32.8 #1)
+EIP: 0060:[<f89d074c>] EFLAGS: 00010297 CPU: 3
+EIP is at pppol2tp_xmit+0x341/0x4da [pppol2tp]
+EAX: 00000000 EBX: f64d1680 ECX: 000005b9 EDX: 00000000
+ESI: f6b91850 EDI: f64d16ac EBP: f6a0c4c0 ESP: f70a9cac
+ DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
+Process swapper (pid: 0, ti=f70a8000 task=f70a31c0 task.ti=f70a8000)
+Stack:
+ 000005a9 000005b9 f734c400 f66652c0 f7352e00 f67dc800 00000000 f6b91800
+<0> 000005a3 f70ef6c4 f67dcda9 000005a3 f89b192e 00000246 000005a3 f64d1680
+<0> f63633e0 f6363320 f64d1680 f65a7320 f65a7364 f65856c0 f64d1680 f679f02f
+Call Trace:
+ [<f89b192e>] ? ppp_push+0x459/0x50e [ppp_generic]
+ [<f89b217f>] ? ppp_xmit_process+0x3b6/0x430 [ppp_generic]
+ [<f89b2306>] ? ppp_start_xmit+0x10d/0x120 [ppp_generic]
+ [<c11c15cb>] ? dev_hard_start_xmit+0x21f/0x2b2
+ [<c11d0947>] ? sch_direct_xmit+0x48/0x10e
+ [<c11c19a0>] ? dev_queue_xmit+0x263/0x3a6
+ [<c11e2a9f>] ? ip_finish_output+0x1f7/0x221
+ [<c11df682>] ? ip_forward_finish+0x2e/0x30
+ [<c11de645>] ? ip_rcv_finish+0x295/0x2a9
+ [<c11c0b19>] ? netif_receive_skb+0x3e9/0x404
+ [<f814b791>] ? e1000_clean_rx_irq+0x253/0x2fc [e1000e]
+ [<f814cb7a>] ? e1000_clean+0x63/0x1fc [e1000e]
+ [<c1047eff>] ? sched_clock_local+0x15/0x11b
+ [<c11c1095>] ? net_rx_action+0x96/0x195
+ [<c1035750>] ? __do_softirq+0xaa/0x151
+ [<c1035828>] ? do_softirq+0x31/0x3c
+ [<c10358fe>] ? irq_exit+0x26/0x58
+ [<c1004b21>] ? do_IRQ+0x78/0x89
+ [<c1003729>] ? common_interrupt+0x29/0x30
+ [<c101ac28>] ? native_safe_halt+0x2/0x3
+ [<c1008c54>] ? default_idle+0x55/0x75
+ [<c1009045>] ? c1e_idle+0xd2/0xd5
+ [<c100233c>] ? cpu_idle+0x46/0x62
+Code: 8d 45 08 f0 ff 45 08 89 6b 08 c7 43 68 7e fb 9c f8 8a 45 24 83 e0 0c 3c 04 75 09 80 63 64 f3 e9 b4 00 00 00 8b 43 18 8b 4c 24 04 <8b> 40 0c 8d 79 11 f6 40 44 0e 8a 43 64 75 51 6a 00 8b 4c 24 08
+EIP: [<f89d074c>] pppol2tp_xmit+0x341/0x4da [pppol2tp] SS:ESP 0068:f70a9cac
+CR2: 000000000000000c
+
+Signed-off-by: James Chapman <jchapman@katalix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/pppol2tp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/pppol2tp.c
++++ b/drivers/net/pppol2tp.c
+@@ -1180,7 +1180,8 @@ static int pppol2tp_xmit(struct ppp_chan
+ /* Calculate UDP checksum if configured to do so */
+ if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
+ skb->ip_summed = CHECKSUM_NONE;
+- else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
++ else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
++ (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ csum = skb_checksum(skb, 0, udp_len, 0);
+ uh->check = csum_tcpudp_magic(inet->inet_saddr,
--- /dev/null
+From 40cad6ae6c20055eb7a7c06055c257dc6460217c Mon Sep 17 00:00:00 2001
+From: James Chapman <jchapman@katalix.com>
+Date: Tue, 16 Mar 2010 06:29:20 +0000
+Subject: l2tp: Fix UDP socket reference count bugs in the pppol2tp driver
+
+From: James Chapman <jchapman@katalix.com>
+
+[ Upstream commit c3259c8a7060d480e8eb2166da0a99d6879146b4 ]
+
+This patch fixes UDP socket refcnt bugs in the pppol2tp driver.
+
+A bug can cause a kernel stack trace when a tunnel socket is closed.
+
+A way to reproduce the issue is to prepare the UDP socket for L2TP (by
+opening a tunnel pppol2tp socket) and then close it before any L2TP
+sessions are added to it. The sequence is
+
+Create UDP socket
+Create tunnel pppol2tp socket to prepare UDP socket for L2TP
+ pppol2tp_connect: session_id=0, peer_session_id=0
+L2TP SCCRP control frame received (tunnel_id==0)
+ pppol2tp_recv_core: sock_hold()
+ pppol2tp_recv_core: sock_put
+L2TP ZLB control frame received (tunnel_id=nnn)
+ pppol2tp_recv_core: sock_hold()
+ pppol2tp_recv_core: sock_put
+Close tunnel management socket
+ pppol2tp_release: session_id=0, peer_session_id=0
+Close UDP socket
+ udp_lib_close: BUG
+
+The addition of sock_hold() in pppol2tp_connect() solves the problem.
+
+For data frames, two sock_put() calls were added to plug a refcnt leak
+per received data frame. The ref that is grabbed at the top of
+pppol2tp_recv_core() must always be released, but this wasn't done for
+accepted data frames or data frames discarded because of bad UDP
+checksums. This leak meant that any UDP socket that had passed L2TP
+data traffic (i.e. L2TP data frames, not just L2TP control frames)
+using pppol2tp would not be released by the kernel.
+
+WARNING: at include/net/sock.h:435 udp_lib_unhash+0x117/0x120()
+Pid: 1086, comm: openl2tpd Not tainted 2.6.33-rc1 #8
+Call Trace:
+ [<c119e9b7>] ? udp_lib_unhash+0x117/0x120
+ [<c101b871>] ? warn_slowpath_common+0x71/0xd0
+ [<c119e9b7>] ? udp_lib_unhash+0x117/0x120
+ [<c101b8e3>] ? warn_slowpath_null+0x13/0x20
+ [<c119e9b7>] ? udp_lib_unhash+0x117/0x120
+ [<c11598a7>] ? sk_common_release+0x17/0x90
+ [<c11a5e33>] ? inet_release+0x33/0x60
+ [<c11577b0>] ? sock_release+0x10/0x60
+ [<c115780f>] ? sock_close+0xf/0x30
+ [<c106e542>] ? __fput+0x52/0x150
+ [<c106b68e>] ? filp_close+0x3e/0x70
+ [<c101d2e2>] ? put_files_struct+0x62/0xb0
+ [<c101eaf7>] ? do_exit+0x5e7/0x650
+ [<c1081623>] ? mntput_no_expire+0x13/0x70
+ [<c106b68e>] ? filp_close+0x3e/0x70
+ [<c101eb8a>] ? do_group_exit+0x2a/0x70
+ [<c101ebe1>] ? sys_exit_group+0x11/0x20
+ [<c10029b0>] ? sysenter_do_call+0x12/0x26
+
+Signed-off-by: James Chapman <jchapman@katalix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/pppol2tp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/pppol2tp.c
++++ b/drivers/net/pppol2tp.c
+@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct soc
+
+ /* Try to dequeue as many skbs from reorder_q as we can. */
+ pppol2tp_recv_dequeue(session);
++ sock_put(sock);
+
+ return 0;
+
+@@ -772,6 +773,7 @@ discard_bad_csum:
+ UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
+ tunnel->stats.rx_errors++;
+ kfree_skb(skb);
++ sock_put(sock);
+
+ return 0;
+
+@@ -1662,6 +1664,7 @@ static int pppol2tp_connect(struct socke
+ if (tunnel_sock == NULL)
+ goto end;
+
++ sock_hold(tunnel_sock);
+ tunnel = tunnel_sock->sk_user_data;
+ } else {
+ tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
--- /dev/null
+From c44db18ecbe35e460de965c99024e1f087dc739d Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:43 +0000
+Subject: llc: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 79545b681961d7001c1f4c3eb9ffb87bed4485db ]
+
+Make llc adapt to the limited socket backlog change.
+
+Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/llc/llc_conn.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/llc/llc_conn.c
++++ b/net/llc/llc_conn.c
+@@ -756,7 +756,8 @@ void llc_conn_handler(struct llc_sap *sa
+ else {
+ dprintk("%s: adding to backlog...\n", __func__);
+ llc_set_backlog_type(skb, LLC_PACKET);
+- sk_add_backlog(sk, skb);
++ if (sk_add_backlog_limited(sk, skb))
++ goto drop_unlock;
+ }
+ out:
+ bh_unlock_sock(sk);
--- /dev/null
+From 256010274c8212e7dbe26bbf2a84d8705733d50e Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Sun, 7 Mar 2010 16:21:39 +0000
+Subject: net: add __must_check to sk_add_backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 4045635318538d3ddd2007720412fdc4b08f6a62 ]
+
+Add the "__must_check" tag to sk_add_backlog() so that any failure to
+check and drop packets will be warned about.
+
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/sock.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -589,7 +589,7 @@ static inline void __sk_add_backlog(stru
+ }
+
+ /* The per-socket spinlock must be held here. */
+-static inline int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
++static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+ if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
+ return -ENOBUFS;
--- /dev/null
+From 0495e1a25511cbaa27f391668c733a22d83df7d4 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:40 +0000
+Subject: net: add limit for socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 8eae939f1400326b06d0c9afe53d2a484a326871 ]
+
+We got system OOM while running some UDP netperf testing on the loopback
+device. The case is multiple senders sent stream UDP packets to a single
+receiver via loopback on local host. Of course, the receiver is not able
+to handle all the packets in time. But we surprisingly found that these
+packets were not discarded due to the receiver's sk->sk_rcvbuf limit.
+Instead, they are kept queuing to sk->sk_backlog and finally ate up all
+the memory. We believe this is a secure hole that a none privileged user
+can crash the system.
+
+The root cause for this problem is, when the receiver is doing
+__release_sock() (i.e. after userspace recv, kernel udp_recvmsg ->
+skb_free_datagram_locked -> release_sock), it moves skbs from backlog to
+sk_receive_queue with the softirq enabled. In the above case, multiple
+busy senders will almost make it an endless loop. The skbs in the
+backlog end up eat all the system memory.
+
+The issue is not only for UDP. Any protocols using socket backlog is
+potentially affected. The patch adds limit for socket backlog so that
+the backlog size cannot be expanded endlessly.
+
+Reported-by: Alex Shi <alex.shi@intel.com>
+Cc: David Miller <davem@davemloft.net>
+Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru
+Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
+Cc: Patrick McHardy <kaber@trash.net>
+Cc: Vlad Yasevich <vladislav.yasevich@hp.com>
+Cc: Sridhar Samudrala <sri@us.ibm.com>
+Cc: Jon Maloy <jon.maloy@ericsson.com>
+Cc: Allan Stephens <allan.stephens@windriver.com>
+Cc: Andrew Hendry <andrew.hendry@gmail.com>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/sock.h | 15 ++++++++++++++-
+ net/core/sock.c | 16 ++++++++++++++--
+ 2 files changed, 28 insertions(+), 3 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -253,6 +253,8 @@ struct sock {
+ struct {
+ struct sk_buff *head;
+ struct sk_buff *tail;
++ int len;
++ int limit;
+ } sk_backlog;
+ wait_queue_head_t *sk_sleep;
+ struct dst_entry *sk_dst_cache;
+@@ -574,7 +576,7 @@ static inline int sk_stream_memory_free(
+ return sk->sk_wmem_queued < sk->sk_sndbuf;
+ }
+
+-/* The per-socket spinlock must be held here. */
++/* OOB backlog add */
+ static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+ if (!sk->sk_backlog.tail) {
+@@ -586,6 +588,17 @@ static inline void sk_add_backlog(struct
+ skb->next = NULL;
+ }
+
++/* The per-socket spinlock must be held here. */
++static inline int sk_add_backlog_limited(struct sock *sk, struct sk_buff *skb)
++{
++ if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
++ return -ENOBUFS;
++
++ sk_add_backlog(sk, skb);
++ sk->sk_backlog.len += skb->truesize;
++ return 0;
++}
++
+ static inline int sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+ {
+ return sk->sk_backlog_rcv(sk, skb);
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, stru
+ rc = sk_backlog_rcv(sk, skb);
+
+ mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
+- } else
+- sk_add_backlog(sk, skb);
++ } else if (sk_add_backlog_limited(sk, skb)) {
++ bh_unlock_sock(sk);
++ atomic_inc(&sk->sk_drops);
++ goto discard_and_relse;
++ }
++
+ bh_unlock_sock(sk);
+ out:
+ sock_put(sk);
+@@ -1138,6 +1142,7 @@ struct sock *sk_clone(const struct sock
+ sock_lock_init(newsk);
+ bh_lock_sock(newsk);
+ newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL;
++ newsk->sk_backlog.len = 0;
+
+ atomic_set(&newsk->sk_rmem_alloc, 0);
+ /*
+@@ -1541,6 +1546,12 @@ static void __release_sock(struct sock *
+
+ bh_lock_sock(sk);
+ } while ((skb = sk->sk_backlog.head) != NULL);
++
++ /*
++ * Doing the zeroing here guarantee we can not loop forever
++ * while a wild producer attempts to flood us.
++ */
++ sk->sk_backlog.len = 0;
+ }
+
+ /**
+@@ -1873,6 +1884,7 @@ void sock_init_data(struct socket *sock,
+ sk->sk_allocation = GFP_KERNEL;
+ sk->sk_rcvbuf = sysctl_rmem_default;
+ sk->sk_sndbuf = sysctl_wmem_default;
++ sk->sk_backlog.limit = sk->sk_rcvbuf << 1;
+ sk->sk_state = TCP_CLOSE;
+ sk_set_socket(sk, sock);
+
--- /dev/null
+From 30864b52e64e0949548d11ab09a38fad9c6a7bac Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:47 +0000
+Subject: net: backlog functions rename
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit a3a858ff18a72a8d388e31ab0d98f7e944841a62 ]
+
+sk_add_backlog -> __sk_add_backlog
+sk_add_backlog_limited -> sk_add_backlog
+
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ include/net/sock.h | 6 +++---
+ net/core/sock.c | 2 +-
+ net/dccp/minisocks.c | 2 +-
+ net/ipv4/tcp_ipv4.c | 2 +-
+ net/ipv4/tcp_minisocks.c | 2 +-
+ net/ipv4/udp.c | 2 +-
+ net/ipv6/tcp_ipv6.c | 2 +-
+ net/ipv6/udp.c | 4 ++--
+ net/llc/llc_c_ac.c | 2 +-
+ net/llc/llc_conn.c | 2 +-
+ net/sctp/input.c | 4 ++--
+ net/tipc/socket.c | 2 +-
+ net/x25/x25_dev.c | 2 +-
+ 13 files changed, 17 insertions(+), 17 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -577,7 +577,7 @@ static inline int sk_stream_memory_free(
+ }
+
+ /* OOB backlog add */
+-static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
++static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+ if (!sk->sk_backlog.tail) {
+ sk->sk_backlog.head = sk->sk_backlog.tail = skb;
+@@ -589,12 +589,12 @@ static inline void sk_add_backlog(struct
+ }
+
+ /* The per-socket spinlock must be held here. */
+-static inline int sk_add_backlog_limited(struct sock *sk, struct sk_buff *skb)
++static inline int sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+ if (sk->sk_backlog.len >= max(sk->sk_backlog.limit, sk->sk_rcvbuf << 1))
+ return -ENOBUFS;
+
+- sk_add_backlog(sk, skb);
++ __sk_add_backlog(sk, skb);
+ sk->sk_backlog.len += skb->truesize;
+ return 0;
+ }
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -340,7 +340,7 @@ int sk_receive_skb(struct sock *sk, stru
+ rc = sk_backlog_rcv(sk, skb);
+
+ mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
+- } else if (sk_add_backlog_limited(sk, skb)) {
++ } else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ atomic_inc(&sk->sk_drops);
+ goto discard_and_relse;
+--- a/net/dccp/minisocks.c
++++ b/net/dccp/minisocks.c
+@@ -254,7 +254,7 @@ int dccp_child_process(struct sock *pare
+ * in main socket hash table and lock on listening
+ * socket does not protect us more.
+ */
+- sk_add_backlog(child, skb);
++ __sk_add_backlog(child, skb);
+ }
+
+ bh_unlock_sock(child);
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1677,7 +1677,7 @@ process:
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v4_do_rcv(sk, skb);
+ }
+- } else if (sk_add_backlog_limited(sk, skb)) {
++ } else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ goto discard_and_relse;
+ }
+--- a/net/ipv4/tcp_minisocks.c
++++ b/net/ipv4/tcp_minisocks.c
+@@ -728,7 +728,7 @@ int tcp_child_process(struct sock *paren
+ * in main socket hash table and lock on listening
+ * socket does not protect us more.
+ */
+- sk_add_backlog(child, skb);
++ __sk_add_backlog(child, skb);
+ }
+
+ bh_unlock_sock(child);
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1372,7 +1372,7 @@ int udp_queue_rcv_skb(struct sock *sk, s
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ rc = __udp_queue_rcv_skb(sk, skb);
+- else if (sk_add_backlog_limited(sk, skb)) {
++ else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ goto drop;
+ }
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1732,7 +1732,7 @@ process:
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v6_do_rcv(sk, skb);
+ }
+- } else if (sk_add_backlog_limited(sk, skb)) {
++ } else if (sk_add_backlog(sk, skb)) {
+ bh_unlock_sock(sk);
+ goto discard_and_relse;
+ }
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -584,7 +584,7 @@ static void flush_stack(struct sock **st
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ udpv6_queue_rcv_skb(sk, skb1);
+- else if (sk_add_backlog_limited(sk, skb1)) {
++ else if (sk_add_backlog(sk, skb1)) {
+ kfree_skb(skb1);
+ bh_unlock_sock(sk);
+ goto drop;
+@@ -760,7 +760,7 @@ int __udp6_lib_rcv(struct sk_buff *skb,
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ udpv6_queue_rcv_skb(sk, skb);
+- else if (sk_add_backlog_limited(sk, skb)) {
++ else if (sk_add_backlog(sk, skb)) {
+ atomic_inc(&sk->sk_drops);
+ bh_unlock_sock(sk);
+ sock_put(sk);
+--- a/net/llc/llc_c_ac.c
++++ b/net/llc/llc_c_ac.c
+@@ -1437,7 +1437,7 @@ static void llc_process_tmr_ev(struct so
+ llc_conn_state_process(sk, skb);
+ else {
+ llc_set_backlog_type(skb, LLC_EVENT);
+- sk_add_backlog(sk, skb);
++ __sk_add_backlog(sk, skb);
+ }
+ }
+ }
+--- a/net/llc/llc_conn.c
++++ b/net/llc/llc_conn.c
+@@ -756,7 +756,7 @@ void llc_conn_handler(struct llc_sap *sa
+ else {
+ dprintk("%s: adding to backlog...\n", __func__);
+ llc_set_backlog_type(skb, LLC_PACKET);
+- if (sk_add_backlog_limited(sk, skb))
++ if (sk_add_backlog(sk, skb))
+ goto drop_unlock;
+ }
+ out:
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -341,7 +341,7 @@ int sctp_backlog_rcv(struct sock *sk, st
+ sctp_bh_lock_sock(sk);
+
+ if (sock_owned_by_user(sk)) {
+- if (sk_add_backlog_limited(sk, skb))
++ if (sk_add_backlog(sk, skb))
+ sctp_chunk_free(chunk);
+ else
+ backloged = 1;
+@@ -375,7 +375,7 @@ static int sctp_add_backlog(struct sock
+ struct sctp_ep_common *rcvr = chunk->rcvr;
+ int ret;
+
+- ret = sk_add_backlog_limited(sk, skb);
++ ret = sk_add_backlog(sk, skb);
+ if (!ret) {
+ /* Hold the assoc/ep while hanging on the backlog queue.
+ * This way, we know structures we need will not disappear
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -1322,7 +1322,7 @@ static u32 dispatch(struct tipc_port *tp
+ if (!sock_owned_by_user(sk)) {
+ res = filter_rcv(sk, buf);
+ } else {
+- if (sk_add_backlog_limited(sk, buf))
++ if (sk_add_backlog(sk, buf))
+ res = TIPC_ERR_OVERLOAD;
+ else
+ res = TIPC_OK;
+--- a/net/x25/x25_dev.c
++++ b/net/x25/x25_dev.c
+@@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_bu
+ if (!sock_owned_by_user(sk)) {
+ queued = x25_process_rx_frame(sk, skb);
+ } else {
+- queued = !sk_add_backlog_limited(sk, skb);
++ queued = !sk_add_backlog(sk, skb);
+ }
+ bh_unlock_sock(sk);
+ sock_put(sk);
--- /dev/null
+From 188ec168334863547e75a8525f7160c71f37f976 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Mon, 29 Mar 2010 21:33:28 -0700
+Subject: net: Potential null skb->dev dereference
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 0641e4fbf2f824faee00ea74c459a088d94905fd ]
+
+When doing "ifenslave -d bond0 eth0", there is chance to get NULL
+dereference in netif_receive_skb(), because dev->master suddenly becomes
+NULL after we tested it.
+
+We should use ACCESS_ONCE() to avoid this (or rcu_dereference())
+
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/netdevice.h | 8 ++++----
+ net/8021q/vlan_core.c | 4 ++--
+ net/core/dev.c | 8 +++++---
+ 3 files changed, 11 insertions(+), 9 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2023,12 +2023,12 @@ static inline void skb_bond_set_mac_by_m
+ * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
+ * ARP on active-backup slaves with arp_validate enabled.
+ */
+-static inline int skb_bond_should_drop(struct sk_buff *skb)
++static inline int skb_bond_should_drop(struct sk_buff *skb,
++ struct net_device *master)
+ {
+- struct net_device *dev = skb->dev;
+- struct net_device *master = dev->master;
+-
+ if (master) {
++ struct net_device *dev = skb->dev;
++
+ if (master->priv_flags & IFF_MASTER_ARPMON)
+ dev->last_rx = jiffies;
+
+--- a/net/8021q/vlan_core.c
++++ b/net/8021q/vlan_core.c
+@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *sk
+ if (netpoll_rx(skb))
+ return NET_RX_DROP;
+
+- if (skb_bond_should_drop(skb))
++ if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
+ goto drop;
+
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
+@@ -82,7 +82,7 @@ vlan_gro_common(struct napi_struct *napi
+ {
+ struct sk_buff *p;
+
+- if (skb_bond_should_drop(skb))
++ if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master)))
+ goto drop;
+
+ __vlan_hwaccel_put_tag(skb, vlan_tci);
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2421,6 +2421,7 @@ int netif_receive_skb(struct sk_buff *sk
+ {
+ struct packet_type *ptype, *pt_prev;
+ struct net_device *orig_dev;
++ struct net_device *master;
+ struct net_device *null_or_orig;
+ int ret = NET_RX_DROP;
+ __be16 type;
+@@ -2440,11 +2441,12 @@ int netif_receive_skb(struct sk_buff *sk
+
+ null_or_orig = NULL;
+ orig_dev = skb->dev;
+- if (orig_dev->master) {
+- if (skb_bond_should_drop(skb))
++ master = ACCESS_ONCE(orig_dev->master);
++ if (master) {
++ if (skb_bond_should_drop(skb, master))
+ null_or_orig = orig_dev; /* deliver only exact match */
+ else
+- skb->dev = orig_dev->master;
++ skb->dev = master;
+ }
+
+ __get_cpu_var(netdev_rx_stat).total++;
--- /dev/null
+From c6dd9976265f64670c90fbe7f39372d950f50e6b Mon Sep 17 00:00:00 2001
+From: Steven J. Magnani <steve@digidescorp.com>
+Date: Tue, 16 Mar 2010 05:22:44 +0000
+Subject: NET_DMA: free skbs periodically
+
+From: Steven J. Magnani <steve@digidescorp.com>
+
+[ Upstream commit 73852e8151b7d7a529fbe019ab6d2d0c02d8f3f2 ]
+
+Under NET_DMA, data transfer can grind to a halt when userland issues a
+large read on a socket with a high RCVLOWAT (i.e., 512 KB for both).
+This appears to be because the NET_DMA design queues up lots of memcpy
+operations, but doesn't issue or wait for them (and thus free the
+associated skbs) until it is time for tcp_recvmesg() to return.
+The socket hangs when its TCP window goes to zero before enough data is
+available to satisfy the read.
+
+Periodically issue asynchronous memcpy operations, and free skbs for ones
+that have completed, to prevent sockets from going into zero-window mode.
+
+Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/tcp.c | 63 ++++++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 43 insertions(+), 20 deletions(-)
+
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1254,6 +1254,39 @@ static void tcp_prequeue_process(struct
+ tp->ucopy.memory = 0;
+ }
+
++#ifdef CONFIG_NET_DMA
++static void tcp_service_net_dma(struct sock *sk, bool wait)
++{
++ dma_cookie_t done, used;
++ dma_cookie_t last_issued;
++ struct tcp_sock *tp = tcp_sk(sk);
++
++ if (!tp->ucopy.dma_chan)
++ return;
++
++ last_issued = tp->ucopy.dma_cookie;
++ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
++
++ do {
++ if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
++ last_issued, &done,
++ &used) == DMA_SUCCESS) {
++ /* Safe to free early-copied skbs now */
++ __skb_queue_purge(&sk->sk_async_wait_queue);
++ break;
++ } else {
++ struct sk_buff *skb;
++ while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
++ (dma_async_is_complete(skb->dma_cookie, done,
++ used) == DMA_SUCCESS)) {
++ __skb_dequeue(&sk->sk_async_wait_queue);
++ kfree_skb(skb);
++ }
++ }
++ } while (wait);
++}
++#endif
++
+ static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
+ {
+ struct sk_buff *skb;
+@@ -1546,6 +1579,10 @@ int tcp_recvmsg(struct kiocb *iocb, stru
+ /* __ Set realtime policy in scheduler __ */
+ }
+
++#ifdef CONFIG_NET_DMA
++ if (tp->ucopy.dma_chan)
++ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
++#endif
+ if (copied >= target) {
+ /* Do not sleep, just process backlog. */
+ release_sock(sk);
+@@ -1554,6 +1591,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru
+ sk_wait_data(sk, &timeo);
+
+ #ifdef CONFIG_NET_DMA
++ tcp_service_net_dma(sk, false); /* Don't block */
+ tp->ucopy.wakeup = 0;
+ #endif
+
+@@ -1633,6 +1671,9 @@ do_prequeue:
+ copied = -EFAULT;
+ break;
+ }
++
++ dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
++
+ if ((offset + used) == skb->len)
+ copied_early = 1;
+
+@@ -1702,27 +1743,9 @@ skip_copy:
+ }
+
+ #ifdef CONFIG_NET_DMA
+- if (tp->ucopy.dma_chan) {
+- dma_cookie_t done, used;
+-
+- dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+-
+- while (dma_async_memcpy_complete(tp->ucopy.dma_chan,
+- tp->ucopy.dma_cookie, &done,
+- &used) == DMA_IN_PROGRESS) {
+- /* do partial cleanup of sk_async_wait_queue */
+- while ((skb = skb_peek(&sk->sk_async_wait_queue)) &&
+- (dma_async_is_complete(skb->dma_cookie, done,
+- used) == DMA_SUCCESS)) {
+- __skb_dequeue(&sk->sk_async_wait_queue);
+- kfree_skb(skb);
+- }
+- }
++ tcp_service_net_dma(sk, true); /* Wait for queue to drain */
++ tp->ucopy.dma_chan = NULL;
+
+- /* Safe to free early-copied skbs now */
+- __skb_queue_purge(&sk->sk_async_wait_queue);
+- tp->ucopy.dma_chan = NULL;
+- }
+ if (tp->ucopy.pinned_list) {
+ dma_unpin_iovec_pages(tp->ucopy.pinned_list);
+ tp->ucopy.pinned_list = NULL;
--- /dev/null
+From d61c8adbf0d896b820d8aed1b7a01939071d5cfc Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Mon, 29 Mar 2010 21:28:23 -0700
+Subject: netfilter: ctnetlink: fix reliable event delivery if message building fails
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 37b7ef7203240b3aba577bb1ff6765fe15225976 ]
+
+This patch fixes a bug that allows to lose events when reliable
+event delivery mode is used, ie. if NETLINK_BROADCAST_SEND_ERROR
+and NETLINK_RECV_NO_ENOBUFS socket options are set.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/netfilter/nfnetlink.h | 2 +-
+ net/netfilter/nf_conntrack_netlink.c | 3 ++-
+ net/netfilter/nfnetlink.c | 4 ++--
+ 3 files changed, 5 insertions(+), 4 deletions(-)
+
+--- a/include/linux/netfilter/nfnetlink.h
++++ b/include/linux/netfilter/nfnetlink.h
+@@ -76,7 +76,7 @@ extern int nfnetlink_subsys_unregister(c
+ extern int nfnetlink_has_listeners(unsigned int group);
+ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
+ int echo, gfp_t flags);
+-extern void nfnetlink_set_err(u32 pid, u32 group, int error);
++extern int nfnetlink_set_err(u32 pid, u32 group, int error);
+ extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
+
+ extern void nfnl_lock(void);
+--- a/net/netfilter/nf_conntrack_netlink.c
++++ b/net/netfilter/nf_conntrack_netlink.c
+@@ -571,7 +571,8 @@ nla_put_failure:
+ nlmsg_failure:
+ kfree_skb(skb);
+ errout:
+- nfnetlink_set_err(0, group, -ENOBUFS);
++ if (nfnetlink_set_err(0, group, -ENOBUFS) > 0)
++ return -ENOBUFS;
+ return 0;
+ }
+ #endif /* CONFIG_NF_CONNTRACK_EVENTS */
+--- a/net/netfilter/nfnetlink.c
++++ b/net/netfilter/nfnetlink.c
+@@ -114,9 +114,9 @@ int nfnetlink_send(struct sk_buff *skb,
+ }
+ EXPORT_SYMBOL_GPL(nfnetlink_send);
+
+-void nfnetlink_set_err(u32 pid, u32 group, int error)
++int nfnetlink_set_err(u32 pid, u32 group, int error)
+ {
+- netlink_set_err(nfnl, pid, group, error);
++ return netlink_set_err(nfnl, pid, group, error);
+ }
+ EXPORT_SYMBOL_GPL(nfnetlink_set_err);
+
--- /dev/null
+From 0531f67fda935fca8fd6cb1d5c6219a0a1911c43 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Thu, 18 Mar 2010 14:24:42 +0000
+Subject: netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err()
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 1a50307ba1826e4da0024e64b245ce4eadf7688a ]
+
+Currently, ENOBUFS errors are reported to the socket via
+netlink_set_err() even if NETLINK_RECV_NO_ENOBUFS is set. However,
+that should not happen. This fixes this problem and it changes the
+prototype of netlink_set_err() to return the number of sockets that
+have set the NETLINK_RECV_NO_ENOBUFS socket option. This return
+value is used in the next patch in these bugfix series.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/netlink.h | 2 +-
+ net/netlink/af_netlink.c | 17 ++++++++++++++---
+ 2 files changed, 15 insertions(+), 4 deletions(-)
+
+--- a/include/linux/netlink.h
++++ b/include/linux/netlink.h
+@@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct
+ extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
+ extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
+ __u32 group, gfp_t allocation);
+-extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
++extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
+ extern int netlink_register_notifier(struct notifier_block *nb);
+ extern int netlink_unregister_notifier(struct notifier_block *nb);
+
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct
+ struct netlink_set_err_data *p)
+ {
+ struct netlink_sock *nlk = nlk_sk(sk);
++ int ret = 0;
+
+ if (sk == p->exclude_sk)
+ goto out;
+@@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct
+ !test_bit(p->group - 1, nlk->groups))
+ goto out;
+
++ if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) {
++ ret = 1;
++ goto out;
++ }
++
+ sk->sk_err = p->code;
+ sk->sk_error_report(sk);
+ out:
+- return 0;
++ return ret;
+ }
+
+ /**
+@@ -1116,12 +1122,16 @@ out:
+ * @pid: the PID of a process that we want to skip (if any)
+ * @groups: the broadcast group that will notice the error
+ * @code: error code, must be negative (as usual in kernelspace)
++ *
++ * This function returns the number of broadcast listeners that have set the
++ * NETLINK_RECV_NO_ENOBUFS socket option.
+ */
+-void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
++int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
+ {
+ struct netlink_set_err_data info;
+ struct hlist_node *node;
+ struct sock *sk;
++ int ret = 0;
+
+ info.exclude_sk = ssk;
+ info.pid = pid;
+@@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u
+ read_lock(&nl_table_lock);
+
+ sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list)
+- do_one_set_err(sk, &info);
++ ret += do_one_set_err(sk, &info);
+
+ read_unlock(&nl_table_lock);
++ return ret;
+ }
+ EXPORT_SYMBOL(netlink_set_err);
+
--- /dev/null
+From e4905f5f2c61875cee329132c40d124274139272 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Tue, 16 Mar 2010 13:30:44 +0000
+Subject: netlink: fix unaligned access in nla_get_be64()
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit f5d410f2ea7ba340f11815a56e05b9fa9421c421 ]
+
+This patch fixes a unaligned access in nla_get_be64() that was
+introduced by myself in a17c859849402315613a0015ac8fbf101acf0cc1.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/net/netlink.h | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/net/netlink.h
++++ b/include/net/netlink.h
+@@ -945,7 +945,11 @@ static inline u64 nla_get_u64(const stru
+ */
+ static inline __be64 nla_get_be64(const struct nlattr *nla)
+ {
+- return *(__be64 *) nla_data(nla);
++ __be64 tmp;
++
++ nla_memcpy(&tmp, nla, sizeof(tmp));
++
++ return tmp;
+ }
+
+ /**
--- /dev/null
+From b0516a171b2edab15cdc336272e3a253321aab91 Mon Sep 17 00:00:00 2001
+From: Meelis Roos <mroos@linux.ee>
+Date: Mon, 8 Mar 2010 10:53:08 -0800
+Subject: qlogicpti: Remove slash in QlogicPTI irq name
+
+From: Meelis Roos <mroos@linux.ee>
+
+[ Upstream commit 77d3926306bf4eecac50150ba5625797219f14ba ]
+
+qlogicpti driver registers its irq with a name containing slash.
+This results in
+
+[ 71.049735] WARNING: at fs/proc/generic.c:316 __xlate_proc_name+0xa8/0xb8()
+[ 71.132815] name 'Qlogic/PTI'
+
+because proc_mkdir with the name of the irq fails. Fix it by just
+removing the slash from irq name. Discovered and tested on real hardware
+(Sun Ultra 1).
+
+Signed-off-by: Meelis Roos <mroos@linux.ee>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/qlogicpti.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/qlogicpti.c
++++ b/drivers/scsi/qlogicpti.c
+@@ -738,7 +738,7 @@ static int __devinit qpti_register_irq(s
+ * sanely maintain.
+ */
+ if (request_irq(qpti->irq, qpti_intr,
+- IRQF_SHARED, "Qlogic/PTI", qpti))
++ IRQF_SHARED, "QlogicPTI", qpti))
+ goto fail;
+
+ printk("qlogicpti%d: IRQ %d ", qpti->qpti_id, qpti->irq);
--- /dev/null
+From cdec71f9b0697de47d06e34619b45e9998bc1ca2 Mon Sep 17 00:00:00 2001
+From: Neil Horman <nhorman@redhat.com>
+Date: Mon, 29 Mar 2010 13:16:02 -0700
+Subject: r8169: offical fix for CVE-2009-4537 (overlength frame DMAs)
+
+From: Neil Horman <nhorman@redhat.com>
+
+[ Upstream commit c0cd884af045338476b8e69a61fceb3f34ff22f1 ]
+
+Official patch to fix the r8169 frame length check error.
+
+Based on this initial thread:
+http://marc.info/?l=linux-netdev&m=126202972828626&w=1
+This is the official patch to fix the frame length problems in the r8169
+driver. As noted in the previous thread, while this patch incurs a performance
+hit on the driver, its possible to improve performance dynamically by updating
+the mtu and rx_copybreak values at runtime to return performance to what it was
+for those NICS which are unaffected by the ideosyncracy (if there are any).
+
+Summary:
+
+ A while back Eric submitted a patch for r8169 in which the proper
+allocated frame size was written to RXMaxSize to prevent the NIC from dmaing too
+much data. This was done in commit fdd7b4c3302c93f6833e338903ea77245eb510b4. A
+long time prior to that however, Francois posted
+126fa4b9ca5d9d7cb7d46f779ad3bd3631ca387c, which expiclitly disabled the MaxSize
+setting due to the fact that the hardware behaved in odd ways when overlong
+frames were received on NIC's supported by this driver. This was mentioned in a
+security conference recently:
+http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html
+
+It seems that if we can't enable frame size filtering, then, as Eric correctly
+noticed, we can find ourselves DMA-ing too much data to a buffer, causing
+corruption. As a result is seems that we are forced to allocate a frame which
+is ready to handle a maximally sized receive.
+
+This obviously has performance issues with it, so to mitigate that issue, this
+patch does two things:
+
+1) Raises the copybreak value to the frame allocation size, which should force
+appropriately sized packets to get allocated on rx, rather than a full new 16k
+buffer.
+
+2) This patch only disables frame filtering initially (i.e., during the NIC
+open), changing the MTU results in ring buffer allocation of a size in relation
+to the new mtu (along with a warning indicating that this is dangerous).
+
+Because of item (2), individuals who can't cope with the performance hit (or can
+otherwise filter frames to prevent the bug), or who have hardware they are sure
+is unaffected by this issue, can manually lower the copybreak and reset the mtu
+such that performance is restored easily.
+
+Signed-off-by: Neil Horman <nhorman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/r8169.c | 29 ++++++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -186,7 +186,12 @@ static struct pci_device_id rtl8169_pci_
+
+ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl);
+
+-static int rx_copybreak = 200;
++/*
++ * we set our copybreak very high so that we don't have
++ * to allocate 16k frames all the time (see note in
++ * rtl8169_open()
++ */
++static int rx_copybreak = 16383;
+ static int use_dac;
+ static struct {
+ u32 msg_enable;
+@@ -3245,9 +3250,13 @@ static void __devexit rtl8169_remove_one
+ }
+
+ static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
+- struct net_device *dev)
++ unsigned int mtu)
+ {
+- unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
++ unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
++
++ if (max_frame != 16383)
++ printk(KERN_WARNING "WARNING! Changing of MTU on this NIC"
++ "May lead to frame reception errors!\n");
+
+ tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
+ }
+@@ -3259,7 +3268,17 @@ static int rtl8169_open(struct net_devic
+ int retval = -ENOMEM;
+
+
+- rtl8169_set_rxbufsize(tp, dev);
++ /*
++ * Note that we use a magic value here, its wierd I know
++ * its done because, some subset of rtl8169 hardware suffers from
++ * a problem in which frames received that are longer than
++ * the size set in RxMaxSize register return garbage sizes
++ * when received. To avoid this we need to turn off filtering,
++ * which is done by setting a value of 16383 in the RxMaxSize register
++ * and allocating 16k frames to handle the largest possible rx value
++ * thats what the magic math below does.
++ */
++ rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN);
+
+ /*
+ * Rx and Tx desscriptors needs 256 bytes alignment.
+@@ -3912,7 +3931,7 @@ static int rtl8169_change_mtu(struct net
+
+ rtl8169_down(dev);
+
+- rtl8169_set_rxbufsize(tp, dev);
++ rtl8169_set_rxbufsize(tp, dev->mtu);
+
+ ret = rtl8169_init_ring(dev);
+ if (ret < 0)
--- /dev/null
+From bc36a3fb21af50cda344b12082c44c5b54c072e7 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sun, 28 Mar 2010 18:58:28 -0700
+Subject: Revert "ide: skip probe if there are no devices on the port (v2)"
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 9ce41aed0d392246eb788786253f242e829fd5e1 ]
+
+This reverts commit a20b2a44eca52818ef52a94959480b7e6ea2f528.
+
+As requested by David Fries. This makes CDROMs which are slave drives
+on a ribbon without a master disappear and causes other similar kinds
+of badness.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/ide-probe.c | 12 +++---------
+ 1 file changed, 3 insertions(+), 9 deletions(-)
+
+--- a/drivers/ide/ide-probe.c
++++ b/drivers/ide/ide-probe.c
+@@ -695,14 +695,8 @@ static int ide_probe_port(ide_hwif_t *hw
+ if (irqd)
+ disable_irq(hwif->irq);
+
+- rc = ide_port_wait_ready(hwif);
+- if (rc == -ENODEV) {
+- printk(KERN_INFO "%s: no devices on the port\n", hwif->name);
+- goto out;
+- } else if (rc == -EBUSY)
+- printk(KERN_ERR "%s: not ready before the probe\n", hwif->name);
+- else
+- rc = -ENODEV;
++ if (ide_port_wait_ready(hwif) == -EBUSY)
++ printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
+
+ /*
+ * Second drive should only exist if first drive was found,
+@@ -713,7 +707,7 @@ static int ide_probe_port(ide_hwif_t *hw
+ if (drive->dev_flags & IDE_DFLAG_PRESENT)
+ rc = 0;
+ }
+-out:
++
+ /*
+ * Use cached IRQ number. It might be (and is...) changed by probe
+ * code above
--- /dev/null
+From 4c1017d750c992cb093c9e0c2b4d297880db76e1 Mon Sep 17 00:00:00 2001
+From: Vitaliy Gusev <vgusev@openvz.org>
+Date: Tue, 16 Mar 2010 01:07:51 +0000
+Subject: route: Fix caught BUG_ON during rt_secret_rebuild_oneshot()
+
+From: Vitaliy Gusev <vgusev@openvz.org>
+
+[ Upstream commit 858a18a6a2f74e8f0e5b2e9671d4b74694aba708 ]
+
+route: Fix caught BUG_ON during rt_secret_rebuild_oneshot()
+
+Call rt_secret_rebuild can cause BUG_ON(timer_pending(&net->ipv4.rt_secret_timer)) in
+add_timer as there is not any synchronization for call rt_secret_rebuild_oneshot()
+for the same net namespace.
+
+Also this issue affects to rt_secret_reschedule().
+
+Thus use mod_timer enstead.
+
+Signed-off-by: Vitaliy Gusev <vgusev@openvz.org>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/route.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -922,10 +922,8 @@ static void rt_secret_rebuild_oneshot(st
+ {
+ del_timer_sync(&net->ipv4.rt_secret_timer);
+ rt_cache_invalidate(net);
+- if (ip_rt_secret_interval) {
+- net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval;
+- add_timer(&net->ipv4.rt_secret_timer);
+- }
++ if (ip_rt_secret_interval)
++ mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
+ }
+
+ static void rt_emergency_hash_rebuild(struct net *net)
+@@ -3072,22 +3070,20 @@ static void rt_secret_reschedule(int old
+ rtnl_lock();
+ for_each_net(net) {
+ int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
++ long time;
+
+ if (!new)
+ continue;
+
+ if (deleted) {
+- long time = net->ipv4.rt_secret_timer.expires - jiffies;
++ time = net->ipv4.rt_secret_timer.expires - jiffies;
+
+ if (time <= 0 || (time += diff) <= 0)
+ time = 0;
+-
+- net->ipv4.rt_secret_timer.expires = time;
+ } else
+- net->ipv4.rt_secret_timer.expires = new;
++ time = new;
+
+- net->ipv4.rt_secret_timer.expires += jiffies;
+- add_timer(&net->ipv4.rt_secret_timer);
++ mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
+ }
+ rtnl_unlock();
+ }
--- /dev/null
+From d297f86c51d0ce84e787614211a58dff05fab041 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:44 +0000
+Subject: sctp: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 50b1a782f845140f4138f14a1ce8a4a6dd0cc82f ]
+
+Make sctp adapt to the limited socket backlog change.
+
+Cc: Vlad Yasevich <vladislav.yasevich@hp.com>
+Cc: Sridhar Samudrala <sri@us.ibm.com>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/sctp/input.c | 42 +++++++++++++++++++++++++++---------------
+ net/sctp/socket.c | 3 +++
+ 2 files changed, 30 insertions(+), 15 deletions(-)
+
+--- a/net/sctp/input.c
++++ b/net/sctp/input.c
+@@ -75,7 +75,7 @@ static struct sctp_association *__sctp_l
+ const union sctp_addr *peer,
+ struct sctp_transport **pt);
+
+-static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
++static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
+
+
+ /* Calculate the SCTP checksum of an SCTP packet. */
+@@ -265,8 +265,13 @@ int sctp_rcv(struct sk_buff *skb)
+ }
+
+ if (sock_owned_by_user(sk)) {
++ if (sctp_add_backlog(sk, skb)) {
++ sctp_bh_unlock_sock(sk);
++ sctp_chunk_free(chunk);
++ skb = NULL; /* sctp_chunk_free already freed the skb */
++ goto discard_release;
++ }
+ SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG);
+- sctp_add_backlog(sk, skb);
+ } else {
+ SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_SOFTIRQ);
+ sctp_inq_push(&chunk->rcvr->inqueue, chunk);
+@@ -336,8 +341,10 @@ int sctp_backlog_rcv(struct sock *sk, st
+ sctp_bh_lock_sock(sk);
+
+ if (sock_owned_by_user(sk)) {
+- sk_add_backlog(sk, skb);
+- backloged = 1;
++ if (sk_add_backlog_limited(sk, skb))
++ sctp_chunk_free(chunk);
++ else
++ backloged = 1;
+ } else
+ sctp_inq_push(inqueue, chunk);
+
+@@ -362,22 +369,27 @@ done:
+ return 0;
+ }
+
+-static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
++static int sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+ struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
+ struct sctp_ep_common *rcvr = chunk->rcvr;
++ int ret;
+
+- /* Hold the assoc/ep while hanging on the backlog queue.
+- * This way, we know structures we need will not disappear from us
+- */
+- if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
+- sctp_association_hold(sctp_assoc(rcvr));
+- else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
+- sctp_endpoint_hold(sctp_ep(rcvr));
+- else
+- BUG();
++ ret = sk_add_backlog_limited(sk, skb);
++ if (!ret) {
++ /* Hold the assoc/ep while hanging on the backlog queue.
++ * This way, we know structures we need will not disappear
++ * from us
++ */
++ if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
++ sctp_association_hold(sctp_assoc(rcvr));
++ else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
++ sctp_endpoint_hold(sctp_ep(rcvr));
++ else
++ BUG();
++ }
++ return ret;
+
+- sk_add_backlog(sk, skb);
+ }
+
+ /* Handle icmp frag needed error. */
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -3720,6 +3720,9 @@ SCTP_STATIC int sctp_init_sock(struct so
+ SCTP_DBG_OBJCNT_INC(sock);
+ percpu_counter_inc(&sctp_sockets_allocated);
+
++ /* Set socket backlog limit. */
++ sk->sk_backlog.limit = sysctl_sctp_rmem[1];
++
+ local_bh_disable();
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+ local_bh_enable();
mac80211-retry-null-data-frame-for-power-save.patch
ath9k-enable-ieee80211_hw_reports_tx_ack_status-flag-for-ath9k.patch
leds-gpio-fix-default-state-handling-on-of-platforms.patch
+icside-bring-back-maskproc-method.patch
+revert-ide-skip-probe-if-there-are-no-devices-on-the-port-v2.patch
+ide-fix-promise-udma33-ide-driver-pdc202xx_old.patch
+qlogicpti-remove-slash-in-qlogicpti-irq-name.patch
+sparc64-properly-truncate-pt_regs-framepointer-in-perf-callback.patch
+sparc64-add-very-basic-xvr-1000-framebuffer-driver.patch
+l2tp-fix-oops-in-pppol2tp_xmit.patch
+l2tp-fix-udp-socket-reference-count-bugs-in-the-pppol2tp-driver.patch
+route-fix-caught-bug_on-during-rt_secret_rebuild_oneshot.patch
+net-add-limit-for-socket-backlog.patch
+tcp-use-limited-socket-backlog.patch
+udp-use-limited-socket-backlog.patch
+llc-use-limited-socket-backlog.patch
+sctp-use-limited-socket-backlog.patch
+tipc-use-limited-socket-backlog.patch
+x25-use-limited-socket-backlog.patch
+net-backlog-functions-rename.patch
+net-add-__must_check-to-sk_add_backlog.patch
+bonding-fix-device-leak-on-error-in-bond_create.patch
+e100-fix-ring-parameter-change-handling-regression.patch
+ip_gre-include-route-header_len-in-max_headroom-calculation.patch
+ipsec-fix-bogus-bundle-flowi.patch
+ipv4-check-rt_genid-in-dst_check.patch
+ipv4-don-t-drop-redirected-route-cache-entry-unless-ptmu-actually-expired.patch
+ipv6-don-t-drop-cache-route-entry-unless-timer-actually-expired.patch
+net_dma-free-skbs-periodically.patch
+netlink-fix-netlink_recv_no_enobufs-in-netlink_set_err.patch
+netfilter-ctnetlink-fix-reliable-event-delivery-if-message-building-fails.patch
+netlink-fix-unaligned-access-in-nla_get_be64.patch
+r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch
+net-potential-null-skb-dev-dereference.patch
+skbuff-remove-unused-dma_head-dma_maps-fields.patch
+tcp-fix-tcp_mark_head_lost-with-packets-0.patch
+tcp-fix-oob-pollin-avoidance.patch
+tcp-fix-tcp_make_synack.patch
--- /dev/null
+From 01c5788cad31f344418f9b16c9357c653c9d3af6 Mon Sep 17 00:00:00 2001
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+Date: Tue, 23 Mar 2010 20:40:50 +0000
+Subject: skbuff: remove unused dma_head & dma_maps fields
+
+From: Alexander Duyck <alexander.h.duyck@intel.com>
+
+[ Upstream commit 03e6d819c2cb2cc8ce5642669a0a7c72336ee7a2 ]
+
+The dma map fields in the skb_shared_info structure no longer has any users
+and can be dropped since it is making the skb_shared_info unecessarily larger.
+
+Running slabtop show that we were using 4K slabs for the skb->head on x86_64 w/
+an allocation size of 1522. It turns out that the dma_head and dma_maps array
+made skb_shared large enough that we had crossed over the 2k boundary with
+standard frames and as such we were using 4k blocks of memory for all skbs.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/skbuff.h | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -190,9 +190,6 @@ struct skb_shared_info {
+ atomic_t dataref;
+ unsigned short nr_frags;
+ unsigned short gso_size;
+-#ifdef CONFIG_HAS_DMA
+- dma_addr_t dma_head;
+-#endif
+ /* Warning: this field is not always filled in (UFO)! */
+ unsigned short gso_segs;
+ unsigned short gso_type;
+@@ -201,9 +198,6 @@ struct skb_shared_info {
+ struct sk_buff *frag_list;
+ struct skb_shared_hwtstamps hwtstamps;
+ skb_frag_t frags[MAX_SKB_FRAGS];
+-#ifdef CONFIG_HAS_DMA
+- dma_addr_t dma_maps[MAX_SKB_FRAGS];
+-#endif
+ /* Intermediate layers must ensure that destructor_arg
+ * remains valid until skb destructor */
+ void * destructor_arg;
--- /dev/null
+From cc82b8a8b6592e9d69c2cc4a1074ec6447a3ea7c Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 29 Mar 2010 22:18:29 -0700
+Subject: sparc64: Add very basic XVR-1000 framebuffer driver.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commits 2d378b9179881b46a0faf11430efb421fe03ddd8 and
+ f04e879bf296d136bcafd8c5a26e95599b141671 ]
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Frans van Berckel <fberckel@xs4all.nl>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/Kconfig | 12 ++
+ drivers/video/Makefile | 1
+ drivers/video/sunxvr1000.c | 228 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 241 insertions(+)
+
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -909,6 +909,18 @@ config FB_XVR2500
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
++config FB_XVR1000
++ bool "Sun XVR-1000 support"
++ depends on (FB = y) && SPARC64
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ help
++ This is the framebuffer device for the Sun XVR-1000 and similar
++ graphics cards. The driver only works on sparc64 systems where
++ the system firmware has mostly initialized the card already. It
++ is treated as a completely dumb framebuffer device.
++
+ config FB_PVR2
+ tristate "NEC PowerVR 2 display support"
+ depends on FB && SH_DREAMCAST
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -79,6 +79,7 @@ obj-$(CONFIG_FB_N411) += n41
+ obj-$(CONFIG_FB_HGA) += hgafb.o
+ obj-$(CONFIG_FB_XVR500) += sunxvr500.o
+ obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
++obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
+ obj-$(CONFIG_FB_IGA) += igafb.o
+ obj-$(CONFIG_FB_APOLLO) += dnfb.o
+ obj-$(CONFIG_FB_Q40) += q40fb.o
+--- /dev/null
++++ b/drivers/video/sunxvr1000.c
+@@ -0,0 +1,228 @@
++/* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems
++ *
++ * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/of_device.h>
++
++struct gfb_info {
++ struct fb_info *info;
++
++ char __iomem *fb_base;
++ unsigned long fb_base_phys;
++
++ struct device_node *of_node;
++
++ unsigned int width;
++ unsigned int height;
++ unsigned int depth;
++ unsigned int fb_size;
++
++ u32 pseudo_palette[16];
++};
++
++static int __devinit gfb_get_props(struct gfb_info *gp)
++{
++ gp->width = of_getintprop_default(gp->of_node, "width", 0);
++ gp->height = of_getintprop_default(gp->of_node, "height", 0);
++ gp->depth = of_getintprop_default(gp->of_node, "depth", 32);
++
++ if (!gp->width || !gp->height) {
++ printk(KERN_ERR "gfb: Critical properties missing for %s\n",
++ gp->of_node->full_name);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int gfb_setcolreg(unsigned regno,
++ unsigned red, unsigned green, unsigned blue,
++ unsigned transp, struct fb_info *info)
++{
++ u32 value;
++
++ if (regno < 16) {
++ red >>= 8;
++ green >>= 8;
++ blue >>= 8;
++
++ value = (blue << 16) | (green << 8) | red;
++ ((u32 *)info->pseudo_palette)[regno] = value;
++ }
++
++ return 0;
++}
++
++static struct fb_ops gfb_ops = {
++ .owner = THIS_MODULE,
++ .fb_setcolreg = gfb_setcolreg,
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++ .fb_imageblit = cfb_imageblit,
++};
++
++static int __devinit gfb_set_fbinfo(struct gfb_info *gp)
++{
++ struct fb_info *info = gp->info;
++ struct fb_var_screeninfo *var = &info->var;
++
++ info->flags = FBINFO_DEFAULT;
++ info->fbops = &gfb_ops;
++ info->screen_base = gp->fb_base;
++ info->screen_size = gp->fb_size;
++
++ info->pseudo_palette = gp->pseudo_palette;
++
++ /* Fill fix common fields */
++ strlcpy(info->fix.id, "gfb", sizeof(info->fix.id));
++ info->fix.smem_start = gp->fb_base_phys;
++ info->fix.smem_len = gp->fb_size;
++ info->fix.type = FB_TYPE_PACKED_PIXELS;
++ if (gp->depth == 32 || gp->depth == 24)
++ info->fix.visual = FB_VISUAL_TRUECOLOR;
++ else
++ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
++
++ var->xres = gp->width;
++ var->yres = gp->height;
++ var->xres_virtual = var->xres;
++ var->yres_virtual = var->yres;
++ var->bits_per_pixel = gp->depth;
++
++ var->red.offset = 0;
++ var->red.length = 8;
++ var->green.offset = 8;
++ var->green.length = 8;
++ var->blue.offset = 16;
++ var->blue.length = 8;
++ var->transp.offset = 0;
++ var->transp.length = 0;
++
++ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
++ printk(KERN_ERR "gfb: Cannot allocate color map.\n");
++ return -ENOMEM;
++ }
++
++ return 0;
++}
++
++static int __devinit gfb_probe(struct of_device *op,
++ const struct of_device_id *match)
++{
++ struct device_node *dp = op->node;
++ struct fb_info *info;
++ struct gfb_info *gp;
++ int err;
++
++ info = framebuffer_alloc(sizeof(struct gfb_info), &op->dev);
++ if (!info) {
++ printk(KERN_ERR "gfb: Cannot allocate fb_info\n");
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ gp = info->par;
++ gp->info = info;
++ gp->of_node = dp;
++
++ gp->fb_base_phys = op->resource[6].start;
++
++ err = gfb_get_props(gp);
++ if (err)
++ goto err_release_fb;
++
++ /* Framebuffer length is the same regardless of resolution. */
++ info->fix.line_length = 16384;
++ gp->fb_size = info->fix.line_length * gp->height;
++
++ gp->fb_base = of_ioremap(&op->resource[6], 0,
++ gp->fb_size, "gfb fb");
++ if (!gp->fb_base)
++ goto err_release_fb;
++
++ err = gfb_set_fbinfo(gp);
++ if (err)
++ goto err_unmap_fb;
++
++ printk("gfb: Found device at %s\n", dp->full_name);
++
++ err = register_framebuffer(info);
++ if (err < 0) {
++ printk(KERN_ERR "gfb: Could not register framebuffer %s\n",
++ dp->full_name);
++ goto err_unmap_fb;
++ }
++
++ dev_set_drvdata(&op->dev, info);
++
++ return 0;
++
++err_unmap_fb:
++ of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
++
++err_release_fb:
++ framebuffer_release(info);
++
++err_out:
++ return err;
++}
++
++static int __devexit gfb_remove(struct of_device *op)
++{
++ struct fb_info *info = dev_get_drvdata(&op->dev);
++ struct gfb_info *gp = info->par;
++
++ unregister_framebuffer(info);
++
++ iounmap(gp->fb_base);
++
++ of_iounmap(&op->resource[6], gp->fb_base, gp->fb_size);
++
++ framebuffer_release(info);
++
++ dev_set_drvdata(&op->dev, NULL);
++
++ return 0;
++}
++
++static const struct of_device_id gfb_match[] = {
++ {
++ .name = "SUNW,gfb",
++ },
++ {},
++};
++MODULE_DEVICE_TABLE(of, ffb_match);
++
++static struct of_platform_driver gfb_driver = {
++ .name = "gfb",
++ .match_table = gfb_match,
++ .probe = gfb_probe,
++ .remove = __devexit_p(gfb_remove),
++};
++
++static int __init gfb_init(void)
++{
++ if (fb_get_options("gfb", NULL))
++ return -ENODEV;
++
++ return of_register_driver(&gfb_driver, &of_bus_type);
++}
++
++static void __exit gfb_exit(void)
++{
++ of_unregister_driver(&gfb_driver);
++}
++
++module_init(gfb_init);
++module_exit(gfb_exit);
++
++MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
++MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
++MODULE_VERSION("1.0");
++MODULE_LICENSE("GPL");
--- /dev/null
+From f90d80e990205b2b1020e98c6a6c2fcbccee2349 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 29 Mar 2010 13:08:52 -0700
+Subject: sparc64: Properly truncate pt_regs framepointer in perf callback.
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 9e8307ecaf9f8c8b5b3b22145021204c4e73114a ]
+
+For 32-bit processes, we save the full 64-bits of the regs in pt_regs.
+
+But unlike when the userspace actually does load and store
+instructions, the top 32-bits don't get automatically truncated by the
+cpu in kernel mode (because the kernel doesn't execute with PSTATE_AM
+address masking enabled).
+
+So we have to do it by hand.
+
+Reported-by: Frederic Weisbecker <fweisbec@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/sparc/kernel/perf_event.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/sparc/kernel/perf_event.c
++++ b/arch/sparc/kernel/perf_event.c
+@@ -1337,7 +1337,7 @@ static void perf_callchain_user_32(struc
+ callchain_store(entry, PERF_CONTEXT_USER);
+ callchain_store(entry, regs->tpc);
+
+- ufp = regs->u_regs[UREG_I6];
++ ufp = regs->u_regs[UREG_I6] & 0xffffffffUL;
+ do {
+ struct sparc_stackf32 *usf, sf;
+ unsigned long pc;
--- /dev/null
+From b17f5da6dd40f9a5a60bce31fd94e0d96194af50 Mon Sep 17 00:00:00 2001
+From: Alexandra Kossovsky <Alexandra.Kossovsky@oktetlabs.ru>
+Date: Thu, 18 Mar 2010 20:29:24 -0700
+Subject: tcp: Fix OOB POLLIN avoidance.
+
+From: Alexandra Kossovsky <Alexandra.Kossovsky@oktetlabs.ru>
+
+[ Upstream commit b634f87522dff87712df8bda2a6c9061954d552a ]
+
+From: Alexandra.Kossovsky@oktetlabs.ru
+
+Fixes kernel bugzilla #15541
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -429,7 +429,7 @@ unsigned int tcp_poll(struct file *file,
+ if (tp->urg_seq == tp->copied_seq &&
+ !sock_flag(sk, SOCK_URGINLINE) &&
+ tp->urg_data)
+- target--;
++ target++;
+
+ /* Potential race condition. If read of tp below will
+ * escape above sk->sk_state, we can be illegally awaken
--- /dev/null
+From 8d755c9fa5d65e799b0f7c536b1482d76dc307dd Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Mon, 8 Mar 2010 11:32:01 -0800
+Subject: tcp: Fix tcp_make_synack()
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 28b2774a0d5852236dab77a4147b8b88548110f1 ]
+
+Commit 4957faad (TCPCT part 1g: Responder Cookie => Initiator), part
+of TCP_COOKIE_TRANSACTION implementation, forgot to correctly size
+synack skb in case user data must be included.
+
+Many thanks to Mika Pentillä for spotting this error.
+
+Reported-by: Penttillä Mika <mika.penttila@ixonos.com>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/tcp_output.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2393,13 +2393,17 @@ struct sk_buff *tcp_make_synack(struct s
+ struct tcp_extend_values *xvp = tcp_xv(rvp);
+ struct inet_request_sock *ireq = inet_rsk(req);
+ struct tcp_sock *tp = tcp_sk(sk);
++ const struct tcp_cookie_values *cvp = tp->cookie_values;
+ struct tcphdr *th;
+ struct sk_buff *skb;
+ struct tcp_md5sig_key *md5;
+ int tcp_header_size;
+ int mss;
++ int s_data_desired = 0;
+
+- skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
++ if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
++ s_data_desired = cvp->s_data_desired;
++ skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC);
+ if (skb == NULL)
+ return NULL;
+
+@@ -2454,16 +2458,12 @@ struct sk_buff *tcp_make_synack(struct s
+ TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
+
+ if (OPTION_COOKIE_EXTENSION & opts.options) {
+- const struct tcp_cookie_values *cvp = tp->cookie_values;
+-
+- if (cvp != NULL &&
+- cvp->s_data_constant &&
+- cvp->s_data_desired > 0) {
+- u8 *buf = skb_put(skb, cvp->s_data_desired);
++ if (s_data_desired) {
++ u8 *buf = skb_put(skb, s_data_desired);
+
+ /* copy data directly from the listening socket. */
+- memcpy(buf, cvp->s_data_payload, cvp->s_data_desired);
+- TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired;
++ memcpy(buf, cvp->s_data_payload, s_data_desired);
++ TCP_SKB_CB(skb)->end_seq += s_data_desired;
+ }
+
+ if (opts.hash_size > 0) {
--- /dev/null
+From 4bf396ed4e77524c5c3fb0c7acc5107818af8fd5 Mon Sep 17 00:00:00 2001
+From: Lennart Schulte <lennart.schulte@nets.rwth-aachen.de>
+Date: Wed, 17 Mar 2010 02:16:29 +0000
+Subject: tcp: Fix tcp_mark_head_lost() with packets == 0
+
+From: Lennart Schulte <lennart.schulte@nets.rwth-aachen.de>
+
+[ Upstream commit 6830c25b7d08fbbd922959425193791bc42079f2 ]
+
+A packet is marked as lost in case packets == 0, although nothing should be done.
+This results in a too early retransmitted packet during recovery in some cases.
+This small patch fixes this issue by returning immediately.
+
+Signed-off-by: Lennart Schulte <lennart.schulte@nets.rwth-aachen.de>
+Signed-off-by: Arnd Hannemann <hannemann@nets.rwth-aachen.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/tcp_input.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2499,6 +2499,9 @@ static void tcp_mark_head_lost(struct so
+ int err;
+ unsigned int mss;
+
++ if (packets == 0)
++ return;
++
+ WARN_ON(packets > tp->packets_out);
+ if (tp->lost_skb_hint) {
+ skb = tp->lost_skb_hint;
--- /dev/null
+From 9dc97b0601a753adda5a76101041165fd86e9132 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:41 +0000
+Subject: tcp: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 6b03a53a5ab7ccf2d5d69f96cf1c739c4d2a8fb9 ]
+
+Make tcp adapt to the limited socket backlog change.
+
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
+Cc: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/ipv4/tcp_ipv4.c | 6 ++++--
+ net/ipv6/tcp_ipv6.c | 6 ++++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1677,8 +1677,10 @@ process:
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v4_do_rcv(sk, skb);
+ }
+- } else
+- sk_add_backlog(sk, skb);
++ } else if (sk_add_backlog_limited(sk, skb)) {
++ bh_unlock_sock(sk);
++ goto discard_and_relse;
++ }
+ bh_unlock_sock(sk);
+
+ sock_put(sk);
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1732,8 +1732,10 @@ process:
+ if (!tcp_prequeue(sk, skb))
+ ret = tcp_v6_do_rcv(sk, skb);
+ }
+- } else
+- sk_add_backlog(sk, skb);
++ } else if (sk_add_backlog_limited(sk, skb)) {
++ bh_unlock_sock(sk);
++ goto discard_and_relse;
++ }
+ bh_unlock_sock(sk);
+
+ sock_put(sk);
--- /dev/null
+From 8e5080598871b71e9785b0b6ba7291548a273a89 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:45 +0000
+Subject: tipc: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 53eecb1be5ae499d399d2923933937a9ea1a284f ]
+
+Make tipc adapt to the limited socket backlog change.
+
+Cc: Jon Maloy <jon.maloy@ericsson.com>
+Cc: Allan Stephens <allan.stephens@windriver.com>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Acked-by: Allan Stephens <allan.stephens@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/tipc/socket.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -1322,8 +1322,10 @@ static u32 dispatch(struct tipc_port *tp
+ if (!sock_owned_by_user(sk)) {
+ res = filter_rcv(sk, buf);
+ } else {
+- sk_add_backlog(sk, buf);
+- res = TIPC_OK;
++ if (sk_add_backlog_limited(sk, buf))
++ res = TIPC_ERR_OVERLOAD;
++ else
++ res = TIPC_OK;
+ }
+ bh_unlock_sock(sk);
+
--- /dev/null
+From 74487b0c81587dec3d1cd9a85673374dc9c35cde Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:42 +0000
+Subject: udp: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 55349790d7cbf0d381873a7ece1dcafcffd4aaa9 ]
+
+Make udp adapt to the limited socket backlog change.
+
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
+Cc: "Pekka Savola (ipv6)" <pekkas@netcore.fi>
+Cc: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/udp.c | 6 ++++--
+ net/ipv6/udp.c | 28 ++++++++++++++++++----------
+ 2 files changed, 22 insertions(+), 12 deletions(-)
+
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1372,8 +1372,10 @@ int udp_queue_rcv_skb(struct sock *sk, s
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ rc = __udp_queue_rcv_skb(sk, skb);
+- else
+- sk_add_backlog(sk, skb);
++ else if (sk_add_backlog_limited(sk, skb)) {
++ bh_unlock_sock(sk);
++ goto drop;
++ }
+ bh_unlock_sock(sk);
+
+ return rc;
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -584,16 +584,20 @@ static void flush_stack(struct sock **st
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ udpv6_queue_rcv_skb(sk, skb1);
+- else
+- sk_add_backlog(sk, skb1);
++ else if (sk_add_backlog_limited(sk, skb1)) {
++ kfree_skb(skb1);
++ bh_unlock_sock(sk);
++ goto drop;
++ }
+ bh_unlock_sock(sk);
+- } else {
+- atomic_inc(&sk->sk_drops);
+- UDP6_INC_STATS_BH(sock_net(sk),
+- UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
+- UDP6_INC_STATS_BH(sock_net(sk),
+- UDP_MIB_INERRORS, IS_UDPLITE(sk));
++ continue;
+ }
++drop:
++ atomic_inc(&sk->sk_drops);
++ UDP6_INC_STATS_BH(sock_net(sk),
++ UDP_MIB_RCVBUFERRORS, IS_UDPLITE(sk));
++ UDP6_INC_STATS_BH(sock_net(sk),
++ UDP_MIB_INERRORS, IS_UDPLITE(sk));
+ }
+ }
+ /*
+@@ -756,8 +760,12 @@ int __udp6_lib_rcv(struct sk_buff *skb,
+ bh_lock_sock(sk);
+ if (!sock_owned_by_user(sk))
+ udpv6_queue_rcv_skb(sk, skb);
+- else
+- sk_add_backlog(sk, skb);
++ else if (sk_add_backlog_limited(sk, skb)) {
++ atomic_inc(&sk->sk_drops);
++ bh_unlock_sock(sk);
++ sock_put(sk);
++ goto discard;
++ }
+ bh_unlock_sock(sk);
+ sock_put(sk);
+ return 0;
--- /dev/null
+From 2ae53e0d5eee46f1f2af0ccf071a65e921af39c9 Mon Sep 17 00:00:00 2001
+From: Zhu Yi <yi.zhu@intel.com>
+Date: Thu, 4 Mar 2010 18:01:46 +0000
+Subject: x25: use limited socket backlog
+
+From: Zhu Yi <yi.zhu@intel.com>
+
+[ Upstream commit 2499849ee8f513e795b9f2c19a42d6356e4943a4 ]
+
+Make x25 adapt to the limited socket backlog change.
+
+Cc: Andrew Hendry <andrew.hendry@gmail.com>
+Signed-off-by: Zhu Yi <yi.zhu@intel.com>
+Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/x25/x25_dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/x25/x25_dev.c
++++ b/net/x25/x25_dev.c
+@@ -53,7 +53,7 @@ static int x25_receive_data(struct sk_bu
+ if (!sock_owned_by_user(sk)) {
+ queued = x25_process_rx_frame(sk, skb);
+ } else {
+- sk_add_backlog(sk, skb);
++ queued = !sk_add_backlog_limited(sk, skb);
+ }
+ bh_unlock_sock(sk);
+ sock_put(sk);