From: Greg Kroah-Hartman Date: Tue, 1 Mar 2016 21:42:33 +0000 (-0800) Subject: 4.4-stable patches X-Git-Tag: v3.10.99~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4f3e3c618b55a5c4a949cc92787407a8c8f5b73e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: acpi-pci-hotplug-unlock-in-error-path-in-acpiphp_enable_slot.patch acpi-revert-acpi-video-add-dell-inspiron-5737-to-the-blacklist.patch acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-portege-r700.patch acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-satellite-r830.patch cpufreq-fix-null-reference-crash-while-accessing-policy-governor_data.patch cpufreq-pxa2xx-fix-pxa_cpufreq_change_voltage-prototype.patch dmaengine-at_xdmac-fix-resume-for-cyclic-transfers.patch dmaengine-dw-disable-block-irqs-for-non-cyclic-xfer.patch dmaengine-dw-fix-cyclic-transfer-callbacks.patch dmaengine-dw-fix-cyclic-transfer-setup.patch hwmon-ads1015-handle-negative-conversion-values-correctly.patch hwmon-dell-smm-blacklist-dell-studio-xps-8000.patch hwmon-gpio-fan-remove-un-necessary-speed_index-lookup-for-thermal-hook.patch ib-cm-fix-a-recently-introduced-deadlock.patch ib-mlx5-expose-correct-maximum-number-of-cqe-capacity.patch ib-qib-fix-mcast-detach-when-qp-not-attached.patch ib-qib-support-creating-qps-with-gfp_noio-flag.patch ideapad-laptop-add-lenovo-ideapad-y700-17isk-to-no_hw_rfkill-dmi-list.patch ideapad-laptop-add-lenovo-yoga-700-to-no_hw_rfkill-dmi-list.patch lib-sw842-select-crc32.patch libceph-don-t-bail-early-from-try_read-when-skipping-a-message.patch libceph-don-t-spam-dmesg-with-stray-reply-warnings.patch libceph-fix-ceph_msg_revoke.patch libceph-use-the-right-footer-size-when-skipping-a-message.patch nfit-fix-multi-interface-dimm-handling-acpi6.1-compatibility.patch revert-staging-panel-usleep_range-is-preferred-over-udelay.patch sd-optimal-i-o-size-is-in-bytes-not-sectors.patch seccomp-always-propagate-no_new_privs-on-tsync.patch staging-speakup-fix-getting-port-information.patch thermal-do-thermal-zone-update-after-a-cooling-device-registered.patch thermal-handle-thermal-zone-device-properly-during-system-sleep.patch thermal-initialize-thermal-zone-device-correctly.patch toshiba_acpi-fix-blank-screen-at-boot-if-transflective-backlight-is-supported.patch uapi-update-install-list-after-nvme.h-rename.patch --- diff --git a/queue-4.4/acpi-pci-hotplug-unlock-in-error-path-in-acpiphp_enable_slot.patch b/queue-4.4/acpi-pci-hotplug-unlock-in-error-path-in-acpiphp_enable_slot.patch new file mode 100644 index 00000000000..fc01098ca11 --- /dev/null +++ b/queue-4.4/acpi-pci-hotplug-unlock-in-error-path-in-acpiphp_enable_slot.patch @@ -0,0 +1,35 @@ +From 2c3033a0664dfae91e1dee7fabac10f24354b958 Mon Sep 17 00:00:00 2001 +From: Insu Yun +Date: Sat, 23 Jan 2016 15:44:19 -0500 +Subject: ACPI / PCI / hotplug: unlock in error path in acpiphp_enable_slot() + +From: Insu Yun + +commit 2c3033a0664dfae91e1dee7fabac10f24354b958 upstream. + +In acpiphp_enable_slot(), there is a missing unlock path +when error occurred. It needs to be unlocked before returning +an error. + +Signed-off-by: Insu Yun +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/acpiphp_glue.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pci/hotplug/acpiphp_glue.c ++++ b/drivers/pci/hotplug/acpiphp_glue.c +@@ -953,8 +953,10 @@ int acpiphp_enable_slot(struct acpiphp_s + { + pci_lock_rescan_remove(); + +- if (slot->flags & SLOT_IS_GOING_AWAY) ++ if (slot->flags & SLOT_IS_GOING_AWAY) { ++ pci_unlock_rescan_remove(); + return -ENODEV; ++ } + + /* configure all functions */ + if (!(slot->flags & SLOT_ENABLED)) diff --git a/queue-4.4/acpi-revert-acpi-video-add-dell-inspiron-5737-to-the-blacklist.patch b/queue-4.4/acpi-revert-acpi-video-add-dell-inspiron-5737-to-the-blacklist.patch new file mode 100644 index 00000000000..84bb0803c74 --- /dev/null +++ b/queue-4.4/acpi-revert-acpi-video-add-dell-inspiron-5737-to-the-blacklist.patch @@ -0,0 +1,49 @@ +From b186b4dcb79b1914c3dadb27ac72dafaa4267998 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 22 Jan 2016 11:41:05 +0100 +Subject: ACPI: Revert "ACPI / video: Add Dell Inspiron 5737 to the blacklist" + +From: Hans de Goede + +commit b186b4dcb79b1914c3dadb27ac72dafaa4267998 upstream. + +The quirk to get "acpi_backlight=vendor" behavior by default on the +Dell Inspiron 5737 was added before we started doing +"acpi_backlight=native" by default on Win8 ready machines. + +Since we now avoid using acpi-video as backlight driver on these machines +by default (using the native driver instead) we no longer need this quirk. + +Moreover the vendor driver does not work after a suspend/resume where +as the native driver does. + +This reverts commit 08a56226d847 (ACPI / video: Add Dell Inspiron 5737 +to the blacklist). + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=111061 +Reported-and-tested-by: erusan@gmail.com +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/video_detect.c | 8 -------- + 1 file changed, 8 deletions(-) + +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -135,14 +135,6 @@ static const struct dmi_system_id video_ + DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), + }, + }, +- { +- .callback = video_detect_force_vendor, +- .ident = "Dell Inspiron 5737", +- .matches = { +- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), +- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5737"), +- }, +- }, + + /* + * These models have a working acpi_video backlight control, and using diff --git a/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-portege-r700.patch b/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-portege-r700.patch new file mode 100644 index 00000000000..d4e3cfcf755 --- /dev/null +++ b/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-portege-r700.patch @@ -0,0 +1,40 @@ +From de588b8ff057d4de0751f337b930f90ca522bab2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 11 Jan 2016 14:46:17 +0100 +Subject: ACPI / video: Add disable_backlight_sysfs_if quirk for the Toshiba Portege R700 + +From: Hans de Goede + +commit de588b8ff057d4de0751f337b930f90ca522bab2 upstream. + +The Toshiba Portege R700 needs disable_backlight_sysfs_if=1, just like +the Toshiba Portege R830. Add a quirk for this. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=21012 +Tested-by: Emma Reisz +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/acpi_video.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -465,6 +465,15 @@ static struct dmi_system_id video_dmi_ta + * as brightness control does not work. + */ + { ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ ++ .callback = video_disable_backlight_sysfs_if, ++ .ident = "Toshiba Portege R700", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R700"), ++ }, ++ }, ++ { + /* https://bugs.freedesktop.org/show_bug.cgi?id=82634 */ + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege R830", diff --git a/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-satellite-r830.patch b/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-satellite-r830.patch new file mode 100644 index 00000000000..4ed4bafafaf --- /dev/null +++ b/queue-4.4/acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-satellite-r830.patch @@ -0,0 +1,40 @@ +From b21f2e81bd3fd8ed260590e72901254bca2193cd Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 14 Jan 2016 14:24:39 +0100 +Subject: ACPI / video: Add disable_backlight_sysfs_if quirk for the Toshiba Satellite R830 + +From: Hans de Goede + +commit b21f2e81bd3fd8ed260590e72901254bca2193cd upstream. + +The Toshiba Satellite R830 needs disable_backlight_sysfs_if=1, just like +the Toshiba Portege R830. Add a quirk for this. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=21012 +Tested-by: To Do +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/acpi_video.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/acpi/acpi_video.c ++++ b/drivers/acpi/acpi_video.c +@@ -482,6 +482,15 @@ static struct dmi_system_id video_dmi_ta + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R830"), + }, + }, ++ { ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=21012 */ ++ .callback = video_disable_backlight_sysfs_if, ++ .ident = "Toshiba Satellite R830", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), ++ }, ++ }, + /* + * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set + * but the IDs actually follow the Device ID Scheme. diff --git a/queue-4.4/cpufreq-fix-null-reference-crash-while-accessing-policy-governor_data.patch b/queue-4.4/cpufreq-fix-null-reference-crash-while-accessing-policy-governor_data.patch new file mode 100644 index 00000000000..81822923dab --- /dev/null +++ b/queue-4.4/cpufreq-fix-null-reference-crash-while-accessing-policy-governor_data.patch @@ -0,0 +1,127 @@ +From e4b133cc4b30b48d488e4e4fffb132f173ce4358 Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Mon, 25 Jan 2016 22:33:46 +0530 +Subject: cpufreq: Fix NULL reference crash while accessing policy->governor_data + +From: Viresh Kumar + +commit e4b133cc4b30b48d488e4e4fffb132f173ce4358 upstream. + +There is a race discovered by Juri, where we are able to: +- create and read a sysfs file before policy->governor_data is being set + to a non NULL value. + OR +- set policy->governor_data to NULL, and reading a file before being + destroyed. + +And so such a crash is reported: + +Unable to handle kernel NULL pointer dereference at virtual address 0000000c +pgd = edfc8000 +[0000000c] *pgd=bfc8c835 +Internal error: Oops: 17 [#1] SMP ARM +Modules linked in: +CPU: 4 PID: 1730 Comm: cat Not tainted 4.5.0-rc1+ #463 +Hardware name: ARM-Versatile Express +task: ee8e8480 ti: ee930000 task.ti: ee930000 +PC is at show_ignore_nice_load_gov_pol+0x24/0x34 +LR is at show+0x4c/0x60 +pc : [] lr : [] psr: a0070013 +sp : ee931dd0 ip : ee931de0 fp : ee931ddc +r10: ee4bc290 r9 : 00001000 r8 : ef2cb000 +r7 : ee4bc200 r6 : ef2cb000 r5 : c0af57b0 r4 : ee4bc2e0 +r3 : 00000000 r2 : 00000000 r1 : c0928df4 r0 : ef2cb000 +Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none +Control: 10c5387d Table: adfc806a DAC: 00000051 +Process cat (pid: 1730, stack limit = 0xee930210) +Stack: (0xee931dd0 to 0xee932000) +1dc0: ee931dfc ee931de0 c058ae88 c058f1a4 +1de0: edce3bc0 c07bfca4 edce3ac0 00001000 ee931e24 ee931e00 c01fcb90 c058ae48 +1e00: 00000001 edce3bc0 00000000 00000001 ee931e50 ee8ff480 ee931e34 ee931e28 +1e20: c01fb33c c01fcb0c ee931e8c ee931e38 c01a5210 c01fb314 ee931e9c ee931e48 +1e40: 00000000 edce3bf0 befe4a00 ee931f78 00000000 00000000 000001e4 00000000 +1e60: c00545a8 edce3ac0 00001000 00001000 befe4a00 ee931f78 00000000 00001000 +1e80: ee931ed4 ee931e90 c01fbed8 c01a5038 ed085a58 00020000 00000000 00000000 +1ea0: c0ad72e4 ee931f78 ee8ff488 ee8ff480 c077f3fc 00001000 befe4a00 ee931f78 +1ec0: 00000000 00001000 ee931f44 ee931ed8 c017c328 c01fbdc4 00001000 00000000 +1ee0: ee8ff480 00001000 ee931f44 ee931ef8 c017c65c c03deb10 ee931fac ee931f08 +1f00: c0009270 c001f290 c0a8d968 ef2cb000 ef2cb000 ee8ff480 00000020 ee8ff480 +1f20: ee8ff480 befe4a00 00001000 ee931f78 00000000 00000000 ee931f74 ee931f48 +1f40: c017d1ec c017c2f8 c019c724 c019c684 ee8ff480 ee8ff480 00001000 befe4a00 +1f60: 00000000 00000000 ee931fa4 ee931f78 c017d2a8 c017d160 00000000 00000000 +1f80: 000a9f20 00001000 befe4a00 00000003 c000ffe4 ee930000 00000000 ee931fa8 +1fa0: c000fe40 c017d264 000a9f20 00001000 00000003 befe4a00 00001000 00000000 +Unable to handle kernel NULL pointer dereference at virtual address 0000000c +1fc0: 000a9f20 00001000 befe4a00 00000003 00000000 00000000 00000003 00000001 +pgd = edfc4000 +[0000000c] *pgd=bfcac835 +1fe0: 00000000 befe49dc 000197f8 b6e35dfc 60070010 00000003 3065b49d 134ac2c9 + +[] (show_ignore_nice_load_gov_pol) from [] (show+0x4c/0x60) +[] (show) from [] (sysfs_kf_seq_show+0x90/0xfc) +[] (sysfs_kf_seq_show) from [] (kernfs_seq_show+0x34/0x38) +[] (kernfs_seq_show) from [] (seq_read+0x1e4/0x4e4) +[] (seq_read) from [] (kernfs_fop_read+0x120/0x1a0) +[] (kernfs_fop_read) from [] (__vfs_read+0x3c/0xe0) +[] (__vfs_read) from [] (vfs_read+0x98/0x104) +[] (vfs_read) from [] (SyS_read+0x50/0x90) +[] (SyS_read) from [] (ret_fast_syscall+0x0/0x1c) +Code: e5903044 e1a00001 e3081df4 e34c1092 (e593300c) +---[ end trace 5994b9a5111f35ee ]--- + +Fix that by making sure, policy->governor_data is updated at the right +places only. + +Reported-and-tested-by: Juri Lelli +Signed-off-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq_governor.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/cpufreq/cpufreq_governor.c ++++ b/drivers/cpufreq/cpufreq_governor.c +@@ -356,16 +356,18 @@ static int cpufreq_governor_init(struct + if (!have_governor_per_policy()) + cdata->gdbs_data = dbs_data; + ++ policy->governor_data = dbs_data; ++ + ret = sysfs_create_group(get_governor_parent_kobj(policy), + get_sysfs_attr(dbs_data)); + if (ret) + goto reset_gdbs_data; + +- policy->governor_data = dbs_data; +- + return 0; + + reset_gdbs_data: ++ policy->governor_data = NULL; ++ + if (!have_governor_per_policy()) + cdata->gdbs_data = NULL; + cdata->exit(dbs_data, !policy->governor->initialized); +@@ -386,16 +388,19 @@ static int cpufreq_governor_exit(struct + if (!cdbs->shared || cdbs->shared->policy) + return -EBUSY; + +- policy->governor_data = NULL; + if (!--dbs_data->usage_count) { + sysfs_remove_group(get_governor_parent_kobj(policy), + get_sysfs_attr(dbs_data)); + ++ policy->governor_data = NULL; ++ + if (!have_governor_per_policy()) + cdata->gdbs_data = NULL; + + cdata->exit(dbs_data, policy->governor->initialized == 1); + kfree(dbs_data); ++ } else { ++ policy->governor_data = NULL; + } + + free_common_dbs_info(policy, cdata); diff --git a/queue-4.4/cpufreq-pxa2xx-fix-pxa_cpufreq_change_voltage-prototype.patch b/queue-4.4/cpufreq-pxa2xx-fix-pxa_cpufreq_change_voltage-prototype.patch new file mode 100644 index 00000000000..1b7ddbf88b1 --- /dev/null +++ b/queue-4.4/cpufreq-pxa2xx-fix-pxa_cpufreq_change_voltage-prototype.patch @@ -0,0 +1,45 @@ +From fb2a24a1c6457d21df9fae0dd66b20c63ba56077 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Mon, 25 Jan 2016 16:44:38 +0100 +Subject: cpufreq: pxa2xx: fix pxa_cpufreq_change_voltage prototype + +From: Arnd Bergmann + +commit fb2a24a1c6457d21df9fae0dd66b20c63ba56077 upstream. + +There are two definitions of pxa_cpufreq_change_voltage, with slightly +different prototypes after one of them had its argument marked 'const'. +Now the other one (for !CONFIG_REGULATOR) produces a harmless warning: + +drivers/cpufreq/pxa2xx-cpufreq.c: In function 'pxa_set_target': +drivers/cpufreq/pxa2xx-cpufreq.c:291:36: warning: passing argument 1 of 'pxa_cpufreq_change_voltage' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] + ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]); + ^ +drivers/cpufreq/pxa2xx-cpufreq.c:205:12: note: expected 'struct pxa_freqs *' but argument is of type 'const struct pxa_freqs *' + static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq) + ^ + +This changes the prototype in the same way as the other, which +avoids the warning. + +Fixes: 03c229906311 (cpufreq: pxa: make pxa_freqs arrays const) +Signed-off-by: Arnd Bergmann +Acked-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/pxa2xx-cpufreq.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/cpufreq/pxa2xx-cpufreq.c ++++ b/drivers/cpufreq/pxa2xx-cpufreq.c +@@ -202,7 +202,7 @@ static void __init pxa_cpufreq_init_volt + } + } + #else +-static int pxa_cpufreq_change_voltage(struct pxa_freqs *pxa_freq) ++static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) + { + return 0; + } diff --git a/queue-4.4/dmaengine-at_xdmac-fix-resume-for-cyclic-transfers.patch b/queue-4.4/dmaengine-at_xdmac-fix-resume-for-cyclic-transfers.patch new file mode 100644 index 00000000000..99e89802c94 --- /dev/null +++ b/queue-4.4/dmaengine-at_xdmac-fix-resume-for-cyclic-transfers.patch @@ -0,0 +1,41 @@ +From 611dcadb01c89d1d3521450c05a4ded332e5a32d Mon Sep 17 00:00:00 2001 +From: Songjun Wu +Date: Mon, 18 Jan 2016 11:14:44 +0100 +Subject: dmaengine: at_xdmac: fix resume for cyclic transfers + +From: Songjun Wu + +commit 611dcadb01c89d1d3521450c05a4ded332e5a32d upstream. + +When having cyclic transfers, the channel was paused when performing +suspend but was not correctly resumed. + +Signed-off-by: Songjun Wu +Signed-off-by: Ludovic Desroches +Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver") +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/at_xdmac.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -1688,6 +1688,7 @@ static int at_xdmac_device_terminate_all + list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node) + at_xdmac_remove_xfer(atchan, desc); + ++ clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); + clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); + spin_unlock_irqrestore(&atchan->lock, flags); + +@@ -1820,6 +1821,8 @@ static int atmel_xdmac_resume(struct dev + atchan = to_at_xdmac_chan(chan); + at_xdmac_chan_write(atchan, AT_XDMAC_CC, atchan->save_cc); + if (at_xdmac_chan_is_cyclic(atchan)) { ++ if (at_xdmac_chan_is_paused(atchan)) ++ at_xdmac_device_resume(chan); + at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, atchan->save_cnda); + at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); + at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); diff --git a/queue-4.4/dmaengine-dw-disable-block-irqs-for-non-cyclic-xfer.patch b/queue-4.4/dmaengine-dw-disable-block-irqs-for-non-cyclic-xfer.patch new file mode 100644 index 00000000000..d97d381675a --- /dev/null +++ b/queue-4.4/dmaengine-dw-disable-block-irqs-for-non-cyclic-xfer.patch @@ -0,0 +1,84 @@ +From ee1cdcdae59563535485a5f56ee72c894ab7d7ad Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko +Date: Wed, 10 Feb 2016 15:59:42 +0200 +Subject: dmaengine: dw: disable BLOCK IRQs for non-cyclic xfer + +From: Andy Shevchenko + +commit ee1cdcdae59563535485a5f56ee72c894ab7d7ad upstream. + +The commit 2895b2cad6e7 ("dmaengine: dw: fix cyclic transfer callbacks") +re-enabled BLOCK interrupts with regard to make cyclic transfers work. However, +this change becomes a regression for non-cyclic transfers as interrupt counters +under stress test had been grown enormously (approximately per 4-5 bytes in the +UART loop back test). + +Taking into consideration above enable BLOCK interrupts if and only if channel +is programmed to perform cyclic transfer. + +Fixes: 2895b2cad6e7 ("dmaengine: dw: fix cyclic transfer callbacks") +Signed-off-by: Andy Shevchenko +Acked-by: Mans Rullgard +Tested-by: Mans Rullgard +Acked-by: Viresh Kumar +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/dw/core.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -156,7 +156,6 @@ static void dwc_initialize(struct dw_dma + + /* Enable interrupts */ + channel_set_bit(dw, MASK.XFER, dwc->mask); +- channel_set_bit(dw, MASK.BLOCK, dwc->mask); + channel_set_bit(dw, MASK.ERROR, dwc->mask); + + dwc->initialized = true; +@@ -588,6 +587,9 @@ static void dwc_handle_cyclic(struct dw_ + + spin_unlock_irqrestore(&dwc->lock, flags); + } ++ ++ /* Re-enable interrupts */ ++ channel_set_bit(dw, MASK.BLOCK, dwc->mask); + } + + /* ------------------------------------------------------------------------- */ +@@ -618,11 +620,8 @@ static void dw_dma_tasklet(unsigned long + dwc_scan_descriptors(dw, dwc); + } + +- /* +- * Re-enable interrupts. +- */ ++ /* Re-enable interrupts */ + channel_set_bit(dw, MASK.XFER, dw->all_chan_mask); +- channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask); + channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask); + } + +@@ -1256,6 +1255,7 @@ static void dwc_free_chan_resources(stru + int dw_dma_cyclic_start(struct dma_chan *chan) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); ++ struct dw_dma *dw = to_dw_dma(chan->device); + unsigned long flags; + + if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { +@@ -1264,7 +1264,12 @@ int dw_dma_cyclic_start(struct dma_chan + } + + spin_lock_irqsave(&dwc->lock, flags); ++ ++ /* Enable interrupts to perform cyclic transfer */ ++ channel_set_bit(dw, MASK.BLOCK, dwc->mask); ++ + dwc_dostart(dwc, dwc->cdesc->desc[0]); ++ + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; diff --git a/queue-4.4/dmaengine-dw-fix-cyclic-transfer-callbacks.patch b/queue-4.4/dmaengine-dw-fix-cyclic-transfer-callbacks.patch new file mode 100644 index 00000000000..abe7424673b --- /dev/null +++ b/queue-4.4/dmaengine-dw-fix-cyclic-transfer-callbacks.patch @@ -0,0 +1,144 @@ +From 2895b2cad6e7a95104cf396e5330054453382ae1 Mon Sep 17 00:00:00 2001 +From: Mans Rullgard +Date: Mon, 11 Jan 2016 13:04:29 +0000 +Subject: dmaengine: dw: fix cyclic transfer callbacks + +From: Mans Rullgard + +commit 2895b2cad6e7a95104cf396e5330054453382ae1 upstream. + +Cyclic transfer callbacks rely on block completion interrupts which were +disabled in commit ff7b05f29fd4 ("dmaengine/dw_dmac: Don't handle block +interrupts"). This re-enables block interrupts so the cyclic callbacks +can work. Other transfer types are not affected as they set the INT_EN +bit only on the last block. + +Fixes: ff7b05f29fd4 ("dmaengine/dw_dmac: Don't handle block interrupts") +Signed-off-by: Mans Rullgard +Reviewed-by: Viresh Kumar +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/dw/core.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -156,6 +156,7 @@ static void dwc_initialize(struct dw_dma + + /* Enable interrupts */ + channel_set_bit(dw, MASK.XFER, dwc->mask); ++ channel_set_bit(dw, MASK.BLOCK, dwc->mask); + channel_set_bit(dw, MASK.ERROR, dwc->mask); + + dwc->initialized = true; +@@ -536,16 +537,17 @@ EXPORT_SYMBOL(dw_dma_get_dst_addr); + + /* Called with dwc->lock held and all DMAC interrupts disabled */ + static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc, +- u32 status_err, u32 status_xfer) ++ u32 status_block, u32 status_err, u32 status_xfer) + { + unsigned long flags; + +- if (dwc->mask) { ++ if (status_block & dwc->mask) { + void (*callback)(void *param); + void *callback_param; + + dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n", + channel_readl(dwc, LLP)); ++ dma_writel(dw, CLEAR.BLOCK, dwc->mask); + + callback = dwc->cdesc->period_callback; + callback_param = dwc->cdesc->period_callback_param; +@@ -577,6 +579,7 @@ static void dwc_handle_cyclic(struct dw_ + channel_writel(dwc, CTL_LO, 0); + channel_writel(dwc, CTL_HI, 0); + ++ dma_writel(dw, CLEAR.BLOCK, dwc->mask); + dma_writel(dw, CLEAR.ERROR, dwc->mask); + dma_writel(dw, CLEAR.XFER, dwc->mask); + +@@ -593,10 +596,12 @@ static void dw_dma_tasklet(unsigned long + { + struct dw_dma *dw = (struct dw_dma *)data; + struct dw_dma_chan *dwc; ++ u32 status_block; + u32 status_xfer; + u32 status_err; + int i; + ++ status_block = dma_readl(dw, RAW.BLOCK); + status_xfer = dma_readl(dw, RAW.XFER); + status_err = dma_readl(dw, RAW.ERROR); + +@@ -605,7 +610,8 @@ static void dw_dma_tasklet(unsigned long + for (i = 0; i < dw->dma.chancnt; i++) { + dwc = &dw->chan[i]; + if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) +- dwc_handle_cyclic(dw, dwc, status_err, status_xfer); ++ dwc_handle_cyclic(dw, dwc, status_block, status_err, ++ status_xfer); + else if (status_err & (1 << i)) + dwc_handle_error(dw, dwc); + else if (status_xfer & (1 << i)) +@@ -616,6 +622,7 @@ static void dw_dma_tasklet(unsigned long + * Re-enable interrupts. + */ + channel_set_bit(dw, MASK.XFER, dw->all_chan_mask); ++ channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask); + channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask); + } + +@@ -635,6 +642,7 @@ static irqreturn_t dw_dma_interrupt(int + * softirq handler. + */ + channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); ++ channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); + channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask); + + status = dma_readl(dw, STATUS_INT); +@@ -645,6 +653,7 @@ static irqreturn_t dw_dma_interrupt(int + + /* Try to recover */ + channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1); ++ channel_clear_bit(dw, MASK.BLOCK, (1 << 8) - 1); + channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1); + channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1); + channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1); +@@ -1111,6 +1120,7 @@ static void dw_dma_off(struct dw_dma *dw + dma_writel(dw, CFG, 0); + + channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); ++ channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); + channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask); + channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask); + channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask); +@@ -1216,6 +1226,7 @@ static void dwc_free_chan_resources(stru + + /* Disable interrupts */ + channel_clear_bit(dw, MASK.XFER, dwc->mask); ++ channel_clear_bit(dw, MASK.BLOCK, dwc->mask); + channel_clear_bit(dw, MASK.ERROR, dwc->mask); + + spin_unlock_irqrestore(&dwc->lock, flags); +@@ -1458,6 +1469,7 @@ void dw_dma_cyclic_free(struct dma_chan + + dwc_chan_disable(dw, dwc); + ++ dma_writel(dw, CLEAR.BLOCK, dwc->mask); + dma_writel(dw, CLEAR.ERROR, dwc->mask); + dma_writel(dw, CLEAR.XFER, dwc->mask); + +@@ -1546,9 +1558,6 @@ int dw_dma_probe(struct dw_dma_chip *chi + /* Force dma off, just in case */ + dw_dma_off(dw); + +- /* Disable BLOCK interrupts as well */ +- channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask); +- + /* Create a pool of consistent memory blocks for hardware descriptors */ + dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", chip->dev, + sizeof(struct dw_desc), 4, 0); diff --git a/queue-4.4/dmaengine-dw-fix-cyclic-transfer-setup.patch b/queue-4.4/dmaengine-dw-fix-cyclic-transfer-setup.patch new file mode 100644 index 00000000000..be37a376322 --- /dev/null +++ b/queue-4.4/dmaengine-dw-fix-cyclic-transfer-setup.patch @@ -0,0 +1,66 @@ +From df3bb8a0e619d501cd13334c3e0586edcdcbc716 Mon Sep 17 00:00:00 2001 +From: Mans Rullgard +Date: Mon, 11 Jan 2016 13:04:28 +0000 +Subject: dmaengine: dw: fix cyclic transfer setup + +From: Mans Rullgard + +commit df3bb8a0e619d501cd13334c3e0586edcdcbc716 upstream. + +Commit 61e183f83069 ("dmaengine/dw_dmac: Reconfigure interrupt and +chan_cfg register on resume") moved some channel initialisation to +a new function which must be called before starting a transfer. + +This updates dw_dma_cyclic_start() to use dwc_dostart() like the other +modes, thus ensuring dwc_initialize() gets called and removing some code +duplication. + +Fixes: 61e183f83069 ("dmaengine/dw_dmac: Reconfigure interrupt and chan_cfg register on resume") +Signed-off-by: Mans Rullgard +Reviewed-by: Viresh Kumar +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/dw/core.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +--- a/drivers/dma/dw/core.c ++++ b/drivers/dma/dw/core.c +@@ -1245,7 +1245,6 @@ static void dwc_free_chan_resources(stru + int dw_dma_cyclic_start(struct dma_chan *chan) + { + struct dw_dma_chan *dwc = to_dw_dma_chan(chan); +- struct dw_dma *dw = to_dw_dma(dwc->chan.device); + unsigned long flags; + + if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) { +@@ -1254,27 +1253,7 @@ int dw_dma_cyclic_start(struct dma_chan + } + + spin_lock_irqsave(&dwc->lock, flags); +- +- /* Assert channel is idle */ +- if (dma_readl(dw, CH_EN) & dwc->mask) { +- dev_err(chan2dev(&dwc->chan), +- "%s: BUG: Attempted to start non-idle channel\n", +- __func__); +- dwc_dump_chan_regs(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); +- return -EBUSY; +- } +- +- dma_writel(dw, CLEAR.ERROR, dwc->mask); +- dma_writel(dw, CLEAR.XFER, dwc->mask); +- +- /* Setup DMAC channel registers */ +- channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys); +- channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN); +- channel_writel(dwc, CTL_HI, 0); +- +- channel_set_bit(dw, CH_EN, dwc->mask); +- ++ dwc_dostart(dwc, dwc->cdesc->desc[0]); + spin_unlock_irqrestore(&dwc->lock, flags); + + return 0; diff --git a/queue-4.4/hwmon-ads1015-handle-negative-conversion-values-correctly.patch b/queue-4.4/hwmon-ads1015-handle-negative-conversion-values-correctly.patch new file mode 100644 index 00000000000..9d0aee6d0de --- /dev/null +++ b/queue-4.4/hwmon-ads1015-handle-negative-conversion-values-correctly.patch @@ -0,0 +1,31 @@ +From acc146943957d7418a6846f06e029b2c5e87e0d5 Mon Sep 17 00:00:00 2001 +From: Peter Rosin +Date: Thu, 18 Feb 2016 14:07:52 +0100 +Subject: hwmon: (ads1015) Handle negative conversion values correctly + +From: Peter Rosin + +commit acc146943957d7418a6846f06e029b2c5e87e0d5 upstream. + +Make the divisor signed as DIV_ROUND_CLOSEST is undefined for negative +dividends when the divisor is unsigned. + +Signed-off-by: Peter Rosin +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/ads1015.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hwmon/ads1015.c ++++ b/drivers/hwmon/ads1015.c +@@ -126,7 +126,7 @@ static int ads1015_reg_to_mv(struct i2c_ + struct ads1015_data *data = i2c_get_clientdata(client); + unsigned int pga = data->channel_data[channel].pga; + int fullscale = fullscale_table[pga]; +- const unsigned mask = data->id == ads1115 ? 0x7fff : 0x7ff0; ++ const int mask = data->id == ads1115 ? 0x7fff : 0x7ff0; + + return DIV_ROUND_CLOSEST(reg * fullscale, mask); + } diff --git a/queue-4.4/hwmon-dell-smm-blacklist-dell-studio-xps-8000.patch b/queue-4.4/hwmon-dell-smm-blacklist-dell-studio-xps-8000.patch new file mode 100644 index 00000000000..142b128dbdf --- /dev/null +++ b/queue-4.4/hwmon-dell-smm-blacklist-dell-studio-xps-8000.patch @@ -0,0 +1,50 @@ +From 6220f4ebd7b4db499238c2dc91268a9c473fd01c Mon Sep 17 00:00:00 2001 +From: Thorsten Leemhuis +Date: Sun, 17 Jan 2016 16:03:04 +0100 +Subject: hwmon: (dell-smm) Blacklist Dell Studio XPS 8000 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thorsten Leemhuis + +commit 6220f4ebd7b4db499238c2dc91268a9c473fd01c upstream. + +Since Linux 4.0 the CPU fan speed is going up and down on Dell Studio +XPS 8000 and 8100 for unknown reasons. The 8100 was already +blacklisted in commit a4b45b25f18d ("hwmon: (dell-smm) Blacklist +Dell Studio XPS 8100"). This patch blacklists the XPS 8000. + +Without further debugging on the affected machine, it is not possible +to find the problem. For more details see +https://bugzilla.kernel.org/show_bug.cgi?id=100121 + +Signed-off-by: Thorsten Leemhuis +Acked-by: Pali Rohár +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/dell-smm-hwmon.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/hwmon/dell-smm-hwmon.c ++++ b/drivers/hwmon/dell-smm-hwmon.c +@@ -932,6 +932,17 @@ MODULE_DEVICE_TABLE(dmi, i8k_dmi_table); + static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = { + { + /* ++ * CPU fan speed going up and down on Dell Studio XPS 8000 ++ * for unknown reasons. ++ */ ++ .ident = "Dell Studio XPS 8000", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8000"), ++ }, ++ }, ++ { ++ /* + * CPU fan speed going up and down on Dell Studio XPS 8100 + * for unknown reasons. + */ diff --git a/queue-4.4/hwmon-gpio-fan-remove-un-necessary-speed_index-lookup-for-thermal-hook.patch b/queue-4.4/hwmon-gpio-fan-remove-un-necessary-speed_index-lookup-for-thermal-hook.patch new file mode 100644 index 00000000000..0248642b2b8 --- /dev/null +++ b/queue-4.4/hwmon-gpio-fan-remove-un-necessary-speed_index-lookup-for-thermal-hook.patch @@ -0,0 +1,58 @@ +From 000e0949148382c4962489593a2f05504c2a6771 Mon Sep 17 00:00:00 2001 +From: Nishanth Menon +Date: Fri, 19 Feb 2016 18:09:51 -0600 +Subject: hwmon: (gpio-fan) Remove un-necessary speed_index lookup for thermal hook + +From: Nishanth Menon + +commit 000e0949148382c4962489593a2f05504c2a6771 upstream. + +Thermal hook gpio_fan_get_cur_state is only interested in knowing +the current speed index that was setup in the system, this is +already available as part of fan_data->speed_index which is always +set by set_fan_speed. Using get_fan_speed_index is useful when we +have no idea about the fan speed configuration (for example during +fan_ctrl_init). + +When thermal framework invokes +gpio_fan_get_cur_state=>get_fan_speed_index via gpio_fan_get_cur_state +especially in a polled configuration for thermal governor, we +basically hog the i2c interface to the extent that other functions +fail to get any traffic out :(. + +Instead, just provide the last state set in the driver - since the gpio +fan driver is responsible for the fan state immaterial of override, the +fan_data->speed_index should accurately reflect the state. + +Fixes: b5cf88e46bad ("(gpio-fan): Add thermal control hooks") +Reported-by: Tony Lindgren +Cc: Guenter Roeck +Cc: Eduardo Valentin +Signed-off-by: Nishanth Menon +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/gpio-fan.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +--- a/drivers/hwmon/gpio-fan.c ++++ b/drivers/hwmon/gpio-fan.c +@@ -406,16 +406,11 @@ static int gpio_fan_get_cur_state(struct + unsigned long *state) + { + struct gpio_fan_data *fan_data = cdev->devdata; +- int r; + + if (!fan_data) + return -EINVAL; + +- r = get_fan_speed_index(fan_data); +- if (r < 0) +- return r; +- +- *state = r; ++ *state = fan_data->speed_index; + return 0; + } + diff --git a/queue-4.4/ib-cm-fix-a-recently-introduced-deadlock.patch b/queue-4.4/ib-cm-fix-a-recently-introduced-deadlock.patch new file mode 100644 index 00000000000..6e38db8b907 --- /dev/null +++ b/queue-4.4/ib-cm-fix-a-recently-introduced-deadlock.patch @@ -0,0 +1,121 @@ +From 4bfdf635c668869c69fd18ece37ec66fb6f38fcf Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Fri, 1 Jan 2016 13:17:46 +0100 +Subject: IB/cm: Fix a recently introduced deadlock + +From: Bart Van Assche + +commit 4bfdf635c668869c69fd18ece37ec66fb6f38fcf upstream. + +ib_send_cm_drep() calls cm_enter_timewait() while holding a spinlock +that can be locked from inside an interrupt handler. Hence do not +enable interrupts inside cm_enter_timewait() if called with interrupts +disabled. + +This patch fixes e.g. the following deadlock: +Acked-by: Erez Shitrit + +================================= +[ INFO: inconsistent lock state ] +4.4.0-rc7+ #1 Tainted: G E +--------------------------------- +inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +swapper/8/0 [HC1[1]:SC0[0]:HE0:SE1] takes: +(&(&cm_id_priv->lock)->rlock){?.+...}, at: [] cm_establish+0x +74/0x1b0 [ib_cm] +{HARDIRQ-ON-W} state was registered at: + [] mark_held_locks+0x71/0x90 + [] trace_hardirqs_on_caller+0xa7/0x1c0 + [] trace_hardirqs_on+0xd/0x10 + [] _raw_spin_unlock_irq+0x2b/0x40 + [] cm_enter_timewait+0xae/0x100 [ib_cm] + [] ib_send_cm_drep+0xb6/0x190 [ib_cm] + [] srp_cm_handler+0x128/0x1a0 [ib_srp] + [] cm_process_work+0x20/0xf0 [ib_cm] + [] cm_dreq_handler+0x135/0x2c0 [ib_cm] + [] cm_work_handler+0x75/0xd0 [ib_cm] + [] process_one_work+0x1bd/0x460 + [] worker_thread+0x118/0x420 + [] kthread+0xe4/0x100 + [] ret_from_fork+0x3f/0x70 +irq event stamp: 1672286 +hardirqs last enabled at (1672283): [] poll_idle+0x10/0x80 +hardirqs last disabled at (1672284): [] common_interrupt+0x84/0x89 +softirqs last enabled at (1672286): [] _local_bh_enable+0x1c/0x50 +softirqs last disabled at (1672285): [] irq_enter+0x47/0x70 + +other info that might help us debug this: + Possible unsafe locking scenario: + + CPU0 + ---- + lock(&(&cm_id_priv->lock)->rlock); + + lock(&(&cm_id_priv->lock)->rlock); + + *** DEADLOCK *** + +no locks held by swapper/8/0. + +stack backtrace: +CPU: 8 PID: 0 Comm: swapper/8 Tainted: G E 4.4.0-rc7+ #1 +Hardware name: Dell Inc. PowerEdge R430/03XKDV, BIOS 1.0.2 11/17/2014 + ffff88045af5e950 ffff88046e503a88 ffffffff81251c1b 0000000000000007 + 0000000000000006 0000000000000003 ffff88045af5ddc0 ffff88046e503ad8 + ffffffff810a32f4 0000000000000000 0000000000000000 0000000000000001 +Call Trace: + [] dump_stack+0x4f/0x74 + [] print_usage_bug+0x184/0x190 + [] mark_lock_irq+0xf2/0x290 + [] mark_lock+0x115/0x1b0 + [] mark_irqflags+0x15c/0x170 + [] __lock_acquire+0x1ef/0x560 + [] lock_acquire+0x62/0x80 + [] _raw_spin_lock_irqsave+0x43/0x60 + [] cm_establish+0x74/0x1b0 [ib_cm] + [] ib_cm_notify+0x31/0x100 [ib_cm] + [] srpt_qp_event+0x54/0xd0 [ib_srpt] + [] mlx4_ib_qp_event+0x72/0xc0 [mlx4_ib] + [] mlx4_qp_event+0x69/0xd0 [mlx4_core] + [] mlx4_eq_int+0x51e/0xd50 [mlx4_core] + [] mlx4_msi_x_interrupt+0xf/0x20 [mlx4_core] + [] handle_irq_event_percpu+0x40/0x110 + [] handle_irq_event+0x3f/0x70 + [] handle_edge_irq+0x79/0x120 + [] handle_irq+0x5d/0x130 + [] do_IRQ+0x6d/0x130 + [] common_interrupt+0x89/0x89 + [] cpuidle_enter_state+0xcf/0x200 + [] cpuidle_enter+0x12/0x20 + [] call_cpuidle+0x36/0x60 + [] cpuidle_idle_call+0x63/0x110 + [] cpu_idle_loop+0xfa/0x130 + [] cpu_startup_entry+0xe/0x10 + [] start_secondary+0x83/0x90 + +Fixes: commit be4b499323bf ("IB/cm: Do not queue work to a device that's going away") +Signed-off-by: Bart Van Assche +Cc: Erez Shitrit +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/cm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/core/cm.c ++++ b/drivers/infiniband/core/cm.c +@@ -782,11 +782,11 @@ static void cm_enter_timewait(struct cm_ + wait_time = cm_convert_to_ms(cm_id_priv->av.timeout); + + /* Check if the device started its remove_one */ +- spin_lock_irq(&cm.lock); ++ spin_lock_irqsave(&cm.lock, flags); + if (!cm_dev->going_down) + queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, + msecs_to_jiffies(wait_time)); +- spin_unlock_irq(&cm.lock); ++ spin_unlock_irqrestore(&cm.lock, flags); + + cm_id_priv->timewait_info = NULL; + } diff --git a/queue-4.4/ib-mlx5-expose-correct-maximum-number-of-cqe-capacity.patch b/queue-4.4/ib-mlx5-expose-correct-maximum-number-of-cqe-capacity.patch new file mode 100644 index 00000000000..9f6006157a3 --- /dev/null +++ b/queue-4.4/ib-mlx5-expose-correct-maximum-number-of-cqe-capacity.patch @@ -0,0 +1,33 @@ +From 9f17768611ebf81dfac69948dd12622b6f2e45fc Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Thu, 14 Jan 2016 08:11:40 +0200 +Subject: IB/mlx5: Expose correct maximum number of CQE capacity + +From: Leon Romanovsky + +commit 9f17768611ebf81dfac69948dd12622b6f2e45fc upstream. + +Maximum number of EQE capacity per CQ was mistakenly exposed +as CQE. Fix that. + +Fixes: 938fe83c8dcb ("net/mlx5_core: New device capabilities handling") +Signed-off-by: Leon Romanovsky +Reviewed-by: Sagi Grimberg +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -275,7 +275,7 @@ static int mlx5_ib_query_device(struct i + props->max_sge = min(max_rq_sg, max_sq_sg); + props->max_sge_rd = props->max_sge; + props->max_cq = 1 << MLX5_CAP_GEN(mdev, log_max_cq); +- props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_eq_sz)) - 1; ++ props->max_cqe = (1 << MLX5_CAP_GEN(mdev, log_max_cq_sz)) - 1; + props->max_mr = 1 << MLX5_CAP_GEN(mdev, log_max_mkey); + props->max_pd = 1 << MLX5_CAP_GEN(mdev, log_max_pd); + props->max_qp_rd_atom = 1 << MLX5_CAP_GEN(mdev, log_max_ra_req_qp); diff --git a/queue-4.4/ib-qib-fix-mcast-detach-when-qp-not-attached.patch b/queue-4.4/ib-qib-fix-mcast-detach-when-qp-not-attached.patch new file mode 100644 index 00000000000..af340860069 --- /dev/null +++ b/queue-4.4/ib-qib-fix-mcast-detach-when-qp-not-attached.patch @@ -0,0 +1,161 @@ +From 09dc9cd6528f5b52bcbd3292a6312e762c85260f Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Thu, 7 Jan 2016 16:44:10 -0500 +Subject: IB/qib: fix mcast detach when qp not attached + +From: Mike Marciniszyn + +commit 09dc9cd6528f5b52bcbd3292a6312e762c85260f upstream. + +The code produces the following trace: + +[1750924.419007] general protection fault: 0000 [#3] SMP +[1750924.420364] Modules linked in: nfnetlink autofs4 rpcsec_gss_krb5 nfsv4 +dcdbas rfcomm bnep bluetooth nfsd auth_rpcgss nfs_acl dm_multipath nfs lockd +scsi_dh sunrpc fscache radeon ttm drm_kms_helper drm serio_raw parport_pc +ppdev i2c_algo_bit lpc_ich ipmi_si ib_mthca ib_qib dca lp parport ib_ipoib +mac_hid ib_cm i3000_edac ib_sa ib_uverbs edac_core ib_umad ib_mad ib_core +ib_addr tg3 ptp dm_mirror dm_region_hash dm_log psmouse pps_core +[1750924.420364] CPU: 1 PID: 8401 Comm: python Tainted: G D +3.13.0-39-generic #66-Ubuntu +[1750924.420364] Hardware name: Dell Computer Corporation PowerEdge +860/0XM089, BIOS A04 07/24/2007 +[1750924.420364] task: ffff8800366a9800 ti: ffff88007af1c000 task.ti: +ffff88007af1c000 +[1750924.420364] RIP: 0010:[] [] +qib_mcast_qp_free+0x11/0x50 [ib_qib] +[1750924.420364] RSP: 0018:ffff88007af1dd70 EFLAGS: 00010246 +[1750924.420364] RAX: 0000000000000001 RBX: ffff88007b822688 RCX: +000000000000000f +[1750924.420364] RDX: ffff88007b822688 RSI: ffff8800366c15a0 RDI: +6764697200000000 +[1750924.420364] RBP: ffff88007af1dd78 R08: 0000000000000001 R09: +0000000000000000 +[1750924.420364] R10: 0000000000000011 R11: 0000000000000246 R12: +ffff88007baa1d98 +[1750924.420364] R13: ffff88003ecab000 R14: ffff88007b822660 R15: +0000000000000000 +[1750924.420364] FS: 00007ffff7fd8740(0000) GS:ffff88007fc80000(0000) +knlGS:0000000000000000 +[1750924.420364] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[1750924.420364] CR2: 00007ffff597c750 CR3: 000000006860b000 CR4: +00000000000007e0 +[1750924.420364] Stack: +[1750924.420364] ffff88007b822688 ffff88007af1ddf0 ffffffffa0132429 +000000007af1de20 +[1750924.420364] ffff88007baa1dc8 ffff88007baa0000 ffff88007af1de70 +ffffffffa00cb313 +[1750924.420364] 00007fffffffde88 0000000000000000 0000000000000008 +ffff88003ecab000 +[1750924.420364] Call Trace: +[1750924.420364] [] qib_multicast_detach+0x1e9/0x350 +[ib_qib] +[1750924.568035] [] ? ib_uverbs_modify_qp+0x323/0x3d0 +[ib_uverbs] +[1750924.568035] [] ib_detach_mcast+0x31/0x50 [ib_core] +[1750924.568035] [] ib_uverbs_detach_mcast+0x93/0x170 +[ib_uverbs] +[1750924.568035] [] ib_uverbs_write+0xc6/0x2c0 [ib_uverbs] +[1750924.568035] [] ? apparmor_file_permission+0x18/0x20 +[1750924.568035] [] ? security_file_permission+0x23/0xa0 +[1750924.568035] [] vfs_write+0xb4/0x1f0 +[1750924.568035] [] SyS_write+0x49/0xa0 +[1750924.568035] [] system_call_fastpath+0x1a/0x1f +[1750924.568035] Code: 66 2e 0f 1f 84 00 00 00 00 00 31 c0 5d c3 66 2e 0f 1f +84 00 00 00 00 00 66 90 0f 1f 44 00 00 55 48 89 e5 53 48 89 fb 48 8b 7f 10 + ff 8f 40 01 00 00 74 0e 48 89 df e8 8e f8 06 e1 5b 5d c3 0f +[1750924.568035] RIP [] qib_mcast_qp_free+0x11/0x50 +[ib_qib] +[1750924.568035] RSP +[1750924.650439] ---[ end trace 73d5d4b3f8ad4851 ] + +The fix is to note the qib_mcast_qp that was found. If none is found, then +return EINVAL indicating the error. + +Reviewed-by: Dennis Dalessandro +Reported-by: Jason Gunthorpe +Signed-off-by: Mike Marciniszyn +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib_verbs_mcast.c | 35 ++++++++++++---------------- + 1 file changed, 15 insertions(+), 20 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib_verbs_mcast.c ++++ b/drivers/infiniband/hw/qib/qib_verbs_mcast.c +@@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *i + struct qib_ibdev *dev = to_idev(ibqp->device); + struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num); + struct qib_mcast *mcast = NULL; +- struct qib_mcast_qp *p, *tmp; ++ struct qib_mcast_qp *p, *tmp, *delp = NULL; + struct rb_node *n; + int last = 0; + int ret; + +- if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) { +- ret = -EINVAL; +- goto bail; +- } ++ if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) ++ return -EINVAL; + + spin_lock_irq(&ibp->lock); + +@@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *i + while (1) { + if (n == NULL) { + spin_unlock_irq(&ibp->lock); +- ret = -EINVAL; +- goto bail; ++ return -EINVAL; + } + + mcast = rb_entry(n, struct qib_mcast, rb_node); +@@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *i + */ + list_del_rcu(&p->list); + mcast->n_attached--; ++ delp = p; + + /* If this was the last attached QP, remove the GID too. */ + if (list_empty(&mcast->qp_list)) { +@@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *i + } + + spin_unlock_irq(&ibp->lock); ++ /* QP not attached */ ++ if (!delp) ++ return -EINVAL; ++ /* ++ * Wait for any list walkers to finish before freeing the ++ * list element. ++ */ ++ wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); ++ qib_mcast_qp_free(delp); + +- if (p) { +- /* +- * Wait for any list walkers to finish before freeing the +- * list element. +- */ +- wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1); +- qib_mcast_qp_free(p); +- } + if (last) { + atomic_dec(&mcast->refcount); + wait_event(mcast->wait, !atomic_read(&mcast->refcount)); +@@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *i + dev->n_mcast_grps_allocated--; + spin_unlock_irq(&dev->n_mcast_grps_lock); + } +- +- ret = 0; +- +-bail: +- return ret; ++ return 0; + } + + int qib_mcast_tree_empty(struct qib_ibport *ibp) diff --git a/queue-4.4/ib-qib-support-creating-qps-with-gfp_noio-flag.patch b/queue-4.4/ib-qib-support-creating-qps-with-gfp_noio-flag.patch new file mode 100644 index 00000000000..9419e446fd2 --- /dev/null +++ b/queue-4.4/ib-qib-support-creating-qps-with-gfp_noio-flag.patch @@ -0,0 +1,139 @@ +From fbbeb8632bf0b46ab44cfcedc4654cd7831b7161 Mon Sep 17 00:00:00 2001 +From: Vinit Agnihotri +Date: Mon, 11 Jan 2016 12:57:25 -0500 +Subject: IB/qib: Support creating qps with GFP_NOIO flag + +From: Vinit Agnihotri + +commit fbbeb8632bf0b46ab44cfcedc4654cd7831b7161 upstream. + +The current code is problematic when the QP creation and ipoib is used to +support NFS and NFS desires to do IO for paging purposes. In that case, the +GFP_KERNEL allocation in qib_qp.c causes a deadlock in tight memory +situations. + +This fix adds support to create queue pair with GFP_NOIO flag for connected +mode only to cleanly fail the create queue pair in those situations. + +Reviewed-by: Mike Marciniszyn +Signed-off-by: Vinit Agnihotri +Signed-off-by: Doug Ledford +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/qib/qib_qp.c | 46 +++++++++++++++++++++++++------------ + 1 file changed, 32 insertions(+), 14 deletions(-) + +--- a/drivers/infiniband/hw/qib/qib_qp.c ++++ b/drivers/infiniband/hw/qib/qib_qp.c +@@ -100,9 +100,10 @@ static u32 credit_table[31] = { + 32768 /* 1E */ + }; + +-static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map) ++static void get_map_page(struct qib_qpn_table *qpt, struct qpn_map *map, ++ gfp_t gfp) + { +- unsigned long page = get_zeroed_page(GFP_KERNEL); ++ unsigned long page = get_zeroed_page(gfp); + + /* + * Free the page if someone raced with us installing it. +@@ -121,7 +122,7 @@ static void get_map_page(struct qib_qpn_ + * zero/one for QP type IB_QPT_SMI/IB_QPT_GSI. + */ + static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, +- enum ib_qp_type type, u8 port) ++ enum ib_qp_type type, u8 port, gfp_t gfp) + { + u32 i, offset, max_scan, qpn; + struct qpn_map *map; +@@ -151,7 +152,7 @@ static int alloc_qpn(struct qib_devdata + max_scan = qpt->nmaps - !offset; + for (i = 0;;) { + if (unlikely(!map->page)) { +- get_map_page(qpt, map); ++ get_map_page(qpt, map, gfp); + if (unlikely(!map->page)) + break; + } +@@ -983,13 +984,21 @@ struct ib_qp *qib_create_qp(struct ib_pd + size_t sz; + size_t sg_list_sz; + struct ib_qp *ret; ++ gfp_t gfp; ++ + + if (init_attr->cap.max_send_sge > ib_qib_max_sges || + init_attr->cap.max_send_wr > ib_qib_max_qp_wrs || +- init_attr->create_flags) { +- ret = ERR_PTR(-EINVAL); +- goto bail; +- } ++ init_attr->create_flags & ~(IB_QP_CREATE_USE_GFP_NOIO)) ++ return ERR_PTR(-EINVAL); ++ ++ /* GFP_NOIO is applicable in RC QPs only */ ++ if (init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO && ++ init_attr->qp_type != IB_QPT_RC) ++ return ERR_PTR(-EINVAL); ++ ++ gfp = init_attr->create_flags & IB_QP_CREATE_USE_GFP_NOIO ? ++ GFP_NOIO : GFP_KERNEL; + + /* Check receive queue parameters if no SRQ is specified. */ + if (!init_attr->srq) { +@@ -1021,7 +1030,8 @@ struct ib_qp *qib_create_qp(struct ib_pd + sz = sizeof(struct qib_sge) * + init_attr->cap.max_send_sge + + sizeof(struct qib_swqe); +- swq = vmalloc((init_attr->cap.max_send_wr + 1) * sz); ++ swq = __vmalloc((init_attr->cap.max_send_wr + 1) * sz, ++ gfp, PAGE_KERNEL); + if (swq == NULL) { + ret = ERR_PTR(-ENOMEM); + goto bail; +@@ -1037,13 +1047,13 @@ struct ib_qp *qib_create_qp(struct ib_pd + } else if (init_attr->cap.max_recv_sge > 1) + sg_list_sz = sizeof(*qp->r_sg_list) * + (init_attr->cap.max_recv_sge - 1); +- qp = kzalloc(sz + sg_list_sz, GFP_KERNEL); ++ qp = kzalloc(sz + sg_list_sz, gfp); + if (!qp) { + ret = ERR_PTR(-ENOMEM); + goto bail_swq; + } + RCU_INIT_POINTER(qp->next, NULL); +- qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), GFP_KERNEL); ++ qp->s_hdr = kzalloc(sizeof(*qp->s_hdr), gfp); + if (!qp->s_hdr) { + ret = ERR_PTR(-ENOMEM); + goto bail_qp; +@@ -1058,8 +1068,16 @@ struct ib_qp *qib_create_qp(struct ib_pd + qp->r_rq.max_sge = init_attr->cap.max_recv_sge; + sz = (sizeof(struct ib_sge) * qp->r_rq.max_sge) + + sizeof(struct qib_rwqe); +- qp->r_rq.wq = vmalloc_user(sizeof(struct qib_rwq) + +- qp->r_rq.size * sz); ++ if (gfp != GFP_NOIO) ++ qp->r_rq.wq = vmalloc_user( ++ sizeof(struct qib_rwq) + ++ qp->r_rq.size * sz); ++ else ++ qp->r_rq.wq = __vmalloc( ++ sizeof(struct qib_rwq) + ++ qp->r_rq.size * sz, ++ gfp, PAGE_KERNEL); ++ + if (!qp->r_rq.wq) { + ret = ERR_PTR(-ENOMEM); + goto bail_qp; +@@ -1090,7 +1108,7 @@ struct ib_qp *qib_create_qp(struct ib_pd + dev = to_idev(ibpd->device); + dd = dd_from_dev(dev); + err = alloc_qpn(dd, &dev->qpn_table, init_attr->qp_type, +- init_attr->port_num); ++ init_attr->port_num, gfp); + if (err < 0) { + ret = ERR_PTR(err); + vfree(qp->r_rq.wq); diff --git a/queue-4.4/ideapad-laptop-add-lenovo-ideapad-y700-17isk-to-no_hw_rfkill-dmi-list.patch b/queue-4.4/ideapad-laptop-add-lenovo-ideapad-y700-17isk-to-no_hw_rfkill-dmi-list.patch new file mode 100644 index 00000000000..0f99d9dd979 --- /dev/null +++ b/queue-4.4/ideapad-laptop-add-lenovo-ideapad-y700-17isk-to-no_hw_rfkill-dmi-list.patch @@ -0,0 +1,40 @@ +From edde316acb5f07c04abf09a92f59db5d2efd14e2 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Wed, 9 Dec 2015 21:12:52 -0500 +Subject: ideapad-laptop: Add Lenovo ideapad Y700-17ISK to no_hw_rfkill dmi list + +From: Josh Boyer + +commit edde316acb5f07c04abf09a92f59db5d2efd14e2 upstream. + +One of the newest ideapad models also lacks a physical hw rfkill switch, +and trying to read the hw rfkill switch through the ideapad module +causes it to always reported blocking breaking wifi. + +Fix it by adding this model to the DMI list. + +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1286293 +Signed-off-by: Josh Boyer +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -865,6 +865,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo ideapad Y700-17ISK", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-17ISK"), ++ }, ++ }, ++ { + .ident = "Lenovo Yoga 2 11 / 13 / Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/queue-4.4/ideapad-laptop-add-lenovo-yoga-700-to-no_hw_rfkill-dmi-list.patch b/queue-4.4/ideapad-laptop-add-lenovo-yoga-700-to-no_hw_rfkill-dmi-list.patch new file mode 100644 index 00000000000..1ccc625a719 --- /dev/null +++ b/queue-4.4/ideapad-laptop-add-lenovo-yoga-700-to-no_hw_rfkill-dmi-list.patch @@ -0,0 +1,42 @@ +From 6b31de3e698582fe0b8f7f4bab15831b73204800 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Sun, 24 Jan 2016 10:46:42 -0500 +Subject: ideapad-laptop: Add Lenovo Yoga 700 to no_hw_rfkill dmi list + +From: Josh Boyer + +commit 6b31de3e698582fe0b8f7f4bab15831b73204800 upstream. + +Like the Yoga 900 models the Lenovo Yoga 700 does not have a +hw rfkill switch, and trying to read the hw rfkill switch through the +ideapad module causes it to always reported blocking breaking wifi. + +This commit adds the Lenovo Yoga 700 to the no_hw_rfkill dmi list, fixing +the wifi breakage. + +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1295272 +Tested-by: +Signed-off-by: Josh Boyer +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -900,6 +900,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo Yoga 700", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 700"), ++ }, ++ }, ++ { + .ident = "Lenovo Yoga 900", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/queue-4.4/lib-sw842-select-crc32.patch b/queue-4.4/lib-sw842-select-crc32.patch new file mode 100644 index 00000000000..7ea5706fd36 --- /dev/null +++ b/queue-4.4/lib-sw842-select-crc32.patch @@ -0,0 +1,45 @@ +From 5b57167749274961baf15ed1f05a4996b3ab0487 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 13 Jan 2016 23:24:02 +0100 +Subject: lib: sw842: select crc32 + +From: Arnd Bergmann + +commit 5b57167749274961baf15ed1f05a4996b3ab0487 upstream. + +The sw842 library code was merged in linux-4.1 and causes a very rare randconfig +failure when CONFIG_CRC32 is not set: + + lib/built-in.o: In function `sw842_compress': + oid_registry.c:(.text+0x12ddc): undefined reference to `crc32_be' + lib/built-in.o: In function `sw842_decompress': + oid_registry.c:(.text+0x137e4): undefined reference to `crc32_be' + +This adds an explict 'select CRC32' statement, similar to what the other users +of the crc32 code have. In practice, CRC32 is always enabled anyway because +over 100 other symbols select it. + +Signed-off-by: Arnd Bergmann +Fixes: 2da572c959dd ("lib: add software 842 compression/decompression") +Acked-by: Dan Streetman +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + lib/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -210,9 +210,11 @@ config RANDOM32_SELFTEST + # compression support is select'ed if needed + # + config 842_COMPRESS ++ select CRC32 + tristate + + config 842_DECOMPRESS ++ select CRC32 + tristate + + config ZLIB_INFLATE diff --git a/queue-4.4/libceph-don-t-bail-early-from-try_read-when-skipping-a-message.patch b/queue-4.4/libceph-don-t-bail-early-from-try_read-when-skipping-a-message.patch new file mode 100644 index 00000000000..beaa3e945f0 --- /dev/null +++ b/queue-4.4/libceph-don-t-bail-early-from-try_read-when-skipping-a-message.patch @@ -0,0 +1,47 @@ +From e7a88e82fe380459b864e05b372638aeacb0f52d Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Wed, 17 Feb 2016 20:04:08 +0100 +Subject: libceph: don't bail early from try_read() when skipping a message + +From: Ilya Dryomov + +commit e7a88e82fe380459b864e05b372638aeacb0f52d upstream. + +The contract between try_read() and try_write() is that when called +each processes as much data as possible. When instructed by osd_client +to skip a message, try_read() is violating this contract by returning +after receiving and discarding a single message instead of checking for +more. try_write() then gets a chance to write out more requests, +generating more replies/skips for try_read() to handle, forcing the +messenger into a starvation loop. + +Reported-by: Varada Kari +Signed-off-by: Ilya Dryomov +Tested-by: Varada Kari +Reviewed-by: Alex Elder +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/messenger.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -2340,7 +2340,7 @@ static int read_partial_message(struct c + con->in_base_pos = -front_len - middle_len - data_len - + sizeof(m->footer); + con->in_tag = CEPH_MSGR_TAG_READY; +- return 0; ++ return 1; + } else if ((s64)seq - (s64)con->in_seq > 1) { + pr_err("read_partial_message bad seq %lld expected %lld\n", + seq, con->in_seq + 1); +@@ -2366,7 +2366,7 @@ static int read_partial_message(struct c + sizeof(m->footer); + con->in_tag = CEPH_MSGR_TAG_READY; + con->in_seq++; +- return 0; ++ return 1; + } + + BUG_ON(!con->in_msg); diff --git a/queue-4.4/libceph-don-t-spam-dmesg-with-stray-reply-warnings.patch b/queue-4.4/libceph-don-t-spam-dmesg-with-stray-reply-warnings.patch new file mode 100644 index 00000000000..2ee47e64f70 --- /dev/null +++ b/queue-4.4/libceph-don-t-spam-dmesg-with-stray-reply-warnings.patch @@ -0,0 +1,35 @@ +From cd8140c673d9ba9be3591220e1b2226d9e1e40d3 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 19 Feb 2016 11:38:57 +0100 +Subject: libceph: don't spam dmesg with stray reply warnings + +From: Ilya Dryomov + +commit cd8140c673d9ba9be3591220e1b2226d9e1e40d3 upstream. + +Commit d15f9d694b77 ("libceph: check data_len in ->alloc_msg()") +mistakenly bumped the log level on the "tid %llu unknown, skipping" +message. Turn it back into a dout() - stray replies are perfectly +normal when OSDs flap, crash, get killed for testing purposes, etc. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Alex Elder +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/osd_client.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ceph/osd_client.c ++++ b/net/ceph/osd_client.c +@@ -2843,8 +2843,8 @@ static struct ceph_msg *get_reply(struct + mutex_lock(&osdc->request_mutex); + req = __lookup_request(osdc, tid); + if (!req) { +- pr_warn("%s osd%d tid %llu unknown, skipping\n", +- __func__, osd->o_osd, tid); ++ dout("%s osd%d tid %llu unknown, skipping\n", __func__, ++ osd->o_osd, tid); + m = NULL; + *skip = 1; + goto out; diff --git a/queue-4.4/libceph-fix-ceph_msg_revoke.patch b/queue-4.4/libceph-fix-ceph_msg_revoke.patch new file mode 100644 index 00000000000..b0b195f9654 --- /dev/null +++ b/queue-4.4/libceph-fix-ceph_msg_revoke.patch @@ -0,0 +1,252 @@ +From 67645d7619738e51c668ca69f097cb90b5470422 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Mon, 28 Dec 2015 13:18:34 +0300 +Subject: libceph: fix ceph_msg_revoke() + +From: Ilya Dryomov + +commit 67645d7619738e51c668ca69f097cb90b5470422 upstream. + +There are a number of problems with revoking a "was sending" message: + +(1) We never make any attempt to revoke data - only kvecs contibute to +con->out_skip. However, once the header (envelope) is written to the +socket, our peer learns data_len and sets itself to expect at least +data_len bytes to follow front or front+middle. If ceph_msg_revoke() +is called while the messenger is sending message's data portion, +anything we send after that call is counted by the OSD towards the now +revoked message's data portion. The effects vary, the most common one +is the eventual hang - higher layers get stuck waiting for the reply to +the message that was sent out after ceph_msg_revoke() returned and +treated by the OSD as a bunch of data bytes. This is what Matt ran +into. + +(2) Flat out zeroing con->out_kvec_bytes worth of bytes to handle kvecs +is wrong. If ceph_msg_revoke() is called before the tag is sent out or +while the messenger is sending the header, we will get a connection +reset, either due to a bad tag (0 is not a valid tag) or a bad header +CRC, which kind of defeats the purpose of revoke. Currently the kernel +client refuses to work with header CRCs disabled, but that will likely +change in the future, making this even worse. + +(3) con->out_skip is not reset on connection reset, leading to one or +more spurious connection resets if we happen to get a real one between +con->out_skip is set in ceph_msg_revoke() and before it's cleared in +write_partial_skip(). + +Fixing (1) and (3) is trivial. The idea behind fixing (2) is to never +zero the tag or the header, i.e. send out tag+header regardless of when +ceph_msg_revoke() is called. That way the header is always correct, no +unnecessary resets are induced and revoke stands ready for disabled +CRCs. Since ceph_msg_revoke() rips out con->out_msg, introduce a new +"message out temp" and copy the header into it before sending. + +Reported-by: Matt Conner +Signed-off-by: Ilya Dryomov +Tested-by: Matt Conner +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ceph/messenger.h | 2 - + net/ceph/messenger.c | 78 +++++++++++++++++++++++++++++++---------- + 2 files changed, 60 insertions(+), 20 deletions(-) + +--- a/include/linux/ceph/messenger.h ++++ b/include/linux/ceph/messenger.h +@@ -220,6 +220,7 @@ struct ceph_connection { + struct ceph_entity_addr actual_peer_addr; + + /* message out temps */ ++ struct ceph_msg_header out_hdr; + struct ceph_msg *out_msg; /* sending message (== tail of + out_sent) */ + bool out_msg_done; +@@ -229,7 +230,6 @@ struct ceph_connection { + int out_kvec_left; /* kvec's left in out_kvec */ + int out_skip; /* skip this many bytes */ + int out_kvec_bytes; /* total bytes left */ +- bool out_kvec_is_msg; /* kvec refers to out_msg */ + int out_more; /* there is more data after the kvecs */ + __le64 out_temp_ack; /* for writing an ack */ + struct ceph_timespec out_temp_keepalive2; /* for writing keepalive2 +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -672,6 +672,8 @@ static void reset_connection(struct ceph + } + con->in_seq = 0; + con->in_seq_acked = 0; ++ ++ con->out_skip = 0; + } + + /* +@@ -771,6 +773,8 @@ static u32 get_global_seq(struct ceph_me + + static void con_out_kvec_reset(struct ceph_connection *con) + { ++ BUG_ON(con->out_skip); ++ + con->out_kvec_left = 0; + con->out_kvec_bytes = 0; + con->out_kvec_cur = &con->out_kvec[0]; +@@ -779,9 +783,9 @@ static void con_out_kvec_reset(struct ce + static void con_out_kvec_add(struct ceph_connection *con, + size_t size, void *data) + { +- int index; ++ int index = con->out_kvec_left; + +- index = con->out_kvec_left; ++ BUG_ON(con->out_skip); + BUG_ON(index >= ARRAY_SIZE(con->out_kvec)); + + con->out_kvec[index].iov_len = size; +@@ -790,6 +794,27 @@ static void con_out_kvec_add(struct ceph + con->out_kvec_bytes += size; + } + ++/* ++ * Chop off a kvec from the end. Return residual number of bytes for ++ * that kvec, i.e. how many bytes would have been written if the kvec ++ * hadn't been nuked. ++ */ ++static int con_out_kvec_skip(struct ceph_connection *con) ++{ ++ int off = con->out_kvec_cur - con->out_kvec; ++ int skip = 0; ++ ++ if (con->out_kvec_bytes > 0) { ++ skip = con->out_kvec[off + con->out_kvec_left - 1].iov_len; ++ BUG_ON(con->out_kvec_bytes < skip); ++ BUG_ON(!con->out_kvec_left); ++ con->out_kvec_bytes -= skip; ++ con->out_kvec_left--; ++ } ++ ++ return skip; ++} ++ + #ifdef CONFIG_BLOCK + + /* +@@ -1197,7 +1222,6 @@ static void prepare_write_message_footer + m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE; + + dout("prepare_write_message_footer %p\n", con); +- con->out_kvec_is_msg = true; + con->out_kvec[v].iov_base = &m->footer; + if (con->peer_features & CEPH_FEATURE_MSG_AUTH) { + if (con->ops->sign_message) +@@ -1225,7 +1249,6 @@ static void prepare_write_message(struct + u32 crc; + + con_out_kvec_reset(con); +- con->out_kvec_is_msg = true; + con->out_msg_done = false; + + /* Sneak an ack in there first? If we can get it into the same +@@ -1265,18 +1288,19 @@ static void prepare_write_message(struct + + /* tag + hdr + front + middle */ + con_out_kvec_add(con, sizeof (tag_msg), &tag_msg); +- con_out_kvec_add(con, sizeof (m->hdr), &m->hdr); ++ con_out_kvec_add(con, sizeof(con->out_hdr), &con->out_hdr); + con_out_kvec_add(con, m->front.iov_len, m->front.iov_base); + + if (m->middle) + con_out_kvec_add(con, m->middle->vec.iov_len, + m->middle->vec.iov_base); + +- /* fill in crc (except data pages), footer */ ++ /* fill in hdr crc and finalize hdr */ + crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc)); + con->out_msg->hdr.crc = cpu_to_le32(crc); +- con->out_msg->footer.flags = 0; ++ memcpy(&con->out_hdr, &con->out_msg->hdr, sizeof(con->out_hdr)); + ++ /* fill in front and middle crc, footer */ + crc = crc32c(0, m->front.iov_base, m->front.iov_len); + con->out_msg->footer.front_crc = cpu_to_le32(crc); + if (m->middle) { +@@ -1288,6 +1312,7 @@ static void prepare_write_message(struct + dout("%s front_crc %u middle_crc %u\n", __func__, + le32_to_cpu(con->out_msg->footer.front_crc), + le32_to_cpu(con->out_msg->footer.middle_crc)); ++ con->out_msg->footer.flags = 0; + + /* is there a data payload? */ + con->out_msg->footer.data_crc = 0; +@@ -1492,7 +1517,6 @@ static int write_partial_kvec(struct cep + } + } + con->out_kvec_left = 0; +- con->out_kvec_is_msg = false; + ret = 1; + out: + dout("write_partial_kvec %p %d left in %d kvecs ret = %d\n", con, +@@ -1584,6 +1608,7 @@ static int write_partial_skip(struct cep + { + int ret; + ++ dout("%s %p %d left\n", __func__, con, con->out_skip); + while (con->out_skip > 0) { + size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE); + +@@ -2506,13 +2531,13 @@ more: + + more_kvec: + /* kvec data queued? */ +- if (con->out_skip) { +- ret = write_partial_skip(con); ++ if (con->out_kvec_left) { ++ ret = write_partial_kvec(con); + if (ret <= 0) + goto out; + } +- if (con->out_kvec_left) { +- ret = write_partial_kvec(con); ++ if (con->out_skip) { ++ ret = write_partial_skip(con); + if (ret <= 0) + goto out; + } +@@ -3050,16 +3075,31 @@ void ceph_msg_revoke(struct ceph_msg *ms + ceph_msg_put(msg); + } + if (con->out_msg == msg) { +- dout("%s %p msg %p - was sending\n", __func__, con, msg); +- con->out_msg = NULL; +- if (con->out_kvec_is_msg) { +- con->out_skip = con->out_kvec_bytes; +- con->out_kvec_is_msg = false; +- } +- msg->hdr.seq = 0; ++ BUG_ON(con->out_skip); ++ /* footer */ ++ if (con->out_msg_done) { ++ con->out_skip += con_out_kvec_skip(con); ++ } else { ++ BUG_ON(!msg->data_length); ++ if (con->peer_features & CEPH_FEATURE_MSG_AUTH) ++ con->out_skip += sizeof(msg->footer); ++ else ++ con->out_skip += sizeof(msg->old_footer); ++ } ++ /* data, middle, front */ ++ if (msg->data_length) ++ con->out_skip += msg->cursor.total_resid; ++ if (msg->middle) ++ con->out_skip += con_out_kvec_skip(con); ++ con->out_skip += con_out_kvec_skip(con); + ++ dout("%s %p msg %p - was sending, will write %d skip %d\n", ++ __func__, con, msg, con->out_kvec_bytes, con->out_skip); ++ msg->hdr.seq = 0; ++ con->out_msg = NULL; + ceph_msg_put(msg); + } ++ + mutex_unlock(&con->mutex); + } + diff --git a/queue-4.4/libceph-use-the-right-footer-size-when-skipping-a-message.patch b/queue-4.4/libceph-use-the-right-footer-size-when-skipping-a-message.patch new file mode 100644 index 00000000000..8a614ee24ec --- /dev/null +++ b/queue-4.4/libceph-use-the-right-footer-size-when-skipping-a-message.patch @@ -0,0 +1,54 @@ +From dbc0d3caff5b7591e0cf8e34ca686ca6f4479ee1 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 19 Feb 2016 11:38:57 +0100 +Subject: libceph: use the right footer size when skipping a message + +From: Ilya Dryomov + +commit dbc0d3caff5b7591e0cf8e34ca686ca6f4479ee1 upstream. + +ceph_msg_footer is 21 bytes long, while ceph_msg_footer_old is only 13. +Don't skip too much when CEPH_FEATURE_MSG_AUTH isn't negotiated. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Alex Elder +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/messenger.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/net/ceph/messenger.c ++++ b/net/ceph/messenger.c +@@ -1200,6 +1200,13 @@ static bool ceph_msg_data_advance(struct + return new_piece; + } + ++static size_t sizeof_footer(struct ceph_connection *con) ++{ ++ return (con->peer_features & CEPH_FEATURE_MSG_AUTH) ? ++ sizeof(struct ceph_msg_footer) : ++ sizeof(struct ceph_msg_footer_old); ++} ++ + static void prepare_message_data(struct ceph_msg *msg, u32 data_len) + { + BUG_ON(!msg); +@@ -2338,7 +2345,7 @@ static int read_partial_message(struct c + ceph_pr_addr(&con->peer_addr.in_addr), + seq, con->in_seq + 1); + con->in_base_pos = -front_len - middle_len - data_len - +- sizeof(m->footer); ++ sizeof_footer(con); + con->in_tag = CEPH_MSGR_TAG_READY; + return 1; + } else if ((s64)seq - (s64)con->in_seq > 1) { +@@ -2363,7 +2370,7 @@ static int read_partial_message(struct c + /* skip this message */ + dout("alloc_msg said skip message\n"); + con->in_base_pos = -front_len - middle_len - data_len - +- sizeof(m->footer); ++ sizeof_footer(con); + con->in_tag = CEPH_MSGR_TAG_READY; + con->in_seq++; + return 1; diff --git a/queue-4.4/nfit-fix-multi-interface-dimm-handling-acpi6.1-compatibility.patch b/queue-4.4/nfit-fix-multi-interface-dimm-handling-acpi6.1-compatibility.patch new file mode 100644 index 00000000000..e45df36b235 --- /dev/null +++ b/queue-4.4/nfit-fix-multi-interface-dimm-handling-acpi6.1-compatibility.patch @@ -0,0 +1,179 @@ +From 6697b2cf69d4363266ca47eaebc49ef13dabc1c9 Mon Sep 17 00:00:00 2001 +From: Dan Williams +Date: Thu, 4 Feb 2016 16:51:00 -0800 +Subject: nfit: fix multi-interface dimm handling, acpi6.1 compatibility + +From: Dan Williams + +commit 6697b2cf69d4363266ca47eaebc49ef13dabc1c9 upstream. + +ACPI 6.1 clarified that multi-interface dimms require multiple control +region entries (DCRs) per dimm. Previously we were assuming that a +control region is only present when block-data-windows are present. +This implementation was done with an eye to be compatibility with the +looser ACPI 6.0 interpretation of this table. + +1/ When coalescing the memory device (MEMDEV) tables for a single dimm, +coalesce on device_handle rather than control region index. + +2/ Whenever we disocver a control region with non-zero block windows +re-scan for block-data-window (BDW) entries. + +We may need to revisit this if a DIMM ever implements a format interface +outside of blk or pmem, but that is not on the foreseeable horizon. + +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/nfit.c | 71 +++++++++++++++++++++++++--------------------------- + 1 file changed, 35 insertions(+), 36 deletions(-) + +--- a/drivers/acpi/nfit.c ++++ b/drivers/acpi/nfit.c +@@ -468,37 +468,16 @@ static void nfit_mem_find_spa_bdw(struct + nfit_mem->bdw = NULL; + } + +-static int nfit_mem_add(struct acpi_nfit_desc *acpi_desc, ++static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc, + struct nfit_mem *nfit_mem, struct acpi_nfit_system_address *spa) + { + u16 dcr = __to_nfit_memdev(nfit_mem)->region_index; + struct nfit_memdev *nfit_memdev; + struct nfit_flush *nfit_flush; +- struct nfit_dcr *nfit_dcr; + struct nfit_bdw *nfit_bdw; + struct nfit_idt *nfit_idt; + u16 idt_idx, range_index; + +- list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) { +- if (nfit_dcr->dcr->region_index != dcr) +- continue; +- nfit_mem->dcr = nfit_dcr->dcr; +- break; +- } +- +- if (!nfit_mem->dcr) { +- dev_dbg(acpi_desc->dev, "SPA %d missing:%s%s\n", +- spa->range_index, __to_nfit_memdev(nfit_mem) +- ? "" : " MEMDEV", nfit_mem->dcr ? "" : " DCR"); +- return -ENODEV; +- } +- +- /* +- * We've found enough to create an nvdimm, optionally +- * find an associated BDW +- */ +- list_add(&nfit_mem->list, &acpi_desc->dimms); +- + list_for_each_entry(nfit_bdw, &acpi_desc->bdws, list) { + if (nfit_bdw->bdw->region_index != dcr) + continue; +@@ -507,12 +486,12 @@ static int nfit_mem_add(struct acpi_nfit + } + + if (!nfit_mem->bdw) +- return 0; ++ return; + + nfit_mem_find_spa_bdw(acpi_desc, nfit_mem); + + if (!nfit_mem->spa_bdw) +- return 0; ++ return; + + range_index = nfit_mem->spa_bdw->range_index; + list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { +@@ -537,8 +516,6 @@ static int nfit_mem_add(struct acpi_nfit + } + break; + } +- +- return 0; + } + + static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc, +@@ -547,7 +524,6 @@ static int nfit_mem_dcr_init(struct acpi + struct nfit_mem *nfit_mem, *found; + struct nfit_memdev *nfit_memdev; + int type = nfit_spa_type(spa); +- u16 dcr; + + switch (type) { + case NFIT_SPA_DCR: +@@ -558,14 +534,18 @@ static int nfit_mem_dcr_init(struct acpi + } + + list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { +- int rc; ++ struct nfit_dcr *nfit_dcr; ++ u32 device_handle; ++ u16 dcr; + + if (nfit_memdev->memdev->range_index != spa->range_index) + continue; + found = NULL; + dcr = nfit_memdev->memdev->region_index; ++ device_handle = nfit_memdev->memdev->device_handle; + list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) +- if (__to_nfit_memdev(nfit_mem)->region_index == dcr) { ++ if (__to_nfit_memdev(nfit_mem)->device_handle ++ == device_handle) { + found = nfit_mem; + break; + } +@@ -578,6 +558,31 @@ static int nfit_mem_dcr_init(struct acpi + if (!nfit_mem) + return -ENOMEM; + INIT_LIST_HEAD(&nfit_mem->list); ++ list_add(&nfit_mem->list, &acpi_desc->dimms); ++ } ++ ++ list_for_each_entry(nfit_dcr, &acpi_desc->dcrs, list) { ++ if (nfit_dcr->dcr->region_index != dcr) ++ continue; ++ /* ++ * Record the control region for the dimm. For ++ * the ACPI 6.1 case, where there are separate ++ * control regions for the pmem vs blk ++ * interfaces, be sure to record the extended ++ * blk details. ++ */ ++ if (!nfit_mem->dcr) ++ nfit_mem->dcr = nfit_dcr->dcr; ++ else if (nfit_mem->dcr->windows == 0 ++ && nfit_dcr->dcr->windows) ++ nfit_mem->dcr = nfit_dcr->dcr; ++ break; ++ } ++ ++ if (dcr && !nfit_mem->dcr) { ++ dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n", ++ spa->range_index, dcr); ++ return -ENODEV; + } + + if (type == NFIT_SPA_DCR) { +@@ -594,6 +599,7 @@ static int nfit_mem_dcr_init(struct acpi + nfit_mem->idt_dcr = nfit_idt->idt; + break; + } ++ nfit_mem_init_bdw(acpi_desc, nfit_mem, spa); + } else { + /* + * A single dimm may belong to multiple SPA-PM +@@ -602,13 +608,6 @@ static int nfit_mem_dcr_init(struct acpi + */ + nfit_mem->memdev_pmem = nfit_memdev->memdev; + } +- +- if (found) +- continue; +- +- rc = nfit_mem_add(acpi_desc, nfit_mem, spa); +- if (rc) +- return rc; + } + + return 0; diff --git a/queue-4.4/revert-staging-panel-usleep_range-is-preferred-over-udelay.patch b/queue-4.4/revert-staging-panel-usleep_range-is-preferred-over-udelay.patch new file mode 100644 index 00000000000..84d7c93c215 --- /dev/null +++ b/queue-4.4/revert-staging-panel-usleep_range-is-preferred-over-udelay.patch @@ -0,0 +1,153 @@ +From b64a1cbef6df47c986ad622b5b2e4d3d1940070c Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee +Date: Sat, 23 Jan 2016 14:49:20 +0530 +Subject: Revert "Staging: panel: usleep_range is preferred over udelay" + +From: Sudip Mukherjee + +commit b64a1cbef6df47c986ad622b5b2e4d3d1940070c upstream. + +This reverts commit ebd43516d3879f882a403836bba8bc5791f26a28. + +We should not be sleeping inside spin_lock. + +Fixes: ebd43516d387 ("Staging: panel: usleep_range is preferred over udelay") +Cc: Sirnam Swetha +Signed-off-by: Sudip Mukherjee +Reported-by: Huang, Ying +Tested-by: Huang, Ying +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c +index 79ac19246548..70b8f4fabfad 100644 +--- a/drivers/staging/panel/panel.c ++++ b/drivers/staging/panel/panel.c +@@ -825,8 +825,7 @@ static void lcd_write_cmd_s(int cmd) + lcd_send_serial(0x1F); /* R/W=W, RS=0 */ + lcd_send_serial(cmd & 0x0F); + lcd_send_serial((cmd >> 4) & 0x0F); +- /* the shortest command takes at least 40 us */ +- usleep_range(40, 100); ++ udelay(40); /* the shortest command takes at least 40 us */ + spin_unlock_irq(&pprt_lock); + } + +@@ -837,8 +836,7 @@ static void lcd_write_data_s(int data) + lcd_send_serial(0x5F); /* R/W=W, RS=1 */ + lcd_send_serial(data & 0x0F); + lcd_send_serial((data >> 4) & 0x0F); +- /* the shortest data takes at least 40 us */ +- usleep_range(40, 100); ++ udelay(40); /* the shortest data takes at least 40 us */ + spin_unlock_irq(&pprt_lock); + } + +@@ -848,20 +846,19 @@ static void lcd_write_cmd_p8(int cmd) + spin_lock_irq(&pprt_lock); + /* present the data to the data port */ + w_dtr(pprt, cmd); +- /* maintain the data during 20 us before the strobe */ +- usleep_range(20, 100); ++ udelay(20); /* maintain the data during 20 us before the strobe */ + + bits.e = BIT_SET; + bits.rs = BIT_CLR; + bits.rw = BIT_CLR; + set_ctrl_bits(); + +- usleep_range(40, 100); /* maintain the strobe during 40 us */ ++ udelay(40); /* maintain the strobe during 40 us */ + + bits.e = BIT_CLR; + set_ctrl_bits(); + +- usleep_range(120, 500); /* the shortest command takes at least 120 us */ ++ udelay(120); /* the shortest command takes at least 120 us */ + spin_unlock_irq(&pprt_lock); + } + +@@ -871,20 +868,19 @@ static void lcd_write_data_p8(int data) + spin_lock_irq(&pprt_lock); + /* present the data to the data port */ + w_dtr(pprt, data); +- /* maintain the data during 20 us before the strobe */ +- usleep_range(20, 100); ++ udelay(20); /* maintain the data during 20 us before the strobe */ + + bits.e = BIT_SET; + bits.rs = BIT_SET; + bits.rw = BIT_CLR; + set_ctrl_bits(); + +- usleep_range(40, 100); /* maintain the strobe during 40 us */ ++ udelay(40); /* maintain the strobe during 40 us */ + + bits.e = BIT_CLR; + set_ctrl_bits(); + +- usleep_range(45, 100); /* the shortest data takes at least 45 us */ ++ udelay(45); /* the shortest data takes at least 45 us */ + spin_unlock_irq(&pprt_lock); + } + +@@ -894,7 +890,7 @@ static void lcd_write_cmd_tilcd(int cmd) + spin_lock_irq(&pprt_lock); + /* present the data to the control port */ + w_ctr(pprt, cmd); +- usleep_range(60, 120); ++ udelay(60); + spin_unlock_irq(&pprt_lock); + } + +@@ -904,7 +900,7 @@ static void lcd_write_data_tilcd(int data) + spin_lock_irq(&pprt_lock); + /* present the data to the data port */ + w_dtr(pprt, data); +- usleep_range(60, 120); ++ udelay(60); + spin_unlock_irq(&pprt_lock); + } + +@@ -947,7 +943,7 @@ static void lcd_clear_fast_s(void) + lcd_send_serial(0x5F); /* R/W=W, RS=1 */ + lcd_send_serial(' ' & 0x0F); + lcd_send_serial((' ' >> 4) & 0x0F); +- usleep_range(40, 100); /* the shortest data takes at least 40 us */ ++ udelay(40); /* the shortest data takes at least 40 us */ + } + spin_unlock_irq(&pprt_lock); + +@@ -971,7 +967,7 @@ static void lcd_clear_fast_p8(void) + w_dtr(pprt, ' '); + + /* maintain the data during 20 us before the strobe */ +- usleep_range(20, 100); ++ udelay(20); + + bits.e = BIT_SET; + bits.rs = BIT_SET; +@@ -979,13 +975,13 @@ static void lcd_clear_fast_p8(void) + set_ctrl_bits(); + + /* maintain the strobe during 40 us */ +- usleep_range(40, 100); ++ udelay(40); + + bits.e = BIT_CLR; + set_ctrl_bits(); + + /* the shortest data takes at least 45 us */ +- usleep_range(45, 100); ++ udelay(45); + } + spin_unlock_irq(&pprt_lock); + +@@ -1007,7 +1003,7 @@ static void lcd_clear_fast_tilcd(void) + for (pos = 0; pos < lcd.height * lcd.hwidth; pos++) { + /* present the data to the data port */ + w_dtr(pprt, ' '); +- usleep_range(60, 120); ++ udelay(60); + } + + spin_unlock_irq(&pprt_lock); diff --git a/queue-4.4/sd-optimal-i-o-size-is-in-bytes-not-sectors.patch b/queue-4.4/sd-optimal-i-o-size-is-in-bytes-not-sectors.patch new file mode 100644 index 00000000000..c154665b1ea --- /dev/null +++ b/queue-4.4/sd-optimal-i-o-size-is-in-bytes-not-sectors.patch @@ -0,0 +1,37 @@ +From d0eb20a863ba7dc1d3f4b841639671f134560be2 Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Wed, 20 Jan 2016 11:01:23 -0500 +Subject: sd: Optimal I/O size is in bytes, not sectors + +From: Martin K. Petersen + +commit d0eb20a863ba7dc1d3f4b841639671f134560be2 upstream. + +Commit ca369d51b3e1 ("block/sd: Fix device-imposed transfer length +limits") accidentally switched optimal I/O size reporting from bytes to +block layer sectors. + +Signed-off-by: Martin K. Petersen +Reported-by: Christian Borntraeger +Tested-by: Christian Borntraeger +Fixes: ca369d51b3e1649be4a72addd6d6a168cfb3f537 +Reviewed-by: James E.J. Bottomley +Reviewed-by: Ewan D. Milne +Reviewed-by: Matthew R. Ochs +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -2893,7 +2893,7 @@ static int sd_revalidate_disk(struct gen + sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS && + sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_CACHE_SIZE) + rw_max = q->limits.io_opt = +- logical_to_sectors(sdp, sdkp->opt_xfer_blocks); ++ sdkp->opt_xfer_blocks * sdp->sector_size; + else + rw_max = BLK_DEF_MAX_SECTORS; + diff --git a/queue-4.4/seccomp-always-propagate-no_new_privs-on-tsync.patch b/queue-4.4/seccomp-always-propagate-no_new_privs-on-tsync.patch new file mode 100644 index 00000000000..bd6f0a40b45 --- /dev/null +++ b/queue-4.4/seccomp-always-propagate-no_new_privs-on-tsync.patch @@ -0,0 +1,60 @@ +From 103502a35cfce0710909da874f092cb44823ca03 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Sat, 26 Dec 2015 06:00:48 +0100 +Subject: seccomp: always propagate NO_NEW_PRIVS on tsync + +From: Jann Horn + +commit 103502a35cfce0710909da874f092cb44823ca03 upstream. + +Before this patch, a process with some permissive seccomp filter +that was applied by root without NO_NEW_PRIVS was able to add +more filters to itself without setting NO_NEW_PRIVS by setting +the new filter from a throwaway thread with NO_NEW_PRIVS. + +Signed-off-by: Jann Horn +Signed-off-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/seccomp.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/kernel/seccomp.c ++++ b/kernel/seccomp.c +@@ -316,24 +316,24 @@ static inline void seccomp_sync_threads( + put_seccomp_filter(thread); + smp_store_release(&thread->seccomp.filter, + caller->seccomp.filter); ++ ++ /* ++ * Don't let an unprivileged task work around ++ * the no_new_privs restriction by creating ++ * a thread that sets it up, enters seccomp, ++ * then dies. ++ */ ++ if (task_no_new_privs(caller)) ++ task_set_no_new_privs(thread); ++ + /* + * Opt the other thread into seccomp if needed. + * As threads are considered to be trust-realm + * equivalent (see ptrace_may_access), it is safe to + * allow one thread to transition the other. + */ +- if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) { +- /* +- * Don't let an unprivileged task work around +- * the no_new_privs restriction by creating +- * a thread that sets it up, enters seccomp, +- * then dies. +- */ +- if (task_no_new_privs(caller)) +- task_set_no_new_privs(thread); +- ++ if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) + seccomp_assign_mode(thread, SECCOMP_MODE_FILTER); +- } + } + } + diff --git a/queue-4.4/series b/queue-4.4/series index e2db8553ac6..e270955b326 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -233,3 +233,37 @@ drm-fix-treatment-of-drm_vblank_offdelay-in-drm_vblank_on-v2.patch drm-radeon-don-t-hang-in-radeon_flip_work_func-on-disabled-crtc.-v2.patch drm-radeon-pm-adjust-display-configuration-after-powerstate.patch make-sure-that-freeing-shmem-fast-symlinks-is-rcu-delayed.patch +toshiba_acpi-fix-blank-screen-at-boot-if-transflective-backlight-is-supported.patch +ideapad-laptop-add-lenovo-ideapad-y700-17isk-to-no_hw_rfkill-dmi-list.patch +ideapad-laptop-add-lenovo-yoga-700-to-no_hw_rfkill-dmi-list.patch +uapi-update-install-list-after-nvme.h-rename.patch +lib-sw842-select-crc32.patch +acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-portege-r700.patch +acpi-video-add-disable_backlight_sysfs_if-quirk-for-the-toshiba-satellite-r830.patch +acpi-revert-acpi-video-add-dell-inspiron-5737-to-the-blacklist.patch +acpi-pci-hotplug-unlock-in-error-path-in-acpiphp_enable_slot.patch +nfit-fix-multi-interface-dimm-handling-acpi6.1-compatibility.patch +dmaengine-dw-fix-cyclic-transfer-setup.patch +dmaengine-dw-fix-cyclic-transfer-callbacks.patch +dmaengine-at_xdmac-fix-resume-for-cyclic-transfers.patch +dmaengine-dw-disable-block-irqs-for-non-cyclic-xfer.patch +ib-cm-fix-a-recently-introduced-deadlock.patch +ib-qib-fix-mcast-detach-when-qp-not-attached.patch +ib-qib-support-creating-qps-with-gfp_noio-flag.patch +ib-mlx5-expose-correct-maximum-number-of-cqe-capacity.patch +thermal-initialize-thermal-zone-device-correctly.patch +thermal-handle-thermal-zone-device-properly-during-system-sleep.patch +thermal-do-thermal-zone-update-after-a-cooling-device-registered.patch +hwmon-dell-smm-blacklist-dell-studio-xps-8000.patch +hwmon-gpio-fan-remove-un-necessary-speed_index-lookup-for-thermal-hook.patch +hwmon-ads1015-handle-negative-conversion-values-correctly.patch +cpufreq-pxa2xx-fix-pxa_cpufreq_change_voltage-prototype.patch +cpufreq-fix-null-reference-crash-while-accessing-policy-governor_data.patch +seccomp-always-propagate-no_new_privs-on-tsync.patch +libceph-fix-ceph_msg_revoke.patch +libceph-don-t-bail-early-from-try_read-when-skipping-a-message.patch +libceph-use-the-right-footer-size-when-skipping-a-message.patch +libceph-don-t-spam-dmesg-with-stray-reply-warnings.patch +sd-optimal-i-o-size-is-in-bytes-not-sectors.patch +staging-speakup-fix-getting-port-information.patch +revert-staging-panel-usleep_range-is-preferred-over-udelay.patch diff --git a/queue-4.4/staging-speakup-fix-getting-port-information.patch b/queue-4.4/staging-speakup-fix-getting-port-information.patch new file mode 100644 index 00000000000..d29e98dd13a --- /dev/null +++ b/queue-4.4/staging-speakup-fix-getting-port-information.patch @@ -0,0 +1,59 @@ +From 327b882d3bcc1fba82dbd39b5cf5a838c81218e2 Mon Sep 17 00:00:00 2001 +From: Samuel Thibault +Date: Fri, 15 Jan 2016 00:47:41 +0100 +Subject: Staging: speakup: Fix getting port information + +From: Samuel Thibault + +commit 327b882d3bcc1fba82dbd39b5cf5a838c81218e2 upstream. + +Commit f79b0d9c223c ("staging: speakup: Fixed warning +instead of ") broke the port information in the speakup +driver: SERIAL_PORT_DFNS only gets defined if asm/serial.h is included, +and no other header includes asm/serial.h. + +We here make sure serialio.c does get the arch-specific definition of +SERIAL_PORT_DFNS from asm/serial.h, if any. + +Along the way, this makes sure that we do have information for the +requested serial port number (index) + +Fixes: f79b0d9c223c ("staging: speakup: Fixed warning instead of ") +Signed-off-by: Samuel Thibault +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/speakup/serialio.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/staging/speakup/serialio.c ++++ b/drivers/staging/speakup/serialio.c +@@ -6,6 +6,11 @@ + #include "spk_priv.h" + #include "serialio.h" + ++#include ++/* WARNING: Do not change this to without testing that ++ * SERIAL_PORT_DFNS does get defined to the appropriate value. */ ++#include ++ + #ifndef SERIAL_PORT_DFNS + #define SERIAL_PORT_DFNS + #endif +@@ -23,9 +28,15 @@ const struct old_serial_port *spk_serial + int baud = 9600, quot = 0; + unsigned int cval = 0; + int cflag = CREAD | HUPCL | CLOCAL | B9600 | CS8; +- const struct old_serial_port *ser = rs_table + index; ++ const struct old_serial_port *ser; + int err; + ++ if (index >= ARRAY_SIZE(rs_table)) { ++ pr_info("no port info for ttyS%d\n", index); ++ return NULL; ++ } ++ ser = rs_table + index; ++ + /* Divisor, bytesize and parity */ + quot = ser->baud_base / baud; + cval = cflag & (CSIZE | CSTOPB); diff --git a/queue-4.4/thermal-do-thermal-zone-update-after-a-cooling-device-registered.patch b/queue-4.4/thermal-do-thermal-zone-update-after-a-cooling-device-registered.patch new file mode 100644 index 00000000000..641ebb3fab9 --- /dev/null +++ b/queue-4.4/thermal-do-thermal-zone-update-after-a-cooling-device-registered.patch @@ -0,0 +1,104 @@ +From 4511f7166a2deb5f7a578cf87fd2fe1ae83527e3 Mon Sep 17 00:00:00 2001 +From: Chen Yu +Date: Fri, 30 Oct 2015 16:32:10 +0800 +Subject: Thermal: do thermal zone update after a cooling device registered + +From: Chen Yu + +commit 4511f7166a2deb5f7a578cf87fd2fe1ae83527e3 upstream. + +When a new cooling device is registered, we need to update the +thermal zone to set the new registered cooling device to a proper +state. + +This fixes a problem that the system is cool, while the fan devices +are left running on full speed after boot, if fan device is registered +after thermal zone device. + +Here is the history of why current patch looks like this: +https://patchwork.kernel.org/patch/7273041/ + +Reference:https://bugzilla.kernel.org/show_bug.cgi?id=92431 +Tested-by: Manuel Krause +Tested-by: szegad +Tested-by: prash +Tested-by: amish +Reviewed-by: Javi Merino +Signed-off-by: Zhang Rui +Signed-off-by: Chen Yu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/thermal_core.c | 14 +++++++++++++- + include/linux/thermal.h | 2 ++ + 2 files changed, 15 insertions(+), 1 deletion(-) + +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1341,6 +1341,7 @@ int thermal_zone_bind_cooling_device(str + if (!result) { + list_add_tail(&dev->tz_node, &tz->thermal_instances); + list_add_tail(&dev->cdev_node, &cdev->thermal_instances); ++ atomic_set(&tz->need_update, 1); + } + mutex_unlock(&cdev->lock); + mutex_unlock(&tz->lock); +@@ -1450,6 +1451,7 @@ __thermal_cooling_device_register(struct + const struct thermal_cooling_device_ops *ops) + { + struct thermal_cooling_device *cdev; ++ struct thermal_zone_device *pos = NULL; + int result; + + if (type && strlen(type) >= THERMAL_NAME_LENGTH) +@@ -1494,6 +1496,12 @@ __thermal_cooling_device_register(struct + /* Update binding information for 'this' new cdev */ + bind_cdev(cdev); + ++ mutex_lock(&thermal_list_lock); ++ list_for_each_entry(pos, &thermal_tz_list, node) ++ if (atomic_cmpxchg(&pos->need_update, 1, 0)) ++ thermal_zone_device_update(pos); ++ mutex_unlock(&thermal_list_lock); ++ + return cdev; + } + +@@ -1826,6 +1834,8 @@ struct thermal_zone_device *thermal_zone + tz->trips = trips; + tz->passive_delay = passive_delay; + tz->polling_delay = polling_delay; ++ /* A new thermal zone needs to be updated anyway. */ ++ atomic_set(&tz->need_update, 1); + + dev_set_name(&tz->device, "thermal_zone%d", tz->id); + result = device_register(&tz->device); +@@ -1921,7 +1931,9 @@ struct thermal_zone_device *thermal_zone + INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); + + thermal_zone_device_reset(tz); +- thermal_zone_device_update(tz); ++ /* Update the new thermal zone and mark it as already updated. */ ++ if (atomic_cmpxchg(&tz->need_update, 1, 0)) ++ thermal_zone_device_update(tz); + + return tz; + +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -170,6 +170,7 @@ struct thermal_attr { + * @forced_passive: If > 0, temperature at which to switch on all ACPI + * processor cooling devices. Currently only used by the + * step-wise governor. ++ * @need_update: if equals 1, thermal_zone_device_update needs to be invoked. + * @ops: operations this &thermal_zone_device supports + * @tzp: thermal zone parameters + * @governor: pointer to the governor for this thermal zone +@@ -197,6 +198,7 @@ struct thermal_zone_device { + int emul_temperature; + int passive; + unsigned int forced_passive; ++ atomic_t need_update; + struct thermal_zone_device_ops *ops; + struct thermal_zone_params *tzp; + struct thermal_governor *governor; diff --git a/queue-4.4/thermal-handle-thermal-zone-device-properly-during-system-sleep.patch b/queue-4.4/thermal-handle-thermal-zone-device-properly-during-system-sleep.patch new file mode 100644 index 00000000000..5d25174aec2 --- /dev/null +++ b/queue-4.4/thermal-handle-thermal-zone-device-properly-during-system-sleep.patch @@ -0,0 +1,130 @@ +From ff140fea847e1c2002a220571ab106c2456ed252 Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Fri, 30 Oct 2015 16:31:58 +0800 +Subject: Thermal: handle thermal zone device properly during system sleep + +From: Zhang Rui + +commit ff140fea847e1c2002a220571ab106c2456ed252 upstream. + +Current thermal code does not handle system sleep well because +1. the cooling device cooling state may be changed during suspend +2. the previous temperature reading becomes invalid after resumed because + it is got before system sleep +3. updating thermal zone device during suspending/resuming + is wrong because some devices may have already been suspended + or may have not been resumed. + +Thus, the proper way to do this is to cancel all thermal zone +device update requirements during suspend/resume, and after all +the devices have been resumed, reset and update every registered +thermal zone devices. + +This also fixes a regression introduced by: +Commit 19593a1fb1f6 ("ACPI / fan: convert to platform driver") +Because, with above commit applied, all the fan devices are attached +to the acpi_general_pm_domain, and they are turned on by the pm_domain +automatically after resume, without the awareness of thermal core. + +Reference: https://bugzilla.kernel.org/show_bug.cgi?id=78201 +Reference: https://bugzilla.kernel.org/show_bug.cgi?id=91411 +Tested-by: Manuel Krause +Tested-by: szegad +Tested-by: prash +Tested-by: amish +Tested-by: Matthias +Reviewed-by: Javi Merino +Signed-off-by: Zhang Rui +Signed-off-by: Chen Yu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/thermal_core.c | 42 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #define CREATE_TRACE_POINTS + #include +@@ -59,6 +60,8 @@ static LIST_HEAD(thermal_governor_list); + static DEFINE_MUTEX(thermal_list_lock); + static DEFINE_MUTEX(thermal_governor_lock); + ++static atomic_t in_suspend; ++ + static struct thermal_governor *def_governor; + + static struct thermal_governor *__find_governor(const char *name) +@@ -554,6 +557,9 @@ void thermal_zone_device_update(struct t + { + int count; + ++ if (atomic_read(&in_suspend)) ++ return; ++ + if (!tz->ops->get_temp) + return; + +@@ -2155,6 +2161,36 @@ static void thermal_unregister_governors + thermal_gov_power_allocator_unregister(); + } + ++static int thermal_pm_notify(struct notifier_block *nb, ++ unsigned long mode, void *_unused) ++{ ++ struct thermal_zone_device *tz; ++ ++ switch (mode) { ++ case PM_HIBERNATION_PREPARE: ++ case PM_RESTORE_PREPARE: ++ case PM_SUSPEND_PREPARE: ++ atomic_set(&in_suspend, 1); ++ break; ++ case PM_POST_HIBERNATION: ++ case PM_POST_RESTORE: ++ case PM_POST_SUSPEND: ++ atomic_set(&in_suspend, 0); ++ list_for_each_entry(tz, &thermal_tz_list, node) { ++ thermal_zone_device_reset(tz); ++ thermal_zone_device_update(tz); ++ } ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static struct notifier_block thermal_pm_nb = { ++ .notifier_call = thermal_pm_notify, ++}; ++ + static int __init thermal_init(void) + { + int result; +@@ -2175,6 +2211,11 @@ static int __init thermal_init(void) + if (result) + goto exit_netlink; + ++ result = register_pm_notifier(&thermal_pm_nb); ++ if (result) ++ pr_warn("Thermal: Can not register suspend notifier, return %d\n", ++ result); ++ + return 0; + + exit_netlink: +@@ -2194,6 +2235,7 @@ error: + + static void __exit thermal_exit(void) + { ++ unregister_pm_notifier(&thermal_pm_nb); + of_thermal_destroy_zones(); + genetlink_exit(); + class_unregister(&thermal_class); diff --git a/queue-4.4/thermal-initialize-thermal-zone-device-correctly.patch b/queue-4.4/thermal-initialize-thermal-zone-device-correctly.patch new file mode 100644 index 00000000000..ed8b92120da --- /dev/null +++ b/queue-4.4/thermal-initialize-thermal-zone-device-correctly.patch @@ -0,0 +1,134 @@ +From bb431ba26c5cd0a17c941ca6c3a195a3a6d5d461 Mon Sep 17 00:00:00 2001 +From: Zhang Rui +Date: Fri, 30 Oct 2015 16:31:47 +0800 +Subject: Thermal: initialize thermal zone device correctly + +From: Zhang Rui + +commit bb431ba26c5cd0a17c941ca6c3a195a3a6d5d461 upstream. + +After thermal zone device registered, as we have not read any +temperature before, thus tz->temperature should not be 0, +which actually means 0C, and thermal trend is not available. +In this case, we need specially handling for the first +thermal_zone_device_update(). + +Both thermal core framework and step_wise governor is +enhanced to handle this. And since the step_wise governor +is the only one that uses trends, so it's the only thermal +governor that needs to be updated. + +Tested-by: Manuel Krause +Tested-by: szegad +Tested-by: prash +Tested-by: amish +Tested-by: Matthias +Reviewed-by: Javi Merino +Signed-off-by: Zhang Rui +Signed-off-by: Chen Yu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/thermal/step_wise.c | 17 +++++++++++++++-- + drivers/thermal/thermal_core.c | 19 +++++++++++++++++-- + drivers/thermal/thermal_core.h | 1 + + include/linux/thermal.h | 3 +++ + 4 files changed, 36 insertions(+), 4 deletions(-) + +--- a/drivers/thermal/step_wise.c ++++ b/drivers/thermal/step_wise.c +@@ -63,6 +63,19 @@ static unsigned long get_target_state(st + next_target = instance->target; + dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state); + ++ if (!instance->initialized) { ++ if (throttle) { ++ next_target = (cur_state + 1) >= instance->upper ? ++ instance->upper : ++ ((cur_state + 1) < instance->lower ? ++ instance->lower : (cur_state + 1)); ++ } else { ++ next_target = THERMAL_NO_TARGET; ++ } ++ ++ return next_target; ++ } ++ + switch (trend) { + case THERMAL_TREND_RAISING: + if (throttle) { +@@ -149,7 +162,7 @@ static void thermal_zone_trip_update(str + dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n", + old_target, (int)instance->target); + +- if (old_target == instance->target) ++ if (instance->initialized && old_target == instance->target) + continue; + + /* Activate a passive thermal instance */ +@@ -161,7 +174,7 @@ static void thermal_zone_trip_update(str + instance->target == THERMAL_NO_TARGET) + update_passive_instance(tz, trip_type, -1); + +- ++ instance->initialized = true; + instance->cdev->updated = false; /* cdev needs update */ + } + +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -532,8 +532,22 @@ static void update_temperature(struct th + mutex_unlock(&tz->lock); + + trace_thermal_temperature(tz); +- dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", +- tz->last_temperature, tz->temperature); ++ if (tz->last_temperature == THERMAL_TEMP_INVALID) ++ dev_dbg(&tz->device, "last_temperature N/A, current_temperature=%d\n", ++ tz->temperature); ++ else ++ dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", ++ tz->last_temperature, tz->temperature); ++} ++ ++static void thermal_zone_device_reset(struct thermal_zone_device *tz) ++{ ++ struct thermal_instance *pos; ++ ++ tz->temperature = THERMAL_TEMP_INVALID; ++ tz->passive = 0; ++ list_for_each_entry(pos, &tz->thermal_instances, tz_node) ++ pos->initialized = false; + } + + void thermal_zone_device_update(struct thermal_zone_device *tz) +@@ -1900,6 +1914,7 @@ struct thermal_zone_device *thermal_zone + + INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); + ++ thermal_zone_device_reset(tz); + thermal_zone_device_update(tz); + + return tz; +--- a/drivers/thermal/thermal_core.h ++++ b/drivers/thermal/thermal_core.h +@@ -41,6 +41,7 @@ struct thermal_instance { + struct thermal_zone_device *tz; + struct thermal_cooling_device *cdev; + int trip; ++ bool initialized; + unsigned long upper; /* Highest cooling state for this trip point */ + unsigned long lower; /* Lowest cooling state for this trip point */ + unsigned long target; /* expected cooling state */ +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -43,6 +43,9 @@ + /* Default weight of a bound cooling device */ + #define THERMAL_WEIGHT_DEFAULT 0 + ++/* use value, which < 0K, to indicate an invalid/uninitialized temperature */ ++#define THERMAL_TEMP_INVALID -274000 ++ + /* Unit conversion macros */ + #define DECI_KELVIN_TO_CELSIUS(t) ({ \ + long _t = (t); \ diff --git a/queue-4.4/toshiba_acpi-fix-blank-screen-at-boot-if-transflective-backlight-is-supported.patch b/queue-4.4/toshiba_acpi-fix-blank-screen-at-boot-if-transflective-backlight-is-supported.patch new file mode 100644 index 00000000000..f38fb0ed83d --- /dev/null +++ b/queue-4.4/toshiba_acpi-fix-blank-screen-at-boot-if-transflective-backlight-is-supported.patch @@ -0,0 +1,42 @@ +From bae5336f0aaedffa115dab9cb3d8a4e4aed3a26a Mon Sep 17 00:00:00 2001 +From: Azael Avalos +Date: Sun, 15 Nov 2015 20:32:47 -0700 +Subject: toshiba_acpi: Fix blank screen at boot if transflective backlight is supported + +From: Azael Avalos + +commit bae5336f0aaedffa115dab9cb3d8a4e4aed3a26a upstream. + +If transflective backlight is supported and the brightness is zero +(lowest brightness level), the set_lcd_brightness function will activate +the transflective backlight, making the LCD appear to be turned off. + +This patch fixes the issue by incrementing the brightness level, and +by doing so, avoiding the activation of the tranflective backlight. + +Reported-and-tested-by: Fabian Koester +Signed-off-by: Azael Avalos +Signed-off-by: Darren Hart +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/toshiba_acpi.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/platform/x86/toshiba_acpi.c ++++ b/drivers/platform/x86/toshiba_acpi.c +@@ -2484,6 +2484,14 @@ static int toshiba_acpi_setup_backlight( + brightness = __get_lcd_brightness(dev); + if (brightness < 0) + return 0; ++ /* ++ * If transflective backlight is supported and the brightness is zero ++ * (lowest brightness level), the set_lcd_brightness function will ++ * activate the transflective backlight, making the LCD appear to be ++ * turned off, simply increment the brightness level to avoid that. ++ */ ++ if (dev->tr_backlight_supported && brightness == 0) ++ brightness++; + ret = set_lcd_brightness(dev, brightness); + if (ret) { + pr_debug("Backlight method is read-only, disabling backlight support\n"); diff --git a/queue-4.4/uapi-update-install-list-after-nvme.h-rename.patch b/queue-4.4/uapi-update-install-list-after-nvme.h-rename.patch new file mode 100644 index 00000000000..1290e9d9236 --- /dev/null +++ b/queue-4.4/uapi-update-install-list-after-nvme.h-rename.patch @@ -0,0 +1,34 @@ +From a9cf8284b45110a4d98aea180a89c857e53bf850 Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Sun, 10 Jan 2016 20:14:11 -0500 +Subject: uapi: update install list after nvme.h rename + +From: Mike Frysinger + +commit a9cf8284b45110a4d98aea180a89c857e53bf850 upstream. + +Commit 9d99a8dda154 ("nvme: move hardware structures out of the uapi +version of nvme.h") renamed nvme.h to nvme_ioctl.h, but the uapi list +still refers to nvme.h. People trying to install the headers hit a +failure as the header no longer exists. + +Signed-off-by: Mike Frysinger +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + include/uapi/linux/Kbuild | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/uapi/linux/Kbuild ++++ b/include/uapi/linux/Kbuild +@@ -307,7 +307,7 @@ header-y += nfs_mount.h + header-y += nl80211.h + header-y += n_r3964.h + header-y += nubus.h +-header-y += nvme.h ++header-y += nvme_ioctl.h + header-y += nvram.h + header-y += omap3isp.h + header-y += omapfb.h