--- /dev/null
+From linville@tuxdriver.com Fri May 7 15:21:31 2010
+From: "John W. Linville" <linville@tuxdriver.com>
+Date: Fri, 30 Apr 2010 11:19:58 -0400
+Subject: ath9k: reorder ieee80211_free_hw behind ath9k_uninit_hw to avoid oops
+To: stable@kernel.org
+Cc: "John W. Linville" <linville@tuxdriver.com>
+Message-ID: <1272640798-5823-1-git-send-email-linville@tuxdriver.com>
+
+From: John W. Linville <linville@tuxdriver.com>
+
+This code only exists in 2.6.33 -- 2.6.32 and 2.6.34 are not affected.
+
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+
+ drivers/net/wireless/ath/ath9k/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ath9k/main.c
++++ b/drivers/net/wireless/ath/ath9k/main.c
+@@ -1358,9 +1358,9 @@ void ath_cleanup(struct ath_softc *sc)
+ free_irq(sc->irq, sc);
+ ath_bus_cleanup(common);
+ kfree(sc->sec_wiphy);
+- ieee80211_free_hw(sc->hw);
+
+ ath9k_uninit_hw(sc);
++ ieee80211_free_hw(sc->hw);
+ }
+
+ static int ath9k_reg_notifier(struct wiphy *wiphy,
--- /dev/null
+From c441b8d2cb2194b05550a558d6d95d8944e56a84 Mon Sep 17 00:00:00 2001
+From: Michael Chan <mchan@broadcom.com>
+Date: Tue, 27 Apr 2010 11:28:09 +0000
+Subject: bnx2: Fix lost MSI-X problem on 5709 NICs.
+
+From: Michael Chan <mchan@broadcom.com>
+
+commit c441b8d2cb2194b05550a558d6d95d8944e56a84 upstream.
+
+It has been reported that under certain heavy traffic conditions in MSI-X
+mode, the driver can lose an MSI-X vector causing all packets in the
+associated rx/tx ring pair to be dropped. The problem is caused by
+the chip dropping the write to unmask the MSI-X vector by the kernel
+(when migrating the IRQ for example).
+
+This can be prevented by increasing the GRC timeout value for these
+register read and write operations.
+
+Thanks to Dell for helping us debug this problem.
+
+Signed-off-by: Michael Chan <mchan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/bnx2.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/bnx2.c
++++ b/drivers/net/bnx2.c
+@@ -4772,8 +4772,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
+ rc = bnx2_alloc_bad_rbuf(bp);
+ }
+
+- if (bp->flags & BNX2_FLAG_USING_MSIX)
++ if (bp->flags & BNX2_FLAG_USING_MSIX) {
+ bnx2_setup_msix_tbl(bp);
++ /* Prevent MSIX table reads and write from timing out */
++ REG_WR(bp, BNX2_MISC_ECO_HW_CTL,
++ BNX2_MISC_ECO_HW_CTL_LARGE_GRC_TMOUT_EN);
++ }
+
+ return rc;
+ }
--- /dev/null
+From 56151e753468e34aeb322af4b0309ab727c97d2e Mon Sep 17 00:00:00 2001
+From: Wufei <fei.wu@windriver.com>
+Date: Wed, 28 Apr 2010 17:42:32 -0400
+Subject: kgdb: don't needlessly skip PAGE_USER test for Fsl booke
+
+From: Wufei <fei.wu@windriver.com>
+
+commit 56151e753468e34aeb322af4b0309ab727c97d2e upstream.
+
+The bypassing of this test is a leftover from 2.4 vintage
+kernels, and is no longer appropriate, or even used by KGDB.
+Currently KGDB uses probe_kernel_write() for all access to
+memory via the KGDB core, so it can simply be deleted.
+
+This fixes CVE-2010-1446.
+
+CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+CC: Paul Mackerras <paulus@samba.org>
+CC: Kumar Gala <galak@kernel.crashing.org>
+Signed-off-by: Wufei <fei.wu@windriver.com>
+Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/mm/fsl_booke_mmu.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/arch/powerpc/mm/fsl_booke_mmu.c
++++ b/arch/powerpc/mm/fsl_booke_mmu.c
+@@ -155,15 +155,10 @@ static void settlbcam(int index, unsigne
+ if (cur_cpu_spec->cpu_features & MMU_FTR_BIG_PHYS)
+ TLBCAM[index].MAS7 = (u64)phys >> 32;
+
+-#ifndef CONFIG_KGDB /* want user access for breakpoints */
+ if (flags & _PAGE_USER) {
+ TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+ TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+ }
+-#else
+- TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR;
+- TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0);
+-#endif
+
+ tlbcam_addrs[index].start = virt;
+ tlbcam_addrs[index].limit = virt + size - 1;
--- /dev/null
+From 0212f2602a38e740d5a96aba4cebfc2ebc993ecf Mon Sep 17 00:00:00 2001
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Date: Mon, 1 Mar 2010 02:58:16 +0000
+Subject: powerpc: Move checks in pseries_mach_cpu_die()
+
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+
+commit 0212f2602a38e740d5a96aba4cebfc2ebc993ecf upstream.
+
+Rearrange condition checks for better code readability and
+ prevention of possible race conditions when
+ preferred_offline_state can potentially change during the
+ execution of pseries_mach_cpu_die(). The patch will make
+ pseries_mach_cpu_die() put cpu in one of the consistent states
+ and not hit the run over BUG()
+
+Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Cc: Gautham R Shenoy <ego@in.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 30 +++++++++++++--------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -140,25 +140,25 @@ static void pseries_mach_cpu_die(void)
+ if (!get_lppaca()->shared_proc)
+ get_lppaca()->donate_dedicated_cpu = 0;
+ get_lppaca()->idle = 0;
+- }
+
+- if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
+- unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
++ if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) {
++ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+
+- /*
+- * Call to start_secondary_resume() will not return.
+- * Kernel stack will be reset and start_secondary()
+- * will be called to continue the online operation.
+- */
+- start_secondary_resume();
++ /*
++ * Call to start_secondary_resume() will not return.
++ * Kernel stack will be reset and start_secondary()
++ * will be called to continue the online operation.
++ */
++ start_secondary_resume();
++ }
++ }
+
+- } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
++ /* Requested state is CPU_STATE_OFFLINE at this point */
++ WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE);
+
+- set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
+- unregister_slb_shadow(hard_smp_processor_id(),
+- __pa(get_slb_shadow()));
+- rtas_stop_self();
+- }
++ set_cpu_current_state(cpu, CPU_STATE_OFFLINE);
++ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
++ rtas_stop_self();
+
+ /* Should never get here... */
+ BUG();
--- /dev/null
+From a8e6da093ea8642b1320fb5d64134366f2a8d0ac Mon Sep 17 00:00:00 2001
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Date: Mon, 1 Mar 2010 02:58:23 +0000
+Subject: powerpc: Reduce printk from pseries_mach_cpu_die()
+
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+
+commit a8e6da093ea8642b1320fb5d64134366f2a8d0ac upstream.
+
+Remove debug printks in pseries_mach_cpu_die(). These are
+noisy at runtime. Traceevents can be added to instrument this
+section of code.
+
+The following KERN_INFO printks are removed:
+
+cpu 62 (hwid 62) returned from cede.
+Decrementer value = b2802fff Timebase value = 2fa8f95035f4a
+cpu 62 (hwid 62) got prodded to go online
+cpu 58 (hwid 58) ceding for offline with hint 2
+
+Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Cc: Gautham R Shenoy <ego@in.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -122,21 +122,10 @@ static void pseries_mach_cpu_die(void)
+ if (!get_lppaca()->shared_proc)
+ get_lppaca()->donate_dedicated_cpu = 1;
+
+- printk(KERN_INFO
+- "cpu %u (hwid %u) ceding for offline with hint %d\n",
+- cpu, hwcpu, cede_latency_hint);
+ while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
+ extended_cede_processor(cede_latency_hint);
+- printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n",
+- cpu, hwcpu);
+- printk(KERN_INFO
+- "Decrementer value = %x Timebase value = %llx\n",
+- get_dec(), get_tb());
+ }
+
+- printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n",
+- cpu, hwcpu);
+-
+ if (!get_lppaca()->shared_proc)
+ get_lppaca()->donate_dedicated_cpu = 0;
+ get_lppaca()->idle = 0;
--- /dev/null
+From 8dbce53cc249a76e9450708d291fce5a7e29c6a1 Mon Sep 17 00:00:00 2001
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Date: Mon, 1 Mar 2010 02:58:09 +0000
+Subject: powerpc: Reset kernel stack on cpu online from cede state
+
+From: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+
+commit 8dbce53cc249a76e9450708d291fce5a7e29c6a1 upstream.
+
+Cpu hotplug (offline) without dlpar operation will place cpu
+in cede state and the extended_cede_processor() function will
+return when resumed.
+
+Kernel stack pointer needs to be reset before
+start_secondary() is called to continue the online operation.
+
+Added new function start_secondary_resume() to do the above
+steps.
+
+Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
+Cc: Gautham R Shenoy <ego@in.ibm.com>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/powerpc/kernel/head_64.S | 11 +++++++++++
+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 9 ++++-----
+ arch/powerpc/platforms/pseries/offline_states.h | 1 +
+ 3 files changed, 16 insertions(+), 5 deletions(-)
+
+--- a/arch/powerpc/kernel/head_64.S
++++ b/arch/powerpc/kernel/head_64.S
+@@ -615,6 +615,17 @@ _GLOBAL(start_secondary_prolog)
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl .start_secondary
+ b .
++/*
++ * Reset stack pointer and call start_secondary
++ * to continue with online operation when woken up
++ * from cede in cpu offline.
++ */
++_GLOBAL(start_secondary_resume)
++ ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */
++ li r3,0
++ std r3,0(r1) /* Zero the stack frame pointer */
++ bl .start_secondary
++ b .
+ #endif
+
+ /*
+--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
++++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
+@@ -146,12 +146,11 @@ static void pseries_mach_cpu_die(void)
+ unregister_slb_shadow(hwcpu, __pa(get_slb_shadow()));
+
+ /*
+- * NOTE: Calling start_secondary() here for now to
+- * start new context.
+- * However, need to do it cleanly by resetting the
+- * stack pointer.
++ * Call to start_secondary_resume() will not return.
++ * Kernel stack will be reset and start_secondary()
++ * will be called to continue the online operation.
+ */
+- start_secondary();
++ start_secondary_resume();
+
+ } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
+
+--- a/arch/powerpc/platforms/pseries/offline_states.h
++++ b/arch/powerpc/platforms/pseries/offline_states.h
+@@ -35,4 +35,5 @@ static inline void set_default_offline_s
+
+ extern enum cpu_state_vals get_preferred_offline_state(int cpu);
+ extern int start_secondary(void);
++extern void start_secondary_resume(void);
+ #endif
--- /dev/null
+From 78f1cd02457252e1ffbc6caa44a17424a45286b8 Mon Sep 17 00:00:00 2001
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Sat, 27 Mar 2010 19:35:46 -0700
+Subject: r8169: fix broken register writes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Francois Romieu <romieu@fr.zoreil.com>
+
+commit 78f1cd02457252e1ffbc6caa44a17424a45286b8 upstream.
+
+This is quite similar to b39fe41f481d20c201012e4483e76c203802dda7
+though said registers are not even documented as 64-bit registers
+- as opposed to the initial TxDescStartAddress ones - but as single
+bytes which must be combined into 32 bits at the MMIO read/write
+level before being merged into a 64 bit logical entity.
+
+Credits go to Ben Hutchings <ben@decadent.org.uk> for the MAR
+registers (aka "multicast is broken for ages on ARM) and to
+Timo Teräs <timo.teras@iki.fi> for the MAC registers.
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/r8169.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -2832,8 +2832,8 @@ static void rtl_rar_set(struct rtl8169_p
+ spin_lock_irq(&tp->lock);
+
+ RTL_W8(Cfg9346, Cfg9346_Unlock);
+- RTL_W32(MAC0, low);
+ RTL_W32(MAC4, high);
++ RTL_W32(MAC0, low);
+ RTL_W8(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&tp->lock);
+@@ -4813,8 +4813,8 @@ static void rtl_set_rx_mode(struct net_d
+ mc_filter[1] = swab32(data);
+ }
+
+- RTL_W32(MAR0 + 0, mc_filter[0]);
+ RTL_W32(MAR0 + 4, mc_filter[1]);
++ RTL_W32(MAR0 + 0, mc_filter[0]);
+
+ RTL_W32(RxConfig, tmp);
+
--- /dev/null
+From 908ba2bfd22253f26fa910cd855e4ccffb1467d0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?fran=C3=A7ois=20romieu?= <romieu@fr.zoreil.com>
+Date: Mon, 26 Apr 2010 11:42:58 +0000
+Subject: r8169: more broken register writes workaround
+
+From: =?UTF-8?q?fran=C3=A7ois=20romieu?= <romieu@fr.zoreil.com>
+
+commit 908ba2bfd22253f26fa910cd855e4ccffb1467d0 upstream.
+
+78f1cd02457252e1ffbc6caa44a17424a45286b8 ("fix broken register writes")
+does not work for Al Viro's r8169 (XID 18000000).
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/r8169.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -2832,8 +2832,13 @@ static void rtl_rar_set(struct rtl8169_p
+ spin_lock_irq(&tp->lock);
+
+ RTL_W8(Cfg9346, Cfg9346_Unlock);
++
+ RTL_W32(MAC4, high);
++ RTL_R32(MAC4);
++
+ RTL_W32(MAC0, low);
++ RTL_R32(MAC0);
++
+ RTL_W8(Cfg9346, Cfg9346_Lock);
+
+ spin_unlock_irq(&tp->lock);
--- /dev/null
+From 4c020a961a812ffae9846b917304cea504c3a733 Mon Sep 17 00:00:00 2001
+From: David Dillow <dave@thedillows.org>
+Date: Wed, 3 Mar 2010 16:33:10 +0000
+Subject: r8169: use correct barrier between cacheable and non-cacheable memory
+
+From: David Dillow <dave@thedillows.org>
+
+commit 4c020a961a812ffae9846b917304cea504c3a733 upstream.
+
+r8169 needs certain writes to be visible to other CPUs or the NIC before
+touching the hardware, but was using smp_wmb() which is only required to
+order cacheable memory access. Switch to wmb() which is required to
+order both cacheable and non-cacheable memory.
+
+Noticed by Catalin Marinas and Paul Mackerras.
+
+Signed-off-by: David Dillow <dave@thedillows.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/r8169.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -4316,7 +4316,7 @@ static netdev_tx_t rtl8169_start_xmit(st
+
+ tp->cur_tx += frags + 1;
+
+- smp_wmb();
++ wmb();
+
+ RTL_W8(TxPoll, NPQ); /* set polling bit */
+
+@@ -4675,7 +4675,7 @@ static int rtl8169_poll(struct napi_stru
+ * until it does.
+ */
+ tp->intr_mask = 0xffff;
+- smp_wmb();
++ wmb();
+ RTL_W16(IntrMask, tp->intr_event);
+ }
+
--- /dev/null
+From e7efe5932b1d3916c79326a4221693ea90a900e2 Mon Sep 17 00:00:00 2001
+From: Douglas Gilbert <dgilbert@interlog.com>
+Date: Sun, 3 Jan 2010 13:51:15 -0500
+Subject: [SCSI] skip sense logging for some ATA PASS-THROUGH cdbs
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+commit e7efe5932b1d3916c79326a4221693ea90a900e2 upstream.
+
+Further to the lsml thread titled:
+"does scsi_io_completion need to dump sense data for ata pass through (ck_cond =
+1) ?"
+
+This is a patch to skip logging when the sense data is
+associated with a SENSE_KEY of "RECOVERED_ERROR" and the
+additional sense code is "ATA PASS-THROUGH INFORMATION
+AVAILABLE". This only occurs with the SAT ATA PASS-THROUGH
+commands when CK_COND=1 (in the cdb). It indicates that
+the sense data contains ATA registers.
+
+Smartmontools uses such commands on ATA disks connected via
+SAT. Periodic checks such as those done by smartd cause
+nuisance entries into logs that are:
+ - neither errors nor warnings
+ - pointless unless the cdb that caused them are also logged
+
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: James Bottomley <James.Bottomley@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/scsi/scsi_lib.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -773,8 +773,14 @@ void scsi_io_completion(struct scsi_cmnd
+ * we already took a copy of the original into rq->errors which
+ * is what gets returned to the user
+ */
+- if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) {
+- if (!(req->cmd_flags & REQ_QUIET))
++ if (sense_valid && (sshdr.sense_key == RECOVERED_ERROR)) {
++ /* if ATA PASS-THROUGH INFORMATION AVAILABLE skip
++ * print since caller wants ATA registers. Only occurs on
++ * SCSI ATA PASS_THROUGH commands when CK_COND=1
++ */
++ if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d))
++ ;
++ else if (!(req->cmd_flags & REQ_QUIET))
+ scsi_print_sense("", cmd);
+ result = 0;
+ /* BLOCK_PC may have set error */
--- /dev/null
+From dc8bf1b1a6edfc92465526de19772061302f0929 Mon Sep 17 00:00:00 2001
+From: Andre Detsch <adetsch@br.ibm.com>
+Date: Mon, 26 Apr 2010 07:27:07 +0000
+Subject: tg3: Fix INTx fallback when MSI fails
+
+From: Andre Detsch <adetsch@br.ibm.com>
+
+commit dc8bf1b1a6edfc92465526de19772061302f0929 upstream.
+
+tg3: Fix INTx fallback when MSI fails
+
+MSI setup changes the value of irq_vec in struct tg3 *tp.
+This attribute must be taken into account and restored before
+we try to do a new request_irq for INTx fallback.
+
+In powerpc, the original code was leading to an EINVAL return within
+request_irq, because the driver was trying to use the disabled MSI
+virtual irq number instead of tp->pdev->irq.
+
+Signed-off-by: Andre Detsch <adetsch@br.ibm.com>
+Acked-by: Michael Chan <mchan@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Brandon Philips <bphilips@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/tg3.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/tg3.c
++++ b/drivers/net/tg3.c
+@@ -8572,6 +8572,7 @@ static int tg3_test_msi(struct tg3 *tp)
+ pci_disable_msi(tp->pdev);
+
+ tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
++ tp->napi[0].irq_vec = tp->pdev->irq;
+
+ err = tg3_request_irq(tp, 0);
+ if (err)
--- /dev/null
+From david@fromorbit.com Fri May 7 15:27:13 2010
+From: Dave Chinner <david@fromorbit.com>
+Date: Tue, 4 May 2010 12:58:20 +1000
+Subject: xfs: add a shrinker to background inode reclaim
+To: stable@kernel.org
+Cc: xfs@oss.sgi.com
+Message-ID: <20100504025820.GI2591@dastard>
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit 9bf729c0af67897ea8498ce17c29b0683f7f2028 upstream
+
+On low memory boxes or those with highmem, kernel can OOM before the
+background reclaims inodes via xfssyncd. Add a shrinker to run inode
+reclaim so that it inode reclaim is expedited when memory is low.
+
+This is more complex than it needs to be because the VM folk don't
+want a context added to the shrinker infrastructure. Hence we need
+to add a global list of XFS mount structures so the shrinker can
+traverse them.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ fs/xfs/linux-2.6/xfs_super.c | 5 +
+ fs/xfs/linux-2.6/xfs_sync.c | 107 ++++++++++++++++++++++++++++++++++++++---
+ fs/xfs/linux-2.6/xfs_sync.h | 7 ++
+ fs/xfs/quota/xfs_qm_syscalls.c | 3 -
+ fs/xfs/xfs_ag.h | 1
+ fs/xfs/xfs_mount.h | 1
+ 6 files changed, 115 insertions(+), 9 deletions(-)
+
+--- a/fs/xfs/linux-2.6/xfs_super.c
++++ b/fs/xfs/linux-2.6/xfs_super.c
+@@ -1160,6 +1160,7 @@ xfs_fs_put_super(
+
+ xfs_unmountfs(mp);
+ xfs_freesb(mp);
++ xfs_inode_shrinker_unregister(mp);
+ xfs_icsb_destroy_counters(mp);
+ xfs_close_devices(mp);
+ xfs_dmops_put(mp);
+@@ -1523,6 +1524,8 @@ xfs_fs_fill_super(
+ if (error)
+ goto fail_vnrele;
+
++ xfs_inode_shrinker_register(mp);
++
+ kfree(mtpt);
+ return 0;
+
+@@ -1767,6 +1770,7 @@ init_xfs_fs(void)
+ goto out_cleanup_procfs;
+
+ vfs_initquota();
++ xfs_inode_shrinker_init();
+
+ error = register_filesystem(&xfs_fs_type);
+ if (error)
+@@ -1794,6 +1798,7 @@ exit_xfs_fs(void)
+ {
+ vfs_exitquota();
+ unregister_filesystem(&xfs_fs_type);
++ xfs_inode_shrinker_destroy();
+ xfs_sysctl_unregister();
+ xfs_cleanup_procfs();
+ xfs_buf_terminate();
+--- a/fs/xfs/linux-2.6/xfs_sync.c
++++ b/fs/xfs/linux-2.6/xfs_sync.c
+@@ -95,7 +95,8 @@ xfs_inode_ag_walk(
+ struct xfs_perag *pag, int flags),
+ int flags,
+ int tag,
+- int exclusive)
++ int exclusive,
++ int *nr_to_scan)
+ {
+ struct xfs_perag *pag = &mp->m_perag[ag];
+ uint32_t first_index;
+@@ -135,7 +136,7 @@ restart:
+ if (error == EFSCORRUPTED)
+ break;
+
+- } while (1);
++ } while ((*nr_to_scan)--);
+
+ if (skipped) {
+ delay(1);
+@@ -153,23 +154,30 @@ xfs_inode_ag_iterator(
+ struct xfs_perag *pag, int flags),
+ int flags,
+ int tag,
+- int exclusive)
++ int exclusive,
++ int *nr_to_scan)
+ {
+ int error = 0;
+ int last_error = 0;
+ xfs_agnumber_t ag;
++ int nr;
+
++ nr = nr_to_scan ? *nr_to_scan : INT_MAX;
+ for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
+ if (!mp->m_perag[ag].pag_ici_init)
+ continue;
+ error = xfs_inode_ag_walk(mp, ag, execute, flags, tag,
+- exclusive);
++ exclusive, &nr);
+ if (error) {
+ last_error = error;
+ if (error == EFSCORRUPTED)
+ break;
+ }
++ if (nr <= 0)
++ break;
+ }
++ if (nr_to_scan)
++ *nr_to_scan = nr;
+ return XFS_ERROR(last_error);
+ }
+
+@@ -289,7 +297,7 @@ xfs_sync_data(
+ ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
+
+ error = xfs_inode_ag_iterator(mp, xfs_sync_inode_data, flags,
+- XFS_ICI_NO_TAG, 0);
++ XFS_ICI_NO_TAG, 0, NULL);
+ if (error)
+ return XFS_ERROR(error);
+
+@@ -311,7 +319,7 @@ xfs_sync_attr(
+ ASSERT((flags & ~SYNC_WAIT) == 0);
+
+ return xfs_inode_ag_iterator(mp, xfs_sync_inode_attr, flags,
+- XFS_ICI_NO_TAG, 0);
++ XFS_ICI_NO_TAG, 0, NULL);
+ }
+
+ STATIC int
+@@ -679,6 +687,7 @@ __xfs_inode_set_reclaim_tag(
+ radix_tree_tag_set(&pag->pag_ici_root,
+ XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
+ XFS_ICI_RECLAIM_TAG);
++ pag->pag_ici_reclaimable++;
+ }
+
+ /*
+@@ -710,6 +719,7 @@ __xfs_inode_clear_reclaim_tag(
+ {
+ radix_tree_tag_clear(&pag->pag_ici_root,
+ XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
++ pag->pag_ici_reclaimable--;
+ }
+
+ STATIC int
+@@ -770,5 +780,88 @@ xfs_reclaim_inodes(
+ int mode)
+ {
+ return xfs_inode_ag_iterator(mp, xfs_reclaim_inode, mode,
+- XFS_ICI_RECLAIM_TAG, 1);
++ XFS_ICI_RECLAIM_TAG, 1, NULL);
++}
++
++/*
++ * Shrinker infrastructure.
++ *
++ * This is all far more complex than it needs to be. It adds a global list of
++ * mounts because the shrinkers can only call a global context. We need to make
++ * the shrinkers pass a context to avoid the need for global state.
++ */
++static LIST_HEAD(xfs_mount_list);
++static struct rw_semaphore xfs_mount_list_lock;
++
++static int
++xfs_reclaim_inode_shrink(
++ int nr_to_scan,
++ gfp_t gfp_mask)
++{
++ struct xfs_mount *mp;
++ xfs_agnumber_t ag;
++ int reclaimable = 0;
++
++ if (nr_to_scan) {
++ if (!(gfp_mask & __GFP_FS))
++ return -1;
++
++ down_read(&xfs_mount_list_lock);
++ list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
++ xfs_inode_ag_iterator(mp, xfs_reclaim_inode, 0,
++ XFS_ICI_RECLAIM_TAG, 1, &nr_to_scan);
++ if (nr_to_scan <= 0)
++ break;
++ }
++ up_read(&xfs_mount_list_lock);
++ }
++
++ down_read(&xfs_mount_list_lock);
++ list_for_each_entry(mp, &xfs_mount_list, m_mplist) {
++ for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
++
++ if (!mp->m_perag[ag].pag_ici_init)
++ continue;
++ reclaimable += mp->m_perag[ag].pag_ici_reclaimable;
++ }
++ }
++ up_read(&xfs_mount_list_lock);
++ return reclaimable;
++}
++
++static struct shrinker xfs_inode_shrinker = {
++ .shrink = xfs_reclaim_inode_shrink,
++ .seeks = DEFAULT_SEEKS,
++};
++
++void __init
++xfs_inode_shrinker_init(void)
++{
++ init_rwsem(&xfs_mount_list_lock);
++ register_shrinker(&xfs_inode_shrinker);
++}
++
++void
++xfs_inode_shrinker_destroy(void)
++{
++ ASSERT(list_empty(&xfs_mount_list));
++ unregister_shrinker(&xfs_inode_shrinker);
++}
++
++void
++xfs_inode_shrinker_register(
++ struct xfs_mount *mp)
++{
++ down_write(&xfs_mount_list_lock);
++ list_add_tail(&mp->m_mplist, &xfs_mount_list);
++ up_write(&xfs_mount_list_lock);
++}
++
++void
++xfs_inode_shrinker_unregister(
++ struct xfs_mount *mp)
++{
++ down_write(&xfs_mount_list_lock);
++ list_del(&mp->m_mplist);
++ up_write(&xfs_mount_list_lock);
+ }
+--- a/fs/xfs/linux-2.6/xfs_sync.h
++++ b/fs/xfs/linux-2.6/xfs_sync.h
+@@ -54,6 +54,11 @@ void __xfs_inode_clear_reclaim_tag(struc
+ int xfs_sync_inode_valid(struct xfs_inode *ip, struct xfs_perag *pag);
+ int xfs_inode_ag_iterator(struct xfs_mount *mp,
+ int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
+- int flags, int tag, int write_lock);
++ int flags, int tag, int write_lock, int *nr_to_scan);
++
++void xfs_inode_shrinker_init(void);
++void xfs_inode_shrinker_destroy(void);
++void xfs_inode_shrinker_register(struct xfs_mount *mp);
++void xfs_inode_shrinker_unregister(struct xfs_mount *mp);
+
+ #endif
+--- a/fs/xfs/quota/xfs_qm_syscalls.c
++++ b/fs/xfs/quota/xfs_qm_syscalls.c
+@@ -891,7 +891,8 @@ xfs_qm_dqrele_all_inodes(
+ uint flags)
+ {
+ ASSERT(mp->m_quotainfo);
+- xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0);
++ xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags,
++ XFS_ICI_NO_TAG, 0, NULL);
+ }
+
+ /*------------------------------------------------------------------------*/
+--- a/fs/xfs/xfs_ag.h
++++ b/fs/xfs/xfs_ag.h
+@@ -229,6 +229,7 @@ typedef struct xfs_perag
+ int pag_ici_init; /* incore inode cache initialised */
+ rwlock_t pag_ici_lock; /* incore inode lock */
+ struct radix_tree_root pag_ici_root; /* incore inode cache root */
++ int pag_ici_reclaimable; /* reclaimable inodes */
+ #endif
+ } xfs_perag_t;
+
+--- a/fs/xfs/xfs_mount.h
++++ b/fs/xfs/xfs_mount.h
+@@ -257,6 +257,7 @@ typedef struct xfs_mount {
+ wait_queue_head_t m_wait_single_sync_task;
+ __int64_t m_update_flags; /* sb flags we need to update
+ on the next remount,rw */
++ struct list_head m_mplist; /* inode shrinker mount list */
+ } xfs_mount_t;
+
+ /*