]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 6 Dec 2012 18:43:49 +0000 (10:43 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 6 Dec 2012 18:43:49 +0000 (10:43 -0800)
added patches:
bnx2x-remove-redundant-warning-log.patch
i7300_edac-fix-error-flag-testing.patch
md-raid10-close-race-that-lose-writes-lost-when-replacement-completes.patch
revert-sched-autogroup-stop-going-ahead-if-autogroup-is-disabled.patch
workqueue-exit-rescuer_thread-as-task_running.patch

queue-3.4/bnx2x-remove-redundant-warning-log.patch [new file with mode: 0644]
queue-3.4/i7300_edac-fix-error-flag-testing.patch [new file with mode: 0644]
queue-3.4/md-raid10-close-race-that-lose-writes-lost-when-replacement-completes.patch [new file with mode: 0644]
queue-3.4/revert-sched-autogroup-stop-going-ahead-if-autogroup-is-disabled.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/workqueue-exit-rescuer_thread-as-task_running.patch [new file with mode: 0644]

diff --git a/queue-3.4/bnx2x-remove-redundant-warning-log.patch b/queue-3.4/bnx2x-remove-redundant-warning-log.patch
new file mode 100644 (file)
index 0000000..555984c
--- /dev/null
@@ -0,0 +1,43 @@
+From 4a25417c20fac00b3afd58ce27408f964d19e708 Mon Sep 17 00:00:00 2001
+From: Ariel Elior <ariele@broadcom.com>
+Date: Thu, 22 Nov 2012 07:16:17 +0000
+Subject: bnx2x: remove redundant warning log
+
+From: Ariel Elior <ariele@broadcom.com>
+
+commit 4a25417c20fac00b3afd58ce27408f964d19e708 upstream.
+
+fix bug where a register which was only meant to be read in 578xx/57712
+devices causes a bogus error message to be logged when read from other
+devices.
+
+Signed-off-by: Ariel Elior <ariele@broadcom.com>
+Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: CAI Qian <caiqian@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c |   11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+@@ -9131,10 +9131,13 @@ static int __devinit bnx2x_prev_unload_c
+  */
+ static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp)
+ {
+-      u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
+-      if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
+-              BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
+-              REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp));
++      if (!CHIP_IS_E1x(bp)) {
++              u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
++              if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
++                      BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
++                      REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR,
++                             1 << BP_FUNC(bp));
++              }
+       }
+ }
diff --git a/queue-3.4/i7300_edac-fix-error-flag-testing.patch b/queue-3.4/i7300_edac-fix-error-flag-testing.patch
new file mode 100644 (file)
index 0000000..4cb4b72
--- /dev/null
@@ -0,0 +1,59 @@
+From 7e06b7a3333f5c7a0cec12aff20d39c5c87c0795 Mon Sep 17 00:00:00 2001
+From: Jean Delvare <jdelvare@suse.de>
+Date: Thu, 18 Oct 2012 15:54:45 +0200
+Subject: i7300_edac: Fix error flag testing
+
+From: Jean Delvare <jdelvare@suse.de>
+
+commit 7e06b7a3333f5c7a0cec12aff20d39c5c87c0795 upstream.
+
+* Right-shift the values in GET_FBD_FAT_IDX and GET_FBD_NF_IDX, so
+  that the callers get the result they expect.
+* Fix definition of FERR_FAT_FBD_ERR_MASK.
+* Call GET_FBD_NF_IDX, not GET_FBD_FAT_IDX, when operating on
+  register FERR_NF_FBD. We were lucky they have the same definition.
+
+This fixes kernel bug #44131:
+https://bugzilla.kernel.org/show_bug.cgi?id=44131
+
+Signed-off-by: Jean Delvare <jdelvare@suse.de>
+Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
+Cc: Doug Thompson <dougthompson@xmission.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/edac/i7300_edac.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/edac/i7300_edac.c
++++ b/drivers/edac/i7300_edac.c
+@@ -215,8 +215,8 @@ static const char *ferr_fat_fbd_name[] =
+       [0]  = "Memory Write error on non-redundant retry or "
+              "FBD configuration Write error on retry",
+ };
+-#define GET_FBD_FAT_IDX(fbderr)       (fbderr & (3 << 28))
+-#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
++#define GET_FBD_FAT_IDX(fbderr)       (((fbderr) >> 28) & 3)
++#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22))
+ #define FERR_NF_FBD   0xa0
+ static const char *ferr_nf_fbd_name[] = {
+@@ -243,7 +243,7 @@ static const char *ferr_nf_fbd_name[] =
+       [1]  = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
+       [0]  = "Uncorrectable Data ECC on Replay",
+ };
+-#define GET_FBD_NF_IDX(fbderr)        (fbderr & (3 << 28))
++#define GET_FBD_NF_IDX(fbderr)        (((fbderr) >> 28) & 3)
+ #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
+                             (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
+                             (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
+@@ -485,7 +485,7 @@ static void i7300_process_fbd_error(stru
+               errnum = find_first_bit(&errors,
+                                       ARRAY_SIZE(ferr_nf_fbd_name));
+               specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
+-              branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0;
++              branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0;
+               pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
+                       REDMEMA, &syndrome);
diff --git a/queue-3.4/md-raid10-close-race-that-lose-writes-lost-when-replacement-completes.patch b/queue-3.4/md-raid10-close-race-that-lose-writes-lost-when-replacement-completes.patch
new file mode 100644 (file)
index 0000000..2887635
--- /dev/null
@@ -0,0 +1,171 @@
+From e7c0c3fa29280d62aa5e11101a674bb3064bd791 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Thu, 22 Nov 2012 14:42:49 +1100
+Subject: md/raid10: close race that lose writes lost when replacement completes.
+
+From: NeilBrown <neilb@suse.de>
+
+commit e7c0c3fa29280d62aa5e11101a674bb3064bd791 upstream.
+
+When a replacement operation completes there is a small window
+when the original device is marked 'faulty' and the replacement
+still looks like a replacement.  The faulty should be removed and
+the replacement moved in place very quickly, bit it isn't instant.
+
+So the code write out to the array must handle the possibility that
+the only working device for some slot in the replacement - but it
+doesn't.  If the primary device is faulty it just gives up.  This
+can lead to corruption.
+
+So make the code more robust: if either  the primary or the
+replacement is present and working, write to them.  Only when
+neither are present do we give up.
+
+This bug has been present since replacement was introduced in
+3.3, so it is suitable for any -stable kernel since then.
+
+Reported-by: "George Spelvin" <linux@horizon.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid10.c |  104 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 55 insertions(+), 49 deletions(-)
+
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -1182,18 +1182,21 @@ retry_write:
+                       blocked_rdev = rrdev;
+                       break;
+               }
++              if (rdev && (test_bit(Faulty, &rdev->flags)
++                           || test_bit(Unmerged, &rdev->flags)))
++                      rdev = NULL;
+               if (rrdev && (test_bit(Faulty, &rrdev->flags)
+                             || test_bit(Unmerged, &rrdev->flags)))
+                       rrdev = NULL;
+               r10_bio->devs[i].bio = NULL;
+               r10_bio->devs[i].repl_bio = NULL;
+-              if (!rdev || test_bit(Faulty, &rdev->flags) ||
+-                  test_bit(Unmerged, &rdev->flags)) {
++
++              if (!rdev && !rrdev) {
+                       set_bit(R10BIO_Degraded, &r10_bio->state);
+                       continue;
+               }
+-              if (test_bit(WriteErrorSeen, &rdev->flags)) {
++              if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
+                       sector_t first_bad;
+                       sector_t dev_sector = r10_bio->devs[i].addr;
+                       int bad_sectors;
+@@ -1235,8 +1238,10 @@ retry_write:
+                                       max_sectors = good_sectors;
+                       }
+               }
+-              r10_bio->devs[i].bio = bio;
+-              atomic_inc(&rdev->nr_pending);
++              if (rdev) {
++                      r10_bio->devs[i].bio = bio;
++                      atomic_inc(&rdev->nr_pending);
++              }
+               if (rrdev) {
+                       r10_bio->devs[i].repl_bio = bio;
+                       atomic_inc(&rrdev->nr_pending);
+@@ -1292,51 +1297,52 @@ retry_write:
+       for (i = 0; i < conf->copies; i++) {
+               struct bio *mbio;
+               int d = r10_bio->devs[i].devnum;
+-              if (!r10_bio->devs[i].bio)
+-                      continue;
+-
+-              mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+-              md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+-                          max_sectors);
+-              r10_bio->devs[i].bio = mbio;
+-
+-              mbio->bi_sector = (r10_bio->devs[i].addr+
+-                                 conf->mirrors[d].rdev->data_offset);
+-              mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
+-              mbio->bi_end_io = raid10_end_write_request;
+-              mbio->bi_rw = WRITE | do_sync | do_fua;
+-              mbio->bi_private = r10_bio;
+-
+-              atomic_inc(&r10_bio->remaining);
+-              spin_lock_irqsave(&conf->device_lock, flags);
+-              bio_list_add(&conf->pending_bio_list, mbio);
+-              conf->pending_count++;
+-              spin_unlock_irqrestore(&conf->device_lock, flags);
+-
+-              if (!r10_bio->devs[i].repl_bio)
+-                      continue;
++              if (r10_bio->devs[i].bio) {
++                      struct md_rdev *rdev = conf->mirrors[d].rdev;
++                      mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
++                      md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
++                                  max_sectors);
++                      r10_bio->devs[i].bio = mbio;
++
++                      mbio->bi_sector = (r10_bio->devs[i].addr+
++                                         rdev->data_offset);
++                      mbio->bi_bdev = rdev->bdev;
++                      mbio->bi_end_io = raid10_end_write_request;
++                      mbio->bi_rw = WRITE | do_sync | do_fua;
++                      mbio->bi_private = r10_bio;
++
++                      atomic_inc(&r10_bio->remaining);
++                      spin_lock_irqsave(&conf->device_lock, flags);
++                      bio_list_add(&conf->pending_bio_list, mbio);
++                      conf->pending_count++;
++                      spin_unlock_irqrestore(&conf->device_lock, flags);
++              }
+-              mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
+-              md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
+-                          max_sectors);
+-              r10_bio->devs[i].repl_bio = mbio;
+-
+-              /* We are actively writing to the original device
+-               * so it cannot disappear, so the replacement cannot
+-               * become NULL here
+-               */
+-              mbio->bi_sector = (r10_bio->devs[i].addr+
+-                                 conf->mirrors[d].replacement->data_offset);
+-              mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
+-              mbio->bi_end_io = raid10_end_write_request;
+-              mbio->bi_rw = WRITE | do_sync | do_fua;
+-              mbio->bi_private = r10_bio;
+-
+-              atomic_inc(&r10_bio->remaining);
+-              spin_lock_irqsave(&conf->device_lock, flags);
+-              bio_list_add(&conf->pending_bio_list, mbio);
+-              conf->pending_count++;
+-              spin_unlock_irqrestore(&conf->device_lock, flags);
++              if (r10_bio->devs[i].repl_bio) {
++                      struct md_rdev *rdev = conf->mirrors[d].replacement;
++                      if (rdev == NULL) {
++                              /* Replacement just got moved to main 'rdev' */
++                              smp_mb();
++                              rdev = conf->mirrors[d].rdev;
++                      }
++                      mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
++                      md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
++                                  max_sectors);
++                      r10_bio->devs[i].repl_bio = mbio;
++
++                      mbio->bi_sector = (r10_bio->devs[i].addr+
++                                         rdev->data_offset);
++                      mbio->bi_bdev = rdev->bdev;
++                      mbio->bi_end_io = raid10_end_write_request;
++                      mbio->bi_rw = WRITE | do_sync | do_fua;
++                      mbio->bi_private = r10_bio;
++
++                      atomic_inc(&r10_bio->remaining);
++                      spin_lock_irqsave(&conf->device_lock, flags);
++                      bio_list_add(&conf->pending_bio_list, mbio);
++                      conf->pending_count++;
++                      spin_unlock_irqrestore(&conf->device_lock, flags);
++              }
+       }
+       /* Don't remove the bias on 'remaining' (one_write_done) until
diff --git a/queue-3.4/revert-sched-autogroup-stop-going-ahead-if-autogroup-is-disabled.patch b/queue-3.4/revert-sched-autogroup-stop-going-ahead-if-autogroup-is-disabled.patch
new file mode 100644 (file)
index 0000000..01a4de9
--- /dev/null
@@ -0,0 +1,89 @@
+From fd8ef11730f1d03d5d6555aa53126e9e34f52f12 Mon Sep 17 00:00:00 2001
+From: Mike Galbraith <efault@gmx.de>
+Date: Mon, 3 Dec 2012 06:25:25 +0100
+Subject: Revert "sched, autogroup: Stop going ahead if autogroup is disabled"
+
+From: Mike Galbraith <efault@gmx.de>
+
+commit fd8ef11730f1d03d5d6555aa53126e9e34f52f12 upstream.
+
+This reverts commit 800d4d30c8f20bd728e5741a3b77c4859a613f7c.
+
+Between commits 8323f26ce342 ("sched: Fix race in task_group()") and
+800d4d30c8f2 ("sched, autogroup: Stop going ahead if autogroup is
+disabled"), autogroup is a wreck.
+
+With both applied, all you have to do to crash a box is disable
+autogroup during boot up, then reboot..  boom, NULL pointer dereference
+due to commit 800d4d30c8f2 not allowing autogroup to move things, and
+commit 8323f26ce342 making that the only way to switch runqueues:
+
+  BUG: unable to handle kernel NULL pointer dereference at           (null)
+  IP: [<ffffffff81063ac0>] effective_load.isra.43+0x50/0x90
+  Pid: 7047, comm: systemd-user-se Not tainted 3.6.8-smp #7 MEDIONPC MS-7502/MS-7502
+  RIP: effective_load.isra.43+0x50/0x90
+  Process systemd-user-se (pid: 7047, threadinfo ffff880221dde000, task ffff88022618b3a0)
+  Call Trace:
+    select_task_rq_fair+0x255/0x780
+    try_to_wake_up+0x156/0x2c0
+    wake_up_state+0xb/0x10
+    signal_wake_up+0x28/0x40
+    complete_signal+0x1d6/0x250
+    __send_signal+0x170/0x310
+    send_signal+0x40/0x80
+    do_send_sig_info+0x47/0x90
+    group_send_sig_info+0x4a/0x70
+    kill_pid_info+0x3a/0x60
+    sys_kill+0x97/0x1a0
+    ? vfs_read+0x120/0x160
+    ? sys_read+0x45/0x90
+    system_call_fastpath+0x16/0x1b
+  Code: 49 0f af 41 50 31 d2 49 f7 f0 48 83 f8 01 48 0f 46 c6 48 2b 07 48 8b bf 40 01 00 00 48 85 ff 74 3a 45 31 c0 48 8b 8f 50 01 00 00 <48> 8b 11 4c 8b 89 80 00 00 00 49 89 d2 48 01 d0 45 8b 59 58 4c
+  RIP  [<ffffffff81063ac0>] effective_load.isra.43+0x50/0x90
+   RSP <ffff880221ddfbd8>
+  CR2: 0000000000000000
+
+Signed-off-by: Mike Galbraith <efault@gmx.de>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: Yong Zhang <yong.zhang0@gmail.com>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/auto_group.c |    4 ----
+ kernel/sched/auto_group.h |    5 -----
+ 2 files changed, 9 deletions(-)
+
+--- a/kernel/sched/auto_group.c
++++ b/kernel/sched/auto_group.c
+@@ -143,15 +143,11 @@ autogroup_move_group(struct task_struct
+       p->signal->autogroup = autogroup_kref_get(ag);
+-      if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled))
+-              goto out;
+-
+       t = p;
+       do {
+               sched_move_task(t);
+       } while_each_thread(p, t);
+-out:
+       unlock_task_sighand(p, &flags);
+       autogroup_kref_put(prev);
+ }
+--- a/kernel/sched/auto_group.h
++++ b/kernel/sched/auto_group.h
+@@ -4,11 +4,6 @@
+ #include <linux/rwsem.h>
+ struct autogroup {
+-      /*
+-       * reference doesn't mean how many thread attach to this
+-       * autogroup now. It just stands for the number of task
+-       * could use this autogroup.
+-       */
+       struct kref             kref;
+       struct task_group       *tg;
+       struct rw_semaphore     lock;
index c64e0644adf547603aa344ad5487fe51882a6ea3..82f00b5b34c1ed6256ea5919d02da112da36a8b7 100644 (file)
@@ -7,3 +7,8 @@ mm-vmemmap-fix-wrong-use-of-virt_to_page.patch
 mm-soft-offline-split-thp-at-the-beginning-of-soft_offline_page.patch
 arm-kirkwood-update-pci-e-fixup.patch
 x86-fpu-avoid-fpu-lazy-restore-after-suspend.patch
