From: Greg Kroah-Hartman Date: Mon, 30 Oct 2017 08:39:48 +0000 (+0100) Subject: 4.13-stable patches X-Git-Tag: v3.18.79~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c1ff8b1ba42a1e6e47a409b028321c8b4861e7af;p=thirdparty%2Fkernel%2Fstable-queue.git 4.13-stable patches 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 nvme-fc-fix-iowait-hang.patch workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch --- diff --git a/queue-3.18/series b/queue-3.18/series new file mode 100644 index 00000000000..27633d31823 --- /dev/null +++ b/queue-3.18/series @@ -0,0 +1,2 @@ +alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch +ceph-unlock-dangling-spinlock-in-try_flush_caps.patch diff --git a/queue-4.13/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch b/queue-4.13/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch new file mode 100644 index 00000000000..dfa04535603 --- /dev/null +++ b/queue-4.13/alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch @@ -0,0 +1,38 @@ +From f265788c336979090ac80b9ae173aa817c4fe40d Mon Sep 17 00:00:00 2001 +From: Hui Wang +Date: Tue, 24 Oct 2017 16:53:34 +0800 +Subject: ALSA: hda - fix headset mic problem for Dell machines with alc236 + +From: Hui Wang + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -6411,6 +6411,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.13/alsa-hda-realtek-add-support-for-alc236-alc3204.patch b/queue-4.13/alsa-hda-realtek-add-support-for-alc236-alc3204.patch new file mode 100644 index 00000000000..272e40da0af --- /dev/null +++ b/queue-4.13/alsa-hda-realtek-add-support-for-alc236-alc3204.patch @@ -0,0 +1,110 @@ +From 736f20a7060857ff569e9e9586ae6c1204a73e07 Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Fri, 20 Oct 2017 15:06:34 +0800 +Subject: ALSA: hda/realtek - Add support for ALC236/ALC3204 + +From: Kailang Yang + +commit 736f20a7060857ff569e9e9586ae6c1204a73e07 upstream. + +Add support for ALC236/ALC3204. +Add headset mode support for ALC236/ALC3204. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -327,6 +327,7 @@ static void alc_fill_eapd_coef(struct hd + case 0x10ec0215: + case 0x10ec0225: + case 0x10ec0233: ++ case 0x10ec0236: + case 0x10ec0255: + case 0x10ec0256: + case 0x10ec0282: +@@ -911,6 +912,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" }, +@@ -3930,6 +3932,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); +@@ -4028,6 +4031,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); +@@ -4160,6 +4164,7 @@ static void alc_headset_mode_default(str + alc_process_coef_fw(codec, alc225_pre_hsmode); + alc_process_coef_fw(codec, coef0225); + break; ++ case 0x10ec0236: + case 0x10ec0255: + case 0x10ec0256: + alc_process_coef_fw(codec, coef0255); +@@ -4256,6 +4261,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; +@@ -4366,6 +4372,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; +@@ -4451,6 +4458,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); +@@ -4705,6 +4713,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; +@@ -6789,6 +6798,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->shutup = alc256_shutup; +@@ -7840,6 +7850,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.13/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch b/queue-4.13/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch new file mode 100644 index 00000000000..cbbd3308eca --- /dev/null +++ b/queue-4.13/ceph-unlock-dangling-spinlock-in-try_flush_caps.patch @@ -0,0 +1,48 @@ +From 6c2838fbdedb9b72a81c931d49e56b229b6cdbca Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Thu, 19 Oct 2017 08:52:58 -0400 +Subject: ceph: unlock dangling spinlock in try_flush_caps() + +From: Jeff Layton + +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 +Reviewed-by: "Yan, Zheng" +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/caps.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/ceph/caps.c ++++ b/fs/ceph/caps.c +@@ -1985,6 +1985,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; + } +@@ -2002,8 +2003,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, true, + &flush_tid, &oldest_flush_tid); diff --git a/queue-4.13/nvme-fc-fix-iowait-hang.patch b/queue-4.13/nvme-fc-fix-iowait-hang.patch new file mode 100644 index 00000000000..f6e5074ec2b --- /dev/null +++ b/queue-4.13/nvme-fc-fix-iowait-hang.patch @@ -0,0 +1,50 @@ +From 8a82dbf19129dde9e6fc9ab25a00dbc7569abe6a Mon Sep 17 00:00:00 2001 +From: James Smart +Date: Mon, 9 Oct 2017 13:39:44 -0700 +Subject: nvme-fc: fix iowait hang +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Smart + +commit 8a82dbf19129dde9e6fc9ab25a00dbc7569abe6a upstream. + +Add missing iowait head initialization. +Fix irqsave vs irq: wait_event_lock_irq() doesn't do irq save/restore + +Fixes: 36715cf4b366 ("nvme_fc: replace ioabort msleep loop with completion”) +Signed-off-by: James Smart +Reviewed-by: Sagi Grimberg +Reviewed-by: Himanshu Madhani +Tested-by: Himanshu Madhani +Signed-off-by: Christoph Hellwig +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nvme/host/fc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/nvme/host/fc.c ++++ b/drivers/nvme/host/fc.c +@@ -2477,10 +2477,10 @@ nvme_fc_delete_association(struct nvme_f + nvme_fc_abort_aen_ops(ctrl); + + /* wait for all io that had to be aborted */ +- spin_lock_irqsave(&ctrl->lock, flags); ++ spin_lock_irq(&ctrl->lock); + wait_event_lock_irq(ctrl->ioabort_wait, ctrl->iocnt == 0, ctrl->lock); + ctrl->flags &= ~FCCTRL_TERMIO; +- spin_unlock_irqrestore(&ctrl->lock, flags); ++ spin_unlock_irq(&ctrl->lock); + + nvme_fc_term_aen_ops(ctrl); + +@@ -2693,6 +2693,7 @@ nvme_fc_init_ctrl(struct device *dev, st + ctrl->rport = rport; + ctrl->dev = lport->dev; + ctrl->cnum = idx; ++ init_waitqueue_head(&ctrl->ioabort_wait); + + get_device(ctrl->dev); + kref_init(&ctrl->ref); diff --git a/queue-4.13/series b/queue-4.13/series new file mode 100644 index 00000000000..668080aebd5 --- /dev/null +++ b/queue-4.13/series @@ -0,0 +1,5 @@ +workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch +nvme-fc-fix-iowait-hang.patch +alsa-hda-realtek-add-support-for-alc236-alc3204.patch +alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch +ceph-unlock-dangling-spinlock-in-try_flush_caps.patch diff --git a/queue-4.13/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch b/queue-4.13/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch new file mode 100644 index 00000000000..c4734575f01 --- /dev/null +++ b/queue-4.13/workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch @@ -0,0 +1,181 @@ +From 692b48258dda7c302e777d7d5f4217244478f1f6 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 9 Oct 2017 08:04:13 -0700 +Subject: workqueue: replace pool->manager_arb mutex with a flag + +From: Tejun Heo + +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: [] __mutex_unlock_slowpath+0xa2/0x280 + [ 1270.474994] + [ 1270.474994] and this task is already holding: + [ 1270.475440] (&pool->lock/1){-.-.}, at: [] 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] + [ 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 +Reported-by: Josef Bacik +Reviewed-by: Lai Jiangshan +Cc: Peter Zijlstra +Cc: Boqun Feng +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ +@@ -165,7 +166,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 */ +@@ -299,6 +299,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? */ +@@ -801,7 +802,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; + +@@ -1980,24 +1981,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; + } + +@@ -3215,7 +3209,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); + +@@ -3285,13 +3278,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); +@@ -3305,8 +3300,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); diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..cbc1250ab53 --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1,4 @@ +workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch +alsa-hda-realtek-add-support-for-alc236-alc3204.patch +alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch +ceph-unlock-dangling-spinlock-in-try_flush_caps.patch diff --git a/queue-4.9/series b/queue-4.9/series new file mode 100644 index 00000000000..cbc1250ab53 --- /dev/null +++ b/queue-4.9/series @@ -0,0 +1,4 @@ +workqueue-replace-pool-manager_arb-mutex-with-a-flag.patch +alsa-hda-realtek-add-support-for-alc236-alc3204.patch +alsa-hda-fix-headset-mic-problem-for-dell-machines-with-alc236.patch +ceph-unlock-dangling-spinlock-in-try_flush_caps.patch