From: Greg Kroah-Hartman Date: Mon, 31 Mar 2014 23:51:12 +0000 (-0700) Subject: 3.13-stable patches X-Git-Tag: v3.4.86~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f4a33430f2dddf52d4efc62573a6c9620264fb61;p=thirdparty%2Fkernel%2Fstable-queue.git 3.13-stable patches 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 --- 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 index 00000000000..4fc9d31c820 --- /dev/null +++ b/queue-3.13/net-mvneta-fix-usage-as-a-module-on-rgmii-configurations.patch @@ -0,0 +1,132 @@ +From e3a8786c10e75903f1269474e21fe8cb49c3a670 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Wed, 26 Mar 2014 00:25:42 +0100 +Subject: net: mvneta: fix usage as a module on RGMII configurations + +From: Thomas Petazzoni + +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 +Signed-off-by: Thomas Petazzoni +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a5261dd1598 --- /dev/null +++ b/queue-3.13/net-mvneta-rename-mvneta_gmac2_psc_enable-to-mvneta_gmac2_pcs_enable.patch @@ -0,0 +1,41 @@ +From a79121d3b57e7ad61f0b5d23eae05214054f3ccd Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +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 + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..483fa2887f6 --- /dev/null +++ b/queue-3.13/random32-avoid-attempt-to-late-reseed-if-in-the-middle-of-seeding.patch @@ -0,0 +1,55 @@ +From 05efa8c943b1d5d90fa8c8147571837573338bb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +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 +Acked-by: Hannes Frederic Sowa +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4382685ab46 --- /dev/null +++ b/queue-3.13/resizable-namespace.c-hashes.patch @@ -0,0 +1,206 @@ +From 0818bf27c05b2de56c5b2bd08cfae2a939bd5f52 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 28 Feb 2014 13:46:44 -0500 +Subject: resizable namespace.c hashes + +From: Al Viro + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #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) diff --git a/queue-3.13/series b/queue-3.13/series index 7084f34871f..bfcda6e6cad 100644 --- a/queue-3.13/series +++ b/queue-3.13/series @@ -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