+workqueue-exit-rescuer_thread-as-task_running.patch
+md-raid10-close-race-that-lose-writes-lost-when-replacement-completes.patch
+i7300_edac-fix-error-flag-testing.patch
+revert-sched-autogroup-stop-going-ahead-if-autogroup-is-disabled.patch
+bnx2x-remove-redundant-warning-log.patch
diff --git a/queue-3.4/workqueue-exit-rescuer_thread-as-task_running.patch b/queue-3.4/workqueue-exit-rescuer_thread-as-task_running.patch
new file mode 100644 (file)
index 0000000..b10cb31
--- /dev/null
@@ -0,0 +1,56 @@
+From 412d32e6c98527078779e5b515823b2810e40324 Mon Sep 17 00:00:00 2001
+From: Mike Galbraith <mgalbraith@suse.de>
+Date: Wed, 28 Nov 2012 07:17:18 +0100
+Subject: workqueue: exit rescuer_thread() as TASK_RUNNING
+
+From: Mike Galbraith <mgalbraith@suse.de>
+
+commit 412d32e6c98527078779e5b515823b2810e40324 upstream.
+
+A rescue thread exiting TASK_INTERRUPTIBLE can lead to a task scheduling
+off, never to be seen again.  In the case where this occurred, an exiting
+thread hit reiserfs homebrew conditional resched while holding a mutex,
+bringing the box to its knees.
+
+PID: 18105  TASK: ffff8807fd412180  CPU: 5   COMMAND: "kdmflush"
+ #0 [ffff8808157e7670] schedule at ffffffff8143f489
+ #1 [ffff8808157e77b8] reiserfs_get_block at ffffffffa038ab2d [reiserfs]
+ #2 [ffff8808157e79a8] __block_write_begin at ffffffff8117fb14
+ #3 [ffff8808157e7a98] reiserfs_write_begin at ffffffffa0388695 [reiserfs]
+ #4 [ffff8808157e7ad8] generic_perform_write at ffffffff810ee9e2
+ #5 [ffff8808157e7b58] generic_file_buffered_write at ffffffff810eeb41
+ #6 [ffff8808157e7ba8] __generic_file_aio_write at ffffffff810f1a3a
+ #7 [ffff8808157e7c58] generic_file_aio_write at ffffffff810f1c88
+ #8 [ffff8808157e7cc8] do_sync_write at ffffffff8114f850
+ #9 [ffff8808157e7dd8] do_acct_process at ffffffff810a268f
+    [exception RIP: kernel_thread_helper]
+    RIP: ffffffff8144a5c0  RSP: ffff8808157e7f58  RFLAGS: 00000202
+    RAX: 0000000000000000  RBX: 0000000000000000  RCX: 0000000000000000
+    RDX: 0000000000000000  RSI: ffffffff8107af60  RDI: ffff8803ee491d18
+    RBP: 0000000000000000   R8: 0000000000000000   R9: 0000000000000000
+    R10: 0000000000000000  R11: 0000000000000000  R12: 0000000000000000
+    R13: 0000000000000000  R14: 0000000000000000  R15: 0000000000000000
+    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
+
+Signed-off-by: Mike Galbraith <mgalbraith@suse.de>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -2040,8 +2040,10 @@ static int rescuer_thread(void *__wq)
+ repeat:
+       set_current_state(TASK_INTERRUPTIBLE);
+-      if (kthread_should_stop())
++      if (kthread_should_stop()) {
++              __set_current_state(TASK_RUNNING);
+               return 0;
++      }
+       /*
+        * See whether any cpu is asking for help.  Unbounded