From: Greg Kroah-Hartman Date: Wed, 29 Jul 2009 14:50:36 +0000 (-0700) Subject: start up the next .30 queue X-Git-Tag: v2.6.30.4~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6dffb3d59bee3943b32e0ab148381cd7d8626f56;p=thirdparty%2Fkernel%2Fstable-queue.git start up the next .30 queue --- diff --git a/queue-2.6.30/be2net-fix-to-avoid-a-crash-seen-on-ppc-with-lro-and-jumbo-frames.patch b/queue-2.6.30/be2net-fix-to-avoid-a-crash-seen-on-ppc-with-lro-and-jumbo-frames.patch new file mode 100644 index 00000000000..8efa438b537 --- /dev/null +++ b/queue-2.6.30/be2net-fix-to-avoid-a-crash-seen-on-ppc-with-lro-and-jumbo-frames.patch @@ -0,0 +1,145 @@ +From 1e148ff1954d3058db2aac5d090da8d7d2399e6b Mon Sep 17 00:00:00 2001 +From: Ajit Khaparde +Date: Tue, 28 Jul 2009 18:48:50 -0700 +Subject: be2net: Fix to avoid a crash seen on PPC with LRO and Jumbo frames. + +From: Ajit Khaparde + +[ Upstream commit bd46cb6cf11867130a41ea9546dd65688b71f3c2 ] + +While testing the driver on PPC, we ran into a crash with LRO, Jumbo frames. +With CONFIG_PPC_64K_PAGES configured (a default in PPC), MAX_SKB_FRAGS drops to 3 and we were crossing the array limits on skb_shinfo(skb)->frags[]. +Now we coalesce the frags from the same physical page into one slot in +skb_shinfo(skb)->frags[] and go to the next index when the frag is from + +different physical page. + +This patch is against the net-2.6 tree. + +Signed-off-by: Ajit Khaparde +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/benet/be.h | 2 - + drivers/net/benet/be_ethtool.c | 4 +-- + drivers/net/benet/be_main.c | 45 +++++++++++++++++++++++++++++------------ + 3 files changed, 35 insertions(+), 16 deletions(-) + +--- a/drivers/net/benet/be_ethtool.c ++++ b/drivers/net/benet/be_ethtool.c +@@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netde + return -EINVAL; + + adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; +- if (adapter->max_rx_coal > MAX_SKB_FRAGS) +- adapter->max_rx_coal = MAX_SKB_FRAGS - 1; ++ if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME) ++ adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; + + /* if AIC is being turned on now, start with an EQD of 0 */ + if (rx_eq->enable_aic == 0 && +--- a/drivers/net/benet/be.h ++++ b/drivers/net/benet/be.h +@@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_ + #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) + + #define BE_MAX_LRO_DESCRIPTORS 16 +-#define BE_MAX_FRAGS_PER_FRAME 16 ++#define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS)) + + struct be_dma_mem { + void *va; +--- a/drivers/net/benet/be_main.c ++++ b/drivers/net/benet/be_main.c +@@ -682,7 +682,7 @@ static void skb_fill_rx_data(struct be_a + { + struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_rx_page_info *page_info; +- u16 rxq_idx, i, num_rcvd; ++ u16 rxq_idx, i, num_rcvd, j; + u32 pktsize, hdr_len, curr_frag_len; + u8 *start; + +@@ -725,22 +725,33 @@ static void skb_fill_rx_data(struct be_a + + /* More frags present for this completion */ + pktsize -= curr_frag_len; /* account for above copied frag */ +- for (i = 1; i < num_rcvd; i++) { ++ for (i = 1, j = 0; i < num_rcvd; i++) { + index_inc(&rxq_idx, rxq->len); + page_info = get_rx_page_info(adapter, rxq_idx); + + curr_frag_len = min(pktsize, rx_frag_size); + +- skb_shinfo(skb)->frags[i].page = page_info->page; +- skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; +- skb_shinfo(skb)->frags[i].size = curr_frag_len; ++ /* Coalesce all frags from the same physical page in one slot */ ++ if (page_info->page_offset == 0) { ++ /* Fresh page */ ++ j++; ++ skb_shinfo(skb)->frags[j].page = page_info->page; ++ skb_shinfo(skb)->frags[j].page_offset = ++ page_info->page_offset; ++ skb_shinfo(skb)->frags[j].size = 0; ++ skb_shinfo(skb)->nr_frags++; ++ } else { ++ put_page(page_info->page); ++ } ++ ++ skb_shinfo(skb)->frags[j].size += curr_frag_len; + skb->len += curr_frag_len; + skb->data_len += curr_frag_len; +- skb_shinfo(skb)->nr_frags++; + pktsize -= curr_frag_len; + + memset(page_info, 0, sizeof(*page_info)); + } ++ BUG_ON(j > MAX_SKB_FRAGS); + + be_rx_stats_update(adapter, pktsize, num_rcvd); + return; +@@ -803,7 +814,7 @@ static void be_rx_compl_process_lro(stru + struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; + struct be_queue_info *rxq = &adapter->rx_obj.q; + u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; +- u16 i, rxq_idx = 0, vid; ++ u16 i, rxq_idx = 0, vid, j; + + num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); + pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); +@@ -811,20 +822,28 @@ static void be_rx_compl_process_lro(stru + rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); + + remaining = pkt_size; +- for (i = 0; i < num_rcvd; i++) { ++ for (i = 0, j = -1; i < num_rcvd; i++) { + page_info = get_rx_page_info(adapter, rxq_idx); + + curr_frag_len = min(remaining, rx_frag_size); + +- rx_frags[i].page = page_info->page; +- rx_frags[i].page_offset = page_info->page_offset; +- rx_frags[i].size = curr_frag_len; +- remaining -= curr_frag_len; ++ /* Coalesce all frags from the same physical page in one slot */ ++ if (i == 0 || page_info->page_offset == 0) { ++ /* First frag or Fresh page */ ++ j++; ++ rx_frags[j].page = page_info->page; ++ rx_frags[j].page_offset = page_info->page_offset; ++ rx_frags[j].size = 0; ++ } else { ++ put_page(page_info->page); ++ } ++ rx_frags[j].size += curr_frag_len; + ++ remaining -= curr_frag_len; + index_inc(&rxq_idx, rxq->len); +- + memset(page_info, 0, sizeof(*page_info)); + } ++ BUG_ON(j > MAX_SKB_FRAGS); + + if (likely(!vlanf)) { + lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, diff --git a/queue-2.6.30/dsa-fix-88e6xxx-statistics-counter-snapshotting.patch b/queue-2.6.30/dsa-fix-88e6xxx-statistics-counter-snapshotting.patch new file mode 100644 index 00000000000..7f0e530b0df --- /dev/null +++ b/queue-2.6.30/dsa-fix-88e6xxx-statistics-counter-snapshotting.patch @@ -0,0 +1,33 @@ +From f64a11df221d24f737788cbd7cb735b5f7b1f40f Mon Sep 17 00:00:00 2001 +From: Stephane Contri +Date: Thu, 2 Jul 2009 23:26:48 +0000 +Subject: dsa: fix 88e6xxx statistics counter snapshotting + +From: Stephane Contri + +[ Upstream commit 1ded3f59f35a2642852b3e2a1c0fa8a97777e9af ] + +The bit that tells us whether a statistics counter snapshot operation +has completed is located in the GLOBAL register block, not in the +GLOBAL2 register block, so fix up mv88e6xxx_stats_wait() to poll the +right register address. + +Signed-off-by: Stephane Contri +Signed-off-by: Lennert Buytenhek +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dsa/mv88e6xxx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/dsa/mv88e6xxx.c ++++ b/net/dsa/mv88e6xxx.c +@@ -418,7 +418,7 @@ static int mv88e6xxx_stats_wait(struct d + int i; + + for (i = 0; i < 10; i++) { +- ret = REG_READ(REG_GLOBAL2, 0x1d); ++ ret = REG_READ(REG_GLOBAL, 0x1d); + if ((ret & 0x8000) == 0) + return 0; + } diff --git a/queue-2.6.30/e100-work-around-the-driver-using-streaming-dma-mapping-for-rx-descriptors.patch b/queue-2.6.30/e100-work-around-the-driver-using-streaming-dma-mapping-for-rx-descriptors.patch new file mode 100644 index 00000000000..0c2336b30f6 --- /dev/null +++ b/queue-2.6.30/e100-work-around-the-driver-using-streaming-dma-mapping-for-rx-descriptors.patch @@ -0,0 +1,36 @@ +From b0026cfc55039d9fdd0fd82781d06fb15f388809 Mon Sep 17 00:00:00 2001 +From: Krzysztof Halasa +Date: Tue, 14 Jul 2009 11:01:54 +0000 +Subject: E100: work around the driver using streaming DMA mapping for RX descriptors. + +From: Krzysztof Halasa + +[ Upstream commit 303d67c288319768b19ed8dbed429fef7eb7c275 ] + +E100 places it's RX packet descriptors inside skb->data and uses them +with bidirectional streaming DMA mapping. Unfortunately it fails to +transfer skb->data ownership to the device after it reads the +descriptor's status, breaking on non-coherent (e.g., ARM) platforms. + +This have to be converted to use coherent memory for the descriptors. + +Signed-off-by: Krzysztof Halasa +Acked-by: Jeff Kirsher +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/e100.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/e100.c ++++ b/drivers/net/e100.c +@@ -1762,6 +1762,9 @@ static int e100_rx_indicate(struct nic * + + if (ioread8(&nic->csr->scb.status) & rus_no_res) + nic->ru_running = RU_SUSPENDED; ++ pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, ++ sizeof(struct rfd), ++ PCI_DMA_BIDIRECTIONAL); + return -ENODATA; + } + diff --git a/queue-2.6.30/gro-flush-gro-packets-in-napi_disable_pending-path.patch b/queue-2.6.30/gro-flush-gro-packets-in-napi_disable_pending-path.patch new file mode 100644 index 00000000000..b40afcb8e1b --- /dev/null +++ b/queue-2.6.30/gro-flush-gro-packets-in-napi_disable_pending-path.patch @@ -0,0 +1,43 @@ +From cf45340261e1209d1b400c49ea8d80145885b259 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Fri, 26 Jun 2009 19:27:04 -0700 +Subject: gro: Flush GRO packets in napi_disable_pending path + +From: Herbert Xu + +[ Upstream commit ff780cd8f2fa928b193554f593b36d1243554212 ] + +When NAPI is disabled while we're in net_rx_action, we end up +calling __napi_complete without flushing GRO packets. This is +a bug as it would cause the GRO packets to linger, of course it +also literally BUGs to catch error like this :) + +This patch changes it to napi_complete, with the obligatory IRQ +reenabling. This should be safe because we've only just disabled +IRQs and it does not materially affect the test conditions in +between. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2788,9 +2788,11 @@ static void net_rx_action(struct softirq + * move the instance around on the list at-will. + */ + if (unlikely(work == weight)) { +- if (unlikely(napi_disable_pending(n))) +- __napi_complete(n); +- else ++ if (unlikely(napi_disable_pending(n))) { ++ local_irq_enable(); ++ napi_complete(n); ++ local_irq_disable(); ++ } else + list_move_tail(&n->poll_list, list); + } + diff --git a/queue-2.6.30/gso-stop-fraglists-from-escaping.patch b/queue-2.6.30/gso-stop-fraglists-from-escaping.patch new file mode 100644 index 00000000000..acaaf35fb39 --- /dev/null +++ b/queue-2.6.30/gso-stop-fraglists-from-escaping.patch @@ -0,0 +1,51 @@ +From 78f7e0b43ed392292419dfa20448526460a6b267 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 3 Jun 2009 21:20:51 -0700 +Subject: gso: Stop fraglists from escaping + +From: Herbert Xu + +[ Upstream commit 278b2513f76161a9cf1ebddd620dc9d1714fe573 ] + +As it stands skb fraglists can get past the check in dev_queue_xmit +if the skb is marked as GSO. In particular, if the packet doesn't +have the proper checksums for GSO, but can otherwise be handled by +the underlying device, we will not perform the fraglist check on it +at all. + +If the underlying device cannot handle fraglists, then this will +break. + +The fix is as simple as moving the fraglist check from the device +check into skb_gso_ok. + +This has caused crashes with Xen when used together with GRO which +can generate GSO packets with fraglists. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netdevice.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1856,15 +1856,14 @@ static inline int net_gso_ok(int feature + + static inline int skb_gso_ok(struct sk_buff *skb, int features) + { +- return net_gso_ok(features, skb_shinfo(skb)->gso_type); ++ return net_gso_ok(features, skb_shinfo(skb)->gso_type) && ++ (!skb_shinfo(skb)->frag_list || (features & NETIF_F_FRAGLIST)); + } + + static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) + { + return skb_is_gso(skb) && + (!skb_gso_ok(skb, dev->features) || +- (skb_shinfo(skb)->frag_list && +- !(dev->features & NETIF_F_FRAGLIST)) || + unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); + } + diff --git a/queue-2.6.30/inet-call-skb_orphan-before-tproxy-activates.patch b/queue-2.6.30/inet-call-skb_orphan-before-tproxy-activates.patch new file mode 100644 index 00000000000..4ebb069389a --- /dev/null +++ b/queue-2.6.30/inet-call-skb_orphan-before-tproxy-activates.patch @@ -0,0 +1,46 @@ +From 96be3d9f2d52809fda8486c35278190e121916da Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Fri, 26 Jun 2009 19:22:37 -0700 +Subject: inet: Call skb_orphan before tproxy activates + +From: Herbert Xu + +[ Upstream commit 71f9dacd2e4d233029e9e956ca3f79531f411827 ] + +As transparent proxying looks up the socket early and assigns +it to the skb for later processing, we must drop any existing +socket ownership prior to that in order to distinguish between +the case where tproxy is active and where it is not. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_input.c | 3 +++ + net/ipv6/ip6_input.c | 3 +++ + 2 files changed, 6 insertions(+) + +--- a/net/ipv4/ip_input.c ++++ b/net/ipv4/ip_input.c +@@ -437,6 +437,9 @@ int ip_rcv(struct sk_buff *skb, struct n + /* Remove any debris in the socket control block */ + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + ++ /* Must drop socket now because of tproxy. */ ++ skb_orphan(skb); ++ + return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, + ip_rcv_finish); + +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -139,6 +139,9 @@ int ipv6_rcv(struct sk_buff *skb, struct + + rcu_read_unlock(); + ++ /* Must drop socket now because of tproxy. */ ++ skb_orphan(skb); ++ + return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, + ip6_rcv_finish); + err: diff --git a/queue-2.6.30/ipsec-fix-name-of-cast-algorithm.patch b/queue-2.6.30/ipsec-fix-name-of-cast-algorithm.patch new file mode 100644 index 00000000000..b4089bfc92a --- /dev/null +++ b/queue-2.6.30/ipsec-fix-name-of-cast-algorithm.patch @@ -0,0 +1,32 @@ +From d4bb58e416dde076c2bb1ac962196881647c0c0e Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Wed, 24 Jun 2009 03:55:41 -0700 +Subject: ipsec: Fix name of CAST algorithm + +From: Herbert Xu + +[ Upstream commit 245acb87729bc76ba65c7476665c01837e0cdccb ] + +Our CAST algorithm is called cast5, not cast128. Clearly nobody +has ever used it :) + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_algo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/xfrm/xfrm_algo.c ++++ b/net/xfrm/xfrm_algo.c +@@ -292,8 +292,8 @@ static struct xfrm_algo_desc ealg_list[] + } + }, + { +- .name = "cbc(cast128)", +- .compat = "cast128", ++ .name = "cbc(cast5)", ++ .compat = "cast5", + + .uinfo = { + .encr = { diff --git a/queue-2.6.30/iwlwifi-only-show-active-power-level-via-sysfs.patch b/queue-2.6.30/iwlwifi-only-show-active-power-level-via-sysfs.patch new file mode 100644 index 00000000000..6eb4d3e03aa --- /dev/null +++ b/queue-2.6.30/iwlwifi-only-show-active-power-level-via-sysfs.patch @@ -0,0 +1,91 @@ +From reinette.chatre@intel.com Wed Jul 29 07:46:14 2009 +From: Reinette Chatre +Date: Tue, 28 Jul 2009 20:35:50 -0700 +Subject: iwlwifi: only show active power level via sysfs +To: Greg KH +Cc: "John W. Linville" , "stable@kernel.org" +Message-ID: <1248838550.1216.802.camel@rc-desk> + +From: Reinette Chatre + +commit 872ed1902f511a8947021c562f5728a5bf0640b5 upstream. + +This changes the power_level file to adhere to the "one value +per file" sysfs rule. The user will know which power level was +requested as it will be the number just written to this file. It +is thus not necessary to create a new sysfs file for this value. + +In addition it fixes a problem where powertop's parsing expects +this value to be the first value in this file without any descriptions. + +Signed-off-by: Reinette Chatre +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/iwl-agn.c | 19 +------------------ + drivers/net/wireless/iwlwifi/iwl3945-base.c | 19 +------------------ + 2 files changed, 2 insertions(+), 36 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c ++++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c +@@ -4623,27 +4623,10 @@ static ssize_t show_power_level(struct d + struct device_attribute *attr, char *buf) + { + struct iwl_priv *priv = dev_get_drvdata(d); +- int mode = priv->power_data.user_power_setting; +- int system = priv->power_data.system_power_setting; + int level = priv->power_data.power_mode; + char *p = buf; + +- switch (system) { +- case IWL_POWER_SYS_AUTO: +- p += sprintf(p, "SYSTEM:auto"); +- break; +- case IWL_POWER_SYS_AC: +- p += sprintf(p, "SYSTEM:ac"); +- break; +- case IWL_POWER_SYS_BATTERY: +- p += sprintf(p, "SYSTEM:battery"); +- break; +- } +- +- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? +- "fixed" : "auto"); +- p += sprintf(p, "\tINDEX:%d", level); +- p += sprintf(p, "\n"); ++ p += sprintf(p, "%d\n", level); + return p - buf + 1; + } + +--- a/drivers/net/wireless/iwlwifi/iwl-agn.c ++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c +@@ -3101,27 +3101,10 @@ static ssize_t show_power_level(struct d + struct device_attribute *attr, char *buf) + { + struct iwl_priv *priv = dev_get_drvdata(d); +- int mode = priv->power_data.user_power_setting; +- int system = priv->power_data.system_power_setting; + int level = priv->power_data.power_mode; + char *p = buf; + +- switch (system) { +- case IWL_POWER_SYS_AUTO: +- p += sprintf(p, "SYSTEM:auto"); +- break; +- case IWL_POWER_SYS_AC: +- p += sprintf(p, "SYSTEM:ac"); +- break; +- case IWL_POWER_SYS_BATTERY: +- p += sprintf(p, "SYSTEM:battery"); +- break; +- } +- +- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ? +- "fixed" : "auto"); +- p += sprintf(p, "\tINDEX:%d", level); +- p += sprintf(p, "\n"); ++ p += sprintf(p, "%d\n", level); + return p - buf + 1; + } + diff --git a/queue-2.6.30/net-move-rx-skb_orphan-call-to-where-needed.patch b/queue-2.6.30/net-move-rx-skb_orphan-call-to-where-needed.patch new file mode 100644 index 00000000000..071e50a96e9 --- /dev/null +++ b/queue-2.6.30/net-move-rx-skb_orphan-call-to-where-needed.patch @@ -0,0 +1,106 @@ +From 25ab51e5176883d5405db2ee061b0b33341bb5f6 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Fri, 26 Jun 2009 11:31:57 -0700 +Subject: net: Move rx skb_orphan call to where needed + +From: Herbert Xu + +[ Upstream commit 329c44e3948473916bccd253a37ac2a66dad9862 ] + +In order to get the tun driver to account packets, we need to be +able to receive packets with destructors set. To be on the safe +side, I added an skb_orphan call for all protocols by default since +some of them (IP in particular) cannot handle receiving packets +destructors properly. + +Now it seems that at least one protocol (CAN) expects to be able +to pass skb->sk through the rx path without getting clobbered. + +So this patch attempts to fix this properly by moving the skb_orphan +call to where it's actually needed. In particular, I've added it +to skb_set_owner_[rw] which is what most users of skb->destructor +call. + +This is actually an improvement for tun too since it means that +we only give back the amount charged to the socket when the skb +is passed to another socket that will also be charged accordingly. + +Signed-off-by: Herbert Xu +Tested-by: Oliver Hartkopp +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sctp/sctp.h | 1 + + include/net/sock.h | 2 ++ + net/ax25/ax25_in.c | 3 +-- + net/core/dev.c | 2 -- + net/irda/af_irda.c | 3 --- + net/irda/ircomm/ircomm_lmp.c | 1 + + 6 files changed, 5 insertions(+), 7 deletions(-) + +--- a/include/net/sctp/sctp.h ++++ b/include/net/sctp/sctp.h +@@ -448,6 +448,7 @@ static inline void sctp_skb_set_owner_r( + { + struct sctp_ulpevent *event = sctp_skb2event(skb); + ++ skb_orphan(skb); + skb->sk = sk; + skb->destructor = sctp_sock_rfree; + atomic_add(event->rmem_len, &sk->sk_rmem_alloc); +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1231,6 +1231,8 @@ static inline void skb_set_owner_w(struc + + static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) + { ++ skb_orphan(skb); ++ skb_orphan(skb); + skb->sk = sk; + skb->destructor = sock_rfree; + atomic_add(skb->truesize, &sk->sk_rmem_alloc); +--- a/net/ax25/ax25_in.c ++++ b/net/ax25/ax25_in.c +@@ -437,8 +437,7 @@ free: + int ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *ptype, struct net_device *orig_dev) + { +- skb->sk = NULL; /* Initially we don't know who it's for */ +- skb->destructor = NULL; /* Who initializes this, dammit?! */ ++ skb_orphan(skb); + + if (!net_eq(dev_net(dev), &init_net)) { + kfree_skb(skb); +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2284,8 +2284,6 @@ ncls: + if (!skb) + goto out; + +- skb_orphan(skb); +- + type = skb->protocol; + list_for_each_entry_rcu(ptype, + &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -913,9 +913,6 @@ static int irda_accept(struct socket *so + /* Clean up the original one to keep it in listen state */ + irttp_listen(self->tsap); + +- /* Wow ! What is that ? Jean II */ +- skb->sk = NULL; +- skb->destructor = NULL; + kfree_skb(skb); + sk->sk_ack_backlog--; + +--- a/net/irda/ircomm/ircomm_lmp.c ++++ b/net/irda/ircomm/ircomm_lmp.c +@@ -196,6 +196,7 @@ static int ircomm_lmp_data_request(struc + /* Don't forget to refcount it - see ircomm_tty_do_softint() */ + skb_get(skb); + ++ skb_orphan(skb); + skb->destructor = ircomm_lmp_flow_control; + + if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) { diff --git a/queue-2.6.30/net-sk_prot_alloc-should-not-blindly-overwrite-memory.patch b/queue-2.6.30/net-sk_prot_alloc-should-not-blindly-overwrite-memory.patch new file mode 100644 index 00000000000..62702d2c6a0 --- /dev/null +++ b/queue-2.6.30/net-sk_prot_alloc-should-not-blindly-overwrite-memory.patch @@ -0,0 +1,52 @@ +From c3584af0954f6ceaa347e7393e12f8076ae9366b Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 8 Jul 2009 19:36:05 +0000 +Subject: net: sk_prot_alloc() should not blindly overwrite memory + +From: Eric Dumazet + +[ Upstream commit e912b1142be8f1e2c71c71001dc992c6e5eb2ec1 ] + +Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code correctness +depends on sk->sk_nulls_node.next being always valid. A NULL +value is not allowed as it might fault a lockless reader. + +Current sk_prot_alloc() implementation doesnt respect this hypothesis, +calling kmem_cache_alloc() with __GFP_ZERO. Just call memset() around +the forbidden field. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -935,8 +935,23 @@ static struct sock *sk_prot_alloc(struct + struct kmem_cache *slab; + + slab = prot->slab; +- if (slab != NULL) +- sk = kmem_cache_alloc(slab, priority); ++ if (slab != NULL) { ++ sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); ++ if (!sk) ++ return sk; ++ if (priority & __GFP_ZERO) { ++ /* ++ * caches using SLAB_DESTROY_BY_RCU should let ++ * sk_node.next un-modified. Special care is taken ++ * when initializing object to zero. ++ */ ++ if (offsetof(struct sock, sk_node.next) != 0) ++ memset(sk, 0, offsetof(struct sock, sk_node.next)); ++ memset(&sk->sk_node.pprev, 0, ++ prot->obj_size - offsetof(struct sock, ++ sk_node.pprev)); ++ } ++ } + else + sk = kmalloc(prot->obj_size, priority); + diff --git a/queue-2.6.30/net-sock_copy-fixes.patch b/queue-2.6.30/net-sock_copy-fixes.patch new file mode 100644 index 00000000000..2cb75e1d0b1 --- /dev/null +++ b/queue-2.6.30/net-sock_copy-fixes.patch @@ -0,0 +1,153 @@ +From 89b8dcb97369f49e1d44535d34a797457325018a Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 28 Jul 2009 18:59:07 -0700 +Subject: net: sock_copy() fixes + +From: Eric Dumazet + +[ Upstream commit 4dc6dc7162c08b9965163c9ab3f9375d4adff2c7 ] + +Commit e912b1142be8f1e2c71c71001dc992c6e5eb2ec1 +(net: sk_prot_alloc() should not blindly overwrite memory) +took care of not zeroing whole new socket at allocation time. + +sock_copy() is another spot where we should be very careful. +We should not set refcnt to a non null value, until +we are sure other fields are correctly setup, or +a lockless reader could catch this socket by mistake, +while not fully (re)initialized. + +This patch puts sk_node & sk_refcnt to the very beginning +of struct sock to ease sock_copy() & sk_prot_alloc() job. + +We add appropriate smp_wmb() before sk_refcnt initializations +to match our RCU requirements (changes to sock keys should +be committed to memory before sk_refcnt setting) + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 32 +++++++++++++++++++------------- + net/core/sock.c | 20 ++++++++++++++++++-- + 2 files changed, 37 insertions(+), 15 deletions(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -103,15 +103,15 @@ struct net; + + /** + * struct sock_common - minimal network layer representation of sockets ++ * @skc_node: main hash linkage for various protocol lookup tables ++ * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol ++ * @skc_refcnt: reference count ++ * @skc_hash: hash value used with various protocol lookup tables + * @skc_family: network address family + * @skc_state: Connection state + * @skc_reuse: %SO_REUSEADDR setting + * @skc_bound_dev_if: bound device index if != 0 +- * @skc_node: main hash linkage for various protocol lookup tables +- * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol + * @skc_bind_node: bind hash linkage for various protocol lookup tables +- * @skc_refcnt: reference count +- * @skc_hash: hash value used with various protocol lookup tables + * @skc_prot: protocol handlers inside a network family + * @skc_net: reference to the network namespace of this socket + * +@@ -119,17 +119,21 @@ struct net; + * for struct sock and struct inet_timewait_sock. + */ + struct sock_common { +- unsigned short skc_family; +- volatile unsigned char skc_state; +- unsigned char skc_reuse; +- int skc_bound_dev_if; ++ /* ++ * first fields are not copied in sock_copy() ++ */ + union { + struct hlist_node skc_node; + struct hlist_nulls_node skc_nulls_node; + }; +- struct hlist_node skc_bind_node; + atomic_t skc_refcnt; ++ + unsigned int skc_hash; ++ unsigned short skc_family; ++ volatile unsigned char skc_state; ++ unsigned char skc_reuse; ++ int skc_bound_dev_if; ++ struct hlist_node skc_bind_node; + struct proto *skc_prot; + #ifdef CONFIG_NET_NS + struct net *skc_net; +@@ -207,15 +211,17 @@ struct sock { + * don't add nothing before this first member (__sk_common) --acme + */ + struct sock_common __sk_common; ++#define sk_node __sk_common.skc_node ++#define sk_nulls_node __sk_common.skc_nulls_node ++#define sk_refcnt __sk_common.skc_refcnt ++ ++#define sk_copy_start __sk_common.skc_hash ++#define sk_hash __sk_common.skc_hash + #define sk_family __sk_common.skc_family + #define sk_state __sk_common.skc_state + #define sk_reuse __sk_common.skc_reuse + #define sk_bound_dev_if __sk_common.skc_bound_dev_if +-#define sk_node __sk_common.skc_node +-#define sk_nulls_node __sk_common.skc_nulls_node + #define sk_bind_node __sk_common.skc_bind_node +-#define sk_refcnt __sk_common.skc_refcnt +-#define sk_hash __sk_common.skc_hash + #define sk_prot __sk_common.skc_prot + #define sk_net __sk_common.skc_net + unsigned char sk_shutdown : 2, +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -915,13 +915,19 @@ static inline void sock_lock_init(struct + af_family_keys + sk->sk_family); + } + ++/* ++ * Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet, ++ * even temporarly, because of RCU lookups. sk_node should also be left as is. ++ */ + static void sock_copy(struct sock *nsk, const struct sock *osk) + { + #ifdef CONFIG_SECURITY_NETWORK + void *sptr = nsk->sk_security; + #endif +- +- memcpy(nsk, osk, osk->sk_prot->obj_size); ++ BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) != ++ sizeof(osk->sk_node) + sizeof(osk->sk_refcnt)); ++ memcpy(&nsk->sk_copy_start, &osk->sk_copy_start, ++ osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start)); + #ifdef CONFIG_SECURITY_NETWORK + nsk->sk_security = sptr; + security_sk_clone(osk, nsk); +@@ -1118,6 +1124,11 @@ struct sock *sk_clone(const struct sock + + newsk->sk_err = 0; + newsk->sk_priority = 0; ++ /* ++ * Before updating sk_refcnt, we must commit prior changes to memory ++ * (Documentation/RCU/rculist_nulls.txt for details) ++ */ ++ smp_wmb(); + atomic_set(&newsk->sk_refcnt, 2); + + /* +@@ -1809,6 +1820,11 @@ void sock_init_data(struct socket *sock, + + sk->sk_stamp = ktime_set(-1L, 0); + ++ /* ++ * Before updating sk_refcnt, we must commit prior changes to memory ++ * (Documentation/RCU/rculist_nulls.txt for details) ++ */ ++ smp_wmb(); + atomic_set(&sk->sk_refcnt, 1); + atomic_set(&sk->sk_drops, 0); + } diff --git a/queue-2.6.30/series b/queue-2.6.30/series new file mode 100644 index 00000000000..39949c4df7d --- /dev/null +++ b/queue-2.6.30/series @@ -0,0 +1,13 @@ +iwlwifi-only-show-active-power-level-via-sysfs.patch +be2net-fix-to-avoid-a-crash-seen-on-ppc-with-lro-and-jumbo-frames.patch +dsa-fix-88e6xxx-statistics-counter-snapshotting.patch +e100-work-around-the-driver-using-streaming-dma-mapping-for-rx-descriptors.patch +ipsec-fix-name-of-cast-algorithm.patch +sky2-fix-checksum-endianness.patch +usbnet-cdc_subset-fix-issues-talking-to-pxa-gadgets.patch +net-sk_prot_alloc-should-not-blindly-overwrite-memory.patch +net-sock_copy-fixes.patch +gro-flush-gro-packets-in-napi_disable_pending-path.patch +gso-stop-fraglists-from-escaping.patch +net-move-rx-skb_orphan-call-to-where-needed.patch +inet-call-skb_orphan-before-tproxy-activates.patch diff --git a/queue-2.6.30/sky2-fix-checksum-endianness.patch b/queue-2.6.30/sky2-fix-checksum-endianness.patch new file mode 100644 index 00000000000..be05e45323c --- /dev/null +++ b/queue-2.6.30/sky2-fix-checksum-endianness.patch @@ -0,0 +1,46 @@ +From f97a5f71d912f9eff7ceb940a7d91e225ed0499c Mon Sep 17 00:00:00 2001 +From: Anton Vorontsov +Date: Fri, 26 Jun 2009 09:28:42 -0700 +Subject: sky2: Fix checksum endianness + +From: Anton Vorontsov + +[ Upstream commit b9389796fa4c87fbdff33816e317cdae5f36dd0b ] + +sky2 driver on PowerPC targets floods kernel log with following errors: + + eth1: hw csum failure. + Call Trace: + [ef84b8a0] [c00075e4] show_stack+0x50/0x160 (unreliable) + [ef84b8d0] [c02fa178] netdev_rx_csum_fault+0x3c/0x5c + [ef84b8f0] [c02f6920] __skb_checksum_complete_head+0x7c/0x84 + [ef84b900] [c02f693c] __skb_checksum_complete+0x14/0x24 + [ef84b910] [c0337e08] tcp_v4_rcv+0x4c8/0x6f8 + [ef84b940] [c031a9c8] ip_local_deliver+0x98/0x210 + [ef84b960] [c031a788] ip_rcv+0x38c/0x534 + [ef84b990] [c0300338] netif_receive_skb+0x260/0x36c + [ef84b9c0] [c025de00] sky2_poll+0x5dc/0xcf8 + [ef84ba20] [c02fb7fc] net_rx_action+0xc0/0x144 + +The NIC is Yukon-2 EC chip revision 1. + +Converting checksum field from le16 to CPU byte order fixes the issue. + +Signed-off-by: Anton Vorontsov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/sky2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/sky2.c ++++ b/drivers/net/sky2.c +@@ -2441,7 +2441,7 @@ static int sky2_status_intr(struct sky2_ + if (likely(status >> 16 == (status & 0xffff))) { + skb = sky2->rx_ring[sky2->rx_next].skb; + skb->ip_summed = CHECKSUM_COMPLETE; +- skb->csum = status & 0xffff; ++ skb->csum = le16_to_cpu(status); + } else { + printk(KERN_NOTICE PFX "%s: hardware receive " + "checksum problem (status = %#x)\n", diff --git a/queue-2.6.30/usbnet-cdc_subset-fix-issues-talking-to-pxa-gadgets.patch b/queue-2.6.30/usbnet-cdc_subset-fix-issues-talking-to-pxa-gadgets.patch new file mode 100644 index 00000000000..0c6f56a8d6b --- /dev/null +++ b/queue-2.6.30/usbnet-cdc_subset-fix-issues-talking-to-pxa-gadgets.patch @@ -0,0 +1,40 @@ +From ad5231dbf63323c059668245eaa83b8bb53981f1 Mon Sep 17 00:00:00 2001 +From: David Brownell +Date: Sat, 20 Jun 2009 01:21:53 -0700 +Subject: usbnet cdc_subset: fix issues talking to PXA gadgets + +From: David Brownell + +[ Upstream commit 6be832529a8129c9d90a1d3a78c5d503a710b6fc ] + +The host-side CDC subset driver is binding more specifically +than it should ... only to PXA 210/25x/26x Linux-USB gadgets. + +Loosen that restriction to match the gadget driver driver. +This will various PXA 27x and PXA 3xx devices happier when +talking to Linux hosts, potentially others. + +Signed-off-by: David Brownell +Tested-by: Aric D. Blumer +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_subset.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/usb/cdc_subset.c ++++ b/drivers/net/usb/cdc_subset.c +@@ -307,9 +307,10 @@ static const struct usb_device_id produc + USB_DEVICE (0x1286, 0x8001), // "blob" bootloader + .driver_info = (unsigned long) &blob_info, + }, { +- // Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config +- // e.g. Gumstix, current OpenZaurus, ... +- USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203), ++ // Linux Ethernet/RNDIS gadget, mostly on PXA, second config ++ // e.g. Gumstix, current OpenZaurus, ... or anything else ++ // that just enables this gadget option. ++ USB_DEVICE (0x0525, 0xa4a2), + .driver_info = (unsigned long) &linuxdev_info, + }, + #endif