From: Greg Kroah-Hartman Date: Tue, 30 Mar 2010 20:26:13 +0000 (-0700) Subject: .33 patches X-Git-Tag: v2.6.27.46~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1e69077190c71383874cd7d04e6cc77935d1c0f;p=thirdparty%2Fkernel%2Fstable-queue.git .33 patches --- diff --git a/queue-2.6.33/bonding-fix-device-leak-on-error-in-bond_create.patch b/queue-2.6.33/bonding-fix-device-leak-on-error-in-bond_create.patch new file mode 100644 index 00000000000..4a17b929de3 --- /dev/null +++ b/queue-2.6.33/bonding-fix-device-leak-on-error-in-bond_create.patch @@ -0,0 +1,31 @@ +From 01a3b2650e2c0e7fbd84e974d90c550a87f1554c Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Sat, 27 Feb 2010 02:52:05 -0800 +Subject: bonding: fix device leak on error in bond_create() + +From: Patrick McHardy + +[ Upstream commit 8d6184e4881b423522136aeb3ec1cbd9c35e8813 ] + +When the register_netdevice() call fails, the newly allocated device is +not freed. + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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(); diff --git a/queue-2.6.33/e100-fix-ring-parameter-change-handling-regression.patch b/queue-2.6.33/e100-fix-ring-parameter-change-handling-regression.patch new file mode 100644 index 00000000000..5bec826273a --- /dev/null +++ b/queue-2.6.33/e100-fix-ring-parameter-change-handling-regression.patch @@ -0,0 +1,41 @@ +From 9ce366a41de84db6b1267857b079b0005a017d2d Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 15 Mar 2010 15:23:30 -0700 +Subject: e100: Fix ring parameter change handling regression. + +From: David S. Miller + +[ 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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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", diff --git a/queue-2.6.33/icside-bring-back-maskproc-method.patch b/queue-2.6.33/icside-bring-back-maskproc-method.patch new file mode 100644 index 00000000000..50d70fcf20e --- /dev/null +++ b/queue-2.6.33/icside-bring-back-maskproc-method.patch @@ -0,0 +1,173 @@ +From 39c0fe2347e5b19352542eefb4cae9b6073b8312 Mon Sep 17 00:00:00 2001 +From: Bartlomiej Zolnierkiewicz +Date: Tue, 5 Jan 2010 07:07:27 +0000 +Subject: icside: bring back ->maskproc method + +From: Bartlomiej Zolnierkiewicz + +[ 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 +Signed-off-by: Bartlomiej Zolnierkiewicz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-2.6.33/ide-fix-promise-udma33-ide-driver-pdc202xx_old.patch b/queue-2.6.33/ide-fix-promise-udma33-ide-driver-pdc202xx_old.patch new file mode 100644 index 00000000000..b3b6c7eadc8 --- /dev/null +++ b/queue-2.6.33/ide-fix-promise-udma33-ide-driver-pdc202xx_old.patch @@ -0,0 +1,88 @@ +From 5e249f8401d4955d7a5f18e36d9b2654a1ed4da3 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Sun, 3 Jan 2010 12:35:42 +0000 +Subject: ide: Fix Promise UDMA33 IDE driver (pdc202xx_old) + +From: Russell King + +[ 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 +Tested-by: Russell King +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + } + diff --git a/queue-2.6.33/ip_gre-include-route-header_len-in-max_headroom-calculation.patch b/queue-2.6.33/ip_gre-include-route-header_len-in-max_headroom-calculation.patch new file mode 100644 index 00000000000..71bddc07c56 --- /dev/null +++ b/queue-2.6.33/ip_gre-include-route-header_len-in-max_headroom-calculation.patch @@ -0,0 +1,39 @@ +From b11caf2be6cb62345ac657313adc1b34d44848ef Mon Sep 17 00:00:00 2001 +From: Timo Teräs +Date: Sat, 20 Mar 2010 02:27:58 +0000 +Subject: ip_gre: include route header_len in max_headroom calculation + +From: Timo Teräs + +[ 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 +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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++; diff --git a/queue-2.6.33/ipsec-fix-bogus-bundle-flowi.patch b/queue-2.6.33/ipsec-fix-bogus-bundle-flowi.patch new file mode 100644 index 00000000000..ca22eec2541 --- /dev/null +++ b/queue-2.6.33/ipsec-fix-bogus-bundle-flowi.patch @@ -0,0 +1,103 @@ +From 5701123473ef64bae0519d22f756383b55d5bb04 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Tue, 2 Mar 2010 02:51:56 +0000 +Subject: ipsec: Fix bogus bundle flowi + +From: Herbert Xu + +[ 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 +Signed-off-by: Herbert Xu +Acked-by: Steffen Klassert +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; + diff --git a/queue-2.6.33/ipv4-check-rt_genid-in-dst_check.patch b/queue-2.6.33/ipv4-check-rt_genid-in-dst_check.patch new file mode 100644 index 00000000000..4efccb49e3f --- /dev/null +++ b/queue-2.6.33/ipv4-check-rt_genid-in-dst_check.patch @@ -0,0 +1,97 @@ +From 2638ae735ff6e317f0527b940764ed3000c9fe54 Mon Sep 17 00:00:00 2001 +From: Timo Teräs +Date: Thu, 18 Mar 2010 23:20:20 +0000 +Subject: ipv4: check rt_genid in dst_check + +From: Timo Teräs + +[ 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 +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.33/ipv4-don-t-drop-redirected-route-cache-entry-unless-ptmu-actually-expired.patch b/queue-2.6.33/ipv4-don-t-drop-redirected-route-cache-entry-unless-ptmu-actually-expired.patch new file mode 100644 index 00000000000..1b10d332fd0 --- /dev/null +++ b/queue-2.6.33/ipv4-don-t-drop-redirected-route-cache-entry-unless-ptmu-actually-expired.patch @@ -0,0 +1,64 @@ +From f5668ec496d8d4c03cd775257fe7dc2528dfdeb6 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +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 + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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))); diff --git a/queue-2.6.33/ipv6-don-t-drop-cache-route-entry-unless-timer-actually-expired.patch b/queue-2.6.33/ipv6-don-t-drop-cache-route-entry-unless-timer-actually-expired.patch new file mode 100644 index 00000000000..2c378eee16c --- /dev/null +++ b/queue-2.6.33/ipv6-don-t-drop-cache-route-entry-unless-timer-actually-expired.patch @@ -0,0 +1,48 @@ +From ff9d7bef4e7bf1bd674d2335e1d705a9545bb0a1 Mon Sep 17 00:00:00 2001 +From: YOSHIFUJI Hideaki / 吉藤英明 +Date: Sun, 28 Mar 2010 07:15:45 +0000 +Subject: ipv6: Don't drop cache route entry unless timer actually expired. + +From: YOSHIFUJI Hideaki / 吉藤英明 + +[ 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 . + +Remove cache route entry in ipv6_negative_advice() only if +the timer is expired. + +Signed-off-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.33/l2tp-fix-oops-in-pppol2tp_xmit.patch b/queue-2.6.33/l2tp-fix-oops-in-pppol2tp_xmit.patch new file mode 100644 index 00000000000..3e24dbad6e5 --- /dev/null +++ b/queue-2.6.33/l2tp-fix-oops-in-pppol2tp_xmit.patch @@ -0,0 +1,81 @@ +From 7db2c466705125aaa141420bccbd4ffc98796994 Mon Sep 17 00:00:00 2001 +From: James Chapman +Date: Tue, 16 Mar 2010 06:46:31 +0000 +Subject: l2tp: Fix oops in pppol2tp_xmit + +From: James Chapman + +[ 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: [] 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:[] 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: + [] ? ppp_push+0x459/0x50e [ppp_generic] + [] ? ppp_xmit_process+0x3b6/0x430 [ppp_generic] + [] ? ppp_start_xmit+0x10d/0x120 [ppp_generic] + [] ? dev_hard_start_xmit+0x21f/0x2b2 + [] ? sch_direct_xmit+0x48/0x10e + [] ? dev_queue_xmit+0x263/0x3a6 + [] ? ip_finish_output+0x1f7/0x221 + [] ? ip_forward_finish+0x2e/0x30 + [] ? ip_rcv_finish+0x295/0x2a9 + [] ? netif_receive_skb+0x3e9/0x404 + [] ? e1000_clean_rx_irq+0x253/0x2fc [e1000e] + [] ? e1000_clean+0x63/0x1fc [e1000e] + [] ? sched_clock_local+0x15/0x11b + [] ? net_rx_action+0x96/0x195 + [] ? __do_softirq+0xaa/0x151 + [] ? do_softirq+0x31/0x3c + [] ? irq_exit+0x26/0x58 + [] ? do_IRQ+0x78/0x89 + [] ? common_interrupt+0x29/0x30 + [] ? native_safe_halt+0x2/0x3 + [] ? default_idle+0x55/0x75 + [] ? c1e_idle+0xd2/0xd5 + [] ? 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: [] pppol2tp_xmit+0x341/0x4da [pppol2tp] SS:ESP 0068:f70a9cac +CR2: 000000000000000c + +Signed-off-by: James Chapman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-2.6.33/l2tp-fix-udp-socket-reference-count-bugs-in-the-pppol2tp-driver.patch b/queue-2.6.33/l2tp-fix-udp-socket-reference-count-bugs-in-the-pppol2tp-driver.patch new file mode 100644 index 00000000000..5f3a98e026c --- /dev/null +++ b/queue-2.6.33/l2tp-fix-udp-socket-reference-count-bugs-in-the-pppol2tp-driver.patch @@ -0,0 +1,97 @@ +From 40cad6ae6c20055eb7a7c06055c257dc6460217c Mon Sep 17 00:00:00 2001 +From: James Chapman +Date: Tue, 16 Mar 2010 06:29:20 +0000 +Subject: l2tp: Fix UDP socket reference count bugs in the pppol2tp driver + +From: James Chapman + +[ 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: + [] ? udp_lib_unhash+0x117/0x120 + [] ? warn_slowpath_common+0x71/0xd0 + [] ? udp_lib_unhash+0x117/0x120 + [] ? warn_slowpath_null+0x13/0x20 + [] ? udp_lib_unhash+0x117/0x120 + [] ? sk_common_release+0x17/0x90 + [] ? inet_release+0x33/0x60 + [] ? sock_release+0x10/0x60 + [] ? sock_close+0xf/0x30 + [] ? __fput+0x52/0x150 + [] ? filp_close+0x3e/0x70 + [] ? put_files_struct+0x62/0xb0 + [] ? do_exit+0x5e7/0x650 + [] ? mntput_no_expire+0x13/0x70 + [] ? filp_close+0x3e/0x70 + [] ? do_group_exit+0x2a/0x70 + [] ? sys_exit_group+0x11/0x20 + [] ? sysenter_do_call+0x12/0x26 + +Signed-off-by: James Chapman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.33/llc-use-limited-socket-backlog.patch b/queue-2.6.33/llc-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..4b95dd75406 --- /dev/null +++ b/queue-2.6.33/llc-use-limited-socket-backlog.patch @@ -0,0 +1,33 @@ +From c44db18ecbe35e460de965c99024e1f087dc739d Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:43 +0000 +Subject: llc: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 79545b681961d7001c1f4c3eb9ffb87bed4485db ] + +Make llc adapt to the limited socket backlog change. + +Cc: Arnaldo Carvalho de Melo +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Acked-by: Arnaldo Carvalho de Melo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-2.6.33/net-add-__must_check-to-sk_add_backlog.patch b/queue-2.6.33/net-add-__must_check-to-sk_add_backlog.patch new file mode 100644 index 00000000000..d1a7130755e --- /dev/null +++ b/queue-2.6.33/net-add-__must_check-to-sk_add_backlog.patch @@ -0,0 +1,31 @@ +From 256010274c8212e7dbe26bbf2a84d8705733d50e Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Sun, 7 Mar 2010 16:21:39 +0000 +Subject: net: add __must_check to sk_add_backlog + +From: Zhu Yi + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.33/net-add-limit-for-socket-backlog.patch b/queue-2.6.33/net-add-limit-for-socket-backlog.patch new file mode 100644 index 00000000000..63d8a492769 --- /dev/null +++ b/queue-2.6.33/net-add-limit-for-socket-backlog.patch @@ -0,0 +1,135 @@ +From 0495e1a25511cbaa27f391668c733a22d83df7d4 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:40 +0000 +Subject: net: add limit for socket backlog + +From: Zhu Yi + +[ 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 +Cc: David Miller +Cc: Arnaldo Carvalho de Melo +Cc: Alexey Kuznetsov +Cc: Patrick McHardy +Cc: Vlad Yasevich +Cc: Sridhar Samudrala +Cc: Jon Maloy +Cc: Allan Stephens +Cc: Andrew Hendry +Signed-off-by: Zhu Yi +Signed-off-by: Eric Dumazet +Acked-by: Arnaldo Carvalho de Melo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.33/net-backlog-functions-rename.patch b/queue-2.6.33/net-backlog-functions-rename.patch new file mode 100644 index 00000000000..81e33336504 --- /dev/null +++ b/queue-2.6.33/net-backlog-functions-rename.patch @@ -0,0 +1,210 @@ +From 30864b52e64e0949548d11ab09a38fad9c6a7bac Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:47 +0000 +Subject: net: backlog functions rename + +From: Zhu Yi + +[ Upstream commit a3a858ff18a72a8d388e31ab0d98f7e944841a62 ] + +sk_add_backlog -> __sk_add_backlog +sk_add_backlog_limited -> sk_add_backlog + +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + + +--- + 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); diff --git a/queue-2.6.33/net-potential-null-skb-dev-dereference.patch b/queue-2.6.33/net-potential-null-skb-dev-dereference.patch new file mode 100644 index 00000000000..6a79ee69354 --- /dev/null +++ b/queue-2.6.33/net-potential-null-skb-dev-dereference.patch @@ -0,0 +1,90 @@ +From 188ec168334863547e75a8525f7160c71f37f976 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 29 Mar 2010 21:33:28 -0700 +Subject: net: Potential null skb->dev dereference + +From: Eric Dumazet + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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++; diff --git a/queue-2.6.33/net_dma-free-skbs-periodically.patch b/queue-2.6.33/net_dma-free-skbs-periodically.patch new file mode 100644 index 00000000000..85387baff6c --- /dev/null +++ b/queue-2.6.33/net_dma-free-skbs-periodically.patch @@ -0,0 +1,129 @@ +From c6dd9976265f64670c90fbe7f39372d950f50e6b Mon Sep 17 00:00:00 2001 +From: Steven J. Magnani +Date: Tue, 16 Mar 2010 05:22:44 +0000 +Subject: NET_DMA: free skbs periodically + +From: Steven J. Magnani + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.33/netfilter-ctnetlink-fix-reliable-event-delivery-if-message-building-fails.patch b/queue-2.6.33/netfilter-ctnetlink-fix-reliable-event-delivery-if-message-building-fails.patch new file mode 100644 index 00000000000..fa2d4a8dea4 --- /dev/null +++ b/queue-2.6.33/netfilter-ctnetlink-fix-reliable-event-delivery-if-message-building-fails.patch @@ -0,0 +1,60 @@ +From d61c8adbf0d896b820d8aed1b7a01939071d5cfc Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Mon, 29 Mar 2010 21:28:23 -0700 +Subject: netfilter: ctnetlink: fix reliable event delivery if message building fails + +From: Pablo Neira Ayuso + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.33/netlink-fix-netlink_recv_no_enobufs-in-netlink_set_err.patch b/queue-2.6.33/netlink-fix-netlink_recv_no_enobufs-in-netlink_set_err.patch new file mode 100644 index 00000000000..6e52fc17d25 --- /dev/null +++ b/queue-2.6.33/netlink-fix-netlink_recv_no_enobufs-in-netlink_set_err.patch @@ -0,0 +1,93 @@ +From 0531f67fda935fca8fd6cb1d5c6219a0a1911c43 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Thu, 18 Mar 2010 14:24:42 +0000 +Subject: netlink: fix NETLINK_RECV_NO_ENOBUFS in netlink_set_err() + +From: Pablo Neira Ayuso + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.33/netlink-fix-unaligned-access-in-nla_get_be64.patch b/queue-2.6.33/netlink-fix-unaligned-access-in-nla_get_be64.patch new file mode 100644 index 00000000000..53ad74820c7 --- /dev/null +++ b/queue-2.6.33/netlink-fix-unaligned-access-in-nla_get_be64.patch @@ -0,0 +1,35 @@ +From e4905f5f2c61875cee329132c40d124274139272 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Tue, 16 Mar 2010 13:30:44 +0000 +Subject: netlink: fix unaligned access in nla_get_be64() + +From: Pablo Neira Ayuso + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + + /** diff --git a/queue-2.6.33/qlogicpti-remove-slash-in-qlogicpti-irq-name.patch b/queue-2.6.33/qlogicpti-remove-slash-in-qlogicpti-irq-name.patch new file mode 100644 index 00000000000..598eb92fce9 --- /dev/null +++ b/queue-2.6.33/qlogicpti-remove-slash-in-qlogicpti-irq-name.patch @@ -0,0 +1,38 @@ +From b0516a171b2edab15cdc336272e3a253321aab91 Mon Sep 17 00:00:00 2001 +From: Meelis Roos +Date: Mon, 8 Mar 2010 10:53:08 -0800 +Subject: qlogicpti: Remove slash in QlogicPTI irq name + +From: Meelis Roos + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.33/r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch b/queue-2.6.33/r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch new file mode 100644 index 00000000000..8272ec16631 --- /dev/null +++ b/queue-2.6.33/r8169-offical-fix-for-cve-2009-4537-overlength-frame-dmas.patch @@ -0,0 +1,120 @@ +From cdec71f9b0697de47d06e34619b45e9998bc1ca2 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Mon, 29 Mar 2010 13:16:02 -0700 +Subject: r8169: offical fix for CVE-2009-4537 (overlength frame DMAs) + +From: Neil Horman + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-2.6.33/revert-ide-skip-probe-if-there-are-no-devices-on-the-port-v2.patch b/queue-2.6.33/revert-ide-skip-probe-if-there-are-no-devices-on-the-port-v2.patch new file mode 100644 index 00000000000..5b0b46cc19c --- /dev/null +++ b/queue-2.6.33/revert-ide-skip-probe-if-there-are-no-devices-on-the-port-v2.patch @@ -0,0 +1,50 @@ +From bc36a3fb21af50cda344b12082c44c5b54c072e7 Mon Sep 17 00:00:00 2001 +From: David S. Miller +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 + +[ 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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-2.6.33/route-fix-caught-bug_on-during-rt_secret_rebuild_oneshot.patch b/queue-2.6.33/route-fix-caught-bug_on-during-rt_secret_rebuild_oneshot.patch new file mode 100644 index 00000000000..e84bdc1678f --- /dev/null +++ b/queue-2.6.33/route-fix-caught-bug_on-during-rt_secret_rebuild_oneshot.patch @@ -0,0 +1,70 @@ +From 4c1017d750c992cb093c9e0c2b4d297880db76e1 Mon Sep 17 00:00:00 2001 +From: Vitaliy Gusev +Date: Tue, 16 Mar 2010 01:07:51 +0000 +Subject: route: Fix caught BUG_ON during rt_secret_rebuild_oneshot() + +From: Vitaliy Gusev + +[ 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 +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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(); + } diff --git a/queue-2.6.33/sctp-use-limited-socket-backlog.patch b/queue-2.6.33/sctp-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..e987f3ba288 --- /dev/null +++ b/queue-2.6.33/sctp-use-limited-socket-backlog.patch @@ -0,0 +1,111 @@ +From d297f86c51d0ce84e787614211a58dff05fab041 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:44 +0000 +Subject: sctp: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 50b1a782f845140f4138f14a1ce8a4a6dd0cc82f ] + +Make sctp adapt to the limited socket backlog change. + +Cc: Vlad Yasevich +Cc: Sridhar Samudrala +Signed-off-by: Zhu Yi +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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(); diff --git a/queue-2.6.33/series b/queue-2.6.33/series index 427119d8821..0401f93f49c 100644 --- a/queue-2.6.33/series +++ b/queue-2.6.33/series @@ -109,3 +109,38 @@ ath9k-configure-the-beacon-only-if-the-sta-is-associated.patch 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 diff --git a/queue-2.6.33/skbuff-remove-unused-dma_head-dma_maps-fields.patch b/queue-2.6.33/skbuff-remove-unused-dma_head-dma_maps-fields.patch new file mode 100644 index 00000000000..8d04f4dc1d6 --- /dev/null +++ b/queue-2.6.33/skbuff-remove-unused-dma_head-dma_maps-fields.patch @@ -0,0 +1,49 @@ +From 01c5788cad31f344418f9b16c9357c653c9d3af6 Mon Sep 17 00:00:00 2001 +From: Alexander Duyck +Date: Tue, 23 Mar 2010 20:40:50 +0000 +Subject: skbuff: remove unused dma_head & dma_maps fields + +From: Alexander Duyck + +[ 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 +Signed-off-by: Jeff Kirsher +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.33/sparc64-add-very-basic-xvr-1000-framebuffer-driver.patch b/queue-2.6.33/sparc64-add-very-basic-xvr-1000-framebuffer-driver.patch new file mode 100644 index 00000000000..01c5bb702db --- /dev/null +++ b/queue-2.6.33/sparc64-add-very-basic-xvr-1000-framebuffer-driver.patch @@ -0,0 +1,282 @@ +From cc82b8a8b6592e9d69c2cc4a1074ec6447a3ea7c Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 29 Mar 2010 22:18:29 -0700 +Subject: sparc64: Add very basic XVR-1000 framebuffer driver. + +From: David S. Miller + +[ Upstream commits 2d378b9179881b46a0faf11430efb421fe03ddd8 and + f04e879bf296d136bcafd8c5a26e95599b141671 ] + +Signed-off-by: David S. Miller +Acked-by: Frans van Berckel +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ++#include ++#include ++#include ++#include ++#include ++ ++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 "); ++MODULE_VERSION("1.0"); ++MODULE_LICENSE("GPL"); diff --git a/queue-2.6.33/sparc64-properly-truncate-pt_regs-framepointer-in-perf-callback.patch b/queue-2.6.33/sparc64-properly-truncate-pt_regs-framepointer-in-perf-callback.patch new file mode 100644 index 00000000000..1fbaa7bbb3c --- /dev/null +++ b/queue-2.6.33/sparc64-properly-truncate-pt_regs-framepointer-in-perf-callback.patch @@ -0,0 +1,37 @@ +From f90d80e990205b2b1020e98c6a6c2fcbccee2349 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 29 Mar 2010 13:08:52 -0700 +Subject: sparc64: Properly truncate pt_regs framepointer in perf callback. + +From: David S. Miller + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.33/tcp-fix-oob-pollin-avoidance.patch b/queue-2.6.33/tcp-fix-oob-pollin-avoidance.patch new file mode 100644 index 00000000000..3b6cbc78e14 --- /dev/null +++ b/queue-2.6.33/tcp-fix-oob-pollin-avoidance.patch @@ -0,0 +1,31 @@ +From b17f5da6dd40f9a5a60bce31fd94e0d96194af50 Mon Sep 17 00:00:00 2001 +From: Alexandra Kossovsky +Date: Thu, 18 Mar 2010 20:29:24 -0700 +Subject: tcp: Fix OOB POLLIN avoidance. + +From: Alexandra Kossovsky + +[ Upstream commit b634f87522dff87712df8bda2a6c9061954d552a ] + +From: Alexandra.Kossovsky@oktetlabs.ru + +Fixes kernel bugzilla #15541 + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-2.6.33/tcp-fix-tcp_make_synack.patch b/queue-2.6.33/tcp-fix-tcp_make_synack.patch new file mode 100644 index 00000000000..05df64a58f7 --- /dev/null +++ b/queue-2.6.33/tcp-fix-tcp_make_synack.patch @@ -0,0 +1,65 @@ +From 8d755c9fa5d65e799b0f7c536b1482d76dc307dd Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 8 Mar 2010 11:32:01 -0800 +Subject: tcp: Fix tcp_make_synack() + +From: Eric Dumazet + +[ 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 +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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) { diff --git a/queue-2.6.33/tcp-fix-tcp_mark_head_lost-with-packets-0.patch b/queue-2.6.33/tcp-fix-tcp_mark_head_lost-with-packets-0.patch new file mode 100644 index 00000000000..c701b5f2733 --- /dev/null +++ b/queue-2.6.33/tcp-fix-tcp_mark_head_lost-with-packets-0.patch @@ -0,0 +1,33 @@ +From 4bf396ed4e77524c5c3fb0c7acc5107818af8fd5 Mon Sep 17 00:00:00 2001 +From: Lennart Schulte +Date: Wed, 17 Mar 2010 02:16:29 +0000 +Subject: tcp: Fix tcp_mark_head_lost() with packets == 0 + +From: Lennart Schulte + +[ 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 +Signed-off-by: Arnd Hannemann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-2.6.33/tcp-use-limited-socket-backlog.patch b/queue-2.6.33/tcp-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..5de4e811f1b --- /dev/null +++ b/queue-2.6.33/tcp-use-limited-socket-backlog.patch @@ -0,0 +1,55 @@ +From 9dc97b0601a753adda5a76101041165fd86e9132 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:41 +0000 +Subject: tcp: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 6b03a53a5ab7ccf2d5d69f96cf1c739c4d2a8fb9 ] + +Make tcp adapt to the limited socket backlog change. + +Cc: "David S. Miller" +Cc: Alexey Kuznetsov +Cc: "Pekka Savola (ipv6)" +Cc: Patrick McHardy +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.33/tipc-use-limited-socket-backlog.patch b/queue-2.6.33/tipc-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..fdbedf7a6d7 --- /dev/null +++ b/queue-2.6.33/tipc-use-limited-socket-backlog.patch @@ -0,0 +1,38 @@ +From 8e5080598871b71e9785b0b6ba7291548a273a89 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:45 +0000 +Subject: tipc: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 53eecb1be5ae499d399d2923933937a9ea1a284f ] + +Make tipc adapt to the limited socket backlog change. + +Cc: Jon Maloy +Cc: Allan Stephens +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Acked-by: Allan Stephens +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + diff --git a/queue-2.6.33/udp-use-limited-socket-backlog.patch b/queue-2.6.33/udp-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..d99adb7331f --- /dev/null +++ b/queue-2.6.33/udp-use-limited-socket-backlog.patch @@ -0,0 +1,85 @@ +From 74487b0c81587dec3d1cd9a85673374dc9c35cde Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:42 +0000 +Subject: udp: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 55349790d7cbf0d381873a7ece1dcafcffd4aaa9 ] + +Make udp adapt to the limited socket backlog change. + +Cc: "David S. Miller" +Cc: Alexey Kuznetsov +Cc: "Pekka Savola (ipv6)" +Cc: Patrick McHardy +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-2.6.33/x25-use-limited-socket-backlog.patch b/queue-2.6.33/x25-use-limited-socket-backlog.patch new file mode 100644 index 00000000000..d2f822fe237 --- /dev/null +++ b/queue-2.6.33/x25-use-limited-socket-backlog.patch @@ -0,0 +1,32 @@ +From 2ae53e0d5eee46f1f2af0ccf071a65e921af39c9 Mon Sep 17 00:00:00 2001 +From: Zhu Yi +Date: Thu, 4 Mar 2010 18:01:46 +0000 +Subject: x25: use limited socket backlog + +From: Zhu Yi + +[ Upstream commit 2499849ee8f513e795b9f2c19a42d6356e4943a4 ] + +Make x25 adapt to the limited socket backlog change. + +Cc: Andrew Hendry +Signed-off-by: Zhu Yi +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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);