]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.13-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Mar 2014 23:51:12 +0000 (16:51 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 31 Mar 2014 23:51:12 +0000 (16:51 -0700)
added patches:
net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch
net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch
random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch
resizable-namespace.c-hashes.patch

queue-3.13/net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch [new file with mode: 0644]
queue-3.13/net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch [new file with mode: 0644]
queue-3.13/random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch [new file with mode: 0644]
queue-3.13/resizable-namespace.c-hashes.patch [new file with mode: 0644]
queue-3.13/series

diff --git a/queue-3.13/net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch b/queue-3.13/net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch
new file mode 100644 (file)
index 0000000..4fc9d31
--- /dev/null
@@ -0,0 +1,132 @@
+From e3a8786c10e75903f1269474e21fe8cb49c3a670 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 26 Mar 2014 00:25:42 +0100
+Subject: net: mvneta: fix usage as a module on RGMII configurations
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit e3a8786c10e75903f1269474e21fe8cb49c3a670 upstream.
+
+Commit 5445eaf309ff ('mvneta: Try to fix mvneta when compiled as
+module') fixed the mvneta driver to make it work properly when loaded
+as a module in SGMII configuration, which was tested successful by the
+author on the Armada XP OpenBlocks AX3, which uses SGMII.
+
+However, it turns out that the Armada XP GP, which uses RGMII, is
+affected by a similar problem: its SERDES configuration is lost when
+mvneta is loaded as a module, because this configuration is set by the
+bootloader, and then lost because the clock is gated by the clock
+framework until the mvneta driver is loaded again and the clock is
+re-enabled.
+
+However, it turns out that for the RGMII case, setting the SERDES
+configuration is not sufficient: the PCS enable bit in the
+MVNETA_GMAC_CTRL_2 register must also be set, like in the SGMII
+configuration.
+
+Therefore, this commit reworks the SGMII/RGMII initialization: the
+only difference between the two now is a different SERDES
+configuration, all the rest is identical.
+
+In detail, to achieve this, the commit:
+
+ * Renames MVNETA_SGMII_SERDES_CFG to MVNETA_SERDES_CFG because it is
+   not specific to SGMII, but also used on RGMII configurations.
+
+ * Adds a MVNETA_RGMII_SERDES_PROTO definition, that must be used as
+   the MVNETA_SERDES_CFG value in RGMII configurations.
+
+ * Removes the mvneta_gmac_rgmii_set() and mvneta_port_sgmii_config()
+   functions, and instead directly do the SGMII/RGMII configuration in
+   mvneta_port_up(), from where those functions where called. It is
+   worth mentioning that mvneta_gmac_rgmii_set() had an 'enable'
+   parameter that was always passed as '1', so it was pretty useless.
+
+ * Reworks the mvneta_port_up() function to set the MVNETA_SERDES_CFG
+   register to the appropriate value depending on the RGMII vs. SGMII
+   configuration. It also unconditionally set the PCS_ENABLE bit (was
+   already done for SGMII, but is now also needed for RGMII), and sets
+   the PORT_RGMII bit (which was already done for both SGMII and
+   RGMII).
+
+This commit was successfully tested with mvneta compiled as a module,
+on both the OpenBlocks AX3 (SGMII configuration) and the Armada XP GP
+(RGMII configuration).
+
+Reported-by: Steve McIntyre <steve@einval.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/marvell/mvneta.c |   41 ++++++----------------------------
+ 1 file changed, 8 insertions(+), 33 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -88,8 +88,9 @@
+ #define      MVNETA_TX_IN_PRGRS                  BIT(1)
+ #define      MVNETA_TX_FIFO_EMPTY                BIT(8)
+ #define MVNETA_RX_MIN_FRAME_SIZE                 0x247c
+-#define MVNETA_SGMII_SERDES_CFG                        0x24A0
++#define MVNETA_SERDES_CFG                      0x24A0
+ #define      MVNETA_SGMII_SERDES_PROTO                 0x0cc7
++#define      MVNETA_RGMII_SERDES_PROTO                 0x0667
+ #define MVNETA_TYPE_PRIO                         0x24bc
+ #define      MVNETA_FORCE_UNI                    BIT(21)
+ #define MVNETA_TXQ_CMD_1                         0x24e4
+@@ -706,35 +707,6 @@ static void mvneta_rxq_bm_disable(struct
+       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
+ }
+-
+-
+-/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */
+-static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable)
+-{
+-      u32  val;
+-
+-      val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+-
+-      if (enable)
+-              val |= MVNETA_GMAC2_PORT_RGMII;
+-      else
+-              val &= ~MVNETA_GMAC2_PORT_RGMII;
+-
+-      mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+-}
+-
+-/* Config SGMII port */
+-static void mvneta_port_sgmii_config(struct mvneta_port *pp)
+-{
+-      u32 val;
+-
+-      val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+-      val |= MVNETA_GMAC2_PCS_ENABLE;
+-      mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+-
+-      mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
+-}
+-
+ /* Start the Ethernet port RX and TX activity */
+ static void mvneta_port_up(struct mvneta_port *pp)
+ {
+@@ -2729,12 +2701,15 @@ static void mvneta_port_power_up(struct
+       mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
+       if (phy_mode == PHY_INTERFACE_MODE_SGMII)
+-              mvneta_port_sgmii_config(pp);
++              mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
++      else
++              mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_RGMII_SERDES_PROTO);
+-      mvneta_gmac_rgmii_set(pp, 1);
++      val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
++
++      val |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;
+       /* Cancel Port Reset */
+-      val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+       val &= ~MVNETA_GMAC2_PORT_RESET;
+       mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
diff --git a/queue-3.13/net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch b/queue-3.13/net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch
new file mode 100644 (file)
index 0000000..a5261dd
--- /dev/null
@@ -0,0 +1,41 @@
+From a79121d3b57e7ad61f0b5d23eae05214054f3ccd Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Date: Wed, 26 Mar 2014 00:25:41 +0100
+Subject: net: mvneta: rename MVNETA_GMAC2_PSC_ENABLE to MVNETA_GMAC2_PCS_ENABLE
+
+From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+commit a79121d3b57e7ad61f0b5d23eae05214054f3ccd upstream.
+
+Bit 3 of the MVNETA_GMAC_CTRL_2 is actually used to enable the PCS,
+not the PSC: there was a typo in the name of the define, which this
+commit fixes.
+
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/marvell/mvneta.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -161,7 +161,7 @@
+ #define      MVNETA_GMAC_MAX_RX_SIZE_MASK        0x7ffc
+ #define      MVNETA_GMAC0_PORT_ENABLE            BIT(0)
+ #define MVNETA_GMAC_CTRL_2                       0x2c08
+-#define      MVNETA_GMAC2_PSC_ENABLE             BIT(3)
++#define      MVNETA_GMAC2_PCS_ENABLE             BIT(3)
+ #define      MVNETA_GMAC2_PORT_RGMII             BIT(4)
+ #define      MVNETA_GMAC2_PORT_RESET             BIT(6)
+ #define MVNETA_GMAC_STATUS                       0x2c10
+@@ -729,7 +729,7 @@ static void mvneta_port_sgmii_config(str
+       u32 val;
+       val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
+-      val |= MVNETA_GMAC2_PSC_ENABLE;
++      val |= MVNETA_GMAC2_PCS_ENABLE;
+       mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
+       mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
diff --git a/queue-3.13/random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch b/queue-3.13/random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch
new file mode 100644 (file)
index 0000000..483fa28
--- /dev/null
@@ -0,0 +1,55 @@
+From 05efa8c943b1d5d90fa8c8147571837573338bb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sasha.levin@oracle.com>
+Date: Fri, 28 Mar 2014 17:38:42 +0100
+Subject: random32: avoid attempt to late reseed if in the middle of seeding
+
+From: Sasha Levin <sasha.levin@oracle.com>
+
+commit 05efa8c943b1d5d90fa8c8147571837573338bb6 upstream.
+
+Commit 4af712e8df ("random32: add prandom_reseed_late() and call when
+nonblocking pool becomes initialized") has added a late reseed stage
+that happens as soon as the nonblocking pool is marked as initialized.
+
+This fails in the case that the nonblocking pool gets initialized
+during __prandom_reseed()'s call to get_random_bytes(). In that case
+we'd double back into __prandom_reseed() in an attempt to do a late
+reseed - deadlocking on 'lock' early on in the boot process.
+
+Instead, just avoid even waiting to do a reseed if a reseed is already
+occuring.
+
+Fixes: 4af712e8df99 ("random32: add prandom_reseed_late() and call when nonblocking pool becomes initialized")
+Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/random32.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/lib/random32.c
++++ b/lib/random32.c
+@@ -244,8 +244,19 @@ static void __prandom_reseed(bool late)
+       static bool latch = false;
+       static DEFINE_SPINLOCK(lock);
++      /* Asking for random bytes might result in bytes getting
++       * moved into the nonblocking pool and thus marking it
++       * as initialized. In this case we would double back into
++       * this function and attempt to do a late reseed.
++       * Ignore the pointless attempt to reseed again if we're
++       * already waiting for bytes when the nonblocking pool
++       * got initialized.
++       */
++
+       /* only allow initial seeding (late == false) once */
+-      spin_lock_irqsave(&lock, flags);
++      if (!spin_trylock_irqsave(&lock, flags))
++              return;
++
+       if (latch && !late)
+               goto out;
+       latch = true;
diff --git a/queue-3.13/resizable-namespace.c-hashes.patch b/queue-3.13/resizable-namespace.c-hashes.patch
new file mode 100644 (file)
index 0000000..4382685
--- /dev/null
@@ -0,0 +1,206 @@
+From 0818bf27c05b2de56c5b2bd08cfae2a939bd5f52 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Fri, 28 Feb 2014 13:46:44 -0500
+Subject: resizable namespace.c hashes
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 0818bf27c05b2de56c5b2bd08cfae2a939bd5f52 upstream.
+
+* switch allocation to alloc_large_system_hash()
+* make sizes overridable by boot parameters (mhash_entries=, mphash_entries=)
+* switch mountpoint_hashtable from list_head to hlist_head
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/mount.h     |    2 -
+ fs/namespace.c |   81 ++++++++++++++++++++++++++++++++++++++++-----------------
+ 2 files changed, 59 insertions(+), 24 deletions(-)
+
+--- a/fs/mount.h
++++ b/fs/mount.h
+@@ -19,7 +19,7 @@ struct mnt_pcp {
+ };
+ struct mountpoint {
+-      struct list_head m_hash;
++      struct hlist_node m_hash;
+       struct dentry *m_dentry;
+       int m_count;
+ };
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -23,11 +23,34 @@
+ #include <linux/uaccess.h>
+ #include <linux/proc_ns.h>
+ #include <linux/magic.h>
++#include <linux/bootmem.h>
+ #include "pnode.h"
+ #include "internal.h"
+-#define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head))
+-#define HASH_SIZE (1UL << HASH_SHIFT)
++static unsigned int m_hash_mask __read_mostly;
++static unsigned int m_hash_shift __read_mostly;
++static unsigned int mp_hash_mask __read_mostly;
++static unsigned int mp_hash_shift __read_mostly;
++
++static __initdata unsigned long mhash_entries;
++static int __init set_mhash_entries(char *str)
++{
++      if (!str)
++              return 0;
++      mhash_entries = simple_strtoul(str, &str, 0);
++      return 1;
++}
++__setup("mhash_entries=", set_mhash_entries);
++
++static __initdata unsigned long mphash_entries;
++static int __init set_mphash_entries(char *str)
++{
++      if (!str)
++              return 0;
++      mphash_entries = simple_strtoul(str, &str, 0);
++      return 1;
++}
++__setup("mphash_entries=", set_mphash_entries);
+ static int event;
+ static DEFINE_IDA(mnt_id_ida);
+@@ -37,7 +60,7 @@ static int mnt_id_start = 0;
+ static int mnt_group_start = 1;
+ static struct list_head *mount_hashtable __read_mostly;
+-static struct list_head *mountpoint_hashtable __read_mostly;
++static struct hlist_head *mountpoint_hashtable __read_mostly;
+ static struct kmem_cache *mnt_cache __read_mostly;
+ static DECLARE_RWSEM(namespace_sem);
+@@ -55,12 +78,19 @@ EXPORT_SYMBOL_GPL(fs_kobj);
+  */
+ __cacheline_aligned_in_smp DEFINE_SEQLOCK(mount_lock);
+-static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
++static inline struct list_head *m_hash(struct vfsmount *mnt, struct dentry *dentry)
+ {
+       unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
+       tmp += ((unsigned long)dentry / L1_CACHE_BYTES);
+-      tmp = tmp + (tmp >> HASH_SHIFT);
+-      return tmp & (HASH_SIZE - 1);
++      tmp = tmp + (tmp >> m_hash_shift);
++      return &mount_hashtable[tmp & m_hash_mask];
++}
++
++static inline struct hlist_head *mp_hash(struct dentry *dentry)
++{
++      unsigned long tmp = ((unsigned long)dentry / L1_CACHE_BYTES);
++      tmp = tmp + (tmp >> mp_hash_shift);
++      return &mountpoint_hashtable[tmp & mp_hash_mask];
+ }
+ /*
+@@ -575,7 +605,7 @@ bool legitimize_mnt(struct vfsmount *bas
+  */
+ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
+ {
+-      struct list_head *head = mount_hashtable + hash(mnt, dentry);
++      struct list_head *head = m_hash(mnt, dentry);
+       struct mount *p;
+       list_for_each_entry_rcu(p, head, mnt_hash)
+@@ -590,7 +620,7 @@ struct mount *__lookup_mnt(struct vfsmou
+  */
+ struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
+ {
+-      struct list_head *head = mount_hashtable + hash(mnt, dentry);
++      struct list_head *head = m_hash(mnt, dentry);
+       struct mount *p;
+       list_for_each_entry_reverse(p, head, mnt_hash)
+@@ -633,11 +663,11 @@ struct vfsmount *lookup_mnt(struct path
+ static struct mountpoint *new_mountpoint(struct dentry *dentry)
+ {
+-      struct list_head *chain = mountpoint_hashtable + hash(NULL, dentry);
++      struct hlist_head *chain = mp_hash(dentry);
+       struct mountpoint *mp;
+       int ret;
+-      list_for_each_entry(mp, chain, m_hash) {
++      hlist_for_each_entry(mp, chain, m_hash) {
+               if (mp->m_dentry == dentry) {
+                       /* might be worth a WARN_ON() */
+                       if (d_unlinked(dentry))
+@@ -659,7 +689,7 @@ static struct mountpoint *new_mountpoint
+       mp->m_dentry = dentry;
+       mp->m_count = 1;
+-      list_add(&mp->m_hash, chain);
++      hlist_add_head(&mp->m_hash, chain);
+       return mp;
+ }
+@@ -670,7 +700,7 @@ static void put_mountpoint(struct mountp
+               spin_lock(&dentry->d_lock);
+               dentry->d_flags &= ~DCACHE_MOUNTED;
+               spin_unlock(&dentry->d_lock);
+-              list_del(&mp->m_hash);
++              hlist_del(&mp->m_hash);
+               kfree(mp);
+       }
+ }
+@@ -739,8 +769,7 @@ static void attach_mnt(struct mount *mnt
+                       struct mountpoint *mp)
+ {
+       mnt_set_mountpoint(parent, mp, mnt);
+-      list_add_tail(&mnt->mnt_hash, mount_hashtable +
+-                      hash(&parent->mnt, mp->m_dentry));
++      list_add_tail(&mnt->mnt_hash, m_hash(&parent->mnt, mp->m_dentry));
+       list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
+ }
+@@ -762,8 +791,8 @@ static void commit_tree(struct mount *mn
+       list_splice(&head, n->list.prev);
+-      list_add_tail(&mnt->mnt_hash, mount_hashtable +
+-                              hash(&parent->mnt, mnt->mnt_mountpoint));
++      list_add_tail(&mnt->mnt_hash,
++                              m_hash(&parent->mnt, mnt->mnt_mountpoint));
+       list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
+       touch_mnt_namespace(n);
+ }
+@@ -2777,18 +2806,24 @@ void __init mnt_init(void)
+       mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct mount),
+                       0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
+-      mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
+-      mountpoint_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
++      mount_hashtable = alloc_large_system_hash("Mount-cache",
++                              sizeof(struct list_head),
++                              mhash_entries, 19,
++                              0,
++                              &m_hash_shift, &m_hash_mask, 0, 0);
++      mountpoint_hashtable = alloc_large_system_hash("Mountpoint-cache",
++                              sizeof(struct hlist_head),
++                              mphash_entries, 19,
++                              0,
++                              &mp_hash_shift, &mp_hash_mask, 0, 0);
+       if (!mount_hashtable || !mountpoint_hashtable)
+               panic("Failed to allocate mount hash table\n");
+-      printk(KERN_INFO "Mount-cache hash table entries: %lu\n", HASH_SIZE);
+-
+-      for (u = 0; u < HASH_SIZE; u++)
++      for (u = 0; u <= m_hash_mask; u++)
+               INIT_LIST_HEAD(&mount_hashtable[u]);
+-      for (u = 0; u < HASH_SIZE; u++)
+-              INIT_LIST_HEAD(&mountpoint_hashtable[u]);
++      for (u = 0; u <= mp_hash_mask; u++)
++              INIT_HLIST_HEAD(&mountpoint_hashtable[u]);
+       err = sysfs_init();
+       if (err)
index 7084f34871fcc9bf37211966eb9b4616e18911da..bfcda6e6cada379b8b35be0e4906e520dfd82e6c 100644 (file)
@@ -10,3 +10,7 @@ i2c-cpm-fix-build-by-adding-of_address.h-and-of_irq.h.patch
 drm-i915-undo-gtt-scratch-pte-unmapping-again.patch
 x86-fix-boot-on-uniprocessor-systems.patch
 make-prepend_name-work-correctly-when-called-with-negative-buflen.patch
+net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch
+net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch
+random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch
+resizable-namespace.c-hashes.patch