]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Oct 2017 08:57:06 +0000 (09:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 30 Oct 2017 08:57:06 +0000 (09:57 +0100)
added patches:
alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch
alsa-hda-realtek-add-support-for-alc236-alc3204.patch
ceph-unlock-dangling-spinlock-in-try_flush_caps.patch
workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch

queue-4.4/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch [new file with mode: 0644]
queue-4.4/alsa-hda-realtek-add-support-for-alc236-alc3204.patch [new file with mode: 0644]
queue-4.4/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch [new file with mode: 0644]
queue-4.4/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch [new file with mode: 0644]

diff --git a/queue-4.4/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch b/queue-4.4/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch
new file mode 100644 (file)
index 0000000..37c372d
--- /dev/null
@@ -0,0 +1,38 @@
+From f265788c336979090ac80b9ae173aa817c4fe40d Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Tue, 24 Oct 2017 16:53:34 +0800
+Subject: ALSA: hda - fix headset mic problem for Dell machines with alc236
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit f265788c336979090ac80b9ae173aa817c4fe40d upstream.
+
+We have several Dell laptops which use the codec alc236, the headset
+mic can't work on these machines. Following the commit 736f20a70, we
+add the pin cfg table to make the headset mic work.
+
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5843,6 +5843,14 @@ static const struct snd_hda_pin_quirk al
+               ALC225_STANDARD_PINS,
+               {0x12, 0xb7a60130},
+               {0x1b, 0x90170110}),
++      SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++              {0x12, 0x90a60140},
++              {0x14, 0x90170110},
++              {0x21, 0x02211020}),
++      SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++              {0x12, 0x90a60140},
++              {0x14, 0x90170150},
++              {0x21, 0x02211020}),
+       SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
+               {0x14, 0x90170110},
+               {0x21, 0x02211020}),
diff --git a/queue-4.4/alsa-hda-realtek-add-support-for-alc236-alc3204.patch b/queue-4.4/alsa-hda-realtek-add-support-for-alc236-alc3204.patch
new file mode 100644 (file)
index 0000000..bb8d20a
--- /dev/null
@@ -0,0 +1,110 @@
+From 736f20a7060857ff569e9e9586ae6c1204a73e07 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Fri, 20 Oct 2017 15:06:34 +0800
+Subject: ALSA: hda/realtek - Add support for ALC236/ALC3204
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit 736f20a7060857ff569e9e9586ae6c1204a73e07 upstream.
+
+Add support for ALC236/ALC3204.
+Add headset mode support for ALC236/ALC3204.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -329,6 +329,7 @@ static void alc_fill_eapd_coef(struct hd
+               break;
+       case 0x10ec0225:
+       case 0x10ec0233:
++      case 0x10ec0236:
+       case 0x10ec0255:
+       case 0x10ec0256:
+       case 0x10ec0282:
+@@ -909,6 +910,7 @@ static struct alc_codec_rename_pci_table
+       { 0x10ec0275, 0x1028, 0, "ALC3260" },
+       { 0x10ec0899, 0x1028, 0, "ALC3861" },
+       { 0x10ec0298, 0x1028, 0, "ALC3266" },
++      { 0x10ec0236, 0x1028, 0, "ALC3204" },
+       { 0x10ec0256, 0x1028, 0, "ALC3246" },
+       { 0x10ec0225, 0x1028, 0, "ALC3253" },
+       { 0x10ec0295, 0x1028, 0, "ALC3254" },
+@@ -3694,6 +3696,7 @@ static void alc_headset_mode_unplugged(s
+               alc_process_coef_fw(codec, coef0255_1);
+               alc_process_coef_fw(codec, coef0255);
+               break;
++      case 0x10ec0236:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, coef0256);
+               alc_process_coef_fw(codec, coef0255);
+@@ -3774,6 +3777,7 @@ static void alc_headset_mode_mic_in(stru
+       switch (codec->core.vendor_id) {
++      case 0x10ec0236:
+       case 0x10ec0255:
+       case 0x10ec0256:
+               alc_write_coef_idx(codec, 0x45, 0xc489);
+@@ -3879,6 +3883,7 @@ static void alc_headset_mode_default(str
+       case 0x10ec0295:
+               alc_process_coef_fw(codec, coef0225);
+               break;
++      case 0x10ec0236:
+       case 0x10ec0255:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, coef0255);
+@@ -3962,6 +3967,7 @@ static void alc_headset_mode_ctia(struct
+       case 0x10ec0255:
+               alc_process_coef_fw(codec, coef0255);
+               break;
++      case 0x10ec0236:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, coef0256);
+               break;
+@@ -4052,6 +4058,7 @@ static void alc_headset_mode_omtp(struct
+       case 0x10ec0255:
+               alc_process_coef_fw(codec, coef0255);
+               break;
++      case 0x10ec0236:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, coef0256);
+               break;
+@@ -4119,6 +4126,7 @@ static void alc_determine_headset_type(s
+       };
+       switch (codec->core.vendor_id) {
++      case 0x10ec0236:
+       case 0x10ec0255:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, coef0255);
+@@ -4320,6 +4328,7 @@ static void alc255_set_default_jack_type
+       case 0x10ec0255:
+               alc_process_coef_fw(codec, alc255fw);
+               break;
++      case 0x10ec0236:
+       case 0x10ec0256:
+               alc_process_coef_fw(codec, alc256fw);
+               break;
+@@ -6208,6 +6217,7 @@ static int patch_alc269(struct hda_codec
+       case 0x10ec0255:
+               spec->codec_variant = ALC269_TYPE_ALC255;
+               break;
++      case 0x10ec0236:
+       case 0x10ec0256:
+               spec->codec_variant = ALC269_TYPE_ALC256;
+               spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
+@@ -7147,6 +7157,7 @@ static const struct hda_device_id snd_hd
+       HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
++      HDA_CODEC_ENTRY(0x10ec0236, "ALC236", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0260, "ALC260", patch_alc260),
diff --git a/queue-4.4/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch b/queue-4.4/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch
new file mode 100644 (file)
index 0000000..7d16a7a
--- /dev/null
@@ -0,0 +1,48 @@
+From 6c2838fbdedb9b72a81c931d49e56b229b6cdbca Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Thu, 19 Oct 2017 08:52:58 -0400
+Subject: ceph: unlock dangling spinlock in try_flush_caps()
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 6c2838fbdedb9b72a81c931d49e56b229b6cdbca upstream.
+
+sparse warns:
+
+  fs/ceph/caps.c:2042:9: warning: context imbalance in 'try_flush_caps' - wrong count at exit
+
+We need to exit this function with the lock unlocked, but a couple of
+cases leave it locked.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/caps.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -1850,6 +1850,7 @@ static int try_flush_caps(struct inode *
+ retry:
+       spin_lock(&ci->i_ceph_lock);
+       if (ci->i_ceph_flags & CEPH_I_NOFLUSH) {
++              spin_unlock(&ci->i_ceph_lock);
+               dout("try_flush_caps skipping %p I_NOFLUSH set\n", inode);
+               goto out;
+       }
+@@ -1867,8 +1868,10 @@ retry:
+                       mutex_lock(&session->s_mutex);
+                       goto retry;
+               }
+-              if (cap->session->s_state < CEPH_MDS_SESSION_OPEN)
++              if (cap->session->s_state < CEPH_MDS_SESSION_OPEN) {
++                      spin_unlock(&ci->i_ceph_lock);
+                       goto out;
++              }
+               flushing = __mark_caps_flushing(inode, session, &flush_tid,
+                                               &oldest_flush_tid);
diff --git a/queue-4.4/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch b/queue-4.4/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch
new file mode 100644 (file)
index 0000000..9a73f8c
--- /dev/null
@@ -0,0 +1,181 @@
+From 692b48258dda7c302e777d7d5f4217244478f1f6 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 9 Oct 2017 08:04:13 -0700
+Subject: workqueue: replace pool->manager_arb mutex with a flag
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 692b48258dda7c302e777d7d5f4217244478f1f6 upstream.
+
+Josef reported a HARDIRQ-safe -> HARDIRQ-unsafe lock order detected by
+lockdep:
+
+ [ 1270.472259] WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
+ [ 1270.472783] 4.14.0-rc1-xfstests-12888-g76833e8 #110 Not tainted
+ [ 1270.473240] -----------------------------------------------------
+ [ 1270.473710] kworker/u5:2/5157 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
+ [ 1270.474239]  (&(&lock->wait_lock)->rlock){+.+.}, at: [<ffffffff8da253d2>] __mutex_unlock_slowpath+0xa2/0x280
+ [ 1270.474994]
+ [ 1270.474994] and this task is already holding:
+ [ 1270.475440]  (&pool->lock/1){-.-.}, at: [<ffffffff8d2992f6>] worker_thread+0x366/0x3c0
+ [ 1270.476046] which would create a new lock dependency:
+ [ 1270.476436]  (&pool->lock/1){-.-.} -> (&(&lock->wait_lock)->rlock){+.+.}
+ [ 1270.476949]
+ [ 1270.476949] but this new dependency connects a HARDIRQ-irq-safe lock:
+ [ 1270.477553]  (&pool->lock/1){-.-.}
+ ...
+ [ 1270.488900] to a HARDIRQ-irq-unsafe lock:
+ [ 1270.489327]  (&(&lock->wait_lock)->rlock){+.+.}
+ ...
+ [ 1270.494735]  Possible interrupt unsafe locking scenario:
+ [ 1270.494735]
+ [ 1270.495250]        CPU0                    CPU1
+ [ 1270.495600]        ----                    ----
+ [ 1270.495947]   lock(&(&lock->wait_lock)->rlock);
+ [ 1270.496295]                                local_irq_disable();
+ [ 1270.496753]                                lock(&pool->lock/1);
+ [ 1270.497205]                                lock(&(&lock->wait_lock)->rlock);
+ [ 1270.497744]   <Interrupt>
+ [ 1270.497948]     lock(&pool->lock/1);
+
+, which will cause a irq inversion deadlock if the above lock scenario
+happens.
+
+The root cause of this safe -> unsafe lock order is the
+mutex_unlock(pool->manager_arb) in manage_workers() with pool->lock
+held.
+
+Unlocking mutex while holding an irq spinlock was never safe and this
+problem has been around forever but it never got noticed because the
+only time the mutex is usually trylocked while holding irqlock making
+actual failures very unlikely and lockdep annotation missed the
+condition until the recent b9c16a0e1f73 ("locking/mutex: Fix
+lockdep_assert_held() fail").
+
+Using mutex for pool->manager_arb has always been a bit of stretch.
+It primarily is an mechanism to arbitrate managership between workers
+which can easily be done with a pool flag.  The only reason it became
+a mutex is that pool destruction path wants to exclude parallel
+managing operations.
+
+This patch replaces the mutex with a new pool flag POOL_MANAGER_ACTIVE
+and make the destruction path wait for the current manager on a wait
+queue.
+
+v2: Drop unnecessary flag clearing before pool destruction as
+    suggested by Boqun.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Josef Bacik <josef@toxicpanda.com>
+Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c |   37 +++++++++++++++----------------------
+ 1 file changed, 15 insertions(+), 22 deletions(-)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -68,6 +68,7 @@ enum {
+        * attach_mutex to avoid changing binding state while
+        * worker_attach_to_pool() is in progress.
+        */
++      POOL_MANAGER_ACTIVE     = 1 << 0,       /* being managed */
+       POOL_DISASSOCIATED      = 1 << 2,       /* cpu can't serve workers */
+       /* worker flags */
+@@ -163,7 +164,6 @@ struct worker_pool {
+                                               /* L: hash of busy workers */
+       /* see manage_workers() for details on the two manager mutexes */
+-      struct mutex            manager_arb;    /* manager arbitration */
+       struct worker           *manager;       /* L: purely informational */
+       struct mutex            attach_mutex;   /* attach/detach exclusion */
+       struct list_head        workers;        /* A: attached workers */
+@@ -295,6 +295,7 @@ static struct workqueue_attrs *wq_update
+ static DEFINE_MUTEX(wq_pool_mutex);   /* protects pools and workqueues list */
+ static DEFINE_SPINLOCK(wq_mayday_lock);       /* protects wq->maydays list */
++static DECLARE_WAIT_QUEUE_HEAD(wq_manager_wait); /* wait for manager to go away */
+ static LIST_HEAD(workqueues);         /* PR: list of all workqueues */
+ static bool workqueue_freezing;               /* PL: have wqs started freezing? */
+@@ -808,7 +809,7 @@ static bool need_to_create_worker(struct
+ /* Do we have too many workers and should some go away? */
+ static bool too_many_workers(struct worker_pool *pool)
+ {
+-      bool managing = mutex_is_locked(&pool->manager_arb);
++      bool managing = pool->flags & POOL_MANAGER_ACTIVE;
+       int nr_idle = pool->nr_idle + managing; /* manager is considered idle */
+       int nr_busy = pool->nr_workers - nr_idle;
+@@ -1952,24 +1953,17 @@ static bool manage_workers(struct worker
+ {
+       struct worker_pool *pool = worker->pool;
+-      /*
+-       * Anyone who successfully grabs manager_arb wins the arbitration
+-       * and becomes the manager.  mutex_trylock() on pool->manager_arb
+-       * failure while holding pool->lock reliably indicates that someone
+-       * else is managing the pool and the worker which failed trylock
+-       * can proceed to executing work items.  This means that anyone
+-       * grabbing manager_arb is responsible for actually performing
+-       * manager duties.  If manager_arb is grabbed and released without
+-       * actual management, the pool may stall indefinitely.
+-       */
+-      if (!mutex_trylock(&pool->manager_arb))
++      if (pool->flags & POOL_MANAGER_ACTIVE)
+               return false;
++
++      pool->flags |= POOL_MANAGER_ACTIVE;
+       pool->manager = worker;
+       maybe_create_worker(pool);
+       pool->manager = NULL;
+-      mutex_unlock(&pool->manager_arb);
++      pool->flags &= ~POOL_MANAGER_ACTIVE;
++      wake_up(&wq_manager_wait);
+       return true;
+ }
+@@ -3119,7 +3113,6 @@ static int init_worker_pool(struct worke
+       setup_timer(&pool->mayday_timer, pool_mayday_timeout,
+                   (unsigned long)pool);
+-      mutex_init(&pool->manager_arb);
+       mutex_init(&pool->attach_mutex);
+       INIT_LIST_HEAD(&pool->workers);
+@@ -3189,13 +3182,15 @@ static void put_unbound_pool(struct work
+       hash_del(&pool->hash_node);
+       /*
+-       * Become the manager and destroy all workers.  Grabbing
+-       * manager_arb prevents @pool's workers from blocking on
+-       * attach_mutex.
++       * Become the manager and destroy all workers.  This prevents
++       * @pool's workers from blocking on attach_mutex.  We're the last
++       * manager and @pool gets freed with the flag set.
+        */
+-      mutex_lock(&pool->manager_arb);
+-
+       spin_lock_irq(&pool->lock);
++      wait_event_lock_irq(wq_manager_wait,
++                          !(pool->flags & POOL_MANAGER_ACTIVE), pool->lock);
++      pool->flags |= POOL_MANAGER_ACTIVE;
++
+       while ((worker = first_idle_worker(pool)))
+               destroy_worker(worker);
+       WARN_ON(pool->nr_workers || pool->nr_idle);
+@@ -3209,8 +3204,6 @@ static void put_unbound_pool(struct work
+       if (pool->detach_completion)
+               wait_for_completion(pool->detach_completion);
+-      mutex_unlock(&pool->manager_arb);
+-
+       /* shut down the timers */
+       del_timer_sync(&pool->idle_timer);
+       del_timer_sync(&pool->mayday_timer);