--- /dev/null
+From 38958c15dc640a9249e4f0cd0dfb0ddc7a23464d Mon Sep 17 00:00:00 2001
+From: Rajendra Nayak <rnayak@ti.com>
+Date: Thu, 12 Dec 2013 15:22:49 +0530
+Subject: ARM: DRA7: hwmod: Fix boot crash with DEBUG_LL
+
+From: Rajendra Nayak <rnayak@ti.com>
+
+commit 38958c15dc640a9249e4f0cd0dfb0ddc7a23464d upstream.
+
+With commit '7dedd34: ARM: OMAP2+: hwmod: Fix a crash in _setup_reset() with
+ DEBUG_LL' we moved from parsing cmdline to identify uart used for earlycon
+to using the requsite hwmod CONFIG_DEBUG_OMAPxUARTy FLAGS.
+
+On DRA7 though, we seem to be missing this flag, and atleast on the DRA7 EVM
+where we use uart1 for console, boot fails with DEBUG_LL enabled.
+
+Reported-by: Lokesh Vutla <lokeshvutla@ti.com>
+Tested-by: Lokesh Vutla <lokeshvutla@ti.com> # on a different base
+Signed-off-by: Rajendra Nayak <rnayak@ti.com>
+Fixes: 7dedd346941d ("ARM: OMAP2+: hwmod: Fix a crash in _setup_reset() with DEBUG_LL")
+Signed-off-by: Paul Walmsley <paul@pwsan.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
++++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+@@ -1637,7 +1637,7 @@ static struct omap_hwmod dra7xx_uart1_hw
+ .class = &dra7xx_uart_hwmod_class,
+ .clkdm_name = "l4per_clkdm",
+ .main_clk = "uart1_gfclk_mux",
+- .flags = HWMOD_SWSUP_SIDLE_ACT,
++ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP2UART1_FLAGS,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DRA7XX_CM_L4PER_UART1_CLKCTRL_OFFSET,
--- /dev/null
+From 7e367c18c059c638bf6fb540f1decec18d64cb55 Mon Sep 17 00:00:00 2001
+From: Tony Lindgren <tony@atomide.com>
+Date: Fri, 27 Dec 2013 09:33:27 -0800
+Subject: ARM: OMAP2+: Fix LCD panel backlight regression for LDP legacy booting
+
+From: Tony Lindgren <tony@atomide.com>
+
+commit 7e367c18c059c638bf6fb540f1decec18d64cb55 upstream.
+
+Looks like the LCD panel on LDP has been broken quite a while, and
+recently got fixed by commit 0b2aa8bed3e1 (gpio: twl4030: Fix regression
+for twl gpio output). However, there's still an issue left where the panel
+backlight does not come on if the LCD drivers are built into the
+kernel.
+
+Fix the issue by registering the DPI LCD panel only after the twl4030
+GPIO has probed.
+
+Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+[tony@atomide.com: updated per Tomi's comments]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/board-ldp.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/mach-omap2/board-ldp.c
++++ b/arch/arm/mach-omap2/board-ldp.c
+@@ -243,12 +243,18 @@ static void __init ldp_display_init(void
+
+ static int ldp_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio)
+ {
++ int res;
++
+ /* LCD enable GPIO */
+ ldp_lcd_pdata.enable_gpio = gpio + 7;
+
+ /* Backlight enable GPIO */
+ ldp_lcd_pdata.backlight_gpio = gpio + 15;
+
++ res = platform_device_register(&ldp_lcd_device);
++ if (res)
++ pr_err("Unable to register LCD: %d\n", res);
++
+ return 0;
+ }
+
+@@ -347,7 +353,6 @@ static struct omap2_hsmmc_info mmc[] __i
+
+ static struct platform_device *ldp_devices[] __initdata = {
+ &ldp_gpio_keys_device,
+- &ldp_lcd_device,
+ };
+
+ #ifdef CONFIG_OMAP_MUX
--- /dev/null
+From 6d4c88304794442055eaea1c07f3c7b988b8c924 Mon Sep 17 00:00:00 2001
+From: Suman Anna <s-anna@ti.com>
+Date: Mon, 23 Dec 2013 16:53:11 -0600
+Subject: ARM: OMAP2+: hwmod_data: fix missing OMAP_INTC_START in irq data
+
+From: Suman Anna <s-anna@ti.com>
+
+commit 6d4c88304794442055eaea1c07f3c7b988b8c924 upstream.
+
+Commit 7d7e1eb (ARM: OMAP2+: Prepare for irqs.h removal) and commit
+ec2c082 (ARM: OMAP2+: Remove hardcoded IRQs and enable SPARSE_IRQ)
+updated the way interrupts for OMAP2/3 devices are defined in the
+HWMOD data structures to being an index plus a fixed offset (defined
+by OMAP_INTC_START).
+
+Couple of irqs in the OMAP2/3 hwmod data were misconfigured completely
+as they were missing this OMAP_INTC_START relative offset. Add this
+offset back to fix the incorrect irq data for the following modules:
+ OMAP2 - GPMC, RNG
+ OMAP3 - GPMC, ISP MMU & IVA MMU
+
+Signed-off-by: Suman Anna <s-anna@ti.com>
+Fixes: 7d7e1eba7e92 ("ARM: OMAP2+: Prepare for irqs.h removal")
+Fixes: ec2c0825ca31 ("ARM: OMAP2+: Remove hardcoded IRQs and enable SPARSE_IRQ")
+Cc: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Paul Walmsley <paul@pwsan.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 4 ++--
+ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
++++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+@@ -796,7 +796,7 @@ struct omap_hwmod omap2xxx_counter_32k_h
+
+ /* gpmc */
+ static struct omap_hwmod_irq_info omap2xxx_gpmc_irqs[] = {
+- { .irq = 20 },
++ { .irq = 20 + OMAP_INTC_START, },
+ { .irq = -1 }
+ };
+
+@@ -841,7 +841,7 @@ static struct omap_hwmod_class omap2_rng
+ };
+
+ static struct omap_hwmod_irq_info omap2_rng_mpu_irqs[] = {
+- { .irq = 52 },
++ { .irq = 52 + OMAP_INTC_START, },
+ { .irq = -1 }
+ };
+
+--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
++++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+@@ -2165,7 +2165,7 @@ static struct omap_hwmod_class omap3xxx_
+ };
+
+ static struct omap_hwmod_irq_info omap3xxx_gpmc_irqs[] = {
+- { .irq = 20 },
++ { .irq = 20 + OMAP_INTC_START, },
+ { .irq = -1 }
+ };
+
+@@ -2999,7 +2999,7 @@ static struct omap_mmu_dev_attr mmu_isp_
+
+ static struct omap_hwmod omap3xxx_mmu_isp_hwmod;
+ static struct omap_hwmod_irq_info omap3xxx_mmu_isp_irqs[] = {
+- { .irq = 24 },
++ { .irq = 24 + OMAP_INTC_START, },
+ { .irq = -1 }
+ };
+
+@@ -3041,7 +3041,7 @@ static struct omap_mmu_dev_attr mmu_iva_
+
+ static struct omap_hwmod omap3xxx_mmu_iva_hwmod;
+ static struct omap_hwmod_irq_info omap3xxx_mmu_iva_irqs[] = {
+- { .irq = 28 },
++ { .irq = 28 + OMAP_INTC_START, },
+ { .irq = -1 }
+ };
+
--- /dev/null
+From d721a15c300c5f638a11573a6dd492158e737d6a Mon Sep 17 00:00:00 2001
+From: Ben Dooks <ben.dooks@codethink.co.uk>
+Date: Mon, 16 Dec 2013 12:38:48 +0000
+Subject: ARM: shmobile: r8a7790: fix shdi resource sizes
+
+From: Ben Dooks <ben.dooks@codethink.co.uk>
+
+commit d721a15c300c5f638a11573a6dd492158e737d6a upstream.
+
+The r8a7790.dtsi file has four sdhi nodes which the first two have the wrong
+resource size for their register block. This causes the sh_modbile_sdhi driver
+to fail to communicate with card at-all.
+
+Change sdhi{0,1} node size from 0x100 to 0x200 to correct these nodes
+as per Kuninori Morimoto's response to the original patch where all four
+nodes where changed. sdhi{2,3} are the correct size.
+
+This bug has been present since sdhi resources were added to the r8a7790 by
+8c9b1aa41853272a ("ARM: shmobile: r8a7790: add MMCIF and SDHI DT
+templates") in v3.11-rc2.
+
+Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
+Tested-by: William Towle <william.towle@codethink.co.uk>
+Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/boot/dts/r8a7790.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/r8a7790.dtsi
++++ b/arch/arm/boot/dts/r8a7790.dtsi
+@@ -152,7 +152,7 @@
+
+ sdhi0: sdhi@ee100000 {
+ compatible = "renesas,sdhi-r8a7790";
+- reg = <0 0xee100000 0 0x100>;
++ reg = <0 0xee100000 0 0x200>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 165 4>;
+ cap-sd-highspeed;
+@@ -161,7 +161,7 @@
+
+ sdhi1: sdhi@ee120000 {
+ compatible = "renesas,sdhi-r8a7790";
+- reg = <0 0xee120000 0 0x100>;
++ reg = <0 0xee120000 0 0x200>;
+ interrupt-parent = <&gic>;
+ interrupts = <0 166 4>;
+ cap-sd-highspeed;
--- /dev/null
+From cdc27c27843248ae7eb0df5fc261dd004eaa5670 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 17 Dec 2013 17:09:08 +0000
+Subject: arm64: ptrace: avoid using HW_BREAKPOINT_EMPTY for disabled events
+
+From: Will Deacon <will.deacon@arm.com>
+
+commit cdc27c27843248ae7eb0df5fc261dd004eaa5670 upstream.
+
+Commit 8f34a1da35ae ("arm64: ptrace: use HW_BREAKPOINT_EMPTY type for
+disabled breakpoints") fixed an issue with GDB trying to zero breakpoint
+control registers. The problem there is that the arch hw_breakpoint code
+will attempt to create a (disabled), execute breakpoint of length 0.
+
+This will fail validation and report unexpected failure to GDB. To avoid
+this, we treated disabled breakpoints as HW_BREAKPOINT_EMPTY, but that
+seems to have broken with recent kernels, causing watchpoints to be
+treated as TYPE_INST in the core code and returning ENOSPC for any
+further breakpoints.
+
+This patch fixes the problem by prioritising the `enable' field of the
+breakpoint: if it is cleared, we simply update the perf_event_attr to
+indicate that the thing is disabled and don't bother changing either the
+type or the length. This reinforces the behaviour that the breakpoint
+control register is essentially read-only apart from the enable bit
+when disabling a breakpoint.
+
+Reported-by: Aaron Liu <liucy214@gmail.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/ptrace.c | 36 +++++++++++++++++-------------------
+ 1 file changed, 17 insertions(+), 19 deletions(-)
+
+--- a/arch/arm64/kernel/ptrace.c
++++ b/arch/arm64/kernel/ptrace.c
+@@ -214,31 +214,29 @@ static int ptrace_hbp_fill_attr_ctrl(uns
+ {
+ int err, len, type, disabled = !ctrl.enabled;
+
+- if (disabled) {
+- len = 0;
+- type = HW_BREAKPOINT_EMPTY;
+- } else {
+- err = arch_bp_generic_fields(ctrl, &len, &type);
+- if (err)
+- return err;
++ attr->disabled = disabled;
++ if (disabled)
++ return 0;
+
+- switch (note_type) {
+- case NT_ARM_HW_BREAK:
+- if ((type & HW_BREAKPOINT_X) != type)
+- return -EINVAL;
+- break;
+- case NT_ARM_HW_WATCH:
+- if ((type & HW_BREAKPOINT_RW) != type)
+- return -EINVAL;
+- break;
+- default:
++ err = arch_bp_generic_fields(ctrl, &len, &type);
++ if (err)
++ return err;
++
++ switch (note_type) {
++ case NT_ARM_HW_BREAK:
++ if ((type & HW_BREAKPOINT_X) != type)
++ return -EINVAL;
++ break;
++ case NT_ARM_HW_WATCH:
++ if ((type & HW_BREAKPOINT_RW) != type)
+ return -EINVAL;
+- }
++ break;
++ default:
++ return -EINVAL;
+ }
+
+ attr->bp_len = len;
+ attr->bp_type = type;
+- attr->disabled = disabled;
+
+ return 0;
+ }
--- /dev/null
+From c4602c1c818bd6626178d6d3fcc152d9f2f48ac0 Mon Sep 17 00:00:00 2001
+From: Miao Xie <miaox@cn.fujitsu.com>
+Date: Mon, 16 Dec 2013 15:20:01 +0800
+Subject: ftrace: Initialize the ftrace profiler for each possible cpu
+
+From: Miao Xie <miaox@cn.fujitsu.com>
+
+commit c4602c1c818bd6626178d6d3fcc152d9f2f48ac0 upstream.
+
+Ftrace currently initializes only the online CPUs. This implementation has
+two problems:
+- If we online a CPU after we enable the function profile, and then run the
+ test, we will lose the trace information on that CPU.
+ Steps to reproduce:
+ # echo 0 > /sys/devices/system/cpu/cpu1/online
+ # cd <debugfs>/tracing/
+ # echo <some function name> >> set_ftrace_filter
+ # echo 1 > function_profile_enabled
+ # echo 1 > /sys/devices/system/cpu/cpu1/online
+ # run test
+- If we offline a CPU before we enable the function profile, we will not clear
+ the trace information when we enable the function profile. It will trouble
+ the users.
+ Steps to reproduce:
+ # cd <debugfs>/tracing/
+ # echo <some function name> >> set_ftrace_filter
+ # echo 1 > function_profile_enabled
+ # run test
+ # cat trace_stat/function*
+ # echo 0 > /sys/devices/system/cpu/cpu1/online
+ # echo 0 > function_profile_enabled
+ # echo 1 > function_profile_enabled
+ # cat trace_stat/function*
+ # run test
+ # cat trace_stat/function*
+
+So it is better that we initialize the ftrace profiler for each possible cpu
+every time we enable the function profile instead of just the online ones.
+
+Link: http://lkml.kernel.org/r/1387178401-10619-1-git-send-email-miaox@cn.fujitsu.com
+
+Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ftrace.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -775,7 +775,7 @@ static int ftrace_profile_init(void)
+ int cpu;
+ int ret = 0;
+
+- for_each_online_cpu(cpu) {
++ for_each_possible_cpu(cpu) {
+ ret = ftrace_profile_init_cpu(cpu);
+ if (ret)
+ break;
--- /dev/null
+From 7122c3e9154b5d9a7422f68f02d8acf050fad2b0 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Tue, 10 Dec 2013 16:46:29 +1030
+Subject: scripts/link-vmlinux.sh: only filter kernel symbols for arm
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit 7122c3e9154b5d9a7422f68f02d8acf050fad2b0 upstream.
+
+Actually CONFIG_PAGE_OFFSET isn't same with PAGE_OFFSET, so
+it isn't easy to figue out PAGE_OFFSET defined in header
+file from scripts.
+
+Because CONFIG_PAGE_OFFSET may not be defined in some ARCHs(
+64bit ARCH), or defined as bogus value in !MMU case, so
+this patch only applys the filter on ARM when CONFIG_PAGE_OFFSET
+is defined as the original problem is only on ARM.
+
+Cc: Rusty Russell <rusty@rustcorp.com.au>
+Fixes: f6537f2f0eba4eba3354e48dbe3047db6d8b6254
+Singed-off-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ scripts/link-vmlinux.sh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/scripts/link-vmlinux.sh
++++ b/scripts/link-vmlinux.sh
+@@ -82,7 +82,9 @@ kallsyms()
+ kallsymopt="${kallsymopt} --all-symbols"
+ fi
+
+- kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
++ if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
++ kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
++ fi
+
+ local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \
+ ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
iscsi-target-fix-incorrect-np-np_thread-null-assignment.patch
iser-target-move-init_work-setup-into-isert_create_device_ib_res.patch
target-file-update-hw_max_sectors-based-on-current-block_size.patch
+xfs-fix-infinite-loop-by-detaching-the-group-project-hints-from-user-dquot.patch
+ftrace-initialize-the-ftrace-profiler-for-each-possible-cpu.patch
+scripts-link-vmlinux.sh-only-filter-kernel-symbols-for-arm.patch
+arm64-ptrace-avoid-using-hw_breakpoint_empty-for-disabled-events.patch
+arm-shmobile-r8a7790-fix-shdi-resource-sizes.patch
+arm-dra7-hwmod-fix-boot-crash-with-debug_ll.patch
+arm-omap2-hwmod_data-fix-missing-omap_intc_start-in-irq-data.patch
+arm-omap2-fix-lcd-panel-backlight-regression-for-ldp-legacy-booting.patch
+x86-idle-repair-large-server-50-watt-idle-power-regression.patch
--- /dev/null
+From 40e2d7f9b5dae048789c64672bf3027fbb663ffa Mon Sep 17 00:00:00 2001
+From: Len Brown <len.brown@intel.com>
+Date: Wed, 18 Dec 2013 16:44:57 -0500
+Subject: x86 idle: Repair large-server 50-watt idle-power regression
+
+From: Len Brown <len.brown@intel.com>
+
+commit 40e2d7f9b5dae048789c64672bf3027fbb663ffa upstream.
+
+Linux 3.10 changed the timing of how thread_info->flags is touched:
+
+ x86: Use generic idle loop
+ (7d1a941731fabf27e5fb6edbebb79fe856edb4e5)
+
+This caused Intel NHM-EX and WSM-EX servers to experience a large number
+of immediate MONITOR/MWAIT break wakeups, which caused cpuidle to demote
+from deep C-states to shallow C-states, which caused these platforms
+to experience a significant increase in idle power.
+
+Note that this issue was already present before the commit above,
+however, it wasn't seen often enough to be noticed in power measurements.
+
+Here we extend an errata workaround from the Core2 EX "Dunnington"
+to extend to NHM-EX and WSM-EX, to prevent these immediate
+returns from MWAIT, reducing idle power on these platforms.
+
+While only acpi_idle ran on Dunnington, intel_idle
+may also run on these two newer systems.
+As of today, there are no other models that are known
+to need this tweak.
+
+Link: http://lkml.kernel.org/r/CAJvTdK=%2BaNN66mYpCGgbHGCHhYQAKx-vB0kJSWjVpsNb_hOAtQ@mail.gmail.com
+Signed-off-by: Len Brown <len.brown@intel.com>
+Link: http://lkml.kernel.org/r/baff264285f6e585df757d58b17788feabc68918.1387403066.git.len.brown@intel.com
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/intel.c | 3 ++-
+ drivers/idle/intel_idle.c | 3 +++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/cpu/intel.c
++++ b/arch/x86/kernel/cpu/intel.c
+@@ -387,7 +387,8 @@ static void init_intel(struct cpuinfo_x8
+ set_cpu_cap(c, X86_FEATURE_PEBS);
+ }
+
+- if (c->x86 == 6 && c->x86_model == 29 && cpu_has_clflush)
++ if (c->x86 == 6 && cpu_has_clflush &&
++ (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
+ set_cpu_cap(c, X86_FEATURE_CLFLUSH_MONITOR);
+
+ #ifdef CONFIG_X86_64
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -361,6 +361,9 @@ static int intel_idle(struct cpuidle_dev
+
+ if (!current_set_polling_and_test()) {
+
++ if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
++ clflush((void *)¤t_thread_info()->flags);
++
+ __monitor((void *)¤t_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (!need_resched())
--- /dev/null
+From 718cc6f88cbfc4fbd39609f28c4c86883945f90d Mon Sep 17 00:00:00 2001
+From: Jie Liu <jeff.liu@oracle.com>
+Date: Tue, 26 Nov 2013 21:38:49 +0800
+Subject: xfs: fix infinite loop by detaching the group/project hints from user dquot
+
+From: Jie Liu <jeff.liu@oracle.com>
+
+commit 718cc6f88cbfc4fbd39609f28c4c86883945f90d upstream.
+
+xfs_quota(8) will hang up if trying to turn group/project quota off
+before the user quota is off, this could be 100% reproduced by:
+ # mount -ouquota,gquota /dev/sda7 /xfs
+ # mkdir /xfs/test
+ # xfs_quota -xc 'off -g' /xfs <-- hangs up
+ # echo w > /proc/sysrq-trigger
+ # dmesg
+
+ SysRq : Show Blocked State
+ task PC stack pid father
+ xfs_quota D 0000000000000000 0 27574 2551 0x00000000
+ [snip]
+ Call Trace:
+ [<ffffffff81aaa21d>] schedule+0xad/0xc0
+ [<ffffffff81aa327e>] schedule_timeout+0x35e/0x3c0
+ [<ffffffff8114b506>] ? mark_held_locks+0x176/0x1c0
+ [<ffffffff810ad6c0>] ? call_timer_fn+0x2c0/0x2c0
+ [<ffffffffa0c25380>] ? xfs_qm_shrink_count+0x30/0x30 [xfs]
+ [<ffffffff81aa3306>] schedule_timeout_uninterruptible+0x26/0x30
+ [<ffffffffa0c26155>] xfs_qm_dquot_walk+0x235/0x260 [xfs]
+ [<ffffffffa0c059d8>] ? xfs_perag_get+0x1d8/0x2d0 [xfs]
+ [<ffffffffa0c05805>] ? xfs_perag_get+0x5/0x2d0 [xfs]
+ [<ffffffffa0b7707e>] ? xfs_inode_ag_iterator+0xae/0xf0 [xfs]
+ [<ffffffffa0c22280>] ? xfs_trans_free_dqinfo+0x50/0x50 [xfs]
+ [<ffffffffa0b7709f>] ? xfs_inode_ag_iterator+0xcf/0xf0 [xfs]
+ [<ffffffffa0c261e6>] xfs_qm_dqpurge_all+0x66/0xb0 [xfs]
+ [<ffffffffa0c2497a>] xfs_qm_scall_quotaoff+0x20a/0x5f0 [xfs]
+ [<ffffffffa0c2b8f6>] xfs_fs_set_xstate+0x136/0x180 [xfs]
+ [<ffffffff8136cf7a>] do_quotactl+0x53a/0x6b0
+ [<ffffffff812fba4b>] ? iput+0x5b/0x90
+ [<ffffffff8136d257>] SyS_quotactl+0x167/0x1d0
+ [<ffffffff814cf2ee>] ? trace_hardirqs_on_thunk+0x3a/0x3f
+ [<ffffffff81abcd19>] system_call_fastpath+0x16/0x1b
+
+It's fine if we turn user quota off at first, then turn off other
+kind of quotas if they are enabled since the group/project dquot
+refcount is decreased to zero once the user quota if off. Otherwise,
+those dquots refcount is non-zero due to the user dquot might refer
+to them as hint(s). Hence, above operation cause an infinite loop
+at xfs_qm_dquot_walk() while trying to purge dquot cache.
+
+This problem has been around since Linux 3.4, it was introduced by:
+ [ b84a3a9675 xfs: remove the per-filesystem list of dquots ]
+
+Originally we will release the group dquot pointers because the user
+dquots maybe carrying around as a hint via xfs_qm_detach_gdquots().
+However, with above change, there is no such work to be done before
+purging group/project dquot cache.
+
+In order to solve this problem, this patch introduces a special routine
+xfs_qm_dqpurge_hints(), and it would release the group/project dquot
+pointers the user dquots maybe carrying around as a hint, and then it
+will proceed to purge the user dquot cache if requested.
+
+(cherry picked from commit df8052e7dae00bde6f21b40b6e3e1099770f3afc)
+
+Signed-off-by: Jie Liu <jeff.liu@oracle.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Ben Myers <bpm@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ fs/xfs/xfs_qm.c | 71 +++++++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 50 insertions(+), 21 deletions(-)
+
+--- a/fs/xfs/xfs_qm.c
++++ b/fs/xfs/xfs_qm.c
+@@ -137,8 +137,6 @@ xfs_qm_dqpurge(
+ {
+ struct xfs_mount *mp = dqp->q_mount;
+ struct xfs_quotainfo *qi = mp->m_quotainfo;
+- struct xfs_dquot *gdqp = NULL;
+- struct xfs_dquot *pdqp = NULL;
+
+ xfs_dqlock(dqp);
+ if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) {
+@@ -146,21 +144,6 @@ xfs_qm_dqpurge(
+ return EAGAIN;
+ }
+
+- /*
+- * If this quota has a hint attached, prepare for releasing it now.
+- */
+- gdqp = dqp->q_gdquot;
+- if (gdqp) {
+- xfs_dqlock(gdqp);
+- dqp->q_gdquot = NULL;
+- }
+-
+- pdqp = dqp->q_pdquot;
+- if (pdqp) {
+- xfs_dqlock(pdqp);
+- dqp->q_pdquot = NULL;
+- }
+-
+ dqp->dq_flags |= XFS_DQ_FREEING;
+
+ xfs_dqflock(dqp);
+@@ -209,11 +192,47 @@ xfs_qm_dqpurge(
+ XFS_STATS_DEC(xs_qm_dquot_unused);
+
+ xfs_qm_dqdestroy(dqp);
++ return 0;
++}
++
++/*
++ * Release the group or project dquot pointers the user dquots maybe carrying
++ * around as a hint, and proceed to purge the user dquot cache if requested.
++*/
++STATIC int
++xfs_qm_dqpurge_hints(
++ struct xfs_dquot *dqp,
++ void *data)
++{
++ struct xfs_dquot *gdqp = NULL;
++ struct xfs_dquot *pdqp = NULL;
++ uint flags = *((uint *)data);
++
++ xfs_dqlock(dqp);
++ if (dqp->dq_flags & XFS_DQ_FREEING) {
++ xfs_dqunlock(dqp);
++ return EAGAIN;
++ }
++
++ /* If this quota has a hint attached, prepare for releasing it now */
++ gdqp = dqp->q_gdquot;
++ if (gdqp)
++ dqp->q_gdquot = NULL;
++
++ pdqp = dqp->q_pdquot;
++ if (pdqp)
++ dqp->q_pdquot = NULL;
++
++ xfs_dqunlock(dqp);
+
+ if (gdqp)
+- xfs_qm_dqput(gdqp);
++ xfs_qm_dqrele(gdqp);
+ if (pdqp)
+- xfs_qm_dqput(pdqp);
++ xfs_qm_dqrele(pdqp);
++
++ if (flags & XFS_QMOPT_UQUOTA)
++ return xfs_qm_dqpurge(dqp, NULL);
++
+ return 0;
+ }
+
+@@ -225,8 +244,18 @@ xfs_qm_dqpurge_all(
+ struct xfs_mount *mp,
+ uint flags)
+ {
+- if (flags & XFS_QMOPT_UQUOTA)
+- xfs_qm_dquot_walk(mp, XFS_DQ_USER, xfs_qm_dqpurge, NULL);
++ /*
++ * We have to release group/project dquot hint(s) from the user dquot
++ * at first if they are there, otherwise we would run into an infinite
++ * loop while walking through radix tree to purge other type of dquots
++ * since their refcount is not zero if the user dquot refers to them
++ * as hint.
++ *
++ * Call the special xfs_qm_dqpurge_hints() will end up go through the
++ * general xfs_qm_dqpurge() against user dquot cache if requested.
++ */
++ xfs_qm_dquot_walk(mp, XFS_DQ_USER, xfs_qm_dqpurge_hints, &flags);
++
+ if (flags & XFS_QMOPT_GQUOTA)
+ xfs_qm_dquot_walk(mp, XFS_DQ_GROUP, xfs_qm_dqpurge, NULL);
+ if (flags & XFS_QMOPT_PQUOTA)