]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Apr 2013 21:10:31 +0000 (14:10 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Apr 2013 21:10:31 +0000 (14:10 -0700)
added patches:
8021q-fix-a-potential-use-after-free.patch
af_unix-dont-send-scm_credential-when-dest-socket-is-null.patch
aoe-reserve-enough-headroom-on-skbs.patch
atl1e-drop-pci-msi-support-because-of-packet-corruption.patch
bonding-fix-disabling-of-arp_interval-and-miimon.patch
bonding-fix-miimon-and-arp_interval-delayed-work-race-conditions.patch
bonding-remove-already-created-master-sysfs-link-on-failure.patch
dm9000b-driver-initialization-upgrade.patch
drivers-net-ethernet-cpsw-use-netif_wake_queue-while-restarting-tx-queue.patch
drivers-net-ethernet-davinci_emac-use-netif_wake_queue-while-restarting-tx-queue.patch
ipv6-don-t-accept-multicast-traffic-with-scope-0.patch
ipv6-don-t-accept-node-local-multicast-traffic-from-the-wire.patch
ipv6-fix-bad-free-of-addrconf_init_net.patch
ks8851-fix-interpretation-of-rxlen-field.patch
net-add-a-synchronize_net-in-netdev_rx_handler_unregister.patch
net-fix-_diag_max-constants.patch
net-remove-a-warn_on-in-net_enable_timestamp.patch
pch_gbe-fix-ip_summed-checksum-reporting-on-rx.patch
sky2-receive-overflows-not-counted.patch
sky2-threshold-for-pause-packet-is-set-wrong.patch
smsc75xx-fix-jumbo-frame-support.patch
tcp-preserve-ack-clocking-in-tso.patch
tcp-undo-spurious-timeout-after-sack-reneging.patch
thermal-shorten-too-long-mcast-group-name.patch
unix-fix-a-race-condition-in-unix_release.patch

26 files changed:
queue-3.4/8021q-fix-a-potential-use-after-free.patch [new file with mode: 0644]
queue-3.4/af_unix-dont-send-scm_credential-when-dest-socket-is-null.patch [new file with mode: 0644]
queue-3.4/aoe-reserve-enough-headroom-on-skbs.patch [new file with mode: 0644]
queue-3.4/atl1e-drop-pci-msi-support-because-of-packet-corruption.patch [new file with mode: 0644]
queue-3.4/bonding-fix-disabling-of-arp_interval-and-miimon.patch [new file with mode: 0644]
queue-3.4/bonding-fix-miimon-and-arp_interval-delayed-work-race-conditions.patch [new file with mode: 0644]
queue-3.4/bonding-remove-already-created-master-sysfs-link-on-failure.patch [new file with mode: 0644]
queue-3.4/dm9000b-driver-initialization-upgrade.patch [new file with mode: 0644]
queue-3.4/drivers-net-ethernet-cpsw-use-netif_wake_queue-while-restarting-tx-queue.patch [new file with mode: 0644]
queue-3.4/drivers-net-ethernet-davinci_emac-use-netif_wake_queue-while-restarting-tx-queue.patch [new file with mode: 0644]
queue-3.4/ipv6-don-t-accept-multicast-traffic-with-scope-0.patch [new file with mode: 0644]
queue-3.4/ipv6-don-t-accept-node-local-multicast-traffic-from-the-wire.patch [new file with mode: 0644]
queue-3.4/ipv6-fix-bad-free-of-addrconf_init_net.patch [new file with mode: 0644]
queue-3.4/ks8851-fix-interpretation-of-rxlen-field.patch [new file with mode: 0644]
queue-3.4/net-add-a-synchronize_net-in-netdev_rx_handler_unregister.patch [new file with mode: 0644]
queue-3.4/net-fix-_diag_max-constants.patch [new file with mode: 0644]
queue-3.4/net-remove-a-warn_on-in-net_enable_timestamp.patch [new file with mode: 0644]
queue-3.4/pch_gbe-fix-ip_summed-checksum-reporting-on-rx.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/sky2-receive-overflows-not-counted.patch [new file with mode: 0644]
queue-3.4/sky2-threshold-for-pause-packet-is-set-wrong.patch [new file with mode: 0644]
queue-3.4/smsc75xx-fix-jumbo-frame-support.patch [new file with mode: 0644]
queue-3.4/tcp-preserve-ack-clocking-in-tso.patch [new file with mode: 0644]
queue-3.4/tcp-undo-spurious-timeout-after-sack-reneging.patch [new file with mode: 0644]
queue-3.4/thermal-shorten-too-long-mcast-group-name.patch [new file with mode: 0644]
queue-3.4/unix-fix-a-race-condition-in-unix_release.patch [new file with mode: 0644]

diff --git a/queue-3.4/8021q-fix-a-potential-use-after-free.patch b/queue-3.4/8021q-fix-a-potential-use-after-free.patch
new file mode 100644 (file)
index 0000000..981a847
--- /dev/null
@@ -0,0 +1,56 @@
+From f349eb07527aba350ef6499dec25bdc37c44654a Mon Sep 17 00:00:00 2001
+From: Cong Wang <amwang@redhat.com>
+Date: Fri, 22 Mar 2013 19:14:07 +0000
+Subject: 8021q: fix a potential use-after-free
+
+
+From: Cong Wang <amwang@redhat.com>
+
+[ Upstream commit 4a7df340ed1bac190c124c1601bfc10cde9fb4fb ]
+
+vlan_vid_del() could possibly free ->vlan_info after a RCU grace
+period, however, we may still refer to the freed memory area
+by 'grp' pointer. Found by code inspection.
+
+This patch moves vlan_vid_del() as behind as possible.
+
+Cc: Patrick McHardy <kaber@trash.net>
+Cc: "David S. Miller" <davem@davemloft.net>
+Signed-off-by: Cong Wang <amwang@redhat.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/8021q/vlan.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -86,13 +86,6 @@ void unregister_vlan_dev(struct net_devi
+       grp = &vlan_info->grp;
+-      /* Take it out of our own structures, but be sure to interlock with
+-       * HW accelerating devices or SW vlan input packet processing if
+-       * VLAN is not 0 (leave it there for 802.1p).
+-       */
+-      if (vlan_id)
+-              vlan_vid_del(real_dev, vlan_id);
+-
+       grp->nr_vlan_devs--;
+       if (vlan->flags & VLAN_FLAG_GVRP)
+@@ -108,6 +101,13 @@ void unregister_vlan_dev(struct net_devi
+       if (grp->nr_vlan_devs == 0)
+               vlan_gvrp_uninit_applicant(real_dev);
++      /* Take it out of our own structures, but be sure to interlock with
++       * HW accelerating devices or SW vlan input packet processing if
++       * VLAN is not 0 (leave it there for 802.1p).
++       */
++      if (vlan_id)
++              vlan_vid_del(real_dev, vlan_id);
++
+       /* Get rid of the vlan's reference to real_dev */
+       dev_put(real_dev);
+ }
diff --git a/queue-3.4/af_unix-dont-send-scm_credential-when-dest-socket-is-null.patch b/queue-3.4/af_unix-dont-send-scm_credential-when-dest-socket-is-null.patch
new file mode 100644 (file)
index 0000000..991950b
--- /dev/null
@@ -0,0 +1,36 @@
+From 0548cb9cbc64d221fb3851f7c8a0ccb8bc095acb Mon Sep 17 00:00:00 2001
+From: dingtianhong <dingtianhong@huawei.com>
+Date: Mon, 25 Mar 2013 17:02:04 +0000
+Subject: af_unix: dont send SCM_CREDENTIAL when dest socket is NULL
+
+
+From: dingtianhong <dingtianhong@huawei.com>
+
+[ Upstream commit 14134f6584212d585b310ce95428014b653dfaf6 ]
+
+SCM_SCREDENTIALS should apply to write() syscalls only either source or destination
+socket asserted SOCK_PASSCRED. The original implememtation in maybe_add_creds is wrong,
+and breaks several LSB testcases ( i.e. /tset/LSB.os/netowkr/recvfrom/T.recvfrom).
+
+Origionally-authored-by: Karel Srot <ksrot@redhat.com>
+Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/unix/af_unix.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1414,8 +1414,8 @@ static void maybe_add_creds(struct sk_bu
+       if (UNIXCB(skb).cred)
+               return;
+       if (test_bit(SOCK_PASSCRED, &sock->flags) ||
+-          !other->sk_socket ||
+-          test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
++          (other->sk_socket &&
++          test_bit(SOCK_PASSCRED, &other->sk_socket->flags))) {
+               UNIXCB(skb).pid  = get_pid(task_tgid(current));
+               UNIXCB(skb).cred = get_current_cred();
+       }
diff --git a/queue-3.4/aoe-reserve-enough-headroom-on-skbs.patch b/queue-3.4/aoe-reserve-enough-headroom-on-skbs.patch
new file mode 100644 (file)
index 0000000..040a262
--- /dev/null
@@ -0,0 +1,42 @@
+From b8b0b3cb0166b703a19b509c1466a5ab4cb498c5 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 27 Mar 2013 18:28:41 +0000
+Subject: aoe: reserve enough headroom on skbs
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 91c5746425aed8f7188a351f1224a26aa232e4b3 ]
+
+Some network drivers use a non default hard_header_len
+
+Transmitted skb should take into account dev->hard_header_len, or risk
+crashes or expensive reallocations.
+
+In the case of aoe, lets reserve MAX_HEADER bytes.
+
+David reported a crash in defxx driver, solved by this patch.
+
+Reported-by: David Oostdyk <daveo@ll.mit.edu>
+Tested-by: David Oostdyk <daveo@ll.mit.edu>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Ed Cashin <ecashin@coraid.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/aoe/aoecmd.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/block/aoe/aoecmd.c
++++ b/drivers/block/aoe/aoecmd.c
+@@ -30,8 +30,9 @@ new_skb(ulong len)
+ {
+       struct sk_buff *skb;
+-      skb = alloc_skb(len, GFP_ATOMIC);
++      skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC);
+       if (skb) {
++              skb_reserve(skb, MAX_HEADER);
+               skb_reset_mac_header(skb);
+               skb_reset_network_header(skb);
+               skb->protocol = __constant_htons(ETH_P_AOE);
diff --git a/queue-3.4/atl1e-drop-pci-msi-support-because-of-packet-corruption.patch b/queue-3.4/atl1e-drop-pci-msi-support-because-of-packet-corruption.patch
new file mode 100644 (file)
index 0000000..39f2648
--- /dev/null
@@ -0,0 +1,75 @@
+From f7519c9e43b6d902a36ee9a5eef77f126dda5307 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 28 Mar 2013 18:10:50 +0000
+Subject: atl1e: drop pci-msi support because of packet corruption
+
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 188ab1b105c96656f6bcfb49d0d8bb1b1936b632 ]
+
+Usage of pci-msi results in corrupted dma packet transfers to the host.
+
+Reported-by: rebelyouth <rebelyouth.hacklab@gmail.com>
+Cc: Huang, Xiong <xiong@qca.qualcomm.com>
+Tested-by: Christian Sünkenberg <christian.suenkenberg@student.kit.edu>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/atheros/atl1e/atl1e.h      |    1 -
+ drivers/net/ethernet/atheros/atl1e/atl1e_main.c |   22 ++--------------------
+ 2 files changed, 2 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/ethernet/atheros/atl1e/atl1e.h
++++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h
+@@ -438,7 +438,6 @@ struct atl1e_adapter {
+       struct atl1e_hw        hw;
+       struct atl1e_hw_stats  hw_stats;
+-      bool have_msi;
+       u32 wol;
+       u16 link_speed;
+       u16 link_duplex;
+--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+@@ -1870,37 +1870,19 @@ static void atl1e_free_irq(struct atl1e_
+       struct net_device *netdev = adapter->netdev;
+       free_irq(adapter->pdev->irq, netdev);
+-
+-      if (adapter->have_msi)
+-              pci_disable_msi(adapter->pdev);
+ }
+ static int atl1e_request_irq(struct atl1e_adapter *adapter)
+ {
+       struct pci_dev    *pdev   = adapter->pdev;
+       struct net_device *netdev = adapter->netdev;
+-      int flags = 0;
+       int err = 0;
+-      adapter->have_msi = true;
+-      err = pci_enable_msi(adapter->pdev);
+-      if (err) {
+-              netdev_dbg(adapter->netdev,
+-                         "Unable to allocate MSI interrupt Error: %d\n", err);
+-              adapter->have_msi = false;
+-      } else
+-              netdev->irq = pdev->irq;
+-
+-
+-      if (!adapter->have_msi)
+-              flags |= IRQF_SHARED;
+-      err = request_irq(adapter->pdev->irq, atl1e_intr, flags,
+-                      netdev->name, netdev);
++      err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED,
++                        netdev->name, netdev);
+       if (err) {
+               netdev_dbg(adapter->netdev,
+                          "Unable to allocate interrupt Error: %d\n", err);
+-              if (adapter->have_msi)
+-                      pci_disable_msi(adapter->pdev);
+               return err;
+       }
+       netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n");
diff --git a/queue-3.4/bonding-fix-disabling-of-arp_interval-and-miimon.patch b/queue-3.4/bonding-fix-disabling-of-arp_interval-and-miimon.patch
new file mode 100644 (file)
index 0000000..c6a8e66
--- /dev/null
@@ -0,0 +1,164 @@
+From c12eb97966d0d2796df4b8a99de1605c18a82281 Mon Sep 17 00:00:00 2001
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+Date: Wed, 27 Mar 2013 03:32:41 +0000
+Subject: bonding: fix disabling of arp_interval and miimon
+
+
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+
+[ Upstream commit 1bc7db16782c2a581fb4d53ca853631050f31611 ]
+
+Currently if either arp_interval or miimon is disabled, they both get
+disabled, and upon disabling they get executed once more which is not
+the proper behaviour. Also when doing a no-op and disabling an already
+disabled one, the other again gets disabled.
+Also fix the error messages with the proper valid ranges, and a small
+typo fix in the up delay error message (outputting "down delay", instead
+of "up delay").
+
+Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_sysfs.c |   92 ++++++++++++++++++++-------------------
+ 1 file changed, 48 insertions(+), 44 deletions(-)
+
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -527,7 +527,7 @@ static ssize_t bonding_store_arp_interva
+               goto out;
+       }
+       if (new_value < 0) {
+-              pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
++              pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n",
+                      bond->dev->name, new_value, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+@@ -542,14 +542,15 @@ static ssize_t bonding_store_arp_interva
+       pr_info("%s: Setting ARP monitoring interval to %d.\n",
+               bond->dev->name, new_value);
+       bond->params.arp_interval = new_value;
+-      if (bond->params.miimon) {
+-              pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+-                      bond->dev->name, bond->dev->name);
+-              bond->params.miimon = 0;
+-      }
+-      if (!bond->params.arp_targets[0]) {
+-              pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+-                      bond->dev->name);
++      if (new_value) {
++              if (bond->params.miimon) {
++                      pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
++                              bond->dev->name, bond->dev->name);
++                      bond->params.miimon = 0;
++              }
++              if (!bond->params.arp_targets[0])
++                      pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
++                              bond->dev->name);
+       }
+       if (bond->dev->flags & IFF_UP) {
+               /* If the interface is up, we may need to fire off
+@@ -557,10 +558,13 @@ static ssize_t bonding_store_arp_interva
+                * timer will get fired off when the open function
+                * is called.
+                */
+-              cancel_delayed_work_sync(&bond->mii_work);
+-              queue_delayed_work(bond->wq, &bond->arp_work, 0);
++              if (!new_value) {
++                      cancel_delayed_work_sync(&bond->arp_work);
++              } else {
++                      cancel_delayed_work_sync(&bond->mii_work);
++                      queue_delayed_work(bond->wq, &bond->arp_work, 0);
++              }
+       }
+-
+ out:
+       rtnl_unlock();
+       return ret;
+@@ -702,7 +706,7 @@ static ssize_t bonding_store_downdelay(s
+       }
+       if (new_value < 0) {
+               pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+-                     bond->dev->name, new_value, 1, INT_MAX);
++                     bond->dev->name, new_value, 0, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       } else {
+@@ -757,8 +761,8 @@ static ssize_t bonding_store_updelay(str
+               goto out;
+       }
+       if (new_value < 0) {
+-              pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+-                     bond->dev->name, new_value, 1, INT_MAX);
++              pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n",
++                     bond->dev->name, new_value, 0, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+       } else {
+@@ -968,37 +972,37 @@ static ssize_t bonding_store_miimon(stru
+       }
+       if (new_value < 0) {
+               pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
+-                     bond->dev->name, new_value, 1, INT_MAX);
++                     bond->dev->name, new_value, 0, INT_MAX);
+               ret = -EINVAL;
+               goto out;
+-      } else {
+-              pr_info("%s: Setting MII monitoring interval to %d.\n",
+-                      bond->dev->name, new_value);
+-              bond->params.miimon = new_value;
+-              if (bond->params.updelay)
+-                      pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
+-                              bond->dev->name,
+-                              bond->params.updelay * bond->params.miimon);
+-              if (bond->params.downdelay)
+-                      pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
+-                              bond->dev->name,
+-                              bond->params.downdelay * bond->params.miimon);
+-              if (bond->params.arp_interval) {
+-                      pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
+-                              bond->dev->name);
+-                      bond->params.arp_interval = 0;
+-                      if (bond->params.arp_validate) {
+-                              bond->params.arp_validate =
+-                                      BOND_ARP_VALIDATE_NONE;
+-                      }
+-              }
+-
+-              if (bond->dev->flags & IFF_UP) {
+-                      /* If the interface is up, we may need to fire off
+-                       * the MII timer. If the interface is down, the
+-                       * timer will get fired off when the open function
+-                       * is called.
+-                       */
++      }
++      pr_info("%s: Setting MII monitoring interval to %d.\n",
++              bond->dev->name, new_value);
++      bond->params.miimon = new_value;
++      if (bond->params.updelay)
++              pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
++                      bond->dev->name,
++                      bond->params.updelay * bond->params.miimon);
++      if (bond->params.downdelay)
++              pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
++                      bond->dev->name,
++                      bond->params.downdelay * bond->params.miimon);
++      if (new_value && bond->params.arp_interval) {
++              pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
++                      bond->dev->name);
++              bond->params.arp_interval = 0;
++              if (bond->params.arp_validate)
++                      bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
++      }
++      if (bond->dev->flags & IFF_UP) {
++              /* If the interface is up, we may need to fire off
++               * the MII timer. If the interface is down, the
++               * timer will get fired off when the open function
++               * is called.
++               */
++              if (!new_value) {
++                      cancel_delayed_work_sync(&bond->mii_work);
++              } else {
+                       cancel_delayed_work_sync(&bond->arp_work);
+                       queue_delayed_work(bond->wq, &bond->mii_work, 0);
+               }
diff --git a/queue-3.4/bonding-fix-miimon-and-arp_interval-delayed-work-race-conditions.patch b/queue-3.4/bonding-fix-miimon-and-arp_interval-delayed-work-race-conditions.patch
new file mode 100644 (file)
index 0000000..0c4546c
--- /dev/null
@@ -0,0 +1,284 @@
+From a41de97eaa03dedbe170919b95ce161e0dce818d Mon Sep 17 00:00:00 2001
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+Date: Thu, 29 Nov 2012 01:31:31 +0000
+Subject: bonding: fix miimon and arp_interval delayed work race conditions
+
+
+From: "nikolay@redhat.com" <nikolay@redhat.com>
+
+[ Upstream commit fbb0c41b814d497c656fc7be9e35456f139cb2fb ]
+
+First I would give three observations which will be used later.
+Observation 1: if (delayed_work_pending(wq)) cancel_delayed_work(wq)
+ This usage is wrong because the pending bit is cleared just before the
+ work's fn is executed and if the function re-arms itself we might end up
+ with the work still running. It's safe to call cancel_delayed_work_sync()
+ even if the work is not queued at all.
+Observation 2: Use of INIT_DELAYED_WORK()
+ Work needs to be initialized only once prior to (de/en)queueing.
+Observation 3: IFF_UP is set only after ndo_open is called
+
+Related race conditions:
+1. Race between bonding_store_miimon() and bonding_store_arp_interval()
+ Because of Obs.1 we can end up having both works enqueued.
+2. Multiple races with INIT_DELAYED_WORK()
+ Since the works are not protected by anything between INIT_DELAYED_WORK()
+ and calls to (en/de)queue it is possible for races between the following
+ functions:
+ (races are also possible between the calls to INIT_DELAYED_WORK()
+  and workqueue code)
+ bonding_store_miimon() - bonding_store_arp_interval(), bond_close(),
+                         bond_open(), enqueued functions
+ bonding_store_arp_interval() - bonding_store_miimon(), bond_close(),
+                               bond_open(), enqueued functions
+3. By Obs.1 we need to change bond_cancel_all()
+
+Bugs 1 and 2 are fixed by moving all work initializations in bond_open
+which by Obs. 2 and Obs. 3 and the fact that we make sure that all works
+are cancelled in bond_close(), is guaranteed not to have any work
+enqueued.
+Also RTNL lock is now acquired in bonding_store_miimon/arp_interval so
+they can't race with bond_close and bond_open. The opposing work is
+cancelled only if the IFF_UP flag is set and it is cancelled
+unconditionally. The opposing work is already cancelled if the interface
+is down so no need to cancel it again. This way we don't need new
+synchronizations for the bonding workqueue. These bugs (and fixes) are
+tied together and belong in the same patch.
+Note: I have left 1 line intentionally over 80 characters (84) because I
+      didn't like how it looks broken down. If you'd prefer it otherwise,
+      then simply break it.
+
+ v2: Make description text < 75 columns
+
+Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
+Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c  |   88 +++++++++++----------------------------
+ drivers/net/bonding/bond_sysfs.c |   34 ++++-----------
+ 2 files changed, 36 insertions(+), 86 deletions(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -3398,6 +3398,28 @@ static int bond_xmit_hash_policy_l2(stru
+ /*-------------------------- Device entry points ----------------------------*/
++static void bond_work_init_all(struct bonding *bond)
++{
++      INIT_DELAYED_WORK(&bond->mcast_work,
++                        bond_resend_igmp_join_requests_delayed);
++      INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
++      INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
++      if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
++              INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon);
++      else
++              INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon);
++      INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
++}
++
++static void bond_work_cancel_all(struct bonding *bond)
++{
++      cancel_delayed_work_sync(&bond->mii_work);
++      cancel_delayed_work_sync(&bond->arp_work);
++      cancel_delayed_work_sync(&bond->alb_work);
++      cancel_delayed_work_sync(&bond->ad_work);
++      cancel_delayed_work_sync(&bond->mcast_work);
++}
++
+ static int bond_open(struct net_device *bond_dev)
+ {
+       struct bonding *bond = netdev_priv(bond_dev);
+@@ -3420,41 +3442,27 @@ static int bond_open(struct net_device *
+       }
+       read_unlock(&bond->lock);
+-      INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed);
++      bond_work_init_all(bond);
+       if (bond_is_lb(bond)) {
+               /* bond_alb_initialize must be called before the timer
+                * is started.
+                */
+-              if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) {
+-                      /* something went wrong - fail the open operation */
++              if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
+                       return -ENOMEM;
+-              }
+-
+-              INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+               queue_delayed_work(bond->wq, &bond->alb_work, 0);
+       }
+-      if (bond->params.miimon) {  /* link check interval, in milliseconds. */
+-              INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
++      if (bond->params.miimon)  /* link check interval, in milliseconds. */
+               queue_delayed_work(bond->wq, &bond->mii_work, 0);
+-      }
+       if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
+-              if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+-                      INIT_DELAYED_WORK(&bond->arp_work,
+-                                        bond_activebackup_arp_mon);
+-              else
+-                      INIT_DELAYED_WORK(&bond->arp_work,
+-                                        bond_loadbalance_arp_mon);
+-
+               queue_delayed_work(bond->wq, &bond->arp_work, 0);
+               if (bond->params.arp_validate)
+                       bond->recv_probe = bond_arp_rcv;
+       }
+       if (bond->params.mode == BOND_MODE_8023AD) {
+-              INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
+               queue_delayed_work(bond->wq, &bond->ad_work, 0);
+               /* register to receive LACPDUs */
+               bond->recv_probe = bond_3ad_lacpdu_recv;
+@@ -3469,34 +3477,10 @@ static int bond_close(struct net_device
+       struct bonding *bond = netdev_priv(bond_dev);
+       write_lock_bh(&bond->lock);
+-
+       bond->send_peer_notif = 0;
+-
+       write_unlock_bh(&bond->lock);
+-      if (bond->params.miimon) {  /* link check interval, in milliseconds. */
+-              cancel_delayed_work_sync(&bond->mii_work);
+-      }
+-
+-      if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
+-              cancel_delayed_work_sync(&bond->arp_work);
+-      }
+-
+-      switch (bond->params.mode) {
+-      case BOND_MODE_8023AD:
+-              cancel_delayed_work_sync(&bond->ad_work);
+-              break;
+-      case BOND_MODE_TLB:
+-      case BOND_MODE_ALB:
+-              cancel_delayed_work_sync(&bond->alb_work);
+-              break;
+-      default:
+-              break;
+-      }
+-
+-      if (delayed_work_pending(&bond->mcast_work))
+-              cancel_delayed_work_sync(&bond->mcast_work);
+-
++      bond_work_cancel_all(bond);
+       if (bond_is_lb(bond)) {
+               /* Must be called only after all
+                * slaves have been released
+@@ -4375,26 +4359,6 @@ static void bond_setup(struct net_device
+       bond_dev->features |= bond_dev->hw_features;
+ }
+-static void bond_work_cancel_all(struct bonding *bond)
+-{
+-      if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
+-              cancel_delayed_work_sync(&bond->mii_work);
+-
+-      if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
+-              cancel_delayed_work_sync(&bond->arp_work);
+-
+-      if (bond->params.mode == BOND_MODE_ALB &&
+-          delayed_work_pending(&bond->alb_work))
+-              cancel_delayed_work_sync(&bond->alb_work);
+-
+-      if (bond->params.mode == BOND_MODE_8023AD &&
+-          delayed_work_pending(&bond->ad_work))
+-              cancel_delayed_work_sync(&bond->ad_work);
+-
+-      if (delayed_work_pending(&bond->mcast_work))
+-              cancel_delayed_work_sync(&bond->mcast_work);
+-}
+-
+ /*
+ * Destroy a bonding device.
+ * Must be under rtnl_lock when this function is called.
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -518,6 +518,8 @@ static ssize_t bonding_store_arp_interva
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
++      if (!rtnl_trylock())
++              return restart_syscall();
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               pr_err("%s: no arp_interval value specified.\n",
+                      bond->dev->name);
+@@ -544,10 +546,6 @@ static ssize_t bonding_store_arp_interva
+               pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
+                       bond->dev->name, bond->dev->name);
+               bond->params.miimon = 0;
+-              if (delayed_work_pending(&bond->mii_work)) {
+-                      cancel_delayed_work(&bond->mii_work);
+-                      flush_workqueue(bond->wq);
+-              }
+       }
+       if (!bond->params.arp_targets[0]) {
+               pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
+@@ -559,19 +557,12 @@ static ssize_t bonding_store_arp_interva
+                * timer will get fired off when the open function
+                * is called.
+                */
+-              if (!delayed_work_pending(&bond->arp_work)) {
+-                      if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+-                              INIT_DELAYED_WORK(&bond->arp_work,
+-                                                bond_activebackup_arp_mon);
+-                      else
+-                              INIT_DELAYED_WORK(&bond->arp_work,
+-                                                bond_loadbalance_arp_mon);
+-
+-                      queue_delayed_work(bond->wq, &bond->arp_work, 0);
+-              }
++              cancel_delayed_work_sync(&bond->mii_work);
++              queue_delayed_work(bond->wq, &bond->arp_work, 0);
+       }
+ out:
++      rtnl_unlock();
+       return ret;
+ }
+ static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
+@@ -967,6 +958,8 @@ static ssize_t bonding_store_miimon(stru
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
++      if (!rtnl_trylock())
++              return restart_syscall();
+       if (sscanf(buf, "%d", &new_value) != 1) {
+               pr_err("%s: no miimon value specified.\n",
+                      bond->dev->name);
+@@ -998,10 +991,6 @@ static ssize_t bonding_store_miimon(stru
+                               bond->params.arp_validate =
+                                       BOND_ARP_VALIDATE_NONE;
+                       }
+-                      if (delayed_work_pending(&bond->arp_work)) {
+-                              cancel_delayed_work(&bond->arp_work);
+-                              flush_workqueue(bond->wq);
+-                      }
+               }
+               if (bond->dev->flags & IFF_UP) {
+@@ -1010,15 +999,12 @@ static ssize_t bonding_store_miimon(stru
+                        * timer will get fired off when the open function
+                        * is called.
+                        */
+-                      if (!delayed_work_pending(&bond->mii_work)) {
+-                              INIT_DELAYED_WORK(&bond->mii_work,
+-                                                bond_mii_monitor);
+-                              queue_delayed_work(bond->wq,
+-                                                 &bond->mii_work, 0);
+-                      }
++                      cancel_delayed_work_sync(&bond->arp_work);
++                      queue_delayed_work(bond->wq, &bond->mii_work, 0);
+               }
+       }
+ out:
++      rtnl_unlock();
+       return ret;
+ }
+ static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
diff --git a/queue-3.4/bonding-remove-already-created-master-sysfs-link-on-failure.patch b/queue-3.4/bonding-remove-already-created-master-sysfs-link-on-failure.patch
new file mode 100644 (file)
index 0000000..faa3f68
--- /dev/null
@@ -0,0 +1,34 @@
+From 80213f2c67f0e0601b6616f455660c9b046d36a7 Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Tue, 26 Mar 2013 17:43:28 +0100
+Subject: bonding: remove already created master sysfs link on failure
+
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit 9fe16b78ee17579cb4f333534cf7043e94c67024 ]
+
+If slave sysfs symlink failes to be created - we end up without removing
+the master sysfs symlink. Remove it in case of failure.
+
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_sysfs.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -183,6 +183,11 @@ int bond_create_slave_symlinks(struct ne
+       sprintf(linkname, "slave_%s", slave->name);
+       ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
+                               linkname);
++
++      /* free the master link created earlier in case of error */
++      if (ret)
++              sysfs_remove_link(&(slave->dev.kobj), "master");
++
+       return ret;
+ }
diff --git a/queue-3.4/dm9000b-driver-initialization-upgrade.patch b/queue-3.4/dm9000b-driver-initialization-upgrade.patch
new file mode 100644 (file)
index 0000000..b460304
--- /dev/null
@@ -0,0 +1,302 @@
+From ac7c7f61aa1bde20169ee3e7d1447348d0e3271a Mon Sep 17 00:00:00 2001
+From: Joseph CHANG <josright123@gmail.com>
+Date: Thu, 28 Mar 2013 23:13:42 +0000
+Subject: DM9000B: driver initialization upgrade
+
+
+From: Joseph CHANG <josright123@gmail.com>
+
+[ Upstream commit 6741f40d198c6a5feb23653a1efd4ca47f93d83d ]
+
+Fix bug for DM9000 revision B which contain a DSP PHY
+
+DM9000B use DSP PHY instead previouse DM9000 revisions' analog PHY,
+So need extra change in initialization, For
+explicity PHY Reset and PHY init parameter, and
+first DM9000_NCR reset need NCR_MAC_LBK bit by dm9000_probe().
+
+Following DM9000_NCR reset cause by dm9000_open() clear the
+NCR_MAC_LBK bit.
+
+Without this fix, Power-up FIFO pointers error happen around 2%
+rate among Davicom's customers' boards. With this fix, All above
+cases can be solved.
+
+Signed-off-by: Joseph CHANG <josright123@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/davicom/dm9000.c |  214 +++++++++++++++++-----------------
+ drivers/net/ethernet/davicom/dm9000.h |   11 +
+ 2 files changed, 120 insertions(+), 105 deletions(-)
+
+--- a/drivers/net/ethernet/davicom/dm9000.c
++++ b/drivers/net/ethernet/davicom/dm9000.c
+@@ -257,6 +257,107 @@ static void dm9000_dumpblk_32bit(void __
+               tmp = readl(reg);
+ }
++/*
++ * Sleep, either by using msleep() or if we are suspending, then
++ * use mdelay() to sleep.
++ */
++static void dm9000_msleep(board_info_t *db, unsigned int ms)
++{
++      if (db->in_suspend)
++              mdelay(ms);
++      else
++              msleep(ms);
++}
++
++/* Read a word from phyxcer */
++static int
++dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
++{
++      board_info_t *db = netdev_priv(dev);
++      unsigned long flags;
++      unsigned int reg_save;
++      int ret;
++
++      mutex_lock(&db->addr_lock);
++
++      spin_lock_irqsave(&db->lock, flags);
++
++      /* Save previous register address */
++      reg_save = readb(db->io_addr);
++
++      /* Fill the phyxcer register into REG_0C */
++      iow(db, DM9000_EPAR, DM9000_PHY | reg);
++
++      /* Issue phyxcer read command */
++      iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);
++
++      writeb(reg_save, db->io_addr);
++      spin_unlock_irqrestore(&db->lock, flags);
++
++      dm9000_msleep(db, 1);           /* Wait read complete */
++
++      spin_lock_irqsave(&db->lock, flags);
++      reg_save = readb(db->io_addr);
++
++      iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer read command */
++
++      /* The read data keeps on REG_0D & REG_0E */
++      ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
++
++      /* restore the previous address */
++      writeb(reg_save, db->io_addr);
++      spin_unlock_irqrestore(&db->lock, flags);
++
++      mutex_unlock(&db->addr_lock);
++
++      dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
++      return ret;
++}
++
++/* Write a word to phyxcer */
++static void
++dm9000_phy_write(struct net_device *dev,
++               int phyaddr_unused, int reg, int value)
++{
++      board_info_t *db = netdev_priv(dev);
++      unsigned long flags;
++      unsigned long reg_save;
++
++      dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
++      mutex_lock(&db->addr_lock);
++
++      spin_lock_irqsave(&db->lock, flags);
++
++      /* Save previous register address */
++      reg_save = readb(db->io_addr);
++
++      /* Fill the phyxcer register into REG_0C */
++      iow(db, DM9000_EPAR, DM9000_PHY | reg);
++
++      /* Fill the written data into REG_0D & REG_0E */
++      iow(db, DM9000_EPDRL, value);
++      iow(db, DM9000_EPDRH, value >> 8);
++
++      /* Issue phyxcer write command */
++      iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);
++
++      writeb(reg_save, db->io_addr);
++      spin_unlock_irqrestore(&db->lock, flags);
++
++      dm9000_msleep(db, 1);           /* Wait write complete */
++
++      spin_lock_irqsave(&db->lock, flags);
++      reg_save = readb(db->io_addr);
++
++      iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer write command */
++
++      /* restore the previous address */
++      writeb(reg_save, db->io_addr);
++
++      spin_unlock_irqrestore(&db->lock, flags);
++      mutex_unlock(&db->addr_lock);
++}
++
+ /* dm9000_set_io
+  *
+  * select the specified set of io routines to use with the
+@@ -794,6 +895,9 @@ dm9000_init_dm9000(struct net_device *de
+       iow(db, DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
++      dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
++      dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
++
+       ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
+       /* if wol is needed, then always set NCR_WAKEEN otherwise we end
+@@ -1200,109 +1304,6 @@ dm9000_open(struct net_device *dev)
+       return 0;
+ }
+-/*
+- * Sleep, either by using msleep() or if we are suspending, then
+- * use mdelay() to sleep.
+- */
+-static void dm9000_msleep(board_info_t *db, unsigned int ms)
+-{
+-      if (db->in_suspend)
+-              mdelay(ms);
+-      else
+-              msleep(ms);
+-}
+-
+-/*
+- *   Read a word from phyxcer
+- */
+-static int
+-dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+-{
+-      board_info_t *db = netdev_priv(dev);
+-      unsigned long flags;
+-      unsigned int reg_save;
+-      int ret;
+-
+-      mutex_lock(&db->addr_lock);
+-
+-      spin_lock_irqsave(&db->lock,flags);
+-
+-      /* Save previous register address */
+-      reg_save = readb(db->io_addr);
+-
+-      /* Fill the phyxcer register into REG_0C */
+-      iow(db, DM9000_EPAR, DM9000_PHY | reg);
+-
+-      iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);   /* Issue phyxcer read command */
+-
+-      writeb(reg_save, db->io_addr);
+-      spin_unlock_irqrestore(&db->lock,flags);
+-
+-      dm9000_msleep(db, 1);           /* Wait read complete */
+-
+-      spin_lock_irqsave(&db->lock,flags);
+-      reg_save = readb(db->io_addr);
+-
+-      iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer read command */
+-
+-      /* The read data keeps on REG_0D & REG_0E */
+-      ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
+-
+-      /* restore the previous address */
+-      writeb(reg_save, db->io_addr);
+-      spin_unlock_irqrestore(&db->lock,flags);
+-
+-      mutex_unlock(&db->addr_lock);
+-
+-      dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
+-      return ret;
+-}
+-
+-/*
+- *   Write a word to phyxcer
+- */
+-static void
+-dm9000_phy_write(struct net_device *dev,
+-               int phyaddr_unused, int reg, int value)
+-{
+-      board_info_t *db = netdev_priv(dev);
+-      unsigned long flags;
+-      unsigned long reg_save;
+-
+-      dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
+-      mutex_lock(&db->addr_lock);
+-
+-      spin_lock_irqsave(&db->lock,flags);
+-
+-      /* Save previous register address */
+-      reg_save = readb(db->io_addr);
+-
+-      /* Fill the phyxcer register into REG_0C */
+-      iow(db, DM9000_EPAR, DM9000_PHY | reg);
+-
+-      /* Fill the written data into REG_0D & REG_0E */
+-      iow(db, DM9000_EPDRL, value);
+-      iow(db, DM9000_EPDRH, value >> 8);
+-
+-      iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);   /* Issue phyxcer write command */
+-
+-      writeb(reg_save, db->io_addr);
+-      spin_unlock_irqrestore(&db->lock, flags);
+-
+-      dm9000_msleep(db, 1);           /* Wait write complete */
+-
+-      spin_lock_irqsave(&db->lock,flags);
+-      reg_save = readb(db->io_addr);
+-
+-      iow(db, DM9000_EPCR, 0x0);      /* Clear phyxcer write command */
+-
+-      /* restore the previous address */
+-      writeb(reg_save, db->io_addr);
+-
+-      spin_unlock_irqrestore(&db->lock, flags);
+-      mutex_unlock(&db->addr_lock);
+-}
+-
+ static void
+ dm9000_shutdown(struct net_device *dev)
+ {
+@@ -1501,7 +1502,12 @@ dm9000_probe(struct platform_device *pde
+       db->flags |= DM9000_PLATF_SIMPLE_PHY;
+ #endif
+-      dm9000_reset(db);
++      /* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
++       * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
++       * while probe stage.
++       */
++
++      iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
+       /* try multiple times, DM9000 sometimes gets the read wrong */
+       for (i = 0; i < 8; i++) {
+--- a/drivers/net/ethernet/davicom/dm9000.h
++++ b/drivers/net/ethernet/davicom/dm9000.h
+@@ -69,7 +69,9 @@
+ #define NCR_WAKEEN          (1<<6)
+ #define NCR_FCOL            (1<<4)
+ #define NCR_FDX             (1<<3)
+-#define NCR_LBK             (3<<1)
++
++#define NCR_RESERVED        (3<<1)
++#define NCR_MAC_LBK         (1<<1)
+ #define NCR_RST                   (1<<0)
+ #define NSR_SPEED           (1<<7)
+@@ -167,5 +169,12 @@
+ #define ISR_LNKCHNG           (1<<5)
+ #define ISR_UNDERRUN          (1<<4)
++/* Davicom MII registers.
++ */
++
++#define MII_DM_DSPCR          0x1b    /* DSP Control Register */
++
++#define DSPCR_INIT_PARAM      0xE100  /* DSP init parameter */
++
+ #endif /* _DM9000X_H_ */
diff --git a/queue-3.4/drivers-net-ethernet-cpsw-use-netif_wake_queue-while-restarting-tx-queue.patch b/queue-3.4/drivers-net-ethernet-cpsw-use-netif_wake_queue-while-restarting-tx-queue.patch
new file mode 100644 (file)
index 0000000..311e472
--- /dev/null
@@ -0,0 +1,35 @@
+From 78d16b246484fe9821aa7d93116dbdd95bfa70ba Mon Sep 17 00:00:00 2001
+From: Mugunthan V N <mugunthanvnm@ti.com>
+Date: Wed, 27 Mar 2013 04:41:59 +0000
+Subject: drivers: net: ethernet: cpsw: use netif_wake_queue() while restarting tx queue
+
+
+From: Mugunthan V N <mugunthanvnm@ti.com>
+
+[ Upstream commit b56d6b3fca6d1214dbc9c5655f26e5d4ec04afc8 ]
+
+To restart tx queue use netif_wake_queue() intead of netif_start_queue()
+so that net schedule will restart transmission immediately which will
+increase network performance while doing huge data transfers.
+
+Reported-by: Dan Franke <dan.franke@schneider-electric.com>
+Suggested-by: Sriramakrishnan A G <srk@ti.com>
+Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ti/cpsw.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/ti/cpsw.c
++++ b/drivers/net/ethernet/ti/cpsw.c
+@@ -249,7 +249,7 @@ void cpsw_tx_handler(void *token, int le
+       struct cpsw_priv        *priv = netdev_priv(ndev);
+       if (unlikely(netif_queue_stopped(ndev)))
+-              netif_start_queue(ndev);
++              netif_wake_queue(ndev);
+       priv->stats.tx_packets++;
+       priv->stats.tx_bytes += len;
+       dev_kfree_skb_any(skb);
diff --git a/queue-3.4/drivers-net-ethernet-davinci_emac-use-netif_wake_queue-while-restarting-tx-queue.patch b/queue-3.4/drivers-net-ethernet-davinci_emac-use-netif_wake_queue-while-restarting-tx-queue.patch
new file mode 100644 (file)
index 0000000..036ba7e
--- /dev/null
@@ -0,0 +1,31 @@
+From 1e6851d901fb77cfc326eb7b10d6b344ac832a49 Mon Sep 17 00:00:00 2001
+From: Mugunthan V N <mugunthanvnm@ti.com>
+Date: Wed, 27 Mar 2013 04:42:00 +0000
+Subject: drivers: net: ethernet: davinci_emac: use netif_wake_queue() while restarting tx queue
+
+
+To restart tx queue use netif_wake_queue() intead of netif_start_queue()
+so that net schedule will restart transmission immediately which will
+increase network performance while doing huge data transfers.
+
+Reported-by: Dan Franke <dan.franke@schneider-electric.com>
+Suggested-by: Sriramakrishnan A G <srk@ti.com>
+Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/ti/davinci_emac.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/ti/davinci_emac.c
++++ b/drivers/net/ethernet/ti/davinci_emac.c
+@@ -1052,7 +1052,7 @@ static void emac_tx_handler(void *token,
+       atomic_dec(&priv->cur_tx);
+       if (unlikely(netif_queue_stopped(ndev)))
+-              netif_start_queue(ndev);
++              netif_wake_queue(ndev);
+       ndev->stats.tx_packets++;
+       ndev->stats.tx_bytes += len;
+       dev_kfree_skb_any(skb);
diff --git a/queue-3.4/ipv6-don-t-accept-multicast-traffic-with-scope-0.patch b/queue-3.4/ipv6-don-t-accept-multicast-traffic-with-scope-0.patch
new file mode 100644 (file)
index 0000000..05621f7
--- /dev/null
@@ -0,0 +1,43 @@
+From 89fabcb0892eea1d8d547f7bc4e883e87b9eb970 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Sun, 10 Feb 2013 05:35:22 +0000
+Subject: ipv6: don't accept multicast traffic with scope 0
+
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 20314092c1b41894d8c181bf9aa6f022be2416aa ]
+
+v2:
+a) moved before multicast source address check
+b) changed comment to netdev style
+
+Cc: Erik Hugne <erik.hugne@ericsson.com>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_input.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -111,6 +111,15 @@ int ipv6_rcv(struct sk_buff *skb, struct
+           ipv6_addr_loopback(&hdr->daddr))
+               goto err;
++      /* RFC4291 2.7
++       * Nodes must not originate a packet to a multicast address whose scope
++       * field contains the reserved value 0; if such a packet is received, it
++       * must be silently dropped.
++       */
++      if (ipv6_addr_is_multicast(&hdr->daddr) &&
++          IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 0)
++              goto err;
++
+       /*
+        * RFC4291 2.7
+        * Multicast addresses must not be used as source addresses in IPv6
diff --git a/queue-3.4/ipv6-don-t-accept-node-local-multicast-traffic-from-the-wire.patch b/queue-3.4/ipv6-don-t-accept-node-local-multicast-traffic-from-the-wire.patch
new file mode 100644 (file)
index 0000000..c63ce06
--- /dev/null
@@ -0,0 +1,49 @@
+From ed9063c8a1691f21e2834ff0753080b649bb9e2a Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Tue, 26 Mar 2013 08:13:34 +0000
+Subject: ipv6: don't accept node local multicast traffic from the wire
+
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 1c4a154e5253687c51123956dfcee9e9dfa8542d ]
+
+Erik Hugne's errata proposal (Errata ID: 3480) to RFC4291 has been
+verified: http://www.rfc-editor.org/errata_search.php?eid=3480
+
+We have to check for pkt_type and loopback flag because either the
+packets are allowed to travel over the loopback interface (in which case
+pkt_type is PACKET_HOST and IFF_LOOPBACK flag is set) or they travel
+over a non-loopback interface back to us (in which case PACKET_TYPE is
+PACKET_LOOPBACK and IFF_LOOPBACK flag is not set).
+
+Cc: Erik Hugne <erik.hugne@ericsson.com>
+Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_input.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/net/ipv6/ip6_input.c
++++ b/net/ipv6/ip6_input.c
+@@ -111,6 +111,18 @@ int ipv6_rcv(struct sk_buff *skb, struct
+           ipv6_addr_loopback(&hdr->daddr))
+               goto err;
++      /* RFC4291 Errata ID: 3480
++       * Interface-Local scope spans only a single interface on a
++       * node and is useful only for loopback transmission of
++       * multicast.  Packets with interface-local scope received
++       * from another node must be discarded.
++       */
++      if (!(skb->pkt_type == PACKET_LOOPBACK ||
++            dev->flags & IFF_LOOPBACK) &&
++          ipv6_addr_is_multicast(&hdr->daddr) &&
++          IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1)
++              goto err;
++
+       /* RFC4291 2.7
+        * Nodes must not originate a packet to a multicast address whose scope
+        * field contains the reserved value 0; if such a packet is received, it
diff --git a/queue-3.4/ipv6-fix-bad-free-of-addrconf_init_net.patch b/queue-3.4/ipv6-fix-bad-free-of-addrconf_init_net.patch
new file mode 100644 (file)
index 0000000..5e3af56
--- /dev/null
@@ -0,0 +1,56 @@
+From c6fd6477f525bf75a673dcfb5a51c43b8c3e05c7 Mon Sep 17 00:00:00 2001
+From: Hong Zhiguo <honkiko@gmail.com>
+Date: Tue, 26 Mar 2013 01:52:45 +0800
+Subject: ipv6: fix bad free of addrconf_init_net
+
+
+From: Hong Zhiguo <honkiko@gmail.com>
+
+[ Upstream commit a79ca223e029aa4f09abb337accf1812c900a800 ]
+
+Signed-off-by: Hong Zhiguo <honkiko@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/addrconf.c |   26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -4686,26 +4686,20 @@ static void addrconf_sysctl_unregister(s
+ static int __net_init addrconf_init_net(struct net *net)
+ {
+-      int err;
++      int err = -ENOMEM;
+       struct ipv6_devconf *all, *dflt;
+-      err = -ENOMEM;
+-      all = &ipv6_devconf;
+-      dflt = &ipv6_devconf_dflt;
++      all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
++      if (all == NULL)
++              goto err_alloc_all;
+-      if (!net_eq(net, &init_net)) {
+-              all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
+-              if (all == NULL)
+-                      goto err_alloc_all;
++      dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
++      if (dflt == NULL)
++              goto err_alloc_dflt;
+-              dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
+-              if (dflt == NULL)
+-                      goto err_alloc_dflt;
+-      } else {
+-              /* these will be inherited by all namespaces */
+-              dflt->autoconf = ipv6_defaults.autoconf;
+-              dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
+-      }
++      /* these will be inherited by all namespaces */
++      dflt->autoconf = ipv6_defaults.autoconf;
++      dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
+       net->ipv6.devconf_all = all;
+       net->ipv6.devconf_dflt = dflt;
diff --git a/queue-3.4/ks8851-fix-interpretation-of-rxlen-field.patch b/queue-3.4/ks8851-fix-interpretation-of-rxlen-field.patch
new file mode 100644 (file)
index 0000000..1c03a26
--- /dev/null
@@ -0,0 +1,38 @@
+From d117056fa9d19608c6082cae837e09aab6d46419 Mon Sep 17 00:00:00 2001
+From: "Max.Nekludov@us.elster.com" <Max.Nekludov@us.elster.com>
+Date: Fri, 29 Mar 2013 05:27:36 +0000
+Subject: ks8851: Fix interpretation of rxlen field.
+
+
+From: "Max.Nekludov@us.elster.com" <Max.Nekludov@us.elster.com>
+
+[ Upstream commit 14bc435ea54cb888409efb54fc6b76c13ef530e9 ]
+
+According to the Datasheet (page 52):
+15-12 Reserved
+11-0 RXBC Receive Byte Count
+This field indicates the present received frame byte size.
+
+The code has a bug:
+                 rxh = ks8851_rdreg32(ks, KS_RXFHSR);
+                 rxstat = rxh & 0xffff;
+                 rxlen = rxh >> 16; // BUG!!! 0xFFF mask should be applied
+
+Signed-off-by: Max Nekludov <Max.Nekludov@us.elster.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/micrel/ks8851.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/micrel/ks8851.c
++++ b/drivers/net/ethernet/micrel/ks8851.c
+@@ -547,7 +547,7 @@ static void ks8851_rx_pkts(struct ks8851
+       for (; rxfc != 0; rxfc--) {
+               rxh = ks8851_rdreg32(ks, KS_RXFHSR);
+               rxstat = rxh & 0xffff;
+-              rxlen = rxh >> 16;
++              rxlen = (rxh >> 16) & 0xfff;
+               netif_dbg(ks, rx_status, ks->netdev,
+                         "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen);
diff --git a/queue-3.4/net-add-a-synchronize_net-in-netdev_rx_handler_unregister.patch b/queue-3.4/net-add-a-synchronize_net-in-netdev_rx_handler_unregister.patch
new file mode 100644 (file)
index 0000000..6453f9f
--- /dev/null
@@ -0,0 +1,127 @@
+From b72b6fcd4653971a6714b66a8fc8b2ae9eb08220 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 29 Mar 2013 03:01:22 +0000
+Subject: net: add a synchronize_net() in netdev_rx_handler_unregister()
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 00cfec37484761a44a3b6f4675a54caa618210ae ]
+
+commit 35d48903e97819 (bonding: fix rx_handler locking) added a race
+in bonding driver, reported by Steven Rostedt who did a very good
+diagnosis :
+
+<quoting Steven>
+
+I'm currently debugging a crash in an old 3.0-rt kernel that one of our
+customers is seeing. The bug happens with a stress test that loads and
+unloads the bonding module in a loop (I don't know all the details as
+I'm not the one that is directly interacting with the customer). But the
+bug looks to be something that may still be present and possibly present
+in mainline too. It will just be much harder to trigger it in mainline.
+
+In -rt, interrupts are threads, and can schedule in and out just like
+any other thread. Note, mainline now supports interrupt threads so this
+may be easily reproducible in mainline as well. I don't have the ability
+to tell the customer to try mainline or other kernels, so my hands are
+somewhat tied to what I can do.
+
+But according to a core dump, I tracked down that the eth irq thread
+crashed in bond_handle_frame() here:
+
+        slave = bond_slave_get_rcu(skb->dev);
+        bond = slave->bond; <--- BUG
+
+the slave returned was NULL and accessing slave->bond caused a NULL
+pointer dereference.
+
+Looking at the code that unregisters the handler:
+
+void netdev_rx_handler_unregister(struct net_device *dev)
+{
+
+        ASSERT_RTNL();
+        RCU_INIT_POINTER(dev->rx_handler, NULL);
+        RCU_INIT_POINTER(dev->rx_handler_data, NULL);
+}
+
+Which is basically:
+        dev->rx_handler = NULL;
+        dev->rx_handler_data = NULL;
+
+And looking at __netif_receive_skb() we have:
+
+        rx_handler = rcu_dereference(skb->dev->rx_handler);
+        if (rx_handler) {
+                if (pt_prev) {
+                        ret = deliver_skb(skb, pt_prev, orig_dev);
+                        pt_prev = NULL;
+                }
+                switch (rx_handler(&skb)) {
+
+My question to all of you is, what stops this interrupt from happening
+while the bonding module is unloading?  What happens if the interrupt
+triggers and we have this:
+
+        CPU0                    CPU1
+        ----                    ----
+  rx_handler = skb->dev->rx_handler
+
+                        netdev_rx_handler_unregister() {
+                           dev->rx_handler = NULL;
+                           dev->rx_handler_data = NULL;
+
+  rx_handler()
+   bond_handle_frame() {
+    slave = skb->dev->rx_handler;
+    bond = slave->bond; <-- NULL pointer dereference!!!
+
+What protection am I missing in the bond release handler that would
+prevent the above from happening?
+
+</quoting Steven>
+
+We can fix bug this in two ways. First is adding a test in
+bond_handle_frame() and others to check if rx_handler_data is NULL.
+
+A second way is adding a synchronize_net() in
+netdev_rx_handler_unregister() to make sure that a rcu protected reader
+has the guarantee to see a non NULL rx_handler_data.
+
+The second way is better as it avoids an extra test in fast path.
+
+Reported-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Jiri Pirko <jpirko@redhat.com>
+Cc: Paul E. McKenney <paulmck@us.ibm.com>
+Acked-by: Steven Rostedt <rostedt@goodmis.org>
+Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3124,6 +3124,7 @@ int netdev_rx_handler_register(struct ne
+       if (dev->rx_handler)
+               return -EBUSY;
++      /* Note: rx_handler_data must be set before rx_handler */
+       rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
+       rcu_assign_pointer(dev->rx_handler, rx_handler);
+@@ -3144,6 +3145,11 @@ void netdev_rx_handler_unregister(struct
+       ASSERT_RTNL();
+       RCU_INIT_POINTER(dev->rx_handler, NULL);
++      /* a reader seeing a non NULL rx_handler in a rcu_read_lock()
++       * section has a guarantee to see a non NULL rx_handler_data
++       * as well.
++       */
++      synchronize_net();
+       RCU_INIT_POINTER(dev->rx_handler_data, NULL);
+ }
+ EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
diff --git a/queue-3.4/net-fix-_diag_max-constants.patch b/queue-3.4/net-fix-_diag_max-constants.patch
new file mode 100644 (file)
index 0000000..391bae3
--- /dev/null
@@ -0,0 +1,50 @@
+From ee27ca32bcdb0a6b104eac8131fa550f56b9a2e9 Mon Sep 17 00:00:00 2001
+From: Andrey Vagin <avagin@openvz.org>
+Date: Thu, 21 Mar 2013 20:33:46 +0400
+Subject: net: fix *_DIAG_MAX constants
+
+
+From: Andrey Vagin <avagin@openvz.org>
+
+[ Upstream commit ae5fc98728c8bbbd6d7cab0b9781671fc4419c1b ]
+
+Follow the common pattern and define *_DIAG_MAX like:
+
+        [...]
+        __XXX_DIAG_MAX,
+};
+
+Because everyone is used to do:
+
+        struct nlattr *attrs[XXX_DIAG_MAX+1];
+
+        nla_parse([...], XXX_DIAG_MAX, [...]
+
+Reported-by: Thomas Graf <tgraf@suug.ch>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Pavel Emelyanov <xemul@parallels.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Cc: David Howells <dhowells@redhat.com>
+Signed-off-by: Andrey Vagin <avagin@openvz.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/unix_diag.h |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/include/linux/unix_diag.h
++++ b/include/linux/unix_diag.h
+@@ -38,9 +38,11 @@ enum {
+       UNIX_DIAG_RQLEN,
+       UNIX_DIAG_MEMINFO,
+-      UNIX_DIAG_MAX,
++      __UNIX_DIAG_MAX,
+ };
++#define UNIX_DIAG_MAX (__UNIX_DIAG_MAX - 1)
++
+ struct unix_diag_vfs {
+       __u32   udiag_vfs_ino;
+       __u32   udiag_vfs_dev;
diff --git a/queue-3.4/net-remove-a-warn_on-in-net_enable_timestamp.patch b/queue-3.4/net-remove-a-warn_on-in-net_enable_timestamp.patch
new file mode 100644 (file)
index 0000000..77dd382
--- /dev/null
@@ -0,0 +1,55 @@
+From 177d2275235c4bef03e1c7ffd0904a859cfaa1ea Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 22 Mar 2013 14:38:28 +0000
+Subject: net: remove a WARN_ON() in net_enable_timestamp()
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9979a55a833883242e3a29f3596676edd7199c46 ]
+
+The WARN_ON(in_interrupt()) in net_enable_timestamp() can get false
+positive, in socket clone path, run from softirq context :
+
+[ 3641.624425] WARNING: at net/core/dev.c:1532 net_enable_timestamp+0x7b/0x80()
+[ 3641.668811] Call Trace:
+[ 3641.671254]  <IRQ>  [<ffffffff80286817>] warn_slowpath_common+0x87/0xc0
+[ 3641.677871]  [<ffffffff8028686a>] warn_slowpath_null+0x1a/0x20
+[ 3641.683683]  [<ffffffff80742f8b>] net_enable_timestamp+0x7b/0x80
+[ 3641.689668]  [<ffffffff80732ce5>] sk_clone_lock+0x425/0x450
+[ 3641.695222]  [<ffffffff8078db36>] inet_csk_clone_lock+0x16/0x170
+[ 3641.701213]  [<ffffffff807ae449>] tcp_create_openreq_child+0x29/0x820
+[ 3641.707663]  [<ffffffff807d62e2>] ? ipt_do_table+0x222/0x670
+[ 3641.713354]  [<ffffffff807aaf5b>] tcp_v4_syn_recv_sock+0xab/0x3d0
+[ 3641.719425]  [<ffffffff807af63a>] tcp_check_req+0x3da/0x530
+[ 3641.724979]  [<ffffffff8078b400>] ? inet_hashinfo_init+0x60/0x80
+[ 3641.730964]  [<ffffffff807ade6f>] ? tcp_v4_rcv+0x79f/0xbe0
+[ 3641.736430]  [<ffffffff807ab9bd>] tcp_v4_do_rcv+0x38d/0x4f0
+[ 3641.741985]  [<ffffffff807ae14a>] tcp_v4_rcv+0xa7a/0xbe0
+
+Its safe at this point because the parent socket owns a reference
+on the netstamp_needed, so we cant have a 0 -> 1 transition, which
+requires to lock a mutex.
+
+Instead of refining the check, lets remove it, as all known callers
+are safe. If it ever changes in the future, static_key_slow_inc()
+will complain anyway.
+
+Reported-by: Laurent Chavey <chavey@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1482,7 +1482,6 @@ void net_enable_timestamp(void)
+               return;
+       }
+ #endif
+-      WARN_ON(in_interrupt());
+       static_key_slow_inc(&netstamp_needed);
+ }
+ EXPORT_SYMBOL(net_enable_timestamp);
diff --git a/queue-3.4/pch_gbe-fix-ip_summed-checksum-reporting-on-rx.patch b/queue-3.4/pch_gbe-fix-ip_summed-checksum-reporting-on-rx.patch
new file mode 100644 (file)
index 0000000..fde53b7
--- /dev/null
@@ -0,0 +1,36 @@
+From 67423366589f4f509565b62db6787bef2a3265dc Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Mon, 25 Mar 2013 22:26:21 +0000
+Subject: pch_gbe: fix ip_summed checksum reporting on rx
+
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit 76a0e68129d7d24eb995a6871ab47081bbfa0acc ]
+
+skb->ip_summed should be CHECKSUM_UNNECESSARY when the driver reports that
+checksums were correct and CHECKSUM_NONE in any other case. They're
+currently placed vice versa, which breaks the forwarding scenario. Fix it
+by placing them as described above.
+
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
++++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+@@ -1740,9 +1740,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK)
+-                              skb->ip_summed = CHECKSUM_NONE;
+-                      else
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
++                      else
++                              skb->ip_summed = CHECKSUM_NONE;
+                       napi_gro_receive(&adapter->napi, skb);
+                       (*work_done)++;
index 5769c9e2d62c046337fe4914b2745a70781cd78e..e57d164e65a440d6db976e5ad4a16f7a0da758ba 100644 (file)
@@ -41,3 +41,28 @@ ext4-convert-number-of-blocks-to-clusters-properly.patch
 ext4-use-atomic64_t-for-the-per-flexbg-free_clusters-count.patch
 tracing-protect-tracer-flags-with-trace_types_lock.patch
 tracing-prevent-buffer-overwrite-disabled-for-latency-tracers.patch
+net-remove-a-warn_on-in-net_enable_timestamp.patch
+sky2-receive-overflows-not-counted.patch
+sky2-threshold-for-pause-packet-is-set-wrong.patch
+tcp-preserve-ack-clocking-in-tso.patch
+tcp-undo-spurious-timeout-after-sack-reneging.patch
+8021q-fix-a-potential-use-after-free.patch
+thermal-shorten-too-long-mcast-group-name.patch
+unix-fix-a-race-condition-in-unix_release.patch
+af_unix-dont-send-scm_credential-when-dest-socket-is-null.patch
+bonding-remove-already-created-master-sysfs-link-on-failure.patch
+bonding-fix-miimon-and-arp_interval-delayed-work-race-conditions.patch
+bonding-fix-disabling-of-arp_interval-and-miimon.patch
+drivers-net-ethernet-davinci_emac-use-netif_wake_queue-while-restarting-tx-queue.patch
+drivers-net-ethernet-cpsw-use-netif_wake_queue-while-restarting-tx-queue.patch
+net-fix-_diag_max-constants.patch
+aoe-reserve-enough-headroom-on-skbs.patch
+atl1e-drop-pci-msi-support-because-of-packet-corruption.patch
+dm9000b-driver-initialization-upgrade.patch
+ipv6-don-t-accept-multicast-traffic-with-scope-0.patch
+ipv6-fix-bad-free-of-addrconf_init_net.patch
+ipv6-don-t-accept-node-local-multicast-traffic-from-the-wire.patch
+ks8851-fix-interpretation-of-rxlen-field.patch
+net-add-a-synchronize_net-in-netdev_rx_handler_unregister.patch
+pch_gbe-fix-ip_summed-checksum-reporting-on-rx.patch
+smsc75xx-fix-jumbo-frame-support.patch
diff --git a/queue-3.4/sky2-receive-overflows-not-counted.patch b/queue-3.4/sky2-receive-overflows-not-counted.patch
new file mode 100644 (file)
index 0000000..39df719
--- /dev/null
@@ -0,0 +1,37 @@
+From 2fb8add73bd29045ec74fd777a1d2bc064dfa00e Mon Sep 17 00:00:00 2001
+From: Mirko Lindner <mlindner@marvell.com>
+Date: Tue, 26 Mar 2013 06:38:35 +0000
+Subject: sky2: Receive Overflows not counted
+
+
+From: Mirko Lindner <mlindner@marvell.com>
+
+[ Upstream commit 9cfe8b156c21cf340b3a10ecb3022fbbc1c39185 ]
+
+The sky2 driver doesn't count the Receive Overflows because the MAC
+interrupt for this event is not set in the MAC's interrupt mask.
+The MAC's interrupt mask is set only for Transmit FIFO Underruns.
+
+Fix: The correct setting should be (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR)
+Otherwise the Receive Overflow event will not generate any interrupt.
+The  Receive Overflow interrupt is handled correctly
+
+Signed-off-by: Mirko Lindner <mlindner@marvell.com>
+Acked-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/sky2.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/sky2.h
++++ b/drivers/net/ethernet/marvell/sky2.h
+@@ -2069,7 +2069,7 @@ enum {
+       GM_IS_RX_FF_OR  = 1<<1, /* Receive FIFO Overrun */
+       GM_IS_RX_COMPL  = 1<<0, /* Frame Reception Complete */
+-#define GMAC_DEF_MSK     GM_IS_TX_FF_UR
++#define GMAC_DEF_MSK     (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR)
+ };
+ /*    GMAC_LINK_CTRL  16 bit  GMAC Link Control Reg (YUKON only) */
diff --git a/queue-3.4/sky2-threshold-for-pause-packet-is-set-wrong.patch b/queue-3.4/sky2-threshold-for-pause-packet-is-set-wrong.patch
new file mode 100644 (file)
index 0000000..2cc63af
--- /dev/null
@@ -0,0 +1,35 @@
+From e7db70cb14f6c4cd08d79a1d9394f2727c652334 Mon Sep 17 00:00:00 2001
+From: Mirko Lindner <mlindner@marvell.com>
+Date: Tue, 26 Mar 2013 06:38:42 +0000
+Subject: sky2: Threshold for Pause Packet is set wrong
+
+
+From: Mirko Lindner <mlindner@marvell.com>
+
+[ Upstream commit 74f9f42c1c1650e74fb464f76644c9041f996851 ]
+
+The sky2 driver sets the Rx Upper Threshold for Pause Packet generation to a
+wrong value which leads to only 2kB of RAM remaining space. This can lead to
+Rx overflow errors even with activated flow-control.
+
+Fix: We should increase the value to 8192/8
+
+Signed-off-by: Mirko Lindner <mlindner@marvell.com>
+Acked-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/sky2.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -1066,7 +1066,7 @@ static void sky2_ramset(struct sky2_hw *
+               sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
+               sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
+-              tp = space - 2048/8;
++              tp = space - 8192/8;
+               sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
+               sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
+       } else {
diff --git a/queue-3.4/smsc75xx-fix-jumbo-frame-support.patch b/queue-3.4/smsc75xx-fix-jumbo-frame-support.patch
new file mode 100644 (file)
index 0000000..1594399
--- /dev/null
@@ -0,0 +1,63 @@
+From dc28bc0237c5ea44629a42ffe9efdb8e1079cd50 Mon Sep 17 00:00:00 2001
+From: Steve Glendinning <steve.glendinning@shawell.net>
+Date: Thu, 28 Mar 2013 02:34:41 +0000
+Subject: smsc75xx: fix jumbo frame support
+
+
+From: Steve Glendinning <steve.glendinning@shawell.net>
+
+[ Upstream commit 4c51e53689569398d656e631c17308d9b8e84650 ]
+
+This patch enables RX of jumbo frames for LAN7500.
+
+Previously the driver would transmit jumbo frames succesfully but
+would drop received jumbo frames (incrementing the interface errors
+count).
+
+With this patch applied the device can succesfully receive jumbo
+frames up to MTU 9000 (9014 bytes on the wire including ethernet
+header).
+
+Signed-off-by: Steve Glendinning <steve.glendinning@shawell.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/smsc75xx.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/usb/smsc75xx.c
++++ b/drivers/net/usb/smsc75xx.c
+@@ -725,8 +725,12 @@ static int smsc75xx_set_rx_max_frame_len
+ static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
+ {
+       struct usbnet *dev = netdev_priv(netdev);
++      int ret;
++
++      if (new_mtu > MAX_SINGLE_PACKET_SIZE)
++              return -EINVAL;
+-      int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
++      ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN);
+       check_warn_return(ret, "Failed to set mac rx frame length");
+       return usbnet_change_mtu(netdev, new_mtu);
+@@ -979,7 +983,7 @@ static int smsc75xx_reset(struct usbnet
+       netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
+-      ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
++      ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN);
+       check_warn_return(ret, "Failed to set max rx frame length");
+       ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+@@ -1123,8 +1127,8 @@ static int smsc75xx_rx_fixup(struct usbn
+                       else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
+                               dev->net->stats.rx_frame_errors++;
+               } else {
+-                      /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+-                      if (unlikely(size > (ETH_FRAME_LEN + 12))) {
++                      /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */
++                      if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) {
+                               netif_dbg(dev, rx_err, dev->net,
+                                       "size err rx_cmd_a=0x%08x", rx_cmd_a);
+                               return 0;
diff --git a/queue-3.4/tcp-preserve-ack-clocking-in-tso.patch b/queue-3.4/tcp-preserve-ack-clocking-in-tso.patch
new file mode 100644 (file)
index 0000000..577984a
--- /dev/null
@@ -0,0 +1,88 @@
+From e14385ba8eba252393436ad443b616c25d9d3edc Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 21 Mar 2013 17:36:09 +0000
+Subject: tcp: preserve ACK clocking in TSO
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f4541d60a449afd40448b06496dcd510f505928e ]
+
+A long standing problem with TSO is the fact that tcp_tso_should_defer()
+rearms the deferred timer, while it should not.
+
+Current code leads to following bad bursty behavior :
+
+20:11:24.484333 IP A > B: . 297161:316921(19760) ack 1 win 119
+20:11:24.484337 IP B > A: . ack 263721 win 1117
+20:11:24.485086 IP B > A: . ack 265241 win 1117
+20:11:24.485925 IP B > A: . ack 266761 win 1117
+20:11:24.486759 IP B > A: . ack 268281 win 1117
+20:11:24.487594 IP B > A: . ack 269801 win 1117
+20:11:24.488430 IP B > A: . ack 271321 win 1117
+20:11:24.489267 IP B > A: . ack 272841 win 1117
+20:11:24.490104 IP B > A: . ack 274361 win 1117
+20:11:24.490939 IP B > A: . ack 275881 win 1117
+20:11:24.491775 IP B > A: . ack 277401 win 1117
+20:11:24.491784 IP A > B: . 316921:332881(15960) ack 1 win 119
+20:11:24.492620 IP B > A: . ack 278921 win 1117
+20:11:24.493448 IP B > A: . ack 280441 win 1117
+20:11:24.494286 IP B > A: . ack 281961 win 1117
+20:11:24.495122 IP B > A: . ack 283481 win 1117
+20:11:24.495958 IP B > A: . ack 285001 win 1117
+20:11:24.496791 IP B > A: . ack 286521 win 1117
+20:11:24.497628 IP B > A: . ack 288041 win 1117
+20:11:24.498459 IP B > A: . ack 289561 win 1117
+20:11:24.499296 IP B > A: . ack 291081 win 1117
+20:11:24.500133 IP B > A: . ack 292601 win 1117
+20:11:24.500970 IP B > A: . ack 294121 win 1117
+20:11:24.501388 IP B > A: . ack 295641 win 1117
+20:11:24.501398 IP A > B: . 332881:351881(19000) ack 1 win 119
+
+While the expected behavior is more like :
+
+20:19:49.259620 IP A > B: . 197601:202161(4560) ack 1 win 119
+20:19:49.260446 IP B > A: . ack 154281 win 1212
+20:19:49.261282 IP B > A: . ack 155801 win 1212
+20:19:49.262125 IP B > A: . ack 157321 win 1212
+20:19:49.262136 IP A > B: . 202161:206721(4560) ack 1 win 119
+20:19:49.262958 IP B > A: . ack 158841 win 1212
+20:19:49.263795 IP B > A: . ack 160361 win 1212
+20:19:49.264628 IP B > A: . ack 161881 win 1212
+20:19:49.264637 IP A > B: . 206721:211281(4560) ack 1 win 119
+20:19:49.265465 IP B > A: . ack 163401 win 1212
+20:19:49.265886 IP B > A: . ack 164921 win 1212
+20:19:49.266722 IP B > A: . ack 166441 win 1212
+20:19:49.266732 IP A > B: . 211281:215841(4560) ack 1 win 119
+20:19:49.267559 IP B > A: . ack 167961 win 1212
+20:19:49.268394 IP B > A: . ack 169481 win 1212
+20:19:49.269232 IP B > A: . ack 171001 win 1212
+20:19:49.269241 IP A > B: . 215841:221161(5320) ack 1 win 119
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Yuchung Cheng <ycheng@google.com>
+Cc: Van Jacobson <vanj@google.com>
+Cc: Neal Cardwell <ncardwell@google.com>
+Cc: Nandita Dukkipati <nanditad@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_output.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -1587,8 +1587,11 @@ static int tcp_tso_should_defer(struct s
+                       goto send_now;
+       }
+-      /* Ok, it looks like it is advisable to defer.  */
+-      tp->tso_deferred = 1 | (jiffies << 1);
++      /* Ok, it looks like it is advisable to defer.
++       * Do not rearm the timer if already set to not break TCP ACK clocking.
++       */
++      if (!tp->tso_deferred)
++              tp->tso_deferred = 1 | (jiffies << 1);
+       return 1;
diff --git a/queue-3.4/tcp-undo-spurious-timeout-after-sack-reneging.patch b/queue-3.4/tcp-undo-spurious-timeout-after-sack-reneging.patch
new file mode 100644 (file)
index 0000000..5885a44
--- /dev/null
@@ -0,0 +1,40 @@
+From de5b85d1ca7ac5b79f9274fe6c4a3ed5767feaf5 Mon Sep 17 00:00:00 2001
+From: Yuchung Cheng <ycheng@google.com>
+Date: Sun, 24 Mar 2013 10:42:25 +0000
+Subject: tcp: undo spurious timeout after SACK reneging
+
+
+From: Yuchung Cheng <ycheng@google.com>
+
+[ Upstream commit 7ebe183c6d444ef5587d803b64a1f4734b18c564 ]
+
+On SACK reneging the sender immediately retransmits and forces a
+timeout but disables Eifel (undo). If the (buggy) receiver does not
+drop any packet this can trigger a false slow-start retransmit storm
+driven by the ACKs of the original packets. This can be detected with
+undo and TCP timestamps.
+
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_input.c |    7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2260,11 +2260,8 @@ void tcp_enter_loss(struct sock *sk, int
+       if (tcp_is_reno(tp))
+               tcp_reset_reno_sack(tp);
+-      if (!how) {
+-              /* Push undo marker, if it was plain RTO and nothing
+-               * was retransmitted. */
+-              tp->undo_marker = tp->snd_una;
+-      } else {
++      tp->undo_marker = tp->snd_una;
++      if (how) {
+               tp->sacked_out = 0;
+               tp->fackets_out = 0;
+       }
diff --git a/queue-3.4/thermal-shorten-too-long-mcast-group-name.patch b/queue-3.4/thermal-shorten-too-long-mcast-group-name.patch
new file mode 100644 (file)
index 0000000..e951585
--- /dev/null
@@ -0,0 +1,44 @@
+From 9c1f66cd90250ecca89a66f07f09cc065d52dccc Mon Sep 17 00:00:00 2001
+From: Masatake YAMATO <yamato@redhat.com>
+Date: Mon, 1 Apr 2013 14:50:40 -0400
+Subject: thermal: shorten too long mcast group name
+
+
+From: Masatake YAMATO <yamato@redhat.com>
+
+[ Upstream commits 73214f5d9f33b79918b1f7babddd5c8af28dd23d
+  and f1e79e208076ffe7bad97158275f1c572c04f5c7, the latter
+  adds an assertion to genetlink to prevent this from happening
+  again in the future. ]
+
+The original name is too long.
+
+Signed-off-by: Masatake YAMATO <yamato@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/thermal.h |    2 +-
+ net/netlink/genetlink.c |    1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -108,7 +108,7 @@ struct thermal_zone_device {
+ /* Adding event notification support elements */
+ #define THERMAL_GENL_FAMILY_NAME                "thermal_event"
+ #define THERMAL_GENL_VERSION                    0x01
+-#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
++#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_grp"
+ enum events {
+       THERMAL_AUX0,
+--- a/net/netlink/genetlink.c
++++ b/net/netlink/genetlink.c
+@@ -142,6 +142,7 @@ int genl_register_mc_group(struct genl_f
+       int err = 0;
+       BUG_ON(grp->name[0] == '\0');
++      BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL);
+       genl_lock();
diff --git a/queue-3.4/unix-fix-a-race-condition-in-unix_release.patch b/queue-3.4/unix-fix-a-race-condition-in-unix_release.patch
new file mode 100644 (file)
index 0000000..e892f8e
--- /dev/null
@@ -0,0 +1,66 @@
+From fe05c83620e4b667c0f12d6d2cc2882b84d53376 Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Mon, 25 Mar 2013 03:18:33 +0000
+Subject: unix: fix a race condition in unix_release()
+
+
+From: Paul Moore <pmoore@redhat.com>
+
+[ Upstream commit ded34e0fe8fe8c2d595bfa30626654e4b87621e0 ]
+
+As reported by Jan, and others over the past few years, there is a
+race condition caused by unix_release setting the sock->sk pointer
+to NULL before properly marking the socket as dead/orphaned.  This
+can cause a problem with the LSM hook security_unix_may_send() if
+there is another socket attempting to write to this partially
+released socket in between when sock->sk is set to NULL and it is
+marked as dead/orphaned.  This patch fixes this by only setting
+sock->sk to NULL after the socket has been marked as dead; I also
+take the opportunity to make unix_release_sock() a void function
+as it only ever returned 0/success.
+
+Dave, I think this one should go on the -stable pile.
+
+Special thanks to Jan for coming up with a reproducer for this
+problem.
+
+Reported-by: Jan Stancek <jan.stancek@gmail.com>
+Signed-off-by: Paul Moore <pmoore@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/unix/af_unix.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -374,7 +374,7 @@ static void unix_sock_destructor(struct
+ #endif
+ }
+-static int unix_release_sock(struct sock *sk, int embrion)
++static void unix_release_sock(struct sock *sk, int embrion)
+ {
+       struct unix_sock *u = unix_sk(sk);
+       struct path path;
+@@ -443,8 +443,6 @@ static int unix_release_sock(struct sock
+       if (unix_tot_inflight)
+               unix_gc();              /* Garbage collect fds */
+-
+-      return 0;
+ }
+ static void init_peercred(struct sock *sk)
+@@ -694,9 +692,10 @@ static int unix_release(struct socket *s
+       if (!sk)
+               return 0;
++      unix_release_sock(sk, 0);
+       sock->sk = NULL;
+-      return unix_release_sock(sk, 0);
++      return 0;
+ }
+ static int unix_autobind(struct socket *sock)