summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-09-21 14:55:10 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-09-21 14:55:10 -0700
commit614915851e064c8d4a127bcf669e468aa2ec4eb3 (patch)
tree253dece2270f377827c8b86a0bbff410bb85b537
parent786c54e23f96ae64595a46e801a95eb7a9f0a43a (diff)
downloadstable-queue-614915851e064c8d4a127bcf669e468aa2ec4eb3.tar.gz
3.0 patches
-rw-r--r--queue-3.0/b43-fix-beacon-problem-in-ad-hoc-mode.patch33
-rw-r--r--queue-3.0/blk-cgroup-be-able-to-remove-the-record-of-unplugged-device.patch117
-rw-r--r--queue-3.0/break-out-numa_maps-gather_pte_stats-checks.patch83
-rw-r--r--queue-3.0/floppy-use-del_timer_sync-in-init-cleanup.patch77
-rw-r--r--queue-3.0/iwlagn-workaround-bug-crashing-some-aps.patch38
-rw-r--r--queue-3.0/ixgbe-fix-possible-null-buffer-error.patch45
-rw-r--r--queue-3.0/make-proc-pid-numa_maps-gather_stats-take-variable-page.patch98
-rw-r--r--queue-3.0/rt2800pci-fix-compiler-error-on-powerpc.patch60
-rw-r--r--queue-3.0/rtl2800usb-fix-incorrect-storage-of-mac-address-on.patch48
-rw-r--r--queue-3.0/series14
-rw-r--r--queue-3.0/teach-proc-pid-numa_maps-about-transparent-hugepages.patch55
-rw-r--r--queue-3.0/wireless-reset-beacon_found-while-updating-regulatory.patch39
-rw-r--r--queue-3.0/xen-e820-if-there-is-no-dom0_mem-don-t-tweak-extra_pages.patch78
-rw-r--r--queue-3.0/xen-use-maximum-reservation-to-limit-amount-of-usable-ram.patch75
-rw-r--r--queue-3.0/xz-fix-incorrect-xz_buf_error.patch93
15 files changed, 953 insertions, 0 deletions
diff --git a/queue-3.0/b43-fix-beacon-problem-in-ad-hoc-mode.patch b/queue-3.0/b43-fix-beacon-problem-in-ad-hoc-mode.patch
new file mode 100644
index 0000000000..a05c4be881
--- /dev/null
+++ b/queue-3.0/b43-fix-beacon-problem-in-ad-hoc-mode.patch
@@ -0,0 +1,33 @@
+From 8c23516fbb209ccf8f8c36268311c721faff29ee Mon Sep 17 00:00:00 2001
+From: Manual Munz <freifunk@somakoma.de>
+Date: Sun, 18 Sep 2011 18:24:03 -0500
+Subject: b43: Fix beacon problem in ad-hoc mode
+
+From: Manual Munz <freifunk@somakoma.de>
+
+commit 8c23516fbb209ccf8f8c36268311c721faff29ee upstream.
+
+In ad-hoc mode, driver b43 does not issue beacons.
+
+Signed-off-by: Manual Munz <freifunk@somakoma.de>
+Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/b43/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -1571,7 +1571,8 @@ static void handle_irq_beacon(struct b43
+ u32 cmd, beacon0_valid, beacon1_valid;
+
+ if (!b43_is_mode(wl, NL80211_IFTYPE_AP) &&
+- !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
++ !b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) &&
++ !b43_is_mode(wl, NL80211_IFTYPE_ADHOC))
+ return;
+
+ /* This is the bottom half of the asynchronous beacon update. */
diff --git a/queue-3.0/blk-cgroup-be-able-to-remove-the-record-of-unplugged-device.patch b/queue-3.0/blk-cgroup-be-able-to-remove-the-record-of-unplugged-device.patch
new file mode 100644
index 0000000000..8a3233a5ee
--- /dev/null
+++ b/queue-3.0/blk-cgroup-be-able-to-remove-the-record-of-unplugged-device.patch
@@ -0,0 +1,117 @@
+From d11bb4462c4cc6ddd45c6927c617ad79fa6fb8fc Mon Sep 17 00:00:00 2001
+From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Date: Wed, 21 Sep 2011 10:22:10 +0200
+Subject: blk-cgroup: be able to remove the record of unplugged device
+
+From: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+
+commit d11bb4462c4cc6ddd45c6927c617ad79fa6fb8fc upstream.
+
+The bug is we're not able to remove the device from blkio cgroup's
+per-device control files if it gets unplugged.
+
+To reproduce the bug:
+
+ # mount -t cgroup -o blkio xxx /cgroup
+ # cd /cgroup
+ # echo "8:0 1000" > blkio.throttle.read_bps_device
+ # unplug the device
+ # cat blkio.throttle.read_bps_device
+ 8:0 1000
+ # echo "8:0 0" > blkio.throttle.read_bps_device
+ -bash: echo: write error: No such device
+
+After patching, the device removal will succeed.
+
+Thanks for the comments of Paul, Zefan, and Vivek.
+
+Signed-off-by: Wanlong Gao <gaowanlong@cn.fujitsu.com>
+Cc: Li Zefan <lizf@cn.fujitsu.com>
+Cc: Paul Menage <paul@paulmenage.org>
+Acked-by: Vivek Goyal <vgoyal@redhat.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ block/blk-cgroup.c | 37 ++++++++++++++++---------------------
+ 1 file changed, 16 insertions(+), 21 deletions(-)
+
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -785,10 +785,10 @@ static int blkio_policy_parse_and_set(ch
+ {
+ char *s[4], *p, *major_s = NULL, *minor_s = NULL;
+ int ret;
+- unsigned long major, minor, temp;
++ unsigned long major, minor;
+ int i = 0;
+ dev_t dev;
+- u64 bps, iops;
++ u64 temp;
+
+ memset(s, 0, sizeof(s));
+
+@@ -826,20 +826,23 @@ static int blkio_policy_parse_and_set(ch
+
+ dev = MKDEV(major, minor);
+
+- ret = blkio_check_dev_num(dev);
++ ret = strict_strtoull(s[1], 10, &temp);
+ if (ret)
+- return ret;
++ return -EINVAL;
+
+- newpn->dev = dev;
++ /* For rule removal, do not check for device presence. */
++ if (temp) {
++ ret = blkio_check_dev_num(dev);
++ if (ret)
++ return ret;
++ }
+
+- if (s[1] == NULL)
+- return -EINVAL;
++ newpn->dev = dev;
+
+ switch (plid) {
+ case BLKIO_POLICY_PROP:
+- ret = strict_strtoul(s[1], 10, &temp);
+- if (ret || (temp < BLKIO_WEIGHT_MIN && temp > 0) ||
+- temp > BLKIO_WEIGHT_MAX)
++ if ((temp < BLKIO_WEIGHT_MIN && temp > 0) ||
++ temp > BLKIO_WEIGHT_MAX)
+ return -EINVAL;
+
+ newpn->plid = plid;
+@@ -850,26 +853,18 @@ static int blkio_policy_parse_and_set(ch
+ switch(fileid) {
+ case BLKIO_THROTL_read_bps_device:
+ case BLKIO_THROTL_write_bps_device:
+- ret = strict_strtoull(s[1], 10, &bps);
+- if (ret)
+- return -EINVAL;
+-
+ newpn->plid = plid;
+ newpn->fileid = fileid;
+- newpn->val.bps = bps;
++ newpn->val.bps = temp;
+ break;
+ case BLKIO_THROTL_read_iops_device:
+ case BLKIO_THROTL_write_iops_device:
+- ret = strict_strtoull(s[1], 10, &iops);
+- if (ret)
+- return -EINVAL;
+-
+- if (iops > THROTL_IOPS_MAX)
++ if (temp > THROTL_IOPS_MAX)
+ return -EINVAL;
+
+ newpn->plid = plid;
+ newpn->fileid = fileid;
+- newpn->val.iops = (unsigned int)iops;
++ newpn->val.iops = (unsigned int)temp;
+ break;
+ }
+ break;
diff --git a/queue-3.0/break-out-numa_maps-gather_pte_stats-checks.patch b/queue-3.0/break-out-numa_maps-gather_pte_stats-checks.patch
new file mode 100644
index 0000000000..c83cd47180
--- /dev/null
+++ b/queue-3.0/break-out-numa_maps-gather_pte_stats-checks.patch
@@ -0,0 +1,83 @@
+From 3200a8aaab0c9ccdc0f59b0dac2d4a47029137fa Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+Date: Tue, 20 Sep 2011 15:19:39 -0700
+Subject: break out numa_maps gather_pte_stats() checks
+
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+
+commit 3200a8aaab0c9ccdc0f59b0dac2d4a47029137fa upstream.
+
+gather_pte_stats() does a number of checks on a target page
+to see whether it should even be considered for statistics.
+This breaks that code out in to a separate function so that
+we can use it in the transparent hugepage case in the next
+patch.
+
+Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Reviewed-by: Christoph Lameter <cl@gentwo.org>
+Acked-by: David Rientjes <rientjes@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/task_mmu.c | 39 ++++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -904,6 +904,29 @@ static void gather_stats(struct page *pa
+ md->node[page_to_nid(page)] += nr_pages;
+ }
+
++static struct page *can_gather_numa_stats(pte_t pte, struct vm_area_struct *vma,
++ unsigned long addr)
++{
++ struct page *page;
++ int nid;
++
++ if (!pte_present(pte))
++ return NULL;
++
++ page = vm_normal_page(vma, addr, pte);
++ if (!page)
++ return NULL;
++
++ if (PageReserved(page))
++ return NULL;
++
++ nid = page_to_nid(page);
++ if (!node_isset(nid, node_states[N_HIGH_MEMORY]))
++ return NULL;
++
++ return page;
++}
++
+ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
+ unsigned long end, struct mm_walk *walk)
+ {
+@@ -915,23 +938,9 @@ static int gather_pte_stats(pmd_t *pmd,
+ md = walk->private;
+ orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+ do {
+- struct page *page;
+- int nid;
+-
+- if (!pte_present(*pte))
+- continue;
+-
+- page = vm_normal_page(md->vma, addr, *pte);
++ struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
+ if (!page)
+ continue;
+-
+- if (PageReserved(page))
+- continue;
+-
+- nid = page_to_nid(page);
+- if (!node_isset(nid, node_states[N_HIGH_MEMORY]))
+- continue;
+-
+ gather_stats(page, md, pte_dirty(*pte), 1);
+
+ } while (pte++, addr += PAGE_SIZE, addr != end);
diff --git a/queue-3.0/floppy-use-del_timer_sync-in-init-cleanup.patch b/queue-3.0/floppy-use-del_timer_sync-in-init-cleanup.patch
new file mode 100644
index 0000000000..9dfe86a9da
--- /dev/null
+++ b/queue-3.0/floppy-use-del_timer_sync-in-init-cleanup.patch
@@ -0,0 +1,77 @@
+From 6c4867f6469964e34c5f4ee229a2a7f71a34c7ff Mon Sep 17 00:00:00 2001
+From: Carsten Emde <C.Emde@osadl.org>
+Date: Wed, 21 Sep 2011 10:22:11 +0200
+Subject: floppy: use del_timer_sync() in init cleanup
+
+From: Carsten Emde <C.Emde@osadl.org>
+
+commit 6c4867f6469964e34c5f4ee229a2a7f71a34c7ff upstream.
+
+When no floppy is found the module code can be released while a timer
+function is pending or about to be executed.
+
+CPU0 CPU1
+ floppy_init()
+timer_softirq()
+ spin_lock_irq(&base->lock);
+ detach_timer();
+ spin_unlock_irq(&base->lock);
+ -> Interrupt
+ del_timer();
+ return -ENODEV;
+ module_cleanup();
+ <- EOI
+ call_timer_fn();
+ OOPS
+
+Use del_timer_sync() to prevent this.
+
+Signed-off-by: Carsten Emde <C.Emde@osadl.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/block/floppy.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -4250,7 +4250,7 @@ static int __init floppy_init(void)
+ use_virtual_dma = can_use_virtual_dma & 1;
+ fdc_state[0].address = FDC1;
+ if (fdc_state[0].address == -1) {
+- del_timer(&fd_timeout);
++ del_timer_sync(&fd_timeout);
+ err = -ENODEV;
+ goto out_unreg_region;
+ }
+@@ -4261,7 +4261,7 @@ static int __init floppy_init(void)
+ fdc = 0; /* reset fdc in case of unexpected interrupt */
+ err = floppy_grab_irq_and_dma();
+ if (err) {
+- del_timer(&fd_timeout);
++ del_timer_sync(&fd_timeout);
+ err = -EBUSY;
+ goto out_unreg_region;
+ }
+@@ -4318,7 +4318,7 @@ static int __init floppy_init(void)
+ user_reset_fdc(-1, FD_RESET_ALWAYS, false);
+ }
+ fdc = 0;
+- del_timer(&fd_timeout);
++ del_timer_sync(&fd_timeout);
+ current_drive = 0;
+ initialized = true;
+ if (have_no_fdc) {
+@@ -4368,7 +4368,7 @@ out_unreg_blkdev:
+ unregister_blkdev(FLOPPY_MAJOR, "fd");
+ out_put_disk:
+ while (dr--) {
+- del_timer(&motor_off_timer[dr]);
++ del_timer_sync(&motor_off_timer[dr]);
+ if (disks[dr]->queue)
+ blk_cleanup_queue(disks[dr]->queue);
+ put_disk(disks[dr]);
diff --git a/queue-3.0/iwlagn-workaround-bug-crashing-some-aps.patch b/queue-3.0/iwlagn-workaround-bug-crashing-some-aps.patch
new file mode 100644
index 0000000000..54d624f225
--- /dev/null
+++ b/queue-3.0/iwlagn-workaround-bug-crashing-some-aps.patch
@@ -0,0 +1,38 @@
+From 2249b011432ca3dcce112f0f71e0f531b4bb9347 Mon Sep 17 00:00:00 2001
+From: Don Fry <donald.h.fry@intel.com>
+Date: Thu, 15 Sep 2011 08:36:22 -0700
+Subject: iwlagn: workaround bug crashing some APs
+
+From: Don Fry <donald.h.fry@intel.com>
+
+commit 2249b011432ca3dcce112f0f71e0f531b4bb9347 upstream.
+
+This patch reverts commit 9b7688328422b88a7a15dc0dc123ad9ab1a6e22d which
+was introduced in 2.6.38-rc1. It works around a problem where the iwlagn
+driver stimulates a bug crashing (requiring power cycle to recover) some
+APs under heavy traffic.
+
+Signed-off-by: Don Fry <donald.h.fry@intel.com>
+SIgned-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/iwlwifi/iwl-agn.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -2440,7 +2440,12 @@ static int iwl_mac_setup_register(struct
+ IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+
++ /*
++ * Including the following line will crash some AP's. This
++ * workaround removes the stimulus which causes the crash until
++ * the AP software can be fixed.
+ hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
++ */
+
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
diff --git a/queue-3.0/ixgbe-fix-possible-null-buffer-error.patch b/queue-3.0/ixgbe-fix-possible-null-buffer-error.patch
new file mode 100644
index 0000000000..c46d7adb71
--- /dev/null
+++ b/queue-3.0/ixgbe-fix-possible-null-buffer-error.patch
@@ -0,0 +1,45 @@
+From b811ce9104a7f7663ddae4f7795a194a103b8f90 Mon Sep 17 00:00:00 2001
+From: Jesse Brandeburg <jesse.brandeburg@intel.com>
+Date: Tue, 20 Sep 2011 15:13:03 +0000
+Subject: ixgbe: fix possible null buffer error
+
+From: Jesse Brandeburg <jesse.brandeburg@intel.com>
+
+commit b811ce9104a7f7663ddae4f7795a194a103b8f90 upstream.
+
+It seems that at least one PPC machine would occasionally give a (valid) 0 as
+the return value from dma_map, this caused the ixgbe code to not work
+correctly. A fix is pending in the PPC tree to not return 0 from dma map, but
+we can also fix the driver to make sure we don't mess up in other arches as
+well.
+
+This patch is applicable to all current stable kernels.
+
+Ref: https://bugzilla.redhat.com/show_bug.cgi?id=683611
+
+Reported-by: Neil Horman <nhorman@redhat.com>
+Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
+CC: Alexander Duyck <alexander.h.duyck@intel.com>
+Tested-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/ixgbe/ixgbe_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ixgbe/ixgbe_main.c
++++ b/drivers/net/ixgbe/ixgbe_main.c
+@@ -1366,8 +1366,8 @@ static void ixgbe_clean_rx_irq(struct ix
+ if (ring_is_rsc_enabled(rx_ring))
+ pkt_is_rsc = ixgbe_get_rsc_state(rx_desc);
+
+- /* if this is a skb from previous receive DMA will be 0 */
+- if (rx_buffer_info->dma) {
++ /* linear means we are building an skb from multiple pages */
++ if (!skb_is_nonlinear(skb)) {
+ u16 hlen;
+ if (pkt_is_rsc &&
+ !(staterr & IXGBE_RXD_STAT_EOP) &&
diff --git a/queue-3.0/make-proc-pid-numa_maps-gather_stats-take-variable-page.patch b/queue-3.0/make-proc-pid-numa_maps-gather_stats-take-variable-page.patch
new file mode 100644
index 0000000000..053057e2ed
--- /dev/null
+++ b/queue-3.0/make-proc-pid-numa_maps-gather_stats-take-variable-page.patch
@@ -0,0 +1,98 @@
+From eb4866d0066ffd5446751c102d64feb3318d8bd1 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+Date: Tue, 20 Sep 2011 15:19:38 -0700
+Subject: make /proc/$pid/numa_maps gather_stats() take variable page
+ size
+
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+
+commit eb4866d0066ffd5446751c102d64feb3318d8bd1 upstream.
+
+We need to teach the numa_maps code about transparent huge pages. The
+first step is to teach gather_stats() that the pte it is dealing with
+might represent more than one page.
+
+Note that will we use this in a moment for transparent huge pages since
+they have use a single pmd_t which _acts_ as a "surrogate" for a bunch
+of smaller pte_t's.
+
+I'm a _bit_ unhappy that this interface counts in hugetlbfs page sizes
+for hugetlbfs pages and PAGE_SIZE for normal pages. That means that to
+figure out how many _bytes_ "dirty=1" means, you must first know the
+hugetlbfs page size. That's easier said than done especially if you
+don't have visibility in to the mount.
+
+But, that's probably a discussion for another day especially since it
+would change behavior to fix it. But, just in case anyone wonders why
+this patch only passes a '1' in the hugetlb case...
+
+Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/task_mmu.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -877,30 +877,31 @@ struct numa_maps_private {
+ struct numa_maps md;
+ };
+
+-static void gather_stats(struct page *page, struct numa_maps *md, int pte_dirty)
++static void gather_stats(struct page *page, struct numa_maps *md, int pte_dirty,
++ unsigned long nr_pages)
+ {
+ int count = page_mapcount(page);
+
+- md->pages++;
++ md->pages += nr_pages;
+ if (pte_dirty || PageDirty(page))
+- md->dirty++;
++ md->dirty += nr_pages;
+
+ if (PageSwapCache(page))
+- md->swapcache++;
++ md->swapcache += nr_pages;
+
+ if (PageActive(page) || PageUnevictable(page))
+- md->active++;
++ md->active += nr_pages;
+
+ if (PageWriteback(page))
+- md->writeback++;
++ md->writeback += nr_pages;
+
+ if (PageAnon(page))
+- md->anon++;
++ md->anon += nr_pages;
+
+ if (count > md->mapcount_max)
+ md->mapcount_max = count;
+
+- md->node[page_to_nid(page)]++;
++ md->node[page_to_nid(page)] += nr_pages;
+ }
+
+ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
+@@ -931,7 +932,7 @@ static int gather_pte_stats(pmd_t *pmd,
+ if (!node_isset(nid, node_states[N_HIGH_MEMORY]))
+ continue;
+
+- gather_stats(page, md, pte_dirty(*pte));
++ gather_stats(page, md, pte_dirty(*pte), 1);
+
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ pte_unmap_unlock(orig_pte, ptl);
+@@ -952,7 +953,7 @@ static int gather_hugetbl_stats(pte_t *p
+ return 0;
+
+ md = walk->private;
+- gather_stats(page, md, pte_dirty(*pte));
++ gather_stats(page, md, pte_dirty(*pte), 1);
+ return 0;
+ }
+
diff --git a/queue-3.0/rt2800pci-fix-compiler-error-on-powerpc.patch b/queue-3.0/rt2800pci-fix-compiler-error-on-powerpc.patch
new file mode 100644
index 0000000000..11e0611534
--- /dev/null
+++ b/queue-3.0/rt2800pci-fix-compiler-error-on-powerpc.patch
@@ -0,0 +1,60 @@
+From d331eb51e4d4190b2178c30fcafea54a94a577e8 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Wed, 14 Sep 2011 16:50:22 -0500
+Subject: rt2800pci: Fix compiler error on PowerPC
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit d331eb51e4d4190b2178c30fcafea54a94a577e8 upstream.
+
+Using gcc 4.4.5 on a Powerbook G4 with a PPC cpu, a complicated
+if statement results in incorrect flow, whereas the equivalent switch
+statement works correctly.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3685,19 +3685,23 @@ int rt2800_init_eeprom(struct rt2x00_dev
+ return -ENODEV;
+ }
+
+- if (!rt2x00_rf(rt2x00dev, RF2820) &&
+- !rt2x00_rf(rt2x00dev, RF2850) &&
+- !rt2x00_rf(rt2x00dev, RF2720) &&
+- !rt2x00_rf(rt2x00dev, RF2750) &&
+- !rt2x00_rf(rt2x00dev, RF3020) &&
+- !rt2x00_rf(rt2x00dev, RF2020) &&
+- !rt2x00_rf(rt2x00dev, RF3021) &&
+- !rt2x00_rf(rt2x00dev, RF3022) &&
+- !rt2x00_rf(rt2x00dev, RF3052) &&
+- !rt2x00_rf(rt2x00dev, RF3320) &&
+- !rt2x00_rf(rt2x00dev, RF5370) &&
+- !rt2x00_rf(rt2x00dev, RF5390)) {
+- ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
++ switch (rt2x00dev->chip.rf) {
++ case RF2820:
++ case RF2850:
++ case RF2720:
++ case RF2750:
++ case RF3020:
++ case RF2020:
++ case RF3021:
++ case RF3022:
++ case RF3052:
++ case RF3320:
++ case RF5370:
++ case RF5390:
++ break;
++ default:
++ ERROR(rt2x00dev, "Invalid RF chipset 0x%x detected.\n",
++ rt2x00dev->chip.rf);
+ return -ENODEV;
+ }
+
diff --git a/queue-3.0/rtl2800usb-fix-incorrect-storage-of-mac-address-on.patch b/queue-3.0/rtl2800usb-fix-incorrect-storage-of-mac-address-on.patch
new file mode 100644
index 0000000000..00e7ea908d
--- /dev/null
+++ b/queue-3.0/rtl2800usb-fix-incorrect-storage-of-mac-address-on.patch
@@ -0,0 +1,48 @@
+From daabead1c32f331edcfb255fd973411c667977e8 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Wed, 14 Sep 2011 16:50:23 -0500
+Subject: rtl2800usb: Fix incorrect storage of MAC address on
+ big-endian platforms
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit daabead1c32f331edcfb255fd973411c667977e8 upstream.
+
+The eeprom data is stored in little-endian order in the rt2x00 library.
+As it was converted to cpu order in the read routines, the data need to
+be converted to LE on a big-endian platform.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/rt2x00/rt2800lib.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3512,14 +3512,15 @@ static void rt2800_efuse_read(struct rt2
+ rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, &reg);
+
+ /* Apparently the data is read from end to start */
+- rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3,
+- (u32 *)&rt2x00dev->eeprom[i]);
+- rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2,
+- (u32 *)&rt2x00dev->eeprom[i + 2]);
+- rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1,
+- (u32 *)&rt2x00dev->eeprom[i + 4]);
+- rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0,
+- (u32 *)&rt2x00dev->eeprom[i + 6]);
++ rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
++ /* The returned value is in CPU order, but eeprom is le */
++ rt2x00dev->eeprom[i] = cpu_to_le32(reg);
++ rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
++ *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
++ rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
++ *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg);
++ rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, &reg);
++ *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg);
+
+ mutex_unlock(&rt2x00dev->csr_mutex);
+ }
diff --git a/queue-3.0/series b/queue-3.0/series
index 8bc08bb44c..aa120adeea 100644
--- a/queue-3.0/series
+++ b/queue-3.0/series
@@ -140,3 +140,17 @@ alsa-hda-realtek-fix-auto-mute-with-hp-lo-configuration.patch
cifs-fix-possible-memory-corruption-in-cifsfindnext.patch
fix-the-conflict-between-rwpidforward-and-rw-mount-options.patch
arm-dove-fix-second-spi-initialization-call.patch
+floppy-use-del_timer_sync-in-init-cleanup.patch
+b43-fix-beacon-problem-in-ad-hoc-mode.patch
+ixgbe-fix-possible-null-buffer-error.patch
+xz-fix-incorrect-xz_buf_error.patch
+rt2800pci-fix-compiler-error-on-powerpc.patch
+make-proc-pid-numa_maps-gather_stats-take-variable-page.patch
+break-out-numa_maps-gather_pte_stats-checks.patch
+teach-proc-pid-numa_maps-about-transparent-hugepages.patch
+xen-use-maximum-reservation-to-limit-amount-of-usable-ram.patch
+xen-e820-if-there-is-no-dom0_mem-don-t-tweak-extra_pages.patch
+wireless-reset-beacon_found-while-updating-regulatory.patch
+rtl2800usb-fix-incorrect-storage-of-mac-address-on.patch
+iwlagn-workaround-bug-crashing-some-aps.patch
+blk-cgroup-be-able-to-remove-the-record-of-unplugged-device.patch
diff --git a/queue-3.0/teach-proc-pid-numa_maps-about-transparent-hugepages.patch b/queue-3.0/teach-proc-pid-numa_maps-about-transparent-hugepages.patch
new file mode 100644
index 0000000000..12556daf02
--- /dev/null
+++ b/queue-3.0/teach-proc-pid-numa_maps-about-transparent-hugepages.patch
@@ -0,0 +1,55 @@
+From 32ef43848f283e0ef945d3c67e851c143fea3970 Mon Sep 17 00:00:00 2001
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+Date: Tue, 20 Sep 2011 15:19:41 -0700
+Subject: teach /proc/$pid/numa_maps about transparent hugepages
+
+From: Dave Hansen <dave@linux.vnet.ibm.com>
+
+commit 32ef43848f283e0ef945d3c67e851c143fea3970 upstream.
+
+This is modeled after the smaps code.
+
+It detects transparent hugepages and then does a single gather_stats()
+for the page as a whole. This has two benifits:
+ 1. It is more efficient since it does many pages in a single shot.
+ 2. It does not have to break down the huge page.
+
+Signed-off-by: Dave Hansen <dave@linux.vnet.ibm.com>
+Acked-by: Hugh Dickins <hughd@google.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/task_mmu.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -936,6 +936,26 @@ static int gather_pte_stats(pmd_t *pmd,
+ pte_t *pte;
+
+ md = walk->private;
++ spin_lock(&walk->mm->page_table_lock);
++ if (pmd_trans_huge(*pmd)) {
++ if (pmd_trans_splitting(*pmd)) {
++ spin_unlock(&walk->mm->page_table_lock);
++ wait_split_huge_page(md->vma->anon_vma, pmd);
++ } else {
++ pte_t huge_pte = *(pte_t *)pmd;
++ struct page *page;
++
++ page = can_gather_numa_stats(huge_pte, md->vma, addr);
++ if (page)
++ gather_stats(page, md, pte_dirty(huge_pte),
++ HPAGE_PMD_SIZE/PAGE_SIZE);
++ spin_unlock(&walk->mm->page_table_lock);
++ return 0;
++ }
++ } else {
++ spin_unlock(&walk->mm->page_table_lock);
++ }
++
+ orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+ do {
+ struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
diff --git a/queue-3.0/wireless-reset-beacon_found-while-updating-regulatory.patch b/queue-3.0/wireless-reset-beacon_found-while-updating-regulatory.patch
new file mode 100644
index 0000000000..d66a39b36b
--- /dev/null
+++ b/queue-3.0/wireless-reset-beacon_found-while-updating-regulatory.patch
@@ -0,0 +1,39 @@
+From aa3d7eef398dd4f29045e9889b817d5161afe03e Mon Sep 17 00:00:00 2001
+From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Date: Wed, 14 Sep 2011 14:28:17 +0530
+Subject: wireless: Reset beacon_found while updating regulatory
+
+From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+
+commit aa3d7eef398dd4f29045e9889b817d5161afe03e upstream.
+
+During the association, the regulatory is updated by country IE
+that reaps the previously found beacons. The impact is that
+after a STA disconnects *or* when for any reason a regulatory
+domain change happens the beacon hint flag is not cleared
+therefore preventing future beacon hints to be learned.
+This is important as a regulatory domain change or a restore
+of regulatory settings would set back the passive scan and no-ibss
+flags on the channel. This is the right place to do this given that
+it covers any regulatory domain change.
+
+Reviewed-by: Luis R. Rodriguez <mcgrof@gmail.com>
+Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
+Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ net/wireless/reg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -852,6 +852,7 @@ static void handle_channel(struct wiphy
+ return;
+ }
+
++ chan->beacon_found = false;
+ chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
+ chan->max_antenna_gain = min(chan->orig_mag,
+ (int) MBI_TO_DBI(power_rule->max_antenna_gain));
diff --git a/queue-3.0/xen-e820-if-there-is-no-dom0_mem-don-t-tweak-extra_pages.patch b/queue-3.0/xen-e820-if-there-is-no-dom0_mem-don-t-tweak-extra_pages.patch
new file mode 100644
index 0000000000..664f0c8a47
--- /dev/null
+++ b/queue-3.0/xen-e820-if-there-is-no-dom0_mem-don-t-tweak-extra_pages.patch
@@ -0,0 +1,78 @@
+From e3b73c4a25e9a5705b4ef28b91676caf01f9bc9f Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Tue, 13 Sep 2011 10:17:32 -0400
+Subject: xen/e820: if there is no dom0_mem=, don't tweak extra_pages.
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+commit e3b73c4a25e9a5705b4ef28b91676caf01f9bc9f upstream.
+
+The patch "xen: use maximum reservation to limit amount of usable RAM"
+(d312ae878b6aed3912e1acaaf5d0b2a9d08a4f11) breaks machines that
+do not use 'dom0_mem=' argument with:
+
+reserve RAM buffer: 000000133f2e2000 - 000000133fffffff
+(XEN) mm.c:4976:d0 Global bit is set to kernel page fffff8117e
+(XEN) domain_crash_sync called from entry.S
+(XEN) Domain 0 (vcpu#0) crashed on cpu#0:
+...
+
+The reason being that the last E820 entry is created using the
+'extra_pages' (which is based on how many pages have been freed).
+The mentioned git commit sets the initial value of 'extra_pages'
+using a hypercall which returns the number of pages (if dom0_mem
+has been used) or -1 otherwise. If the later we return with
+MAX_DOMAIN_PAGES as basis for calculation:
+
+ return min(max_pages, MAX_DOMAIN_PAGES);
+
+and use it:
+
+ extra_limit = xen_get_max_pages();
+ if (extra_limit >= max_pfn)
+ extra_pages = extra_limit - max_pfn;
+ else
+ extra_pages = 0;
+
+which means we end up with extra_pages = 128GB in PFNs (33554432)
+- 8GB in PFNs (2097152, on this specific box, can be larger or smaller),
+and then we add that value to the E820 making it:
+
+ Xen: 00000000ff000000 - 0000000100000000 (reserved)
+ Xen: 0000000100000000 - 000000133f2e2000 (usable)
+
+which is clearly wrong. It should look as so:
+
+ Xen: 00000000ff000000 - 0000000100000000 (reserved)
+ Xen: 0000000100000000 - 000000027fbda000 (usable)
+
+Naturally this problem does not present itself if dom0_mem=max:X
+is used.
+
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/xen/setup.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -307,10 +307,12 @@ char * __init xen_memory_setup(void)
+ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+
+ extra_limit = xen_get_max_pages();
+- if (extra_limit >= max_pfn)
+- extra_pages = extra_limit - max_pfn;
+- else
+- extra_pages = 0;
++ if (max_pfn + extra_pages > extra_limit) {
++ if (extra_limit > max_pfn)
++ extra_pages = extra_limit - max_pfn;
++ else
++ extra_pages = 0;
++ }
+
+ extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+
diff --git a/queue-3.0/xen-use-maximum-reservation-to-limit-amount-of-usable-ram.patch b/queue-3.0/xen-use-maximum-reservation-to-limit-amount-of-usable-ram.patch
new file mode 100644
index 0000000000..83cf0472ec
--- /dev/null
+++ b/queue-3.0/xen-use-maximum-reservation-to-limit-amount-of-usable-ram.patch
@@ -0,0 +1,75 @@
+From d312ae878b6aed3912e1acaaf5d0b2a9d08a4f11 Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Fri, 19 Aug 2011 15:57:16 +0100
+Subject: xen: use maximum reservation to limit amount of usable RAM
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+commit d312ae878b6aed3912e1acaaf5d0b2a9d08a4f11 upstream.
+
+Use the domain's maximum reservation to limit the amount of extra RAM
+for the memory balloon. This reduces the size of the pages tables and
+the amount of reserved low memory (which defaults to about 1/32 of the
+total RAM).
+
+On a system with 8 GiB of RAM with the domain limited to 1 GiB the
+kernel reports:
+
+Before:
+
+Memory: 627792k/4472000k available
+
+After:
+
+Memory: 549740k/11132224k available
+
+A increase of about 76 MiB (~1.5% of the unused 7 GiB). The reserved
+low memory is also reduced from 253 MiB to 32 MiB. The total
+additional usable RAM is 329 MiB.
+
+For dom0, this requires at patch to Xen ('x86: use 'dom0_mem' to limit
+the number of pages for dom0') (c/s 23790)
+
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86/xen/setup.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -185,6 +185,19 @@ static unsigned long __init xen_set_iden
+ PFN_UP(start_pci), PFN_DOWN(last));
+ return identity;
+ }
++
++static unsigned long __init xen_get_max_pages(void)
++{
++ unsigned long max_pages = MAX_DOMAIN_PAGES;
++ domid_t domid = DOMID_SELF;
++ int ret;
++
++ ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid);
++ if (ret > 0)
++ max_pages = ret;
++ return min(max_pages, MAX_DOMAIN_PAGES);
++}
++
+ /**
+ * machine_specific_memory_setup - Hook for machine specific memory setup.
+ **/
+@@ -293,6 +306,12 @@ char * __init xen_memory_setup(void)
+
+ sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
+
++ extra_limit = xen_get_max_pages();
++ if (extra_limit >= max_pfn)
++ extra_pages = extra_limit - max_pfn;
++ else
++ extra_pages = 0;
++
+ extra_pages += xen_return_unused_memory(xen_start_info->nr_pages, &e820);
+
+ /*
diff --git a/queue-3.0/xz-fix-incorrect-xz_buf_error.patch b/queue-3.0/xz-fix-incorrect-xz_buf_error.patch
new file mode 100644
index 0000000000..feb075ec08
--- /dev/null
+++ b/queue-3.0/xz-fix-incorrect-xz_buf_error.patch
@@ -0,0 +1,93 @@
+From 9c1f8594df4814ebfd6822ca3c9444fb3445888d Mon Sep 17 00:00:00 2001
+From: Lasse Collin <lasse.collin@tukaani.org>
+Date: Wed, 21 Sep 2011 17:30:50 +0300
+Subject: XZ: Fix incorrect XZ_BUF_ERROR
+
+From: Lasse Collin <lasse.collin@tukaani.org>
+
+commit 9c1f8594df4814ebfd6822ca3c9444fb3445888d upstream.
+
+xz_dec_run() could incorrectly return XZ_BUF_ERROR if all of the
+following was true:
+
+ - The caller knows how many bytes of output to expect and only provides
+ that much output space.
+
+ - When the last output bytes are decoded, the caller-provided input
+ buffer ends right before the LZMA2 end of payload marker. So LZMA2
+ won't provide more output anymore, but it won't know it yet and thus
+ won't return XZ_STREAM_END yet.
+
+ - A BCJ filter is in use and it hasn't left any unfiltered bytes in the
+ temp buffer. This can happen with any BCJ filter, but in practice
+ it's more likely with filters other than the x86 BCJ.
+
+This fixes <https://bugzilla.redhat.com/show_bug.cgi?id=735408> where
+Squashfs thinks that a valid file system is corrupt.
+
+This also fixes a similar bug in single-call mode where the uncompressed
+size of a block using BCJ + LZMA2 was 0 bytes and caller provided no
+output space. Many empty .xz files don't contain any blocks and thus
+don't trigger this bug.
+
+This also tweaks a closely related detail: xz_dec_bcj_run() could call
+xz_dec_lzma2_run() to decode into temp buffer when it was known to be
+useless. This was harmless although it wasted a minuscule number of CPU
+cycles.
+
+Signed-off-by: Lasse Collin <lasse.collin@tukaani.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ lib/xz/xz_dec_bcj.c | 27 ++++++++++++++++++++-------
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+--- a/lib/xz/xz_dec_bcj.c
++++ b/lib/xz/xz_dec_bcj.c
+@@ -441,8 +441,12 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(str
+ * next filter in the chain. Apply the BCJ filter on the new data
+ * in the output buffer. If everything cannot be filtered, copy it
+ * to temp and rewind the output buffer position accordingly.
++ *
++ * This needs to be always run when temp.size == 0 to handle a special
++ * case where the output buffer is full and the next filter has no
++ * more output coming but hasn't returned XZ_STREAM_END yet.
+ */
+- if (s->temp.size < b->out_size - b->out_pos) {
++ if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) {
+ out_start = b->out_pos;
+ memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size);
+ b->out_pos += s->temp.size;
+@@ -465,16 +469,25 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(str
+ s->temp.size = b->out_pos - out_start;
+ b->out_pos -= s->temp.size;
+ memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size);
++
++ /*
++ * If there wasn't enough input to the next filter to fill
++ * the output buffer with unfiltered data, there's no point
++ * to try decoding more data to temp.
++ */
++ if (b->out_pos + s->temp.size < b->out_size)
++ return XZ_OK;
+ }
+
+ /*
+- * If we have unfiltered data in temp, try to fill by decoding more
+- * data from the next filter. Apply the BCJ filter on temp. Then we
+- * hopefully can fill the actual output buffer by copying filtered
+- * data from temp. A mix of filtered and unfiltered data may be left
+- * in temp; it will be taken care on the next call to this function.
++ * We have unfiltered data in temp. If the output buffer isn't full
++ * yet, try to fill the temp buffer by decoding more data from the
++ * next filter. Apply the BCJ filter on temp. Then we hopefully can
++ * fill the actual output buffer by copying filtered data from temp.
++ * A mix of filtered and unfiltered data may be left in temp; it will
++ * be taken care on the next call to this function.
+ */
+- if (s->temp.size > 0) {
++ if (b->out_pos < b->out_size) {
+ /* Make b->out{,_pos,_size} temporarily point to s->temp. */
+ s->out = b->out;
+ s->out_pos = b->out_pos;