From ae00bb5b5212369f9c8df3b69c1b18ef716ea32b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 4 Jun 2013 22:19:52 -0700 Subject: [PATCH] 3.9-stable patches added patches: acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch iommu-amd-workaround-for-erbt1312.patch iwlwifi-mvm-fix-aggregation-drain-flow.patch jfs-fix-a-couple-races.patch xen-netback-remove-skb-in-xen_netbk_alloc_page.patch --- ...tates-to-be-used-for-config_pm-unset.patch | 247 ++++++++++++++++++ ...ul30a-to-acpi-video-detect-blacklist.patch | 40 +++ ...-disable-ce1-on-a-number-of-chipsets.patch | 40 +++ ...u-event-log-interrupt-after-handling.patch | 47 ++++ .../iommu-amd-workaround-for-erbt1312.patch | 83 ++++++ ...lwifi-mvm-fix-aggregation-drain-flow.patch | 181 +++++++++++++ queue-3.9/jfs-fix-a-couple-races.patch | 54 ++++ queue-3.9/series | 8 + ...k-remove-skb-in-xen_netbk_alloc_page.patch | 48 ++++ 9 files changed, 748 insertions(+) create mode 100644 queue-3.9/acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch create mode 100644 queue-3.9/acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch create mode 100644 queue-3.9/drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch create mode 100644 queue-3.9/iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch create mode 100644 queue-3.9/iommu-amd-workaround-for-erbt1312.patch create mode 100644 queue-3.9/iwlwifi-mvm-fix-aggregation-drain-flow.patch create mode 100644 queue-3.9/jfs-fix-a-couple-races.patch create mode 100644 queue-3.9/xen-netback-remove-skb-in-xen_netbk_alloc_page.patch diff --git a/queue-3.9/acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch b/queue-3.9/acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch new file mode 100644 index 00000000000..7d793c64949 --- /dev/null +++ b/queue-3.9/acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch @@ -0,0 +1,247 @@ +From ec4602a9588a196fa1a9af46bfdd37cbf5792db4 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 16 May 2013 22:29:28 +0200 +Subject: ACPI / PM: Allow device power states to be used for CONFIG_PM unset + +From: "Rafael J. Wysocki" + +commit ec4602a9588a196fa1a9af46bfdd37cbf5792db4 upstream. + +Currently, drivers/acpi/device_pm.c depends on CONFIG_PM and all of +the functions defined in there are replaced with static inline stubs +if that option is unset. However, CONFIG_PM means, roughly, "runtime +PM or suspend/hibernation support" and some of those functions are +useful regardless of that. For example, they are used by the ACPI +fan driver for controlling fans and acpi_device_set_power() is called +during device removal. Moreover, device initialization may depend on +setting device power states properly. + +For these reasons, make the routines manipulating ACPI device power +states defined in drivers/acpi/device_pm.c available for CONFIG_PM +unset too. + +Reported-by: Zhang Rui +Reported-and-tested-by: Michel Lespinasse +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/Makefile | 2 + drivers/acpi/device_pm.c | 126 +++++++++++++++++++++++------------------------ + include/acpi/acpi_bus.h | 40 +------------- + 3 files changed, 70 insertions(+), 98 deletions(-) + +--- a/drivers/acpi/Makefile ++++ b/drivers/acpi/Makefile +@@ -24,7 +24,7 @@ acpi-y += nvs.o + # Power management related files + acpi-y += wakeup.o + acpi-y += sleep.o +-acpi-$(CONFIG_PM) += device_pm.o ++acpi-y += device_pm.o + acpi-$(CONFIG_ACPI_SLEEP) += proc.o + + +--- a/drivers/acpi/device_pm.c ++++ b/drivers/acpi/device_pm.c +@@ -37,68 +37,6 @@ + #define _COMPONENT ACPI_POWER_COMPONENT + ACPI_MODULE_NAME("device_pm"); + +-static DEFINE_MUTEX(acpi_pm_notifier_lock); +- +-/** +- * acpi_add_pm_notifier - Register PM notifier for given ACPI device. +- * @adev: ACPI device to add the notifier for. +- * @context: Context information to pass to the notifier routine. +- * +- * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of +- * PM wakeup events. For example, wakeup events may be generated for bridges +- * if one of the devices below the bridge is signaling wakeup, even if the +- * bridge itself doesn't have a wakeup GPE associated with it. +- */ +-acpi_status acpi_add_pm_notifier(struct acpi_device *adev, +- acpi_notify_handler handler, void *context) +-{ +- acpi_status status = AE_ALREADY_EXISTS; +- +- mutex_lock(&acpi_pm_notifier_lock); +- +- if (adev->wakeup.flags.notifier_present) +- goto out; +- +- status = acpi_install_notify_handler(adev->handle, +- ACPI_SYSTEM_NOTIFY, +- handler, context); +- if (ACPI_FAILURE(status)) +- goto out; +- +- adev->wakeup.flags.notifier_present = true; +- +- out: +- mutex_unlock(&acpi_pm_notifier_lock); +- return status; +-} +- +-/** +- * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. +- * @adev: ACPI device to remove the notifier from. +- */ +-acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, +- acpi_notify_handler handler) +-{ +- acpi_status status = AE_BAD_PARAMETER; +- +- mutex_lock(&acpi_pm_notifier_lock); +- +- if (!adev->wakeup.flags.notifier_present) +- goto out; +- +- status = acpi_remove_notify_handler(adev->handle, +- ACPI_SYSTEM_NOTIFY, +- handler); +- if (ACPI_FAILURE(status)) +- goto out; +- +- adev->wakeup.flags.notifier_present = false; +- +- out: +- mutex_unlock(&acpi_pm_notifier_lock); +- return status; +-} +- + /** + * acpi_power_state_string - String representation of ACPI device power state. + * @state: ACPI device power state to return the string representation of. +@@ -376,6 +314,69 @@ bool acpi_bus_power_manageable(acpi_hand + } + EXPORT_SYMBOL(acpi_bus_power_manageable); + ++#ifdef CONFIG_PM ++static DEFINE_MUTEX(acpi_pm_notifier_lock); ++ ++/** ++ * acpi_add_pm_notifier - Register PM notifier for given ACPI device. ++ * @adev: ACPI device to add the notifier for. ++ * @context: Context information to pass to the notifier routine. ++ * ++ * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of ++ * PM wakeup events. For example, wakeup events may be generated for bridges ++ * if one of the devices below the bridge is signaling wakeup, even if the ++ * bridge itself doesn't have a wakeup GPE associated with it. ++ */ ++acpi_status acpi_add_pm_notifier(struct acpi_device *adev, ++ acpi_notify_handler handler, void *context) ++{ ++ acpi_status status = AE_ALREADY_EXISTS; ++ ++ mutex_lock(&acpi_pm_notifier_lock); ++ ++ if (adev->wakeup.flags.notifier_present) ++ goto out; ++ ++ status = acpi_install_notify_handler(adev->handle, ++ ACPI_SYSTEM_NOTIFY, ++ handler, context); ++ if (ACPI_FAILURE(status)) ++ goto out; ++ ++ adev->wakeup.flags.notifier_present = true; ++ ++ out: ++ mutex_unlock(&acpi_pm_notifier_lock); ++ return status; ++} ++ ++/** ++ * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. ++ * @adev: ACPI device to remove the notifier from. ++ */ ++acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, ++ acpi_notify_handler handler) ++{ ++ acpi_status status = AE_BAD_PARAMETER; ++ ++ mutex_lock(&acpi_pm_notifier_lock); ++ ++ if (!adev->wakeup.flags.notifier_present) ++ goto out; ++ ++ status = acpi_remove_notify_handler(adev->handle, ++ ACPI_SYSTEM_NOTIFY, ++ handler); ++ if (ACPI_FAILURE(status)) ++ goto out; ++ ++ adev->wakeup.flags.notifier_present = false; ++ ++ out: ++ mutex_unlock(&acpi_pm_notifier_lock); ++ return status; ++} ++ + bool acpi_bus_can_wakeup(acpi_handle handle) + { + struct acpi_device *device; +@@ -1014,3 +1015,4 @@ void acpi_dev_pm_remove_dependent(acpi_h + mutex_unlock(&adev->physical_node_lock); + } + EXPORT_SYMBOL_GPL(acpi_dev_pm_remove_dependent); ++#endif /* CONFIG_PM */ +--- a/include/acpi/acpi_bus.h ++++ b/include/acpi/acpi_bus.h +@@ -352,7 +352,6 @@ acpi_status acpi_bus_get_status_handle(a + unsigned long long *sta); + int acpi_bus_get_status(struct acpi_device *device); + +-#ifdef CONFIG_PM + int acpi_bus_set_power(acpi_handle handle, int state); + const char *acpi_power_state_string(int state); + int acpi_device_get_power(struct acpi_device *device, int *state); +@@ -360,41 +359,12 @@ int acpi_device_set_power(struct acpi_de + int acpi_bus_init_power(struct acpi_device *device); + int acpi_bus_update_power(acpi_handle handle, int *state_p); + bool acpi_bus_power_manageable(acpi_handle handle); ++ ++#ifdef CONFIG_PM + bool acpi_bus_can_wakeup(acpi_handle handle); +-#else /* !CONFIG_PM */ +-static inline int acpi_bus_set_power(acpi_handle handle, int state) +-{ +- return 0; +-} +-static inline const char *acpi_power_state_string(int state) +-{ +- return "D0"; +-} +-static inline int acpi_device_get_power(struct acpi_device *device, int *state) +-{ +- return 0; +-} +-static inline int acpi_device_set_power(struct acpi_device *device, int state) +-{ +- return 0; +-} +-static inline int acpi_bus_init_power(struct acpi_device *device) +-{ +- return 0; +-} +-static inline int acpi_bus_update_power(acpi_handle handle, int *state_p) +-{ +- return 0; +-} +-static inline bool acpi_bus_power_manageable(acpi_handle handle) +-{ +- return false; +-} +-static inline bool acpi_bus_can_wakeup(acpi_handle handle) +-{ +- return false; +-} +-#endif /* !CONFIG_PM */ ++#else ++static inline bool acpi_bus_can_wakeup(acpi_handle handle) { return false; } ++#endif + + #ifdef CONFIG_ACPI_PROC_EVENT + int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); diff --git a/queue-3.9/acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch b/queue-3.9/acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch new file mode 100644 index 00000000000..950e02cc7d5 --- /dev/null +++ b/queue-3.9/acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch @@ -0,0 +1,40 @@ +From c8f6d8351ba8c89d5cd4c562552ec7ec29274e31 Mon Sep 17 00:00:00 2001 +From: Bastian Triller +Date: Sun, 19 May 2013 11:52:33 +0000 +Subject: ACPI / video: Add "Asus UL30A" to ACPI video detect blacklist + +From: Bastian Triller + +commit c8f6d8351ba8c89d5cd4c562552ec7ec29274e31 upstream. + +Like on UL30VT, the ACPI video driver can't control backlight correctly on +Asus UL30A. Vendor driver (asus-laptop) can work. This patch is to +add "Asus UL30A" to ACPI video detect blacklist in order to use +asus-laptop for video control on the "Asus UL30A" rather than ACPI +video driver. + +Signed-off-by: Bastian Triller +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/video_detect.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -164,6 +164,14 @@ static struct dmi_system_id video_detect + DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"), + }, + }, ++ { ++ .callback = video_detect_force_vendor, ++ .ident = "Asus UL30A", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), ++ }, ++ }, + { }, + }; + diff --git a/queue-3.9/drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch b/queue-3.9/drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch new file mode 100644 index 00000000000..70fe3902e97 --- /dev/null +++ b/queue-3.9/drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch @@ -0,0 +1,40 @@ +From 6d5f83834dc2b064b8c1202ea281820286b675a8 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Mon, 13 May 2013 16:11:12 +1000 +Subject: drm/nvc0/ce: disable ce1 on a number of chipsets + +From: Ben Skeggs + +commit 6d5f83834dc2b064b8c1202ea281820286b675a8 upstream. + +The falcon is present, but the rest of the copy engine doesn't appear to +be... PUNITS doesn't report disabled (maybe the bits for the copy engines +got added later?), so we end up trying to use a non-functional CE1, and +bust all sorts of things.. Most notably, suspend/resume.. + +Signed-off-by: Ben Skeggs +Signed-off-by: Lingzhu Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c ++++ b/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c +@@ -138,7 +138,6 @@ nvc0_identify(struct nouveau_device *dev + device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; +- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + break; + case 0xce: +@@ -225,7 +224,6 @@ nvc0_identify(struct nouveau_device *dev + device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; +- device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + break; + case 0xc8: diff --git a/queue-3.9/iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch b/queue-3.9/iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch new file mode 100644 index 00000000000..6386e2a9044 --- /dev/null +++ b/queue-3.9/iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch @@ -0,0 +1,47 @@ +From 925fe08bce38d1ff052fe2209b9e2b8d5fbb7f98 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Wed, 27 Mar 2013 18:51:52 -0500 +Subject: iommu/amd: Re-enable IOMMU event log interrupt after handling. + +From: Suravee Suthikulpanit + +commit 925fe08bce38d1ff052fe2209b9e2b8d5fbb7f98 upstream. + +Current driver does not clear the IOMMU event log interrupt bit +in the IOMMU status register after processing an interrupt. +This causes the IOMMU hardware to generate event log interrupt only once. +This has been observed in both IOMMU v1 and V2 hardware. +This patch clears the bit by writing 1 to bit 1 of the IOMMU +status register (MMIO Offset 2020h) + +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 3 +++ + drivers/iommu/amd_iommu_types.h | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -703,6 +703,9 @@ static void iommu_poll_events(struct amd + u32 head, tail; + unsigned long flags; + ++ /* enable event interrupts again */ ++ writel(MMIO_STATUS_EVT_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); ++ + spin_lock_irqsave(&iommu->lock, flags); + + head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET); +--- a/drivers/iommu/amd_iommu_types.h ++++ b/drivers/iommu/amd_iommu_types.h +@@ -99,6 +99,7 @@ + #define PASID_MASK 0x000fffff + + /* MMIO status bits */ ++#define MMIO_STATUS_EVT_INT_MASK (1 << 1) + #define MMIO_STATUS_COM_WAIT_INT_MASK (1 << 2) + #define MMIO_STATUS_PPR_INT_MASK (1 << 6) + diff --git a/queue-3.9/iommu-amd-workaround-for-erbt1312.patch b/queue-3.9/iommu-amd-workaround-for-erbt1312.patch new file mode 100644 index 00000000000..855d3e3554c --- /dev/null +++ b/queue-3.9/iommu-amd-workaround-for-erbt1312.patch @@ -0,0 +1,83 @@ +From d3263bc29706e42f74d8800807c2dedf320d77f1 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Thu, 18 Apr 2013 17:55:04 +0200 +Subject: iommu/amd: Workaround for ERBT1312 + +From: Joerg Roedel + +commit d3263bc29706e42f74d8800807c2dedf320d77f1 upstream. + +Work around an IOMMU hardware bug where clearing the +EVT_INT or PPR_INT bit in the status register may race with +the hardware trying to set it again. When not handled the +bit might not be cleared and we lose all future event or ppr +interrupts. + +Reported-by: Suravee Suthikulpanit +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 34 ++++++++++++++++++++++++++-------- + 1 file changed, 26 insertions(+), 8 deletions(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -700,14 +700,23 @@ retry: + + static void iommu_poll_events(struct amd_iommu *iommu) + { +- u32 head, tail; ++ u32 head, tail, status; + unsigned long flags; + +- /* enable event interrupts again */ +- writel(MMIO_STATUS_EVT_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); +- + spin_lock_irqsave(&iommu->lock, flags); + ++ /* enable event interrupts again */ ++ do { ++ /* ++ * Workaround for Erratum ERBT1312 ++ * Clearing the EVT_INT bit may race in the hardware, so read ++ * it again and make sure it was really cleared ++ */ ++ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); ++ writel(MMIO_STATUS_EVT_INT_MASK, ++ iommu->mmio_base + MMIO_STATUS_OFFSET); ++ } while (status & MMIO_STATUS_EVT_INT_MASK); ++ + head = readl(iommu->mmio_base + MMIO_EVT_HEAD_OFFSET); + tail = readl(iommu->mmio_base + MMIO_EVT_TAIL_OFFSET); + +@@ -744,16 +753,25 @@ static void iommu_handle_ppr_entry(struc + static void iommu_poll_ppr_log(struct amd_iommu *iommu) + { + unsigned long flags; +- u32 head, tail; ++ u32 head, tail, status; + + if (iommu->ppr_log == NULL) + return; + +- /* enable ppr interrupts again */ +- writel(MMIO_STATUS_PPR_INT_MASK, iommu->mmio_base + MMIO_STATUS_OFFSET); +- + spin_lock_irqsave(&iommu->lock, flags); + ++ /* enable ppr interrupts again */ ++ do { ++ /* ++ * Workaround for Erratum ERBT1312 ++ * Clearing the PPR_INT bit may race in the hardware, so read ++ * it again and make sure it was really cleared ++ */ ++ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); ++ writel(MMIO_STATUS_PPR_INT_MASK, ++ iommu->mmio_base + MMIO_STATUS_OFFSET); ++ } while (status & MMIO_STATUS_PPR_INT_MASK); ++ + head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET); + tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET); + diff --git a/queue-3.9/iwlwifi-mvm-fix-aggregation-drain-flow.patch b/queue-3.9/iwlwifi-mvm-fix-aggregation-drain-flow.patch new file mode 100644 index 00000000000..13f4f14f914 --- /dev/null +++ b/queue-3.9/iwlwifi-mvm-fix-aggregation-drain-flow.patch @@ -0,0 +1,181 @@ +From e3d4bc8cc0230e8dc8033484666f03f87392a8c4 Mon Sep 17 00:00:00 2001 +From: Emmanuel Grumbach +Date: Tue, 7 May 2013 14:08:24 +0300 +Subject: iwlwifi: mvm: fix aggregation drain flow + +From: Emmanuel Grumbach + +commit e3d4bc8cc0230e8dc8033484666f03f87392a8c4 upstream. + +Move the counter for non-AMPDU frames to mvm. It is needed +for the drain flow which happens once the ieee80211_sta has +been freed, so keeping it in iwl_mvm_sta which is embed into +ieee80211_sta is not a good idea. + +Also, since its purpose it to remove the STA in the fw only +after all the frames for this station have exited the shared +Tx queues, we need to decrement it in the reclaim flow. This +flow can happen after ieee80211_sta has been removed, which +means that we have no iwl_mvm_sta there. So we can't know +what is the vif type. Hence, we know audit these frames for +all the vif types. +In order to avoid spawning sta_drained_wk all the time, we +now check that we are in a flow in which draining might +happen - only when mvmsta is NULL. This is better than +previous code that would spawn sta_drained_wk all the time +in AP mode. + +Signed-off-by: Emmanuel Grumbach +Reviewed-by: Ilan Peer +Reviewed-by: Johannes Berg +Signed-off-by: Johannes Berg +Signed-off-by: Lingzhu Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 - + drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + drivers/net/wireless/iwlwifi/mvm/sta.c | 13 +++++-- + drivers/net/wireless/iwlwifi/mvm/sta.h | 2 - + drivers/net/wireless/iwlwifi/mvm/tx.c | 48 +++++++++++++++++++++------- + 5 files changed, 48 insertions(+), 18 deletions(-) + +--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c ++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c +@@ -886,7 +886,7 @@ static void iwl_mvm_mac_sta_notify(struc + + switch (cmd) { + case STA_NOTIFY_SLEEP: +- if (atomic_read(&mvmsta->pending_frames) > 0) ++ if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0) + ieee80211_sta_block_awake(hw, sta, true); + /* + * The fw updates the STA to be asleep. Tx packets on the Tx +--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h ++++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h +@@ -293,6 +293,7 @@ struct iwl_mvm { + struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT]; + struct work_struct sta_drained_wk; + unsigned long sta_drained[BITS_TO_LONGS(IWL_MVM_STATION_COUNT)]; ++ atomic_t pending_frames[IWL_MVM_STATION_COUNT]; + + /* configured by mac80211 */ + u32 rts_threshold; +--- a/drivers/net/wireless/iwlwifi/mvm/sta.c ++++ b/drivers/net/wireless/iwlwifi/mvm/sta.c +@@ -172,7 +172,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, + mvm_sta->max_agg_bufsize = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + + /* HW restart, don't assume the memory has been zeroed */ +- atomic_set(&mvm_sta->pending_frames, 0); ++ atomic_set(&mvm->pending_frames[sta_id], 0); + mvm_sta->tid_disable_agg = 0; + mvm_sta->tfd_queue_msk = 0; + for (i = 0; i < IEEE80211_NUM_ACS; i++) +@@ -360,14 +360,21 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, + } + + /* ++ * Make sure that the tx response code sees the station as -EBUSY and ++ * calls the drain worker. ++ */ ++ spin_lock_bh(&mvm_sta->lock); ++ /* + * There are frames pending on the AC queues for this station. + * We need to wait until all the frames are drained... + */ +- if (atomic_read(&mvm_sta->pending_frames)) { +- ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); ++ if (atomic_read(&mvm->pending_frames[mvm_sta->sta_id])) { + rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], + ERR_PTR(-EBUSY)); ++ spin_unlock_bh(&mvm_sta->lock); ++ ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); + } else { ++ spin_unlock_bh(&mvm_sta->lock); + ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id); + rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL); + } +--- a/drivers/net/wireless/iwlwifi/mvm/sta.h ++++ b/drivers/net/wireless/iwlwifi/mvm/sta.h +@@ -273,7 +273,6 @@ struct iwl_mvm_tid_data { + * @max_agg_bufsize: the maximal size of the AGG buffer for this station + * @lock: lock to protect the whole struct. Since %tid_data is access from Tx + * and from Tx response flow, it needs a spinlock. +- * @pending_frames: number of frames for this STA on the shared Tx queues. + * @tid_data: per tid data. Look at %iwl_mvm_tid_data. + * + * When mac80211 creates a station it reserves some space (hw->sta_data_size) +@@ -288,7 +287,6 @@ struct iwl_mvm_sta { + u16 tid_disable_agg; + u8 max_agg_bufsize; + spinlock_t lock; +- atomic_t pending_frames; + struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; + struct iwl_lq_sta lq_sta; + struct ieee80211_vif *vif; +--- a/drivers/net/wireless/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/iwlwifi/mvm/tx.c +@@ -416,9 +416,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, + + spin_unlock(&mvmsta->lock); + +- if (mvmsta->vif->type == NL80211_IFTYPE_AP && +- txq_id < IWL_FIRST_AMPDU_QUEUE) +- atomic_inc(&mvmsta->pending_frames); ++ if (txq_id < IWL_FIRST_AMPDU_QUEUE) ++ atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); + + return 0; + +@@ -678,16 +677,41 @@ static void iwl_mvm_rx_tx_cmd_single(str + /* + * If the txq is not an AMPDU queue, there is no chance we freed + * several skbs. Check that out... +- * If there are no pending frames for this STA, notify mac80211 that +- * this station can go to sleep in its STA table. + */ +- if (txq_id < IWL_FIRST_AMPDU_QUEUE && mvmsta && +- !WARN_ON(skb_freed > 1) && +- mvmsta->vif->type == NL80211_IFTYPE_AP && +- atomic_sub_and_test(skb_freed, &mvmsta->pending_frames)) { +- ieee80211_sta_block_awake(mvm->hw, sta, false); +- set_bit(sta_id, mvm->sta_drained); +- schedule_work(&mvm->sta_drained_wk); ++ if (txq_id < IWL_FIRST_AMPDU_QUEUE && !WARN_ON(skb_freed > 1) && ++ atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { ++ if (mvmsta) { ++ /* ++ * If there are no pending frames for this STA, notify ++ * mac80211 that this station can go to sleep in its ++ * STA table. ++ */ ++ if (mvmsta->vif->type == NL80211_IFTYPE_AP) ++ ieee80211_sta_block_awake(mvm->hw, sta, false); ++ /* ++ * We might very well have taken mvmsta pointer while ++ * the station was being removed. The remove flow might ++ * have seen a pending_frame (because we didn't take ++ * the lock) even if now the queues are drained. So make ++ * really sure now that this the station is not being ++ * removed. If it is, run the drain worker to remove it. ++ */ ++ spin_lock_bh(&mvmsta->lock); ++ sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); ++ if (IS_ERR_OR_NULL(sta)) { ++ /* ++ * Station disappeared in the meantime: ++ * so we are draining. ++ */ ++ set_bit(sta_id, mvm->sta_drained); ++ schedule_work(&mvm->sta_drained_wk); ++ } ++ spin_unlock_bh(&mvmsta->lock); ++ } else if (!mvmsta) { ++ /* Tx response without STA, so we are draining */ ++ set_bit(sta_id, mvm->sta_drained); ++ schedule_work(&mvm->sta_drained_wk); ++ } + } + + rcu_read_unlock(); diff --git a/queue-3.9/jfs-fix-a-couple-races.patch b/queue-3.9/jfs-fix-a-couple-races.patch new file mode 100644 index 00000000000..484f90058ad --- /dev/null +++ b/queue-3.9/jfs-fix-a-couple-races.patch @@ -0,0 +1,54 @@ +From 73aaa22d5ffb2630456bac2f9a4ed9b81d0d7271 Mon Sep 17 00:00:00 2001 +From: Dave Kleikamp +Date: Wed, 1 May 2013 11:08:38 -0500 +Subject: jfs: fix a couple races + +From: Dave Kleikamp + +commit 73aaa22d5ffb2630456bac2f9a4ed9b81d0d7271 upstream. + +This patch fixes races uncovered by xfstests testcase 068. + +One race is the result of jfs_sync() trying to write a sync point to the +journal after it has been frozen (or possibly in the process). Since +freezing sync's the journal, there is no need to write a sync point so +we simply want to return. + +The second involves jfs_write_inode() being called on a deleted inode. +It calls jfs_flush_journal which is held up by the jfs_commit thread +doing the final iput on the same deleted inode, which itself is +waiting for the I_SYNC flag to be cleared. jfs_write_inode need not +do anything when i_nlink is zero, which is the easy fix. + +Reported-by: Michael L. Semon +Signed-off-by: Dave Kleikamp +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jfs/inode.c | 2 +- + fs/jfs/jfs_logmgr.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/jfs/inode.c ++++ b/fs/jfs/inode.c +@@ -125,7 +125,7 @@ int jfs_write_inode(struct inode *inode, + { + int wait = wbc->sync_mode == WB_SYNC_ALL; + +- if (test_cflag(COMMIT_Nolink, inode)) ++ if (inode->i_nlink == 0) + return 0; + /* + * If COMMIT_DIRTY is not set, the inode isn't really dirty. +--- a/fs/jfs/jfs_logmgr.c ++++ b/fs/jfs/jfs_logmgr.c +@@ -1058,7 +1058,8 @@ static int lmLogSync(struct jfs_log * lo + */ + void jfs_syncpt(struct jfs_log *log, int hard_sync) + { LOG_LOCK(log); +- lmLogSync(log, hard_sync); ++ if (!test_bit(log_QUIESCE, &log->flag)) ++ lmLogSync(log, hard_sync); + LOG_UNLOCK(log); + } + diff --git a/queue-3.9/series b/queue-3.9/series index 3d2bcab8147..eb20beaa3e6 100644 --- a/queue-3.9/series +++ b/queue-3.9/series @@ -95,3 +95,11 @@ powerpc-pseries-always-enable-config_hotplug_cpu-on-pseries-smp.patch reiserfs-fix-deadlock-with-nfs-racing-on-create-lookup.patch reiserfs-fix-problems-with-chowning-setuid-file-w-xattrs.patch reiserfs-fix-spurious-multiple-fill-in-reiserfs_readdir_dentry.patch +jfs-fix-a-couple-races.patch +xen-netback-remove-skb-in-xen_netbk_alloc_page.patch +iwlwifi-mvm-fix-aggregation-drain-flow.patch +iommu-amd-re-enable-iommu-event-log-interrupt-after-handling.patch +iommu-amd-workaround-for-erbt1312.patch +acpi-pm-allow-device-power-states-to-be-used-for-config_pm-unset.patch +acpi-video-add-asus-ul30a-to-acpi-video-detect-blacklist.patch +drm-nvc0-ce-disable-ce1-on-a-number-of-chipsets.patch diff --git a/queue-3.9/xen-netback-remove-skb-in-xen_netbk_alloc_page.patch b/queue-3.9/xen-netback-remove-skb-in-xen_netbk_alloc_page.patch new file mode 100644 index 00000000000..f8faaf493e4 --- /dev/null +++ b/queue-3.9/xen-netback-remove-skb-in-xen_netbk_alloc_page.patch @@ -0,0 +1,48 @@ +From 27f852282ab9a028f57da96d05c26f38c424a315 Mon Sep 17 00:00:00 2001 +From: Wei Liu +Date: Mon, 25 Mar 2013 01:08:20 +0000 +Subject: xen-netback: remove skb in xen_netbk_alloc_page + +From: Wei Liu + +commit 27f852282ab9a028f57da96d05c26f38c424a315 upstream. + +This variable is never used. + +Signed-off-by: Wei Liu +Acked-by: Ian Campbell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/xen-netback/netback.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -942,7 +942,6 @@ static int netbk_count_requests(struct x + } + + static struct page *xen_netbk_alloc_page(struct xen_netbk *netbk, +- struct sk_buff *skb, + u16 pending_idx) + { + struct page *page; +@@ -976,7 +975,7 @@ static struct gnttab_copy *xen_netbk_get + + index = pending_index(netbk->pending_cons++); + pending_idx = netbk->pending_ring[index]; +- page = xen_netbk_alloc_page(netbk, skb, pending_idx); ++ page = xen_netbk_alloc_page(netbk, pending_idx); + if (!page) + goto err; + +@@ -1381,7 +1380,7 @@ static unsigned xen_netbk_tx_build_gops( + } + + /* XXX could copy straight to head */ +- page = xen_netbk_alloc_page(netbk, skb, pending_idx); ++ page = xen_netbk_alloc_page(netbk, pending_idx); + if (!page) { + kfree_skb(skb); + netbk_tx_err(vif, &txreq, idx); -- 2.47.3