From: Greg Kroah-Hartman Date: Mon, 9 Jul 2012 23:04:52 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.37~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=146d85980a327ea34b339389be1f1d48990c2571;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: be2net-fix-a-race-in-be_xmit.patch bnx2x-fix-checksum-validation.patch bnx2x-fix-panic-when-tx-ring-is-full.patch bonding-fix-corrupted-queue_mapping.patch bql-avoid-possible-inconsistent-calculation.patch bql-avoid-unneeded-limit-decrement.patch bql-fix-posdiff-to-integer-overflow-aware.patch bridge-assign-rtnl_link_ops-to-bridge-devices-created-via-ioctl-v2.patch cipso-handle-cipso-options-correctly-when-netlabel-is-disabled.patch drop_monitor-dont-sleep-in-atomic-context.patch dummy-fix-rcu_sched-self-detected-stalls.patch inetpeer-fix-a-race-in-inetpeer_gc_worker.patch ipv6-fib-restore-ntf_router-exception-in-fib6_age.patch ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch lpc_eth-add-missing-ndo_change_mtu.patch lpc_eth-fix-tx-completion.patch net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch net-neighbour-fix-neigh_dump_info.patch netpoll-fix-netpoll_send_udp-bugs.patch net-remove-skb_orphan_try.patch net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch revert-niu-add-support-for-byte-queue-limits.patch sky2-fix-checksum-bit-management-on-some-chips.patch xen-netfront-teardown-the-device-before-unregistering-it.patch --- diff --git a/queue-3.4/be2net-fix-a-race-in-be_xmit.patch b/queue-3.4/be2net-fix-a-race-in-be_xmit.patch new file mode 100644 index 00000000000..fff3d9c9cbc --- /dev/null +++ b/queue-3.4/be2net-fix-a-race-in-be_xmit.patch @@ -0,0 +1,42 @@ +From 03e05d90cdf2aaebb67594c45af839de52531c07 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 7 Jun 2012 22:59:59 +0000 +Subject: be2net: fix a race in be_xmit() + + +From: Eric Dumazet + +[ Upstream commit cd8f76c0a0c6fce0b2cf23c9bd0123f91453f46d ] + +As soon as hardware is notified of a transmit, we no longer can assume +skb can be dereferenced, as TX completion might have freed the packet. + +Signed-off-by: Eric Dumazet +Cc: Sathya Perla +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/emulex/benet/be_main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/emulex/benet/be_main.c ++++ b/drivers/net/ethernet/emulex/benet/be_main.c +@@ -731,6 +731,8 @@ static netdev_tx_t be_xmit(struct sk_buf + + copied = make_tx_wrbs(adapter, txq, skb, wrb_cnt, dummy_wrb); + if (copied) { ++ int gso_segs = skb_shinfo(skb)->gso_segs; ++ + /* record the sent skb in the sent_skb table */ + BUG_ON(txo->sent_skb_list[start]); + txo->sent_skb_list[start] = skb; +@@ -748,8 +750,7 @@ static netdev_tx_t be_xmit(struct sk_buf + + be_txq_notify(adapter, txq->id, wrb_cnt); + +- be_tx_stats_update(txo, wrb_cnt, copied, +- skb_shinfo(skb)->gso_segs, stopped); ++ be_tx_stats_update(txo, wrb_cnt, copied, gso_segs, stopped); + } else { + txq->head = start; + dev_kfree_skb_any(skb); diff --git a/queue-3.4/bnx2x-fix-checksum-validation.patch b/queue-3.4/bnx2x-fix-checksum-validation.patch new file mode 100644 index 00000000000..e95bd1c0815 --- /dev/null +++ b/queue-3.4/bnx2x-fix-checksum-validation.patch @@ -0,0 +1,106 @@ +From 2cd0a72b38f9ddc83cef62243e1a188150d60d27 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 12 Jun 2012 23:50:04 +0000 +Subject: bnx2x: fix checksum validation + + +From: Eric Dumazet + +[ Upstream commit d6cb3e41386f20fb0777d0b59a2def82c65d37f7 ] + +bnx2x driver incorrectly sets ip_summed to CHECKSUM_UNNECESSARY on +encapsulated segments. TCP stack happily accepts frames with bad +checksums, if they are inside a GRE or IPIP encapsulation. + +Our understanding is that if no IP or L4 csum validation was done by the +hardware, we should leave ip_summed as is (CHECKSUM_NONE), since +hardware doesn't provide CHECKSUM_COMPLETE support in its cqe. + +Then, if IP/L4 checksumming was done by the hardware, set +CHECKSUM_UNNECESSARY if no error was flagged. + +Patch based on findings and analysis from Robert Evans + +Signed-off-by: Eric Dumazet +Cc: Eilon Greenstein +Cc: Yaniv Rosner +Cc: Merav Sicron +Cc: Tom Herbert +Cc: Robert Evans +Cc: Willem de Bruijn +Acked-by: Eilon Greenstein +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 15 ------------- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 27 ++++++++++++++++++------ + 2 files changed, 21 insertions(+), 21 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +@@ -744,21 +744,6 @@ struct bnx2x_fastpath { + + #define ETH_RX_ERROR_FALGS ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG + +-#define BNX2X_IP_CSUM_ERR(cqe) \ +- (!((cqe)->fast_path_cqe.status_flags & \ +- ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG) && \ +- ((cqe)->fast_path_cqe.type_error_flags & \ +- ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG)) +- +-#define BNX2X_L4_CSUM_ERR(cqe) \ +- (!((cqe)->fast_path_cqe.status_flags & \ +- ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG) && \ +- ((cqe)->fast_path_cqe.type_error_flags & \ +- ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) +- +-#define BNX2X_RX_CSUM_OK(cqe) \ +- (!(BNX2X_L4_CSUM_ERR(cqe) || BNX2X_IP_CSUM_ERR(cqe))) +- + #define BNX2X_PRS_FLAG_OVERETH_IPV4(flags) \ + (((le16_to_cpu(flags) & \ + PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) >> \ +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -568,6 +568,25 @@ drop: + fp->eth_q_stats.rx_skb_alloc_failed++; + } + ++static void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe, ++ struct bnx2x_fastpath *fp) ++{ ++ /* Do nothing if no IP/L4 csum validation was done */ ++ ++ if (cqe->fast_path_cqe.status_flags & ++ (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | ++ ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)) ++ return; ++ ++ /* If both IP/L4 validation were done, check if an error was found. */ ++ ++ if (cqe->fast_path_cqe.type_error_flags & ++ (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | ++ ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)) ++ fp->eth_q_stats.hw_csum_err++; ++ else ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++} + + int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) + { +@@ -757,13 +776,9 @@ reuse_rx: + + skb_checksum_none_assert(skb); + +- if (bp->dev->features & NETIF_F_RXCSUM) { ++ if (bp->dev->features & NETIF_F_RXCSUM) ++ bnx2x_csum_validate(skb, cqe, fp); + +- if (likely(BNX2X_RX_CSUM_OK(cqe))) +- skb->ip_summed = CHECKSUM_UNNECESSARY; +- else +- fp->eth_q_stats.hw_csum_err++; +- } + + skb_record_rx_queue(skb, fp->rx_queue); + diff --git a/queue-3.4/bnx2x-fix-panic-when-tx-ring-is-full.patch b/queue-3.4/bnx2x-fix-panic-when-tx-ring-is-full.patch new file mode 100644 index 00000000000..57432fa87c2 --- /dev/null +++ b/queue-3.4/bnx2x-fix-panic-when-tx-ring-is-full.patch @@ -0,0 +1,73 @@ +From c2ef397e0290d9b56a4568c0f47d0cf9626bdb19 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 13 Jun 2012 09:45:16 +0000 +Subject: bnx2x: fix panic when TX ring is full + + +From: Eric Dumazet + +[ Upstream commit bc14786a100cc6a81cd060e8031ec481241b418c ] + +There is a off by one error in the minimal number of BD in +bnx2x_start_xmit() and bnx2x_tx_int() before stopping/resuming tx queue. + +A full size GSO packet, with data included in skb->head really needs +(MAX_SKB_FRAGS + 4) BDs, because of bnx2x_tx_split() + +This error triggers if BQL is disabled and heavy TCP transmit traffic +occurs. + +bnx2x_tx_split() definitely can be called, remove a wrong comment. + +Reported-by: Tomas Hruby +Signed-off-by: Eric Dumazet +Cc: Eilon Greenstein +Cc: Yaniv Rosner +Cc: Merav Sicron +Cc: Tom Herbert +Cc: Robert Evans +Cc: Willem de Bruijn +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -191,7 +191,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struc + + if ((netif_tx_queue_stopped(txq)) && + (bp->state == BNX2X_STATE_OPEN) && +- (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) ++ (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) + netif_tx_wake_queue(txq); + + __netif_tx_unlock(txq); +@@ -2349,8 +2349,6 @@ int bnx2x_poll(struct napi_struct *napi, + /* we split the first BD into headers and data BDs + * to ease the pain of our fellow microcode engineers + * we use one mapping for both BDs +- * So far this has only been observed to happen +- * in Other Operating Systems(TM) + */ + static noinline u16 bnx2x_tx_split(struct bnx2x *bp, + struct bnx2x_fp_txdata *txdata, +@@ -3002,7 +3000,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b + + txdata->tx_bd_prod += nbd; + +- if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { ++ if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { + netif_tx_stop_queue(txq); + + /* paired memory barrier is in bnx2x_tx_int(), we have to keep +@@ -3011,7 +3009,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_b + smp_mb(); + + fp->eth_q_stats.driver_xoff++; +- if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) ++ if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) + netif_tx_wake_queue(txq); + } + txdata->tx_pkt++; diff --git a/queue-3.4/bonding-fix-corrupted-queue_mapping.patch b/queue-3.4/bonding-fix-corrupted-queue_mapping.patch new file mode 100644 index 00000000000..1763ffb6176 --- /dev/null +++ b/queue-3.4/bonding-fix-corrupted-queue_mapping.patch @@ -0,0 +1,113 @@ +From 064505ba06570b605059f0bc781bade239291d49 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 12 Jun 2012 06:03:51 +0000 +Subject: bonding: Fix corrupted queue_mapping + + +From: Eric Dumazet + +[ Upstream commit 5ee31c6898ea5537fcea160999d60dc63bc0c305 ] + +In the transmit path of the bonding driver, skb->cb is used to +stash the skb->queue_mapping so that the bonding device can set its +own queue mapping. This value becomes corrupted since the skb->cb is +also used in __dev_xmit_skb. + +When transmitting through bonding driver, bond_select_queue is +called from dev_queue_xmit. In bond_select_queue the original +skb->queue_mapping is copied into skb->cb (via bond_queue_mapping) +and skb->queue_mapping is overwritten with the bond driver queue. + +Subsequently in dev_queue_xmit, __dev_xmit_skb is called which writes +the packet length into skb->cb, thereby overwriting the stashed +queue mappping. In bond_dev_queue_xmit (called from hard_start_xmit), +the queue mapping for the skb is set to the stashed value which is now +the skb length and hence is an invalid queue for the slave device. + +If we want to save skb->queue_mapping into skb->cb[], best place is to +add a field in struct qdisc_skb_cb, to make sure it wont conflict with +other layers (eg : Qdiscc, Infiniband...) + +This patchs also makes sure (struct qdisc_skb_cb)->data is aligned on 8 +bytes : + +netem qdisc for example assumes it can store an u64 in it, without +misalignment penalty. + +Note : we only have 20 bytes left in (struct qdisc_skb_cb)->data[]. +The largest user is CHOKe and it fills it. + +Based on a previous patch from Tom Herbert. + +Signed-off-by: Eric Dumazet +Reported-by: Tom Herbert +Cc: John Fastabend +Cc: Roland Dreier +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 9 +++++---- + include/net/sch_generic.h | 7 +++++-- + 2 files changed, 10 insertions(+), 6 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -76,6 +76,7 @@ + #include + #include + #include ++#include + #include "bonding.h" + #include "bond_3ad.h" + #include "bond_alb.h" +@@ -381,8 +382,6 @@ struct vlan_entry *bond_next_vlan(struct + return next; + } + +-#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb)) +- + /** + * bond_dev_queue_xmit - Prepare skb for xmit. + * +@@ -395,7 +394,9 @@ int bond_dev_queue_xmit(struct bonding * + { + skb->dev = slave_dev; + +- skb->queue_mapping = bond_queue_mapping(skb); ++ BUILD_BUG_ON(sizeof(skb->queue_mapping) != ++ sizeof(qdisc_skb_cb(skb)->bond_queue_mapping)); ++ skb->queue_mapping = qdisc_skb_cb(skb)->bond_queue_mapping; + + if (unlikely(netpoll_tx_running(slave_dev))) + bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); +@@ -4162,7 +4163,7 @@ static u16 bond_select_queue(struct net_ + /* + * Save the original txq to restore before passing to the driver + */ +- bond_queue_mapping(skb) = skb->queue_mapping; ++ qdisc_skb_cb(skb)->bond_queue_mapping = skb->queue_mapping; + + if (unlikely(txq >= dev->real_num_tx_queues)) { + do { +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -220,13 +220,16 @@ struct tcf_proto { + + struct qdisc_skb_cb { + unsigned int pkt_len; +- unsigned char data[24]; ++ u16 bond_queue_mapping; ++ u16 _pad; ++ unsigned char data[20]; + }; + + static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) + { + struct qdisc_skb_cb *qcb; +- BUILD_BUG_ON(sizeof(skb->cb) < sizeof(unsigned int) + sz); ++ ++ BUILD_BUG_ON(sizeof(skb->cb) < offsetof(struct qdisc_skb_cb, data) + sz); + BUILD_BUG_ON(sizeof(qcb->data) < sz); + } + diff --git a/queue-3.4/bql-avoid-possible-inconsistent-calculation.patch b/queue-3.4/bql-avoid-possible-inconsistent-calculation.patch new file mode 100644 index 00000000000..3caad52951f --- /dev/null +++ b/queue-3.4/bql-avoid-possible-inconsistent-calculation.patch @@ -0,0 +1,58 @@ +From 3cf098894a2fb3d8ec74103ed29f8fadfc727c73 Mon Sep 17 00:00:00 2001 +From: Hiroaki SHIMODA +Date: Wed, 30 May 2012 12:25:37 +0000 +Subject: bql: Avoid possible inconsistent calculation. + + +From: Hiroaki SHIMODA + +[ Upstream commit 914bec1011a25f65cdc94988a6f974bfb9a3c10d ] + +dql->num_queued could change while processing dql_completed(). +To provide consistent calculation, added an on stack variable. + +Signed-off-by: Hiroaki SHIMODA +Cc: Tom Herbert +Cc: Eric Dumazet +Cc: Denys Fedoryshchenko +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/dynamic_queue_limits.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/lib/dynamic_queue_limits.c ++++ b/lib/dynamic_queue_limits.c +@@ -17,16 +17,18 @@ + void dql_completed(struct dql *dql, unsigned int count) + { + unsigned int inprogress, prev_inprogress, limit; +- unsigned int ovlimit, completed; ++ unsigned int ovlimit, completed, num_queued; + bool all_prev_completed; + ++ num_queued = ACCESS_ONCE(dql->num_queued); ++ + /* Can't complete more than what's in queue */ +- BUG_ON(count > dql->num_queued - dql->num_completed); ++ BUG_ON(count > num_queued - dql->num_completed); + + completed = dql->num_completed + count; + limit = dql->limit; +- ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit); +- inprogress = dql->num_queued - completed; ++ ovlimit = POSDIFF(num_queued - dql->num_completed, limit); ++ inprogress = num_queued - completed; + prev_inprogress = dql->prev_num_queued - dql->num_completed; + all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued); + +@@ -106,7 +108,7 @@ void dql_completed(struct dql *dql, unsi + dql->prev_ovlimit = ovlimit; + dql->prev_last_obj_cnt = dql->last_obj_cnt; + dql->num_completed = completed; +- dql->prev_num_queued = dql->num_queued; ++ dql->prev_num_queued = num_queued; + } + EXPORT_SYMBOL(dql_completed); + diff --git a/queue-3.4/bql-avoid-unneeded-limit-decrement.patch b/queue-3.4/bql-avoid-unneeded-limit-decrement.patch new file mode 100644 index 00000000000..d50c62c78d4 --- /dev/null +++ b/queue-3.4/bql-avoid-unneeded-limit-decrement.patch @@ -0,0 +1,73 @@ +From 666d9dab33f6e93fd3be8992b9b7453252f700f3 Mon Sep 17 00:00:00 2001 +From: Hiroaki SHIMODA +Date: Wed, 30 May 2012 12:25:19 +0000 +Subject: bql: Avoid unneeded limit decrement. + + +From: Hiroaki SHIMODA + +[ Upstream commit 25426b794efdc70dde7fd3134dc56fac3e7d562d ] + +When below pattern is observed, + + TIME + dql_queued() dql_completed() | + a) initial state | + | + b) X bytes queued V + + c) Y bytes queued + d) X bytes completed + e) Z bytes queued + f) Y bytes completed + +a) dql->limit has already some value and there is no in-flight packet. +b) X bytes queued. +c) Y bytes queued and excess limit. +d) X bytes completed and dql->prev_ovlimit is set and also + dql->prev_num_queued is set Y. +e) Z bytes queued. +f) Y bytes completed. inprogress and prev_inprogress are true. + +At f), according to the comment, all_prev_completed becomes +true and limit should be increased. But POSDIFF() ignores +(completed == dql->prev_num_queued) case, so limit is decreased. + +Signed-off-by: Hiroaki SHIMODA +Cc: Tom Herbert +Cc: Eric Dumazet +Cc: Denys Fedoryshchenko +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/dynamic_queue_limits.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/lib/dynamic_queue_limits.c ++++ b/lib/dynamic_queue_limits.c +@@ -11,12 +11,14 @@ + #include + + #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0) ++#define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0) + + /* Records completed count and recalculates the queue limit */ + void dql_completed(struct dql *dql, unsigned int count) + { + unsigned int inprogress, prev_inprogress, limit; +- unsigned int ovlimit, all_prev_completed, completed; ++ unsigned int ovlimit, completed; ++ bool all_prev_completed; + + /* Can't complete more than what's in queue */ + BUG_ON(count > dql->num_queued - dql->num_completed); +@@ -26,7 +28,7 @@ void dql_completed(struct dql *dql, unsi + ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit); + inprogress = dql->num_queued - completed; + prev_inprogress = dql->prev_num_queued - dql->num_completed; +- all_prev_completed = POSDIFF(completed, dql->prev_num_queued); ++ all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued); + + if ((ovlimit && !inprogress) || + (dql->prev_ovlimit && all_prev_completed)) { diff --git a/queue-3.4/bql-fix-posdiff-to-integer-overflow-aware.patch b/queue-3.4/bql-fix-posdiff-to-integer-overflow-aware.patch new file mode 100644 index 00000000000..c3d98ad79e7 --- /dev/null +++ b/queue-3.4/bql-fix-posdiff-to-integer-overflow-aware.patch @@ -0,0 +1,34 @@ +From 910573d82ca9be8638b92c644544ba6f92772103 Mon Sep 17 00:00:00 2001 +From: Hiroaki SHIMODA +Date: Wed, 30 May 2012 12:24:39 +0000 +Subject: bql: Fix POSDIFF() to integer overflow aware. + + +From: Hiroaki SHIMODA + +[ Upstream commit 0cfd32b736ae0c36b42697584811042726c07cba ] + +POSDIFF() fails to take into account integer overflow case. + +Signed-off-by: Hiroaki SHIMODA +Cc: Tom Herbert +Cc: Eric Dumazet +Cc: Denys Fedoryshchenko +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + lib/dynamic_queue_limits.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/dynamic_queue_limits.c ++++ b/lib/dynamic_queue_limits.c +@@ -10,7 +10,7 @@ + #include + #include + +-#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0) ++#define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0) + + /* Records completed count and recalculates the queue limit */ + void dql_completed(struct dql *dql, unsigned int count) diff --git a/queue-3.4/bridge-assign-rtnl_link_ops-to-bridge-devices-created-via-ioctl-v2.patch b/queue-3.4/bridge-assign-rtnl_link_ops-to-bridge-devices-created-via-ioctl-v2.patch new file mode 100644 index 00000000000..1258495ae0f --- /dev/null +++ b/queue-3.4/bridge-assign-rtnl_link_ops-to-bridge-devices-created-via-ioctl-v2.patch @@ -0,0 +1,55 @@ +From acb421fa993fe70010b916728d87db53493850d5 Mon Sep 17 00:00:00 2001 +From: stephen hemminger +Date: Tue, 26 Jun 2012 05:48:45 +0000 +Subject: bridge: Assign rtnl_link_ops to bridge devices created via ioctl (v2) + + +From: stephen hemminger + +[ Upstream commit 149ddd83a92b02c658d6c61f3276eb6500d585e8 ] + +This ensures that bridges created with brctl(8) or ioctl(2) directly +also carry IFLA_LINKINFO when dumped over netlink. This also allows +to create a bridge with ioctl(2) and delete it with RTM_DELLINK. + +Signed-off-by: Thomas Graf +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_if.c | 1 + + net/bridge/br_netlink.c | 2 +- + net/bridge/br_private.h | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +--- a/net/bridge/br_if.c ++++ b/net/bridge/br_if.c +@@ -240,6 +240,7 @@ int br_add_bridge(struct net *net, const + return -ENOMEM; + + dev_net_set(dev, net); ++ dev->rtnl_link_ops = &br_link_ops; + + res = register_netdev(dev); + if (res) +--- a/net/bridge/br_netlink.c ++++ b/net/bridge/br_netlink.c +@@ -211,7 +211,7 @@ static int br_validate(struct nlattr *tb + return 0; + } + +-static struct rtnl_link_ops br_link_ops __read_mostly = { ++struct rtnl_link_ops br_link_ops __read_mostly = { + .kind = "bridge", + .priv_size = sizeof(struct net_bridge), + .setup = br_dev_setup, +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -538,6 +538,7 @@ extern int (*br_fdb_test_addr_hook)(stru + #endif + + /* br_netlink.c */ ++extern struct rtnl_link_ops br_link_ops; + extern int br_netlink_init(void); + extern void br_netlink_fini(void); + extern void br_ifinfo_notify(int event, struct net_bridge_port *port); diff --git a/queue-3.4/cipso-handle-cipso-options-correctly-when-netlabel-is-disabled.patch b/queue-3.4/cipso-handle-cipso-options-correctly-when-netlabel-is-disabled.patch new file mode 100644 index 00000000000..c4e5519f7ec --- /dev/null +++ b/queue-3.4/cipso-handle-cipso-options-correctly-when-netlabel-is-disabled.patch @@ -0,0 +1,77 @@ +From facea13ad2ee85d268bff23b100fcbeff5af4f92 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Fri, 1 Jun 2012 05:54:56 +0000 +Subject: cipso: handle CIPSO options correctly when NetLabel is disabled + + +From: Paul Moore + +[ Upstream commit 20e2a86485967c385d7c7befc1646e4d1d39362e ] + +When NetLabel is not enabled, e.g. CONFIG_NETLABEL=n, and the system +receives a CIPSO tagged packet it is dropped (cipso_v4_validate() +returns non-zero). In most cases this is the correct and desired +behavior, however, in the case where we are simply forwarding the +traffic, e.g. acting as a network bridge, this becomes a problem. + +This patch fixes the forwarding problem by providing the basic CIPSO +validation code directly in ip_options_compile() without the need for +the NetLabel or CIPSO code. The new validation code can not perform +any of the CIPSO option label/value verification that +cipso_v4_validate() does, but it can verify the basic CIPSO option +format. + +The behavior when NetLabel is enabled is unchanged. + +Signed-off-by: Paul Moore +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/cipso_ipv4.h | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +--- a/include/net/cipso_ipv4.h ++++ b/include/net/cipso_ipv4.h +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + /* known doi values */ + #define CIPSO_V4_DOI_UNKNOWN 0x00000000 +@@ -285,7 +286,33 @@ static inline int cipso_v4_skbuff_getatt + static inline int cipso_v4_validate(const struct sk_buff *skb, + unsigned char **option) + { +- return -ENOSYS; ++ unsigned char *opt = *option; ++ unsigned char err_offset = 0; ++ u8 opt_len = opt[1]; ++ u8 opt_iter; ++ ++ if (opt_len < 8) { ++ err_offset = 1; ++ goto out; ++ } ++ ++ if (get_unaligned_be32(&opt[2]) == 0) { ++ err_offset = 2; ++ goto out; ++ } ++ ++ for (opt_iter = 6; opt_iter < opt_len;) { ++ if (opt[opt_iter + 1] > (opt_len - opt_iter)) { ++ err_offset = opt_iter + 1; ++ goto out; ++ } ++ opt_iter += opt[opt_iter + 1]; ++ } ++ ++out: ++ *option = opt + err_offset; ++ return err_offset; ++ + } + #endif /* CONFIG_NETLABEL */ + diff --git a/queue-3.4/drop_monitor-dont-sleep-in-atomic-context.patch b/queue-3.4/drop_monitor-dont-sleep-in-atomic-context.patch new file mode 100644 index 00000000000..f3ea70dff62 --- /dev/null +++ b/queue-3.4/drop_monitor-dont-sleep-in-atomic-context.patch @@ -0,0 +1,245 @@ +From ad06508e40b82961ac5f478c2ad6bbc2c9b3b75f Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 4 Jun 2012 00:18:19 +0000 +Subject: drop_monitor: dont sleep in atomic context + + +From: Eric Dumazet + +[ Upstream commit bec4596b4e6770c7037f21f6bd27567b152dc0d6 ] + +drop_monitor calls several sleeping functions while in atomic context. + + BUG: sleeping function called from invalid context at mm/slub.c:943 + in_atomic(): 1, irqs_disabled(): 0, pid: 2103, name: kworker/0:2 + Pid: 2103, comm: kworker/0:2 Not tainted 3.5.0-rc1+ #55 + Call Trace: + [] __might_sleep+0xca/0xf0 + [] kmem_cache_alloc_node+0x1b3/0x1c0 + [] ? queue_delayed_work_on+0x11c/0x130 + [] __alloc_skb+0x4b/0x230 + [] ? reset_per_cpu_data+0x160/0x160 [drop_monitor] + [] reset_per_cpu_data+0x2f/0x160 [drop_monitor] + [] send_dm_alert+0x4b/0xb0 [drop_monitor] + [] process_one_work+0x130/0x4c0 + [] worker_thread+0x159/0x360 + [] ? manage_workers.isra.27+0x240/0x240 + [] kthread+0x93/0xa0 + [] kernel_thread_helper+0x4/0x10 + [] ? kthread_freezable_should_stop+0x80/0x80 + [] ? gs_change+0xb/0xb + +Rework the logic to call the sleeping functions in right context. + +Use standard timer/workqueue api to let system chose any cpu to perform +the allocation and netlink send. + +Also avoid a loop if reset_per_cpu_data() cannot allocate memory : +use mod_timer() to wait 1/10 second before next try. + +Signed-off-by: Eric Dumazet +Cc: Neil Horman +Reviewed-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/drop_monitor.c | 102 +++++++++++++++--------------------------------- + 1 file changed, 33 insertions(+), 69 deletions(-) + +--- a/net/core/drop_monitor.c ++++ b/net/core/drop_monitor.c +@@ -33,9 +33,6 @@ + #define TRACE_ON 1 + #define TRACE_OFF 0 + +-static void send_dm_alert(struct work_struct *unused); +- +- + /* + * Globals, our netlink socket pointer + * and the work handle that will send up +@@ -45,11 +42,10 @@ static int trace_state = TRACE_OFF; + static DEFINE_MUTEX(trace_state_mutex); + + struct per_cpu_dm_data { +- struct work_struct dm_alert_work; +- struct sk_buff __rcu *skb; +- atomic_t dm_hit_count; +- struct timer_list send_timer; +- int cpu; ++ spinlock_t lock; ++ struct sk_buff *skb; ++ struct work_struct dm_alert_work; ++ struct timer_list send_timer; + }; + + struct dm_hw_stat_delta { +@@ -75,13 +71,13 @@ static int dm_delay = 1; + static unsigned long dm_hw_check_delta = 2*HZ; + static LIST_HEAD(hw_stats_list); + +-static void reset_per_cpu_data(struct per_cpu_dm_data *data) ++static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) + { + size_t al; + struct net_dm_alert_msg *msg; + struct nlattr *nla; + struct sk_buff *skb; +- struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1); ++ unsigned long flags; + + al = sizeof(struct net_dm_alert_msg); + al += dm_hit_limit * sizeof(struct net_dm_drop_point); +@@ -96,65 +92,40 @@ static void reset_per_cpu_data(struct pe + sizeof(struct net_dm_alert_msg)); + msg = nla_data(nla); + memset(msg, 0, al); +- } else +- schedule_work_on(data->cpu, &data->dm_alert_work); +- +- /* +- * Don't need to lock this, since we are guaranteed to only +- * run this on a single cpu at a time. +- * Note also that we only update data->skb if the old and new skb +- * pointers don't match. This ensures that we don't continually call +- * synchornize_rcu if we repeatedly fail to alloc a new netlink message. +- */ +- if (skb != oskb) { +- rcu_assign_pointer(data->skb, skb); +- +- synchronize_rcu(); +- +- atomic_set(&data->dm_hit_count, dm_hit_limit); ++ } else { ++ mod_timer(&data->send_timer, jiffies + HZ / 10); + } + ++ spin_lock_irqsave(&data->lock, flags); ++ swap(data->skb, skb); ++ spin_unlock_irqrestore(&data->lock, flags); ++ ++ return skb; + } + +-static void send_dm_alert(struct work_struct *unused) ++static void send_dm_alert(struct work_struct *work) + { + struct sk_buff *skb; +- struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); ++ struct per_cpu_dm_data *data; + +- WARN_ON_ONCE(data->cpu != smp_processor_id()); ++ data = container_of(work, struct per_cpu_dm_data, dm_alert_work); + +- /* +- * Grab the skb we're about to send +- */ +- skb = rcu_dereference_protected(data->skb, 1); ++ skb = reset_per_cpu_data(data); + +- /* +- * Replace it with a new one +- */ +- reset_per_cpu_data(data); +- +- /* +- * Ship it! +- */ + if (skb) + genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); +- +- put_cpu_var(dm_cpu_data); + } + + /* + * This is the timer function to delay the sending of an alert + * in the event that more drops will arrive during the +- * hysteresis period. Note that it operates under the timer interrupt +- * so we don't need to disable preemption here ++ * hysteresis period. + */ +-static void sched_send_work(unsigned long unused) ++static void sched_send_work(unsigned long _data) + { +- struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); ++ struct per_cpu_dm_data *data = (struct per_cpu_dm_data *)_data; + +- schedule_work_on(smp_processor_id(), &data->dm_alert_work); +- +- put_cpu_var(dm_cpu_data); ++ schedule_work(&data->dm_alert_work); + } + + static void trace_drop_common(struct sk_buff *skb, void *location) +@@ -164,33 +135,28 @@ static void trace_drop_common(struct sk_ + struct nlattr *nla; + int i; + struct sk_buff *dskb; +- struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); +- ++ struct per_cpu_dm_data *data; ++ unsigned long flags; + +- rcu_read_lock(); +- dskb = rcu_dereference(data->skb); ++ local_irq_save(flags); ++ data = &__get_cpu_var(dm_cpu_data); ++ spin_lock(&data->lock); ++ dskb = data->skb; + + if (!dskb) + goto out; + +- if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) { +- /* +- * we're already at zero, discard this hit +- */ +- goto out; +- } +- + nlh = (struct nlmsghdr *)dskb->data; + nla = genlmsg_data(nlmsg_data(nlh)); + msg = nla_data(nla); + for (i = 0; i < msg->entries; i++) { + if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { + msg->points[i].count++; +- atomic_inc(&data->dm_hit_count); + goto out; + } + } +- ++ if (msg->entries == dm_hit_limit) ++ goto out; + /* + * We need to create a new entry + */ +@@ -202,13 +168,11 @@ static void trace_drop_common(struct sk_ + + if (!timer_pending(&data->send_timer)) { + data->send_timer.expires = jiffies + dm_delay * HZ; +- add_timer_on(&data->send_timer, smp_processor_id()); ++ add_timer(&data->send_timer); + } + + out: +- rcu_read_unlock(); +- put_cpu_var(dm_cpu_data); +- return; ++ spin_unlock_irqrestore(&data->lock, flags); + } + + static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) +@@ -406,11 +370,11 @@ static int __init init_net_drop_monitor( + + for_each_present_cpu(cpu) { + data = &per_cpu(dm_cpu_data, cpu); +- data->cpu = cpu; + INIT_WORK(&data->dm_alert_work, send_dm_alert); + init_timer(&data->send_timer); +- data->send_timer.data = cpu; ++ data->send_timer.data = (unsigned long)data; + data->send_timer.function = sched_send_work; ++ spin_lock_init(&data->lock); + reset_per_cpu_data(data); + } + diff --git a/queue-3.4/dummy-fix-rcu_sched-self-detected-stalls.patch b/queue-3.4/dummy-fix-rcu_sched-self-detected-stalls.patch new file mode 100644 index 00000000000..86c9e300d3e --- /dev/null +++ b/queue-3.4/dummy-fix-rcu_sched-self-detected-stalls.patch @@ -0,0 +1,39 @@ +From 72dff13e46276dd443b4a6efd225fa84dd46b7c9 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 10 Jun 2012 21:11:57 +0000 +Subject: dummy: fix rcu_sched self-detected stalls + + +From: Eric Dumazet + +[ Upstream commit 16b0dc29c1af9df341428f4c49ada4f626258082 ] + +Trying to "modprobe dummy numdummies=30000" triggers : + +INFO: rcu_sched self-detected stall on CPU { 8} (t=60000 jiffies) + +After this splat, RTNL is locked and reboot is needed. + +We must call cond_resched() to avoid this, even holding RTNL. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/dummy.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/dummy.c ++++ b/drivers/net/dummy.c +@@ -187,8 +187,10 @@ static int __init dummy_init_module(void + rtnl_lock(); + err = __rtnl_link_register(&dummy_link_ops); + +- for (i = 0; i < numdummies && !err; i++) ++ for (i = 0; i < numdummies && !err; i++) { + err = dummy_init_one(); ++ cond_resched(); ++ } + if (err < 0) + __rtnl_link_unregister(&dummy_link_ops); + rtnl_unlock(); diff --git a/queue-3.4/inetpeer-fix-a-race-in-inetpeer_gc_worker.patch b/queue-3.4/inetpeer-fix-a-race-in-inetpeer_gc_worker.patch new file mode 100644 index 00000000000..5ea09405e03 --- /dev/null +++ b/queue-3.4/inetpeer-fix-a-race-in-inetpeer_gc_worker.patch @@ -0,0 +1,76 @@ +From 71f9c079e7d11d8641590c44f30cc50fe36f0e3f Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 5 Jun 2012 03:00:18 +0000 +Subject: inetpeer: fix a race in inetpeer_gc_worker() + + +From: Eric Dumazet + +[ Upstream commit 55432d2b543a4b6dfae54f5c432a566877a85d90 ] + +commit 5faa5df1fa2024 (inetpeer: Invalidate the inetpeer tree along with +the routing cache) added a race : + +Before freeing an inetpeer, we must respect a RCU grace period, and make +sure no user will attempt to increase refcnt. + +inetpeer_invalidate_tree() waits for a RCU grace period before inserting +inetpeer tree into gc_list and waking the worker. At that time, no +concurrent lookup can find a inetpeer in this tree. + +Signed-off-by: Eric Dumazet +Cc: Steffen Klassert +Acked-by: Steffen Klassert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/inetpeer.h | 5 ++++- + net/ipv4/inetpeer.c | 16 ++++++++++++---- + 2 files changed, 16 insertions(+), 5 deletions(-) + +--- a/include/net/inetpeer.h ++++ b/include/net/inetpeer.h +@@ -40,7 +40,10 @@ struct inet_peer { + u32 pmtu_orig; + u32 pmtu_learned; + struct inetpeer_addr_base redirect_learned; +- struct list_head gc_list; ++ union { ++ struct list_head gc_list; ++ struct rcu_head gc_rcu; ++ }; + /* + * Once inet_peer is queued for deletion (refcnt == -1), following fields + * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -560,6 +560,17 @@ bool inet_peer_xrlim_allow(struct inet_p + } + EXPORT_SYMBOL(inet_peer_xrlim_allow); + ++static void inetpeer_inval_rcu(struct rcu_head *head) ++{ ++ struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu); ++ ++ spin_lock_bh(&gc_lock); ++ list_add_tail(&p->gc_list, &gc_list); ++ spin_unlock_bh(&gc_lock); ++ ++ schedule_delayed_work(&gc_work, gc_delay); ++} ++ + void inetpeer_invalidate_tree(int family) + { + struct inet_peer *old, *new, *prev; +@@ -576,10 +587,7 @@ void inetpeer_invalidate_tree(int family + prev = cmpxchg(&base->root, old, new); + if (prev == old) { + base->total = 0; +- spin_lock(&gc_lock); +- list_add_tail(&prev->gc_list, &gc_list); +- spin_unlock(&gc_lock); +- schedule_delayed_work(&gc_work, gc_delay); ++ call_rcu(&prev->gc_rcu, inetpeer_inval_rcu); + } + + out: diff --git a/queue-3.4/ipv6-fib-restore-ntf_router-exception-in-fib6_age.patch b/queue-3.4/ipv6-fib-restore-ntf_router-exception-in-fib6_age.patch new file mode 100644 index 00000000000..696ec5878be --- /dev/null +++ b/queue-3.4/ipv6-fib-restore-ntf_router-exception-in-fib6_age.patch @@ -0,0 +1,32 @@ +From 1a1bdcde369378f24d5c4983138640ee4de9d881 Mon Sep 17 00:00:00 2001 +From: Thomas Graf +Date: Thu, 7 Jun 2012 06:51:04 +0000 +Subject: ipv6: fib: Restore NTF_ROUTER exception in fib6_age() + + +From: Thomas Graf + +[ Upstream commit 8bd74516b1bd9308c17f67583134d93f777203ca ] + +Commit 5339ab8b1dd82 (ipv6: fib: Convert fib6_age() to +dst_neigh_lookup().) seems to have mistakenly inverted the +exception for cached NTF_ROUTER routes. + +Signed-off-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1560,7 +1560,7 @@ static int fib6_age(struct rt6_info *rt, + neigh_flags = neigh->flags; + neigh_release(neigh); + } +- if (neigh_flags & NTF_ROUTER) { ++ if (!(neigh_flags & NTF_ROUTER)) { + RT6_TRACE("purging route %p via non-router but gateway\n", + rt); + return -1; diff --git a/queue-3.4/ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch b/queue-3.4/ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch new file mode 100644 index 00000000000..3df4de2af7b --- /dev/null +++ b/queue-3.4/ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch @@ -0,0 +1,123 @@ +From 5413590847cdbd348b79c5d642fe782c0b9bcdc4 Mon Sep 17 00:00:00 2001 +From: Thomas Graf +Date: Mon, 18 Jun 2012 12:08:33 +0000 +Subject: ipv6: Move ipv6 proc file registration to end of init order + + +From: Thomas Graf + +[ Upstream commit d189634ecab947c10f6f832258b103d0bbfe73cc ] + +/proc/net/ipv6_route reflects the contents of fib_table_hash. The proc +handler is installed in ip6_route_net_init() whereas fib_table_hash is +allocated in fib6_net_init() _after_ the proc handler has been installed. + +This opens up a short time frame to access fib_table_hash with its pants +down. + +Move the registration of the proc files to a later point in the init +order to avoid the race. + +Tested :-) + +Signed-off-by: Thomas Graf +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 41 +++++++++++++++++++++++++++++++---------- + 1 file changed, 31 insertions(+), 10 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2953,10 +2953,6 @@ static int __net_init ip6_route_net_init + net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; + net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; + +-#ifdef CONFIG_PROC_FS +- proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); +- proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); +-#endif + net->ipv6.ip6_rt_gc_expire = 30*HZ; + + ret = 0; +@@ -2977,10 +2973,6 @@ out_ip6_dst_ops: + + static void __net_exit ip6_route_net_exit(struct net *net) + { +-#ifdef CONFIG_PROC_FS +- proc_net_remove(net, "ipv6_route"); +- proc_net_remove(net, "rt6_stats"); +-#endif + kfree(net->ipv6.ip6_null_entry); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + kfree(net->ipv6.ip6_prohibit_entry); +@@ -2989,11 +2981,33 @@ static void __net_exit ip6_route_net_exi + dst_entries_destroy(&net->ipv6.ip6_dst_ops); + } + ++static int __net_init ip6_route_net_init_late(struct net *net) ++{ ++#ifdef CONFIG_PROC_FS ++ proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); ++ proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); ++#endif ++ return 0; ++} ++ ++static void __net_exit ip6_route_net_exit_late(struct net *net) ++{ ++#ifdef CONFIG_PROC_FS ++ proc_net_remove(net, "ipv6_route"); ++ proc_net_remove(net, "rt6_stats"); ++#endif ++} ++ + static struct pernet_operations ip6_route_net_ops = { + .init = ip6_route_net_init, + .exit = ip6_route_net_exit, + }; + ++static struct pernet_operations ip6_route_net_late_ops = { ++ .init = ip6_route_net_init_late, ++ .exit = ip6_route_net_exit_late, ++}; ++ + static struct notifier_block ip6_route_dev_notifier = { + .notifier_call = ip6_route_dev_notify, + .priority = 0, +@@ -3043,19 +3057,25 @@ int __init ip6_route_init(void) + if (ret) + goto xfrm6_init; + ++ ret = register_pernet_subsys(&ip6_route_net_late_ops); ++ if (ret) ++ goto fib6_rules_init; ++ + ret = -ENOBUFS; + if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || + __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || + __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) +- goto fib6_rules_init; ++ goto out_register_late_subsys; + + ret = register_netdevice_notifier(&ip6_route_dev_notifier); + if (ret) +- goto fib6_rules_init; ++ goto out_register_late_subsys; + + out: + return ret; + ++out_register_late_subsys: ++ unregister_pernet_subsys(&ip6_route_net_late_ops); + fib6_rules_init: + fib6_rules_cleanup(); + xfrm6_init: +@@ -3074,6 +3094,7 @@ out_kmem_cache: + void ip6_route_cleanup(void) + { + unregister_netdevice_notifier(&ip6_route_dev_notifier); ++ unregister_pernet_subsys(&ip6_route_net_late_ops); + fib6_rules_cleanup(); + xfrm6_fini(); + fib6_gc_cleanup(); diff --git a/queue-3.4/l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch b/queue-3.4/l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch new file mode 100644 index 00000000000..158ae07f514 --- /dev/null +++ b/queue-3.4/l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch @@ -0,0 +1,51 @@ +From ca49ae5eccf6e744a6df0615f6cd4bcc3622d785 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 8 Jun 2012 06:25:00 +0000 +Subject: l2tp: fix a race in l2tp_ip_sendmsg() + + +From: Eric Dumazet + +[ Upstream commit 4399a4df98a63e30fd16e9d0cecc46ea92269e8f ] + +Commit 081b1b1bb27f (l2tp: fix l2tp_ip_sendmsg() route handling) added +a race, in case IP route cache is disabled. + +In this case, we should not do the dst_release(&rt->dst), since it'll +free the dst immediately, instead of waiting a RCU grace period. + +Signed-off-by: Eric Dumazet +Cc: James Chapman +Cc: Denys Fedoryshchenko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ip.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -516,10 +516,12 @@ static int l2tp_ip_sendmsg(struct kiocb + sk->sk_bound_dev_if); + if (IS_ERR(rt)) + goto no_route; +- if (connected) ++ if (connected) { + sk_setup_caps(sk, &rt->dst); +- else +- dst_release(&rt->dst); /* safe since we hold rcu_read_lock */ ++ } else { ++ skb_dst_set(skb, &rt->dst); ++ goto xmit; ++ } + } + + /* We dont need to clone dst here, it is guaranteed to not disappear. +@@ -527,6 +529,7 @@ static int l2tp_ip_sendmsg(struct kiocb + */ + skb_dst_set_noref(skb, &rt->dst); + ++xmit: + /* Queue the packet to IP for output */ + rc = ip_queue_xmit(skb, &inet->cork.fl); + rcu_read_unlock(); diff --git a/queue-3.4/lpc_eth-add-missing-ndo_change_mtu.patch b/queue-3.4/lpc_eth-add-missing-ndo_change_mtu.patch new file mode 100644 index 00000000000..99dbc249cd8 --- /dev/null +++ b/queue-3.4/lpc_eth-add-missing-ndo_change_mtu.patch @@ -0,0 +1,40 @@ +From dbaead2646f355699f636de9005e6e7576007947 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 10 Jun 2012 23:24:00 +0000 +Subject: lpc_eth: add missing ndo_change_mtu() + + +From: Eric Dumazet + +[ Upstream commit e30478598a8476d02e3b00caa89ce1a3b1dad54b ] + +lpc_eth does a copy of transmitted skbs to DMA area, without checking +skb lengths, so can trigger buffer overflows : + +memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len); + +One way to get bigger skbs is to allow MTU changes above the 1500 limit. + +Calling eth_change_mtu() in ndo_change_mtu() makes sure this cannot +happen. + +Signed-off-by: Eric Dumazet +Cc: Roland Stigge +Cc: Kevin Wells +Acked-by: Roland Stigge +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/nxp/lpc_eth.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/ethernet/nxp/lpc_eth.c ++++ b/drivers/net/ethernet/nxp/lpc_eth.c +@@ -1310,6 +1310,7 @@ static const struct net_device_ops lpc_n + .ndo_set_rx_mode = lpc_eth_set_multicast_list, + .ndo_do_ioctl = lpc_eth_ioctl, + .ndo_set_mac_address = lpc_set_mac_address, ++ .ndo_change_mtu = eth_change_mtu, + }; + + static int lpc_eth_drv_probe(struct platform_device *pdev) diff --git a/queue-3.4/lpc_eth-fix-tx-completion.patch b/queue-3.4/lpc_eth-fix-tx-completion.patch new file mode 100644 index 00000000000..6e512526f2b --- /dev/null +++ b/queue-3.4/lpc_eth-fix-tx-completion.patch @@ -0,0 +1,50 @@ +From 6dfaf84c13b4b573a125ce54f1d70b556fe0dd76 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 11 Jun 2012 07:21:36 +0000 +Subject: lpc_eth: fix tx completion + + +From: Eric Dumazet + +[ Upstream commit 3f16da51b0e533871d22a29682f3c3969d4f7e22 ] + +__lpc_handle_xmit() has two bugs : + +1) It can leak skbs in case TXSTATUS_ERROR is set + +2) It can wake up txqueue while no slot was freed. + +Signed-off-by: Eric Dumazet +Reported-by: Roland Stigge +Tested-by: Roland Stigge +Cc: Kevin Wells +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/nxp/lpc_eth.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/nxp/lpc_eth.c ++++ b/drivers/net/ethernet/nxp/lpc_eth.c +@@ -936,16 +936,16 @@ static void __lpc_handle_xmit(struct net + /* Update stats */ + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; +- +- /* Free buffer */ +- dev_kfree_skb_irq(skb); + } ++ dev_kfree_skb_irq(skb); + + txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base)); + } + +- if (netif_queue_stopped(ndev)) +- netif_wake_queue(ndev); ++ if (pldat->num_used_tx_buffs <= ENET_TX_DESC/2) { ++ if (netif_queue_stopped(ndev)) ++ netif_wake_queue(ndev); ++ } + } + + static int __lpc_handle_recv(struct net_device *ndev, int budget) diff --git a/queue-3.4/net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch b/queue-3.4/net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch new file mode 100644 index 00000000000..d9a49b7329a --- /dev/null +++ b/queue-3.4/net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch @@ -0,0 +1,41 @@ +From ad17d622580fc388627e843cc6776ec38d1d00e3 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 7 Jun 2012 00:07:20 +0000 +Subject: net: l2tp_eth: fix kernel panic on rmmod l2tp_eth + + +From: Eric Dumazet + +[ Upstream commit a06998b88b1651c5f71c0e35f528bf2057188ead ] + +We must prevent module unloading if some devices are still attached to +l2tp_eth driver. + +Signed-off-by: Eric Dumazet +Reported-by: Denys Fedoryshchenko +Tested-by: Denys Fedoryshchenko +Cc: James Chapman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_eth.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/l2tp/l2tp_eth.c ++++ b/net/l2tp/l2tp_eth.c +@@ -167,6 +167,7 @@ static void l2tp_eth_delete(struct l2tp_ + if (dev) { + unregister_netdev(dev); + spriv->dev = NULL; ++ module_put(THIS_MODULE); + } + } + } +@@ -254,6 +255,7 @@ static int l2tp_eth_create(struct net *n + if (rc < 0) + goto out_del_dev; + ++ __module_get(THIS_MODULE); + /* Must be done after register_netdev() */ + strlcpy(session->ifname, dev->name, IFNAMSIZ); + diff --git a/queue-3.4/net-neighbour-fix-neigh_dump_info.patch b/queue-3.4/net-neighbour-fix-neigh_dump_info.patch new file mode 100644 index 00000000000..b1bb05b03b6 --- /dev/null +++ b/queue-3.4/net-neighbour-fix-neigh_dump_info.patch @@ -0,0 +1,72 @@ +From 284363958a02ef4b53866572d0bd5588858eac8e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 7 Jun 2012 04:58:35 +0000 +Subject: net: neighbour: fix neigh_dump_info() + + +From: Eric Dumazet + +[ Upstream commit 4bd6683bd400c8b1d2ad544bb155d86a5d10f91c ] + +Denys found out "ip neigh" output was truncated to +about 54 neighbours. + +Signed-off-by: Eric Dumazet +Reported-by: Denys Fedoryshchenko +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/neighbour.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -2214,9 +2214,7 @@ static int neigh_dump_table(struct neigh + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + +- for (h = 0; h < (1 << nht->hash_shift); h++) { +- if (h < s_h) +- continue; ++ for (h = s_h; h < (1 << nht->hash_shift); h++) { + if (h > s_h) + s_idx = 0; + for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; +@@ -2255,9 +2253,7 @@ static int pneigh_dump_table(struct neig + + read_lock_bh(&tbl->lock); + +- for (h = 0; h <= PNEIGH_HASHMASK; h++) { +- if (h < s_h) +- continue; ++ for (h = s_h; h <= PNEIGH_HASHMASK; h++) { + if (h > s_h) + s_idx = 0; + for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { +@@ -2292,7 +2288,7 @@ static int neigh_dump_info(struct sk_buf + struct neigh_table *tbl; + int t, family, s_t; + int proxy = 0; +- int err = 0; ++ int err; + + read_lock(&neigh_tbl_lock); + family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family; +@@ -2306,7 +2302,7 @@ static int neigh_dump_info(struct sk_buf + + s_t = cb->args[0]; + +- for (tbl = neigh_tables, t = 0; tbl && (err >= 0); ++ for (tbl = neigh_tables, t = 0; tbl; + tbl = tbl->next, t++) { + if (t < s_t || (family && tbl->family != family)) + continue; +@@ -2317,6 +2313,8 @@ static int neigh_dump_info(struct sk_buf + err = pneigh_dump_table(tbl, skb, cb); + else + err = neigh_dump_table(tbl, skb, cb); ++ if (err < 0) ++ break; + } + read_unlock(&neigh_tbl_lock); + diff --git a/queue-3.4/net-remove-skb_orphan_try.patch b/queue-3.4/net-remove-skb_orphan_try.patch new file mode 100644 index 00000000000..81d27bdf956 --- /dev/null +++ b/queue-3.4/net-remove-skb_orphan_try.patch @@ -0,0 +1,128 @@ +From f65ece907db282d2c0f1090ee65f909367862be1 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 14 Jun 2012 06:42:44 +0000 +Subject: net: remove skb_orphan_try() + + +From: Eric Dumazet + +[ Upstream commit 62b1a8ab9b3660bb820d8dfe23148ed6cda38574 ] + +Orphaning skb in dev_hard_start_xmit() makes bonding behavior +unfriendly for applications sending big UDP bursts : Once packets +pass the bonding device and come to real device, they might hit a full +qdisc and be dropped. Without orphaning, the sender is automatically +throttled because sk->sk_wmemalloc reaches sk->sk_sndbuf (assuming +sk_sndbuf is not too big) + +We could try to defer the orphaning adding another test in +dev_hard_start_xmit(), but all this seems of little gain, +now that BQL tends to make packets more likely to be parked +in Qdisc queues instead of NIC TX ring, in cases where performance +matters. + +Reverts commits : +fc6055a5ba31 net: Introduce skb_orphan_try() +87fd308cfc6b net: skb_tx_hash() fix relative to skb_orphan_try() +and removes SKBTX_DRV_NEEDS_SK_REF flag + +Reported-and-bisected-by: Jean-Michel Hautbois +Signed-off-by: Eric Dumazet +Tested-by: Oliver Hartkopp +Acked-by: Oliver Hartkopp +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skbuff.h | 7 ++----- + net/can/raw.c | 3 --- + net/core/dev.c | 23 +---------------------- + net/iucv/af_iucv.c | 1 - + 4 files changed, 3 insertions(+), 31 deletions(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -225,14 +225,11 @@ enum { + /* device driver is going to provide hardware time stamp */ + SKBTX_IN_PROGRESS = 1 << 2, + +- /* ensure the originating sk reference is available on driver level */ +- SKBTX_DRV_NEEDS_SK_REF = 1 << 3, +- + /* device driver supports TX zero-copy buffers */ +- SKBTX_DEV_ZEROCOPY = 1 << 4, ++ SKBTX_DEV_ZEROCOPY = 1 << 3, + + /* generate wifi status information (where possible) */ +- SKBTX_WIFI_STATUS = 1 << 5, ++ SKBTX_WIFI_STATUS = 1 << 4, + }; + + /* +--- a/net/can/raw.c ++++ b/net/can/raw.c +@@ -681,9 +681,6 @@ static int raw_sendmsg(struct kiocb *ioc + if (err < 0) + goto free_skb; + +- /* to be able to check the received tx sock reference in raw_rcv() */ +- skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; +- + skb->dev = dev; + skb->sk = sk; + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2091,25 +2091,6 @@ static int dev_gso_segment(struct sk_buf + return 0; + } + +-/* +- * Try to orphan skb early, right before transmission by the device. +- * We cannot orphan skb if tx timestamp is requested or the sk-reference +- * is needed on driver level for other reasons, e.g. see net/can/raw.c +- */ +-static inline void skb_orphan_try(struct sk_buff *skb) +-{ +- struct sock *sk = skb->sk; +- +- if (sk && !skb_shinfo(skb)->tx_flags) { +- /* skb_tx_hash() wont be able to get sk. +- * We copy sk_hash into skb->rxhash +- */ +- if (!skb->rxhash) +- skb->rxhash = sk->sk_hash; +- skb_orphan(skb); +- } +-} +- + static bool can_checksum_protocol(netdev_features_t features, __be16 protocol) + { + return ((features & NETIF_F_GEN_CSUM) || +@@ -2195,8 +2176,6 @@ int dev_hard_start_xmit(struct sk_buff * + if (!list_empty(&ptype_all)) + dev_queue_xmit_nit(skb, dev); + +- skb_orphan_try(skb); +- + features = netif_skb_features(skb); + + if (vlan_tx_tag_present(skb) && +@@ -2306,7 +2285,7 @@ u16 __skb_tx_hash(const struct net_devic + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else +- hash = (__force u16) skb->protocol ^ skb->rxhash; ++ hash = (__force u16) skb->protocol; + hash = jhash_1word(hash, hashrnd); + + return (u16) (((u64) hash * qcount) >> 32) + qoffset; +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -372,7 +372,6 @@ static int afiucv_hs_send(struct iucv_me + skb_trim(skb, skb->dev->mtu); + } + skb->protocol = ETH_P_AF_IUCV; +- skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; + nskb = skb_clone(skb, GFP_ATOMIC); + if (!nskb) + return -ENOMEM; diff --git a/queue-3.4/net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch b/queue-3.4/net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch new file mode 100644 index 00000000000..e0b45d6aa05 --- /dev/null +++ b/queue-3.4/net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch @@ -0,0 +1,50 @@ +From 9c4257c379851be28c520051838f74eebfa43d7d Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 30 May 2012 21:18:10 +0000 +Subject: net: sock: validate data_len before allocating skb in sock_alloc_send_pskb() + + +From: Jason Wang + +[ Upstream commit cc9b17ad29ecaa20bfe426a8d4dbfb94b13ff1cc ] + +We need to validate the number of pages consumed by data_len, otherwise frags +array could be overflowed by userspace. So this patch validate data_len and +return -EMSGSIZE when data_len may occupies more frags than MAX_SKB_FRAGS. + +Signed-off-by: Jason Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/sock.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -1600,6 +1600,11 @@ struct sk_buff *sock_alloc_send_pskb(str + gfp_t gfp_mask; + long timeo; + int err; ++ int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ ++ err = -EMSGSIZE; ++ if (npages > MAX_SKB_FRAGS) ++ goto failure; + + gfp_mask = sk->sk_allocation; + if (gfp_mask & __GFP_WAIT) +@@ -1618,14 +1623,12 @@ struct sk_buff *sock_alloc_send_pskb(str + if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { + skb = alloc_skb(header_len, gfp_mask); + if (skb) { +- int npages; + int i; + + /* No pages, we're done... */ + if (!data_len) + break; + +- npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + skb->truesize += data_len; + skb_shinfo(skb)->nr_frags = npages; + for (i = 0; i < npages; i++) { diff --git a/queue-3.4/netpoll-fix-netpoll_send_udp-bugs.patch b/queue-3.4/netpoll-fix-netpoll_send_udp-bugs.patch new file mode 100644 index 00000000000..d3bd6b40a70 --- /dev/null +++ b/queue-3.4/netpoll-fix-netpoll_send_udp-bugs.patch @@ -0,0 +1,75 @@ +From ab1bb6e75fbbc50fc93e1bc777c5f8eaf534a4c6 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 12 Jun 2012 19:30:21 +0000 +Subject: netpoll: fix netpoll_send_udp() bugs + + +From: Eric Dumazet + +[ Upstream commit 954fba0274058d27c7c07b5ea07c41b3b7477894 ] + +Bogdan Hamciuc diagnosed and fixed following bug in netpoll_send_udp() : + +"skb->len += len;" instead of "skb_put(skb, len);" + +Meaning that _if_ a network driver needs to call skb_realloc_headroom(), +only packet headers would be copied, leaving garbage in the payload. + +However the skb_realloc_headroom() must be avoided as much as possible +since it requires memory and netpoll tries hard to work even if memory +is exhausted (using a pool of preallocated skbs) + +It appears netpoll_send_udp() reserved 16 bytes for the ethernet header, +which happens to work for typicall drivers but not all. + +Right thing is to use LL_RESERVED_SPACE(dev) +(And also add dev->needed_tailroom of tailroom) + +This patch combines both fixes. + +Many thanks to Bogdan for raising this issue. + +Reported-by: Bogdan Hamciuc +Signed-off-by: Eric Dumazet +Tested-by: Bogdan Hamciuc +Cc: Herbert Xu +Cc: Neil Horman +Reviewed-by: Neil Horman +Reviewed-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -362,22 +362,23 @@ EXPORT_SYMBOL(netpoll_send_skb_on_dev); + + void netpoll_send_udp(struct netpoll *np, const char *msg, int len) + { +- int total_len, eth_len, ip_len, udp_len; ++ int total_len, ip_len, udp_len; + struct sk_buff *skb; + struct udphdr *udph; + struct iphdr *iph; + struct ethhdr *eth; + + udp_len = len + sizeof(*udph); +- ip_len = eth_len = udp_len + sizeof(*iph); +- total_len = eth_len + ETH_HLEN + NET_IP_ALIGN; ++ ip_len = udp_len + sizeof(*iph); ++ total_len = ip_len + LL_RESERVED_SPACE(np->dev); + +- skb = find_skb(np, total_len, total_len - len); ++ skb = find_skb(np, total_len + np->dev->needed_tailroom, ++ total_len - len); + if (!skb) + return; + + skb_copy_to_linear_data(skb, msg, len); +- skb->len += len; ++ skb_put(skb, len); + + skb_push(skb, sizeof(*udph)); + skb_reset_transport_header(skb); diff --git a/queue-3.4/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch b/queue-3.4/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch new file mode 100644 index 00000000000..7d10dc61e98 --- /dev/null +++ b/queue-3.4/r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch @@ -0,0 +1,40 @@ +From 015fc314e55db8fe3f4ac4f995727948cb4f8b31 Mon Sep 17 00:00:00 2001 +From: Devendra Naga +Date: Thu, 31 May 2012 01:51:20 +0000 +Subject: r8169: call netif_napi_del at errpaths and at driver unload + + +From: Devendra Naga + +[ Upstream commit ad1be8d345416a794dea39761a374032aa471a76 ] + +when register_netdev fails, the init'ed NAPIs by netif_napi_add must be +deleted with netif_napi_del, and also when driver unloads, it should +delete the NAPI before unregistering netdevice using unregister_netdev. + +Signed-off-by: Devendra Naga +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/realtek/r8169.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -5966,6 +5966,8 @@ static void __devexit rtl_remove_one(str + + cancel_work_sync(&tp->wk.work); + ++ netif_napi_del(&tp->napi); ++ + unregister_netdev(dev); + + rtl_release_firmware(tp); +@@ -6288,6 +6290,7 @@ out: + return rc; + + err_out_msi_4: ++ netif_napi_del(&tp->napi); + rtl_disable_msi(pdev, tp); + iounmap(ioaddr); + err_out_free_res_3: diff --git a/queue-3.4/revert-niu-add-support-for-byte-queue-limits.patch b/queue-3.4/revert-niu-add-support-for-byte-queue-limits.patch new file mode 100644 index 00000000000..24b4efc5978 --- /dev/null +++ b/queue-3.4/revert-niu-add-support-for-byte-queue-limits.patch @@ -0,0 +1,70 @@ +From 02c753a3b78f39b23defe33bcb37c9b6263dcb53 Mon Sep 17 00:00:00 2001 +From: "David S. Miller" +Date: Fri, 8 Jun 2012 00:28:16 -0700 +Subject: Revert "niu: Add support for byte queue limits." + + +From: "David S. Miller" + +[ Upstream commit 6a2b28ef036ab5c66fdc606fe97d9e5cb34ea409 ] + +This reverts commit efa230f2c68abab817f13473077f8d0cc74f43f3. + +BQL doesn't work with how this driver currently only takes TX +interrupts every 1/4 of the TX ring. That behavior needs to be fixed, +but that's a larger non-trivial task and for now we have to revert +BQL support as this makes the device currently completely unusable. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/sun/niu.c | 12 +----------- + 1 file changed, 1 insertion(+), 11 deletions(-) + +--- a/drivers/net/ethernet/sun/niu.c ++++ b/drivers/net/ethernet/sun/niu.c +@@ -3598,7 +3598,6 @@ static int release_tx_packet(struct niu + static void niu_tx_work(struct niu *np, struct tx_ring_info *rp) + { + struct netdev_queue *txq; +- unsigned int tx_bytes; + u16 pkt_cnt, tmp; + int cons, index; + u64 cs; +@@ -3621,18 +3620,12 @@ static void niu_tx_work(struct niu *np, + netif_printk(np, tx_done, KERN_DEBUG, np->dev, + "%s() pkt_cnt[%u] cons[%d]\n", __func__, pkt_cnt, cons); + +- tx_bytes = 0; +- tmp = pkt_cnt; +- while (tmp--) { +- tx_bytes += rp->tx_buffs[cons].skb->len; ++ while (pkt_cnt--) + cons = release_tx_packet(np, rp, cons); +- } + + rp->cons = cons; + smp_mb(); + +- netdev_tx_completed_queue(txq, pkt_cnt, tx_bytes); +- + out: + if (unlikely(netif_tx_queue_stopped(txq) && + (niu_tx_avail(rp) > NIU_TX_WAKEUP_THRESH(rp)))) { +@@ -4333,7 +4326,6 @@ static void niu_free_channels(struct niu + struct tx_ring_info *rp = &np->tx_rings[i]; + + niu_free_tx_ring_info(np, rp); +- netdev_tx_reset_queue(netdev_get_tx_queue(np->dev, i)); + } + kfree(np->tx_rings); + np->tx_rings = NULL; +@@ -6739,8 +6731,6 @@ static netdev_tx_t niu_start_xmit(struct + prod = NEXT_TX(rp, prod); + } + +- netdev_tx_sent_queue(txq, skb->len); +- + if (prod < rp->prod) + rp->wrap_bit ^= TX_RING_KICK_WRAP; + rp->prod = prod; diff --git a/queue-3.4/series b/queue-3.4/series index 168b3f93818..a569e4d6760 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -13,3 +13,29 @@ arm-7438-1-fill-possible-pmd-empty-section-gaps.patch powerpc-kvm-sldi-should-be-sld.patch powerpc-xmon-use-cpumask-iterator-to-avoid-warning.patch media-smsusb-add-autodetection-support-for-usb-id-2040-f5a0.patch +bql-fix-posdiff-to-integer-overflow-aware.patch +bql-avoid-unneeded-limit-decrement.patch +bql-avoid-possible-inconsistent-calculation.patch +net-sock-validate-data_len-before-allocating-skb-in-sock_alloc_send_pskb.patch +cipso-handle-cipso-options-correctly-when-netlabel-is-disabled.patch +r8169-call-netif_napi_del-at-errpaths-and-at-driver-unload.patch +drop_monitor-dont-sleep-in-atomic-context.patch +inetpeer-fix-a-race-in-inetpeer_gc_worker.patch +net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch +l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch +lpc_eth-add-missing-ndo_change_mtu.patch +lpc_eth-fix-tx-completion.patch +net-neighbour-fix-neigh_dump_info.patch +ipv6-fib-restore-ntf_router-exception-in-fib6_age.patch +ipv6-move-ipv6-proc-file-registration-to-end-of-init-order.patch +sky2-fix-checksum-bit-management-on-some-chips.patch +revert-niu-add-support-for-byte-queue-limits.patch +be2net-fix-a-race-in-be_xmit.patch +dummy-fix-rcu_sched-self-detected-stalls.patch +bonding-fix-corrupted-queue_mapping.patch +netpoll-fix-netpoll_send_udp-bugs.patch +bnx2x-fix-checksum-validation.patch +bnx2x-fix-panic-when-tx-ring-is-full.patch +net-remove-skb_orphan_try.patch +bridge-assign-rtnl_link_ops-to-bridge-devices-created-via-ioctl-v2.patch +xen-netfront-teardown-the-device-before-unregistering-it.patch diff --git a/queue-3.4/sky2-fix-checksum-bit-management-on-some-chips.patch b/queue-3.4/sky2-fix-checksum-bit-management-on-some-chips.patch new file mode 100644 index 00000000000..0782493aedb --- /dev/null +++ b/queue-3.4/sky2-fix-checksum-bit-management-on-some-chips.patch @@ -0,0 +1,45 @@ +From 837f5fa245a35ce33b85d55d43a125000f598a97 Mon Sep 17 00:00:00 2001 +From: stephen hemminger +Date: Wed, 6 Jun 2012 10:01:30 +0000 +Subject: sky2: fix checksum bit management on some chips + + +From: stephen hemminger + +[ Upstream commit 5ff0feac88ced864f44adb145142269196fa79d9 ] + +The newer flavors of Yukon II use a different method for receive +checksum offload. This is indicated in the driver by the SKY2_HW_NEW_LE +flag. On these newer chips, the BMU_ENA_RX_CHKSUM should not be set. + +The driver would get incorrectly toggle the bit, enabling the old +checksum logic on these chips and cause a BUG_ON() assertion. If +receive checksum was toggled via ethtool. + +Reported-by: Kirill Smelkov +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/sky2.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -4381,10 +4381,12 @@ static int sky2_set_features(struct net_ + struct sky2_port *sky2 = netdev_priv(dev); + netdev_features_t changed = dev->features ^ features; + +- if (changed & NETIF_F_RXCSUM) { +- bool on = features & NETIF_F_RXCSUM; +- sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), +- on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); ++ if ((changed & NETIF_F_RXCSUM) && ++ !(sky2->hw->flags & SKY2_HW_NEW_LE)) { ++ sky2_write32(sky2->hw, ++ Q_ADDR(rxqaddr[sky2->port], Q_CSR), ++ (features & NETIF_F_RXCSUM) ++ ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + } + + if (changed & NETIF_F_RXHASH) diff --git a/queue-3.4/xen-netfront-teardown-the-device-before-unregistering-it.patch b/queue-3.4/xen-netfront-teardown-the-device-before-unregistering-it.patch new file mode 100644 index 00000000000..792f1a94aee --- /dev/null +++ b/queue-3.4/xen-netfront-teardown-the-device-before-unregistering-it.patch @@ -0,0 +1,56 @@ +From 84521b50a73f6ee6425f49389675a7641d73d90c Mon Sep 17 00:00:00 2001 +From: Ian Campbell +Date: Mon, 25 Jun 2012 22:48:41 +0000 +Subject: xen/netfront: teardown the device before unregistering it. + + +From: Ian Campbell + +[ Upstream commit 6bc96d047fe32d76ef79f3195c52a542edf7c705 ] + +Fixes: +[ 15.470311] WARNING: at /local/scratch/ianc/devel/kernels/linux/fs/sysfs/file.c:498 sysfs_attr_ns+0x95/0xa0() +[ 15.470326] sysfs: kobject eth0 without dirent +[ 15.470333] Modules linked in: +[ 15.470342] Pid: 12, comm: xenwatch Not tainted 3.4.0-x86_32p-xenU #93 +and +[ 9.150554] BUG: unable to handle kernel paging request at 2b359000 +[ 9.150577] IP: [] linkwatch_do_dev+0x81/0xc0 +[ 9.150592] *pdpt = 000000002c3c9027 *pde = 0000000000000000 +[ 9.150604] Oops: 0002 [#1] SMP +[ 9.150613] Modules linked in: + +This is http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=675190 + +Reported-by: George Shuklin +Signed-off-by: Ian Campbell +Tested-by: William Dauchy +Cc: stable@kernel.org +Cc: 675190@bugs.debian.org +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netfront.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/xen-netfront.c ++++ b/drivers/net/xen-netfront.c +@@ -1935,14 +1935,14 @@ static int __devexit xennet_remove(struc + + dev_dbg(&dev->dev, "%s\n", dev->nodename); + +- unregister_netdev(info->netdev); +- + xennet_disconnect_backend(info); + +- del_timer_sync(&info->rx_refill_timer); +- + xennet_sysfs_delif(info->netdev); + ++ unregister_netdev(info->netdev); ++ ++ del_timer_sync(&info->rx_refill_timer); ++ + free_percpu(info->stats); + + free_netdev(info->netdev);