From: Greg Kroah-Hartman Date: Thu, 15 Jun 2017 14:26:45 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.9.33~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=02fc71861e8d2a446adaa16303c824c77673ff31;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch bnxt_en-enhance-autoneg-support.patch bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch frv-add-atomic64_add_unless.patch frv-add-missing-atomic64-operations.patch kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch mn10300-fix-build-error-of-missing-fpu_save.patch net-next-ethernet-mediatek-change-the-compatible-string.patch proc-add-a-schedule-point-in-proc_pid_readdir.patch r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch vhost-vsock-handle-vhost_vq_init_access-error.patch --- diff --git a/queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch b/queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch new file mode 100644 index 00000000000..c3d06247239 --- /dev/null +++ b/queue-4.9/arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch @@ -0,0 +1,81 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Vineet Gupta +Date: Thu, 12 Jan 2017 14:30:29 -0800 +Subject: ARC: smp-boot: Decouple Non masters waiting API from jump to entry point + +From: Vineet Gupta + + +[ Upstream commit bf02454a741b58682a82c314a9a46bed930ed2f7 ] + +For run-on-reset SMP configs, non master cores call a routine which +waits until Master gives it a "go" signal (currently using a shared +mem flag). The same routine then jumps off the well known entry point of +all non Master cores i.e. @first_lines_of_secondary + +This patch moves out the last part into one single place in early boot +code. + +This is better in terms of absraction (the wait API only waits) and +returns, leaving out the "jump off to" part. + +In actual implementation this requires some restructuring of the early +boot code as well as Master now jumps to BSS setup explicitly, +vs. falling thru into it before. + +Technically this patch doesn't cause any functional change, it just +moves the ugly #ifdef'ry from assembly code to "C" + +Signed-off-by: Vineet Gupta +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arc/kernel/head.S | 14 +++++++------- + arch/arc/kernel/smp.c | 6 ++++-- + 2 files changed, 11 insertions(+), 9 deletions(-) + +--- a/arch/arc/kernel/head.S ++++ b/arch/arc/kernel/head.S +@@ -71,14 +71,14 @@ ENTRY(stext) + GET_CPU_ID r5 + cmp r5, 0 + mov.nz r0, r5 +-#ifdef CONFIG_ARC_SMP_HALT_ON_RESET +- ; Non-Master can proceed as system would be booted sufficiently +- jnz first_lines_of_secondary +-#else ++ bz .Lmaster_proceed ++ + ; Non-Masters wait for Master to boot enough and bring them up +- jnz arc_platform_smp_wait_to_boot +-#endif +- ; Master falls thru ++ ; when they resume, tail-call to entry point ++ mov blink, @first_lines_of_secondary ++ j arc_platform_smp_wait_to_boot ++ ++.Lmaster_proceed: + #endif + + ; Clear BSS before updating any globals +--- a/arch/arc/kernel/smp.c ++++ b/arch/arc/kernel/smp.c +@@ -98,14 +98,16 @@ static void arc_default_smp_cpu_kick(int + + void arc_platform_smp_wait_to_boot(int cpu) + { ++ /* for halt-on-reset, we've waited already */ ++ if (IS_ENABLED(CONFIG_ARC_SMP_HALT_ON_RESET)) ++ return; ++ + while (wake_flag != cpu) + ; + + wake_flag = 0; +- __asm__ __volatile__("j @first_lines_of_secondary \n"); + } + +- + const char *arc_platform_smp_cpuinfo(void) + { + return plat_smp_ops.info ? : ""; diff --git a/queue-4.9/bnxt_en-enhance-autoneg-support.patch b/queue-4.9/bnxt_en-enhance-autoneg-support.patch new file mode 100644 index 00000000000..83043f3e413 --- /dev/null +++ b/queue-4.9/bnxt_en-enhance-autoneg-support.patch @@ -0,0 +1,86 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Michael Chan +Date: Wed, 16 Nov 2016 21:13:08 -0500 +Subject: bnxt_en: Enhance autoneg support. + +From: Michael Chan + + +[ Upstream commit 286ef9d64ea7435a1e323d12b44a309e15cbff0e ] + +On some dual port NICs, the speed setting on one port can affect the +available speed on the other port. Add logic to detect these changes +and adjust the advertised speed settings when necessary. + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 23 +++++++++++++++++++++++ + drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 + + 2 files changed, 24 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -1499,6 +1499,7 @@ static int bnxt_async_event_process(stru + netdev_warn(bp->dev, "Link speed %d no longer supported\n", + speed); + } ++ set_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, &bp->sp_event); + /* fall thru */ + } + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: +@@ -5110,6 +5111,7 @@ static int bnxt_update_link(struct bnxt + struct hwrm_port_phy_qcfg_input req = {0}; + struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr; + u8 link_up = link_info->link_up; ++ u16 diff; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCFG, -1, -1); + +@@ -5197,6 +5199,23 @@ static int bnxt_update_link(struct bnxt + link_info->link_up = 0; + } + mutex_unlock(&bp->hwrm_cmd_lock); ++ ++ diff = link_info->support_auto_speeds ^ link_info->advertising; ++ if ((link_info->support_auto_speeds | diff) != ++ link_info->support_auto_speeds) { ++ /* An advertised speed is no longer supported, so we need to ++ * update the advertisement settings. See bnxt_reset() for ++ * comments about the rtnl_lock() sequence below. ++ */ ++ clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); ++ rtnl_lock(); ++ link_info->advertising = link_info->support_auto_speeds; ++ if (test_bit(BNXT_STATE_OPEN, &bp->state) && ++ (link_info->autoneg & BNXT_AUTONEG_SPEED)) ++ bnxt_hwrm_set_link_setting(bp, true, false); ++ set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); ++ rtnl_unlock(); ++ } + return 0; + } + +@@ -6126,6 +6145,10 @@ static void bnxt_sp_task(struct work_str + if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event)) + bnxt_cfg_ntp_filters(bp); + if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { ++ if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, ++ &bp->sp_event)) ++ bnxt_hwrm_phy_qcaps(bp); ++ + rc = bnxt_update_link(bp, true); + if (rc) + netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +@@ -1089,6 +1089,7 @@ struct bnxt { + #define BNXT_RESET_TASK_SILENT_SP_EVENT 11 + #define BNXT_GENEVE_ADD_PORT_SP_EVENT 12 + #define BNXT_GENEVE_DEL_PORT_SP_EVENT 13 ++#define BNXT_LINK_SPEED_CHNG_SP_EVENT 14 + + struct bnxt_pf_info pf; + #ifdef CONFIG_BNXT_SRIOV diff --git a/queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch b/queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch new file mode 100644 index 00000000000..d03e2160ec4 --- /dev/null +++ b/queue-4.9/bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch @@ -0,0 +1,101 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:07 -0500 +Subject: bnxt_en: Fix bnxt_reset() in the slow path task. + +From: Michael Chan + + +[ Upstream commit a551ee94ea723b4af9b827c7460f108bc13425ee ] + +In bnxt_sp_task(), we set a bit BNXT_STATE_IN_SP_TASK so that bnxt_close() +will synchronize and wait for bnxt_sp_task() to finish. Some functions +in bnxt_sp_task() require us to clear BNXT_STATE_IN_SP_TASK and then +acquire rtnl_lock() to prevent race conditions. + +There are some bugs related to this logic. This patch refactors the code +to have common bnxt_rtnl_lock_sp() and bnxt_rtnl_unlock_sp() to handle +the RTNL and the clearing/setting of the bit. Multiple functions will +need the same logic. We also need to move bnxt_reset() to the end of +bnxt_sp_task(). Functions that clear BNXT_STATE_IN_SP_TASK must be the +last functions to be called in bnxt_sp_task(). The common scheme will +handle the condition properly. + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 38 +++++++++++++++++++----------- + 1 file changed, 25 insertions(+), 13 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -6080,23 +6080,32 @@ bnxt_restart_timer: + mod_timer(&bp->timer, jiffies + bp->current_interval); + } + +-/* Only called from bnxt_sp_task() */ +-static void bnxt_reset(struct bnxt *bp, bool silent) ++static void bnxt_rtnl_lock_sp(struct bnxt *bp) + { +- /* bnxt_reset_task() calls bnxt_close_nic() which waits +- * for BNXT_STATE_IN_SP_TASK to clear. +- * If there is a parallel dev_close(), bnxt_close() may be holding ++ /* We are called from bnxt_sp_task which has BNXT_STATE_IN_SP_TASK ++ * set. If the device is being closed, bnxt_close() may be holding + * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear. So we + * must clear BNXT_STATE_IN_SP_TASK before holding rtnl(). + */ + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_lock(); +- if (test_bit(BNXT_STATE_OPEN, &bp->state)) +- bnxt_reset_task(bp, silent); ++} ++ ++static void bnxt_rtnl_unlock_sp(struct bnxt *bp) ++{ + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_unlock(); + } + ++/* Only called from bnxt_sp_task() */ ++static void bnxt_reset(struct bnxt *bp, bool silent) ++{ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_reset_task(bp, silent); ++ bnxt_rtnl_unlock_sp(bp); ++} ++ + static void bnxt_cfg_ntp_filters(struct bnxt *); + + static void bnxt_sp_task(struct work_struct *work) +@@ -6142,18 +6151,21 @@ static void bnxt_sp_task(struct work_str + bnxt_hwrm_tunnel_dst_port_free( + bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE); + } +- if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) +- bnxt_reset(bp, false); +- +- if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) +- bnxt_reset(bp, true); +- + if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) + bnxt_get_port_module_status(bp); + + if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_port_qstats(bp); + ++ /* These functions below will clear BNXT_STATE_IN_SP_TASK. They ++ * must be the last functions to be called before exiting. ++ */ ++ if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) ++ bnxt_reset(bp, false); ++ ++ if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) ++ bnxt_reset(bp, true); ++ + smp_mb__before_atomic(); + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + } diff --git a/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch new file mode 100644 index 00000000000..b9e5c21a918 --- /dev/null +++ b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch @@ -0,0 +1,48 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:09 -0500 +Subject: bnxt_en: Fix RTNL lock usage on bnxt_get_port_module_status(). + +From: Michael Chan + + +[ Upstream commit 90c694bb71819fb5bd3501ac397307d7e41ddeca ] + +bnxt_get_port_module_status() calls bnxt_update_link() which expects +RTNL to be held. In bnxt_sp_task() that does not hold RTNL, we need to +call it with a prior call to bnxt_rtnl_lock_sp() and the call needs to +be moved to the end of bnxt_sp_task(). + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -6158,9 +6158,6 @@ static void bnxt_sp_task(struct work_str + bnxt_hwrm_tunnel_dst_port_free( + bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE); + } +- if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) +- bnxt_get_port_module_status(bp); +- + if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_port_qstats(bp); + +@@ -6182,6 +6179,12 @@ static void bnxt_sp_task(struct work_str + netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", + rc); + } ++ if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) { ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_get_port_module_status(bp); ++ bnxt_rtnl_unlock_sp(bp); ++ } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, false); + diff --git a/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch new file mode 100644 index 00000000000..5e018696dee --- /dev/null +++ b/queue-4.9/bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch @@ -0,0 +1,99 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:08 -0500 +Subject: bnxt_en: Fix RTNL lock usage on bnxt_update_link(). + +From: Michael Chan + + +[ Upstream commit 0eaa24b971ae251ae9d3be23f77662a655532063 ] + +bnxt_update_link() is called from multiple code paths. Most callers, +such as open, ethtool, already hold RTNL. Only the caller bnxt_sp_task() +does not. So it is a bug to take RTNL inside bnxt_update_link(). + +Fix it by removing the RTNL inside bnxt_update_link(). The function +now expects the caller to always hold RTNL. + +In bnxt_sp_task(), call bnxt_rtnl_lock_sp() before calling +bnxt_update_link(). We also need to move the call to the end of +bnxt_sp_task() since it will be clearing the BNXT_STATE_IN_SP_TASK bit. + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 37 ++++++++++++++---------------- + 1 file changed, 18 insertions(+), 19 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -5204,17 +5204,12 @@ static int bnxt_update_link(struct bnxt + if ((link_info->support_auto_speeds | diff) != + link_info->support_auto_speeds) { + /* An advertised speed is no longer supported, so we need to +- * update the advertisement settings. See bnxt_reset() for +- * comments about the rtnl_lock() sequence below. ++ * update the advertisement settings. Caller holds RTNL ++ * so we can modify link settings. + */ +- clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); +- rtnl_lock(); + link_info->advertising = link_info->support_auto_speeds; +- if (test_bit(BNXT_STATE_OPEN, &bp->state) && +- (link_info->autoneg & BNXT_AUTONEG_SPEED)) ++ if (link_info->autoneg & BNXT_AUTONEG_SPEED) + bnxt_hwrm_set_link_setting(bp, true, false); +- set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); +- rtnl_unlock(); + } + return 0; + } +@@ -6130,7 +6125,6 @@ static void bnxt_cfg_ntp_filters(struct + static void bnxt_sp_task(struct work_struct *work) + { + struct bnxt *bp = container_of(work, struct bnxt, sp_task); +- int rc; + + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + smp_mb__after_atomic(); +@@ -6144,16 +6138,6 @@ static void bnxt_sp_task(struct work_str + + if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event)) + bnxt_cfg_ntp_filters(bp); +- if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { +- if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, +- &bp->sp_event)) +- bnxt_hwrm_phy_qcaps(bp); +- +- rc = bnxt_update_link(bp, true); +- if (rc) +- netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", +- rc); +- } + if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_exec_fwd_req(bp); + if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) { +@@ -6183,6 +6167,21 @@ static void bnxt_sp_task(struct work_str + /* These functions below will clear BNXT_STATE_IN_SP_TASK. They + * must be the last functions to be called before exiting. + */ ++ if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { ++ int rc = 0; ++ ++ if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, ++ &bp->sp_event)) ++ bnxt_hwrm_phy_qcaps(bp); ++ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ rc = bnxt_update_link(bp, true); ++ bnxt_rtnl_unlock_sp(bp); ++ if (rc) ++ netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", ++ rc); ++ } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, false); + diff --git a/queue-4.9/frv-add-atomic64_add_unless.patch b/queue-4.9/frv-add-atomic64_add_unless.patch new file mode 100644 index 00000000000..67f232ba52d --- /dev/null +++ b/queue-4.9/frv-add-atomic64_add_unless.patch @@ -0,0 +1,56 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Sudip Mukherjee +Date: Tue, 24 Jan 2017 15:18:21 -0800 +Subject: frv: add atomic64_add_unless() + +From: Sudip Mukherjee + + +[ Upstream commit 545d58f677b21401f6de1ac12c25cc109f903ace ] + +The build of frv allmodconfig was failing with the error: +lib/atomic64_test.c:209:9: error: + + implicit declaration of function 'atomic64_add_unless' + +All the atomic64 operations were defined in frv, but +atomic64_add_unless() was not done. + +Implement atomic64_add_unless() as done in other arches. + +Link: http://lkml.kernel.org/r/1484781236-6698-1-git-send-email-sudipm.mukherjee@gmail.com +Signed-off-by: Sudip Mukherjee +Cc: David Howells +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/frv/include/asm/atomic.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/arch/frv/include/asm/atomic.h ++++ b/arch/frv/include/asm/atomic.h +@@ -161,6 +161,22 @@ static __inline__ int __atomic_add_unles + return c; + } + ++static inline int atomic64_add_unless(atomic64_t *v, long long i, long long u) ++{ ++ long long c, old; ++ ++ c = atomic64_read(v); ++ for (;;) { ++ if (unlikely(c == u)) ++ break; ++ old = atomic64_cmpxchg(v, c, c + i); ++ if (likely(old == c)) ++ break; ++ c = old; ++ } ++ return c != u; ++} ++ + #define ATOMIC_OP(op) \ + static inline int atomic_fetch_##op(int i, atomic_t *v) \ + { \ diff --git a/queue-4.9/frv-add-missing-atomic64-operations.patch b/queue-4.9/frv-add-missing-atomic64-operations.patch new file mode 100644 index 00000000000..37c529083ac --- /dev/null +++ b/queue-4.9/frv-add-missing-atomic64-operations.patch @@ -0,0 +1,59 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Sudip Mukherjee +Date: Tue, 24 Jan 2017 15:18:43 -0800 +Subject: frv: add missing atomic64 operations + +From: Sudip Mukherjee + + +[ Upstream commit 4180c4c170a5a33b9987b314d248a9d572d89ab0 ] + +Some more atomic64 operations were missing and as a result frv +allmodconfig was failing. Add the missing operations. + +Link: http://lkml.kernel.org/r/1485193844-12850-1-git-send-email-sudip.mukherjee@codethink.co.uk +Signed-off-by: Sudip Mukherjee +Cc: David Howells +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/frv/include/asm/atomic.h | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/arch/frv/include/asm/atomic.h ++++ b/arch/frv/include/asm/atomic.h +@@ -139,7 +139,7 @@ static inline void atomic64_dec(atomic64 + #define atomic64_sub_and_test(i,v) (atomic64_sub_return((i), (v)) == 0) + #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) + #define atomic64_inc_and_test(v) (atomic64_inc_return((v)) == 0) +- ++#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) + + #define atomic_cmpxchg(v, old, new) (cmpxchg(&(v)->counter, old, new)) + #define atomic_xchg(v, new) (xchg(&(v)->counter, new)) +@@ -177,6 +177,23 @@ static inline int atomic64_add_unless(at + return c != u; + } + ++static inline long long atomic64_dec_if_positive(atomic64_t *v) ++{ ++ long long c, old, dec; ++ ++ c = atomic64_read(v); ++ for (;;) { ++ dec = c - 1; ++ if (unlikely(dec < 0)) ++ break; ++ old = atomic64_cmpxchg((v), c, dec); ++ if (likely(old == c)) ++ break; ++ c = old; ++ } ++ return dec; ++} ++ + #define ATOMIC_OP(op) \ + static inline int atomic_fetch_##op(int i, atomic_t *v) \ + { \ diff --git a/queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch b/queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch new file mode 100644 index 00000000000..0d1c14edc92 --- /dev/null +++ b/queue-4.9/kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch @@ -0,0 +1,107 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Don Zickus +Date: Tue, 24 Jan 2017 15:17:53 -0800 +Subject: kernel/watchdog: prevent false hardlockup on overloaded system + +From: Don Zickus + + +[ Upstream commit b94f51183b0617e7b9b4fb4137d4cf1cab7547c2 ] + +On an overloaded system, it is possible that a change in the watchdog +threshold can be delayed long enough to trigger a false positive. + +This can easily be achieved by having a cpu spinning indefinitely on a +task, while another cpu updates watchdog threshold. + +What happens is while trying to park the watchdog threads, the hrtimers +on the other cpus trigger and reprogram themselves with the new slower +watchdog threshold. Meanwhile, the nmi watchdog is still programmed +with the old faster threshold. + +Because the one cpu is blocked, it prevents the thread parking on the +other cpus from completing, which is needed to shutdown the nmi watchdog +and reprogram it correctly. As a result, a false positive from the nmi +watchdog is reported. + +Fix this by setting a park_in_progress flag to block all lockups until +the parking is complete. + +Fix provided by Ulrich Obergfell. + +[akpm@linux-foundation.org: s/park_in_progress/watchdog_park_in_progress/] +Link: http://lkml.kernel.org/r/1481041033-192236-1-git-send-email-dzickus@redhat.com +Signed-off-by: Don Zickus +Reviewed-by: Aaron Tomlin +Cc: Ulrich Obergfell +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nmi.h | 1 + + kernel/watchdog.c | 9 +++++++++ + kernel/watchdog_hld.c | 3 +++ + 3 files changed, 13 insertions(+) + +--- a/include/linux/nmi.h ++++ b/include/linux/nmi.h +@@ -110,6 +110,7 @@ extern int watchdog_user_enabled; + extern int watchdog_thresh; + extern unsigned long watchdog_enabled; + extern unsigned long *watchdog_cpumask_bits; ++extern atomic_t watchdog_park_in_progress; + #ifdef CONFIG_SMP + extern int sysctl_softlockup_all_cpu_backtrace; + extern int sysctl_hardlockup_all_cpu_backtrace; +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -49,6 +49,8 @@ unsigned long *watchdog_cpumask_bits = c + #define for_each_watchdog_cpu(cpu) \ + for_each_cpu_and((cpu), cpu_online_mask, &watchdog_cpumask) + ++atomic_t watchdog_park_in_progress = ATOMIC_INIT(0); ++ + /* + * The 'watchdog_running' variable is set to 1 when the watchdog threads + * are registered/started and is set to 0 when the watchdog threads are +@@ -260,6 +262,9 @@ static enum hrtimer_restart watchdog_tim + int duration; + int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace; + ++ if (atomic_read(&watchdog_park_in_progress) != 0) ++ return HRTIMER_NORESTART; ++ + /* kick the hardlockup detector */ + watchdog_interrupt_count(); + +@@ -467,12 +472,16 @@ static int watchdog_park_threads(void) + { + int cpu, ret = 0; + ++ atomic_set(&watchdog_park_in_progress, 1); ++ + for_each_watchdog_cpu(cpu) { + ret = kthread_park(per_cpu(softlockup_watchdog, cpu)); + if (ret) + break; + } + ++ atomic_set(&watchdog_park_in_progress, 0); ++ + return ret; + } + +--- a/kernel/watchdog_hld.c ++++ b/kernel/watchdog_hld.c +@@ -84,6 +84,9 @@ static void watchdog_overflow_callback(s + /* Ensure the watchdog never gets throttled */ + event->hw.interrupts = 0; + ++ if (atomic_read(&watchdog_park_in_progress) != 0) ++ return; ++ + if (__this_cpu_read(watchdog_nmi_touch) == true) { + __this_cpu_write(watchdog_nmi_touch, false); + return; diff --git a/queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch b/queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch new file mode 100644 index 00000000000..c8097644cd6 --- /dev/null +++ b/queue-4.9/kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch @@ -0,0 +1,578 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Babu Moger +Date: Wed, 14 Dec 2016 15:06:24 -0800 +Subject: kernel/watchdog.c: move hardlockup detector to separate file + +From: Babu Moger + + +[ Upstream commit 73ce0511c43686095efd2f65ef564aab952e07bc ] + +Separate hardlockup code from watchdog.c and move it to watchdog_hld.c. +It is mostly straight forward. Remove everything inside +CONFIG_HARDLOCKUP_DETECTORS. This code will go to file watchdog_hld.c. +Also update the makefile accordigly. + +Link: http://lkml.kernel.org/r/1478034826-43888-3-git-send-email-babu.moger@oracle.com +Signed-off-by: Babu Moger +Acked-by: Don Zickus +Cc: Ingo Molnar +Cc: Jiri Kosina +Cc: Andi Kleen +Cc: Yaowei Bai +Cc: Aaron Tomlin +Cc: Ulrich Obergfell +Cc: Tejun Heo +Cc: Hidehiro Kawai +Cc: Josh Hunt +Cc: "David S. Miller" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + kernel/Makefile | 1 + kernel/watchdog.c | 241 ++------------------------------------------------ + kernel/watchdog_hld.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 239 insertions(+), 230 deletions(-) + create mode 100644 kernel/watchdog_hld.c + +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -84,6 +84,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o + obj-$(CONFIG_KGDB) += debug/ + obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o + obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o ++obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog_hld.o + obj-$(CONFIG_SECCOMP) += seccomp.o + obj-$(CONFIG_RELAY) += relay.o + obj-$(CONFIG_SYSCTL) += utsname_sysctl.o +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -24,7 +24,6 @@ + + #include + #include +-#include + #include + + /* +@@ -100,50 +99,9 @@ static DEFINE_PER_CPU(bool, soft_watchdo + static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts); + static DEFINE_PER_CPU(unsigned long, soft_lockup_hrtimer_cnt); + static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved); +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-static DEFINE_PER_CPU(bool, hard_watchdog_warn); +-static DEFINE_PER_CPU(bool, watchdog_nmi_touch); + static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); +-static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); +-#endif + static unsigned long soft_lockup_nmi_warn; + +-/* boot commands */ +-/* +- * Should we panic when a soft-lockup or hard-lockup occurs: +- */ +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-unsigned int __read_mostly hardlockup_panic = +- CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; +-static unsigned long hardlockup_allcpu_dumped; +-/* +- * We may not want to enable hard lockup detection by default in all cases, +- * for example when running the kernel as a guest on a hypervisor. In these +- * cases this function can be called to disable hard lockup detection. This +- * function should only be executed once by the boot processor before the +- * kernel command line parameters are parsed, because otherwise it is not +- * possible to override this in hardlockup_panic_setup(). +- */ +-void hardlockup_detector_disable(void) +-{ +- watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; +-} +- +-static int __init hardlockup_panic_setup(char *str) +-{ +- if (!strncmp(str, "panic", 5)) +- hardlockup_panic = 1; +- else if (!strncmp(str, "nopanic", 7)) +- hardlockup_panic = 0; +- else if (!strncmp(str, "0", 1)) +- watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; +- else if (!strncmp(str, "1", 1)) +- watchdog_enabled |= NMI_WATCHDOG_ENABLED; +- return 1; +-} +-__setup("nmi_watchdog=", hardlockup_panic_setup); +-#endif +- + unsigned int __read_mostly softlockup_panic = + CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE; + +@@ -264,30 +222,12 @@ void touch_all_softlockup_watchdogs(void + wq_watchdog_touch(-1); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-void touch_nmi_watchdog(void) +-{ +- /* +- * Using __raw here because some code paths have +- * preemption enabled. If preemption is enabled +- * then interrupts should be enabled too, in which +- * case we shouldn't have to worry about the watchdog +- * going off. +- */ +- raw_cpu_write(watchdog_nmi_touch, true); +- touch_softlockup_watchdog(); +-} +-EXPORT_SYMBOL(touch_nmi_watchdog); +- +-#endif +- + void touch_softlockup_watchdog_sync(void) + { + __this_cpu_write(softlockup_touch_sync, true); + __this_cpu_write(watchdog_touch_ts, 0); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR + /* watchdog detector functions */ + static bool is_hardlockup(void) + { +@@ -299,7 +239,6 @@ static bool is_hardlockup(void) + __this_cpu_write(hrtimer_interrupts_saved, hrint); + return false; + } +-#endif + + static int is_softlockup(unsigned long touch_ts) + { +@@ -313,77 +252,22 @@ static int is_softlockup(unsigned long t + return 0; + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +- +-static struct perf_event_attr wd_hw_attr = { +- .type = PERF_TYPE_HARDWARE, +- .config = PERF_COUNT_HW_CPU_CYCLES, +- .size = sizeof(struct perf_event_attr), +- .pinned = 1, +- .disabled = 1, +-}; +- +-/* Callback function for perf event subsystem */ +-static void watchdog_overflow_callback(struct perf_event *event, +- struct perf_sample_data *data, +- struct pt_regs *regs) +-{ +- /* Ensure the watchdog never gets throttled */ +- event->hw.interrupts = 0; +- +- if (__this_cpu_read(watchdog_nmi_touch) == true) { +- __this_cpu_write(watchdog_nmi_touch, false); +- return; +- } +- +- /* check for a hardlockup +- * This is done by making sure our timer interrupt +- * is incrementing. The timer interrupt should have +- * fired multiple times before we overflow'd. If it hasn't +- * then this is a good indication the cpu is stuck +- */ +- if (is_hardlockup()) { +- int this_cpu = smp_processor_id(); +- +- /* only print hardlockups once */ +- if (__this_cpu_read(hard_watchdog_warn) == true) +- return; +- +- pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); +- print_modules(); +- print_irqtrace_events(current); +- if (regs) +- show_regs(regs); +- else +- dump_stack(); +- +- /* +- * Perform all-CPU dump only once to avoid multiple hardlockups +- * generating interleaving traces +- */ +- if (sysctl_hardlockup_all_cpu_backtrace && +- !test_and_set_bit(0, &hardlockup_allcpu_dumped)) +- trigger_allbutself_cpu_backtrace(); +- +- if (hardlockup_panic) +- nmi_panic(regs, "Hard LOCKUP"); +- +- __this_cpu_write(hard_watchdog_warn, true); +- return; +- } +- +- __this_cpu_write(hard_watchdog_warn, false); +- return; +-} +-#endif /* CONFIG_HARDLOCKUP_DETECTOR */ +- + static void watchdog_interrupt_count(void) + { + __this_cpu_inc(hrtimer_interrupts); + } + +-static int watchdog_nmi_enable(unsigned int cpu); +-static void watchdog_nmi_disable(unsigned int cpu); ++/* ++ * These two functions are mostly architecture specific ++ * defining them as weak here. ++ */ ++int __weak watchdog_nmi_enable(unsigned int cpu) ++{ ++ return 0; ++} ++void __weak watchdog_nmi_disable(unsigned int cpu) ++{ ++} + + static int watchdog_enable_all_cpus(void); + static void watchdog_disable_all_cpus(void); +@@ -576,109 +460,6 @@ static void watchdog(unsigned int cpu) + watchdog_nmi_disable(cpu); + } + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-/* +- * People like the simple clean cpu node info on boot. +- * Reduce the watchdog noise by only printing messages +- * that are different from what cpu0 displayed. +- */ +-static unsigned long cpu0_err; +- +-static int watchdog_nmi_enable(unsigned int cpu) +-{ +- struct perf_event_attr *wd_attr; +- struct perf_event *event = per_cpu(watchdog_ev, cpu); +- +- /* nothing to do if the hard lockup detector is disabled */ +- if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) +- goto out; +- +- /* is it already setup and enabled? */ +- if (event && event->state > PERF_EVENT_STATE_OFF) +- goto out; +- +- /* it is setup but not enabled */ +- if (event != NULL) +- goto out_enable; +- +- wd_attr = &wd_hw_attr; +- wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); +- +- /* Try to register using hardware perf events */ +- event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); +- +- /* save cpu0 error for future comparision */ +- if (cpu == 0 && IS_ERR(event)) +- cpu0_err = PTR_ERR(event); +- +- if (!IS_ERR(event)) { +- /* only print for cpu0 or different than cpu0 */ +- if (cpu == 0 || cpu0_err) +- pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n"); +- goto out_save; +- } +- +- /* +- * Disable the hard lockup detector if _any_ CPU fails to set up +- * set up the hardware perf event. The watchdog() function checks +- * the NMI_WATCHDOG_ENABLED bit periodically. +- * +- * The barriers are for syncing up watchdog_enabled across all the +- * cpus, as clear_bit() does not use barriers. +- */ +- smp_mb__before_atomic(); +- clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled); +- smp_mb__after_atomic(); +- +- /* skip displaying the same error again */ +- if (cpu > 0 && (PTR_ERR(event) == cpu0_err)) +- return PTR_ERR(event); +- +- /* vary the KERN level based on the returned errno */ +- if (PTR_ERR(event) == -EOPNOTSUPP) +- pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); +- else if (PTR_ERR(event) == -ENOENT) +- pr_warn("disabled (cpu%i): hardware events not enabled\n", +- cpu); +- else +- pr_err("disabled (cpu%i): unable to create perf event: %ld\n", +- cpu, PTR_ERR(event)); +- +- pr_info("Shutting down hard lockup detector on all cpus\n"); +- +- return PTR_ERR(event); +- +- /* success path */ +-out_save: +- per_cpu(watchdog_ev, cpu) = event; +-out_enable: +- perf_event_enable(per_cpu(watchdog_ev, cpu)); +-out: +- return 0; +-} +- +-static void watchdog_nmi_disable(unsigned int cpu) +-{ +- struct perf_event *event = per_cpu(watchdog_ev, cpu); +- +- if (event) { +- perf_event_disable(event); +- per_cpu(watchdog_ev, cpu) = NULL; +- +- /* should be in cleanup, but blocks oprofile */ +- perf_event_release_kernel(event); +- } +- if (cpu == 0) { +- /* watchdog_nmi_enable() expects this to be zero initially. */ +- cpu0_err = 0; +- } +-} +- +-#else +-static int watchdog_nmi_enable(unsigned int cpu) { return 0; } +-static void watchdog_nmi_disable(unsigned int cpu) { return; } +-#endif /* CONFIG_HARDLOCKUP_DETECTOR */ +- + static struct smp_hotplug_thread watchdog_threads = { + .store = &softlockup_watchdog, + .thread_should_run = watchdog_should_run, +--- /dev/null ++++ b/kernel/watchdog_hld.c +@@ -0,0 +1,227 @@ ++/* ++ * Detect hard lockups on a system ++ * ++ * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc. ++ * ++ * Note: Most of this code is borrowed heavily from the original softlockup ++ * detector, so thanks to Ingo for the initial implementation. ++ * Some chunks also taken from the old x86-specific nmi watchdog code, thanks ++ * to those contributors as well. ++ */ ++ ++#define pr_fmt(fmt) "NMI watchdog: " fmt ++ ++#include ++#include ++#include ++#include ++ ++static DEFINE_PER_CPU(bool, hard_watchdog_warn); ++static DEFINE_PER_CPU(bool, watchdog_nmi_touch); ++static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); ++ ++/* boot commands */ ++/* ++ * Should we panic when a soft-lockup or hard-lockup occurs: ++ */ ++unsigned int __read_mostly hardlockup_panic = ++ CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE; ++static unsigned long hardlockup_allcpu_dumped; ++/* ++ * We may not want to enable hard lockup detection by default in all cases, ++ * for example when running the kernel as a guest on a hypervisor. In these ++ * cases this function can be called to disable hard lockup detection. This ++ * function should only be executed once by the boot processor before the ++ * kernel command line parameters are parsed, because otherwise it is not ++ * possible to override this in hardlockup_panic_setup(). ++ */ ++void hardlockup_detector_disable(void) ++{ ++ watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; ++} ++ ++static int __init hardlockup_panic_setup(char *str) ++{ ++ if (!strncmp(str, "panic", 5)) ++ hardlockup_panic = 1; ++ else if (!strncmp(str, "nopanic", 7)) ++ hardlockup_panic = 0; ++ else if (!strncmp(str, "0", 1)) ++ watchdog_enabled &= ~NMI_WATCHDOG_ENABLED; ++ else if (!strncmp(str, "1", 1)) ++ watchdog_enabled |= NMI_WATCHDOG_ENABLED; ++ return 1; ++} ++__setup("nmi_watchdog=", hardlockup_panic_setup); ++ ++void touch_nmi_watchdog(void) ++{ ++ /* ++ * Using __raw here because some code paths have ++ * preemption enabled. If preemption is enabled ++ * then interrupts should be enabled too, in which ++ * case we shouldn't have to worry about the watchdog ++ * going off. ++ */ ++ raw_cpu_write(watchdog_nmi_touch, true); ++ touch_softlockup_watchdog(); ++} ++EXPORT_SYMBOL(touch_nmi_watchdog); ++ ++static struct perf_event_attr wd_hw_attr = { ++ .type = PERF_TYPE_HARDWARE, ++ .config = PERF_COUNT_HW_CPU_CYCLES, ++ .size = sizeof(struct perf_event_attr), ++ .pinned = 1, ++ .disabled = 1, ++}; ++ ++/* Callback function for perf event subsystem */ ++static void watchdog_overflow_callback(struct perf_event *event, ++ struct perf_sample_data *data, ++ struct pt_regs *regs) ++{ ++ /* Ensure the watchdog never gets throttled */ ++ event->hw.interrupts = 0; ++ ++ if (__this_cpu_read(watchdog_nmi_touch) == true) { ++ __this_cpu_write(watchdog_nmi_touch, false); ++ return; ++ } ++ ++ /* check for a hardlockup ++ * This is done by making sure our timer interrupt ++ * is incrementing. The timer interrupt should have ++ * fired multiple times before we overflow'd. If it hasn't ++ * then this is a good indication the cpu is stuck ++ */ ++ if (is_hardlockup()) { ++ int this_cpu = smp_processor_id(); ++ ++ /* only print hardlockups once */ ++ if (__this_cpu_read(hard_watchdog_warn) == true) ++ return; ++ ++ pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); ++ print_modules(); ++ print_irqtrace_events(current); ++ if (regs) ++ show_regs(regs); ++ else ++ dump_stack(); ++ ++ /* ++ * Perform all-CPU dump only once to avoid multiple hardlockups ++ * generating interleaving traces ++ */ ++ if (sysctl_hardlockup_all_cpu_backtrace && ++ !test_and_set_bit(0, &hardlockup_allcpu_dumped)) ++ trigger_allbutself_cpu_backtrace(); ++ ++ if (hardlockup_panic) ++ nmi_panic(regs, "Hard LOCKUP"); ++ ++ __this_cpu_write(hard_watchdog_warn, true); ++ return; ++ } ++ ++ __this_cpu_write(hard_watchdog_warn, false); ++ return; ++} ++ ++/* ++ * People like the simple clean cpu node info on boot. ++ * Reduce the watchdog noise by only printing messages ++ * that are different from what cpu0 displayed. ++ */ ++static unsigned long cpu0_err; ++ ++int watchdog_nmi_enable(unsigned int cpu) ++{ ++ struct perf_event_attr *wd_attr; ++ struct perf_event *event = per_cpu(watchdog_ev, cpu); ++ ++ /* nothing to do if the hard lockup detector is disabled */ ++ if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED)) ++ goto out; ++ ++ /* is it already setup and enabled? */ ++ if (event && event->state > PERF_EVENT_STATE_OFF) ++ goto out; ++ ++ /* it is setup but not enabled */ ++ if (event != NULL) ++ goto out_enable; ++ ++ wd_attr = &wd_hw_attr; ++ wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh); ++ ++ /* Try to register using hardware perf events */ ++ event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); ++ ++ /* save cpu0 error for future comparision */ ++ if (cpu == 0 && IS_ERR(event)) ++ cpu0_err = PTR_ERR(event); ++ ++ if (!IS_ERR(event)) { ++ /* only print for cpu0 or different than cpu0 */ ++ if (cpu == 0 || cpu0_err) ++ pr_info("enabled on all CPUs, permanently consumes one hw-PMU counter.\n"); ++ goto out_save; ++ } ++ ++ /* ++ * Disable the hard lockup detector if _any_ CPU fails to set up ++ * set up the hardware perf event. The watchdog() function checks ++ * the NMI_WATCHDOG_ENABLED bit periodically. ++ * ++ * The barriers are for syncing up watchdog_enabled across all the ++ * cpus, as clear_bit() does not use barriers. ++ */ ++ smp_mb__before_atomic(); ++ clear_bit(NMI_WATCHDOG_ENABLED_BIT, &watchdog_enabled); ++ smp_mb__after_atomic(); ++ ++ /* skip displaying the same error again */ ++ if (cpu > 0 && (PTR_ERR(event) == cpu0_err)) ++ return PTR_ERR(event); ++ ++ /* vary the KERN level based on the returned errno */ ++ if (PTR_ERR(event) == -EOPNOTSUPP) ++ pr_info("disabled (cpu%i): not supported (no LAPIC?)\n", cpu); ++ else if (PTR_ERR(event) == -ENOENT) ++ pr_warn("disabled (cpu%i): hardware events not enabled\n", ++ cpu); ++ else ++ pr_err("disabled (cpu%i): unable to create perf event: %ld\n", ++ cpu, PTR_ERR(event)); ++ ++ pr_info("Shutting down hard lockup detector on all cpus\n"); ++ ++ return PTR_ERR(event); ++ ++ /* success path */ ++out_save: ++ per_cpu(watchdog_ev, cpu) = event; ++out_enable: ++ perf_event_enable(per_cpu(watchdog_ev, cpu)); ++out: ++ return 0; ++} ++ ++void watchdog_nmi_disable(unsigned int cpu) ++{ ++ struct perf_event *event = per_cpu(watchdog_ev, cpu); ++ ++ if (event) { ++ perf_event_disable(event); ++ per_cpu(watchdog_ev, cpu) = NULL; ++ ++ /* should be in cleanup, but blocks oprofile */ ++ perf_event_release_kernel(event); ++ } ++ if (cpu == 0) { ++ /* watchdog_nmi_enable() expects this to be zero initially. */ ++ cpu0_err = 0; ++ } ++} diff --git a/queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch b/queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch new file mode 100644 index 00000000000..6af7f972daa --- /dev/null +++ b/queue-4.9/kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch @@ -0,0 +1,154 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Babu Moger +Date: Wed, 14 Dec 2016 15:06:21 -0800 +Subject: kernel/watchdog.c: move shared definitions to nmi.h + +From: Babu Moger + + +[ Upstream commit 249e52e35580fcfe5dad53a7dcd7c1252788749c ] + +Patch series "Clean up watchdog handlers", v2. + +This is an attempt to cleanup watchdog handlers. Right now, +kernel/watchdog.c implements both softlockup and hardlockup detectors. +Softlockup code is generic. Hardlockup code is arch specific. Some +architectures don't use hardlockup detectors. They use their own +watchdog detectors. To make both these combination work, we have +numerous #ifdefs in kernel/watchdog.c. + +We are trying here to make these handlers independent of each other. +Also provide an interface for architectures to implement their own +handlers. watchdog_nmi_enable and watchdog_nmi_disable will be defined +as weak such that architectures can override its definitions. + +Thanks to Don Zickus for his suggestions. +Here are our previous discussions +http://www.spinics.net/lists/sparclinux/msg16543.html +http://www.spinics.net/lists/sparclinux/msg16441.html + +This patch (of 3): + +Move shared macros and definitions to nmi.h so that watchdog.c, new file +watchdog_hld.c or any other architecture specific handler can use those +definitions. + +Link: http://lkml.kernel.org/r/1478034826-43888-2-git-send-email-babu.moger@oracle.com +Signed-off-by: Babu Moger +Acked-by: Don Zickus +Cc: Ingo Molnar +Cc: Jiri Kosina +Cc: Andi Kleen +Cc: Yaowei Bai +Cc: Aaron Tomlin +Cc: Ulrich Obergfell +Cc: Tejun Heo +Cc: Hidehiro Kawai +Cc: Josh Hunt +Cc: "David S. Miller" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/nmi.h | 24 ++++++++++++++++++++++++ + kernel/watchdog.c | 28 ++++------------------------ + 2 files changed, 28 insertions(+), 24 deletions(-) + +--- a/include/linux/nmi.h ++++ b/include/linux/nmi.h +@@ -7,6 +7,23 @@ + #include + #include + ++/* ++ * The run state of the lockup detectors is controlled by the content of the ++ * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - ++ * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. ++ * ++ * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled' ++ * are variables that are only used as an 'interface' between the parameters ++ * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The ++ * 'watchdog_thresh' variable is handled differently because its value is not ++ * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh' ++ * is equal zero. ++ */ ++#define NMI_WATCHDOG_ENABLED_BIT 0 ++#define SOFT_WATCHDOG_ENABLED_BIT 1 ++#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) ++#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) ++ + /** + * touch_nmi_watchdog - restart NMI watchdog timeout. + * +@@ -91,9 +108,16 @@ extern int nmi_watchdog_enabled; + extern int soft_watchdog_enabled; + extern int watchdog_user_enabled; + extern int watchdog_thresh; ++extern unsigned long watchdog_enabled; + extern unsigned long *watchdog_cpumask_bits; ++#ifdef CONFIG_SMP + extern int sysctl_softlockup_all_cpu_backtrace; + extern int sysctl_hardlockup_all_cpu_backtrace; ++#else ++#define sysctl_softlockup_all_cpu_backtrace 0 ++#define sysctl_hardlockup_all_cpu_backtrace 0 ++#endif ++extern bool is_hardlockup(void); + struct ctl_table; + extern int proc_watchdog(struct ctl_table *, int , + void __user *, size_t *, loff_t *); +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -26,29 +26,12 @@ + #include + #include + +-/* +- * The run state of the lockup detectors is controlled by the content of the +- * 'watchdog_enabled' variable. Each lockup detector has its dedicated bit - +- * bit 0 for the hard lockup detector and bit 1 for the soft lockup detector. +- * +- * 'watchdog_user_enabled', 'nmi_watchdog_enabled' and 'soft_watchdog_enabled' +- * are variables that are only used as an 'interface' between the parameters +- * in /proc/sys/kernel and the internal state bits in 'watchdog_enabled'. The +- * 'watchdog_thresh' variable is handled differently because its value is not +- * boolean, and the lockup detectors are 'suspended' while 'watchdog_thresh' +- * is equal zero. +- */ +-#define NMI_WATCHDOG_ENABLED_BIT 0 +-#define SOFT_WATCHDOG_ENABLED_BIT 1 +-#define NMI_WATCHDOG_ENABLED (1 << NMI_WATCHDOG_ENABLED_BIT) +-#define SOFT_WATCHDOG_ENABLED (1 << SOFT_WATCHDOG_ENABLED_BIT) +- + static DEFINE_MUTEX(watchdog_proc_mutex); + +-#ifdef CONFIG_HARDLOCKUP_DETECTOR +-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED; ++#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR) ++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED|NMI_WATCHDOG_ENABLED; + #else +-static unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED; ++unsigned long __read_mostly watchdog_enabled = SOFT_WATCHDOG_ENABLED; + #endif + int __read_mostly nmi_watchdog_enabled; + int __read_mostly soft_watchdog_enabled; +@@ -58,9 +41,6 @@ int __read_mostly watchdog_thresh = 10; + #ifdef CONFIG_SMP + int __read_mostly sysctl_softlockup_all_cpu_backtrace; + int __read_mostly sysctl_hardlockup_all_cpu_backtrace; +-#else +-#define sysctl_softlockup_all_cpu_backtrace 0 +-#define sysctl_hardlockup_all_cpu_backtrace 0 + #endif + static struct cpumask watchdog_cpumask __read_mostly; + unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask); +@@ -229,7 +209,7 @@ void touch_softlockup_watchdog_sync(void + } + + /* watchdog detector functions */ +-static bool is_hardlockup(void) ++bool is_hardlockup(void) + { + unsigned long hrint = __this_cpu_read(hrtimer_interrupts); + diff --git a/queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch b/queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch new file mode 100644 index 00000000000..4468e6815fb --- /dev/null +++ b/queue-4.9/mn10300-fix-build-error-of-missing-fpu_save.patch @@ -0,0 +1,42 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Randy Dunlap +Date: Tue, 24 Jan 2017 15:18:49 -0800 +Subject: mn10300: fix build error of missing fpu_save() + +From: Randy Dunlap + + +[ Upstream commit 3705ccfdd1e8b539225ce20e3925a945cc788d67 ] + +When CONFIG_FPU is not enabled on arch/mn10300, causes +a build error with a call to fpu_save(): + + kernel/built-in.o: In function `.L410': + core.c:(.sched.text+0x28a): undefined reference to `fpu_save' + +Fix this by including in so that an empty +static inline fpu_save() is defined. + +Link: http://lkml.kernel.org/r/dc421c4f-4842-4429-1b99-92865c2f24b6@infradead.org +Signed-off-by: Randy Dunlap +Reported-by: kbuild test robot +Reviewed-by: David Howells +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/mn10300/include/asm/switch_to.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/mn10300/include/asm/switch_to.h ++++ b/arch/mn10300/include/asm/switch_to.h +@@ -16,7 +16,7 @@ + struct task_struct; + struct thread_struct; + +-#if !defined(CONFIG_LAZY_SAVE_FPU) ++#if defined(CONFIG_FPU) && !defined(CONFIG_LAZY_SAVE_FPU) + struct fpu_state_struct; + extern asmlinkage void fpu_save(struct fpu_state_struct *); + #define switch_fpu(prev, next) \ diff --git a/queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch b/queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch new file mode 100644 index 00000000000..e1d006ffd4f --- /dev/null +++ b/queue-4.9/net-next-ethernet-mediatek-change-the-compatible-string.patch @@ -0,0 +1,40 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: John Crispin +Date: Wed, 25 Jan 2017 09:20:55 +0100 +Subject: net-next: ethernet: mediatek: change the compatible string + +From: John Crispin + + +[ Upstream commit 8b901f6bbcf12a20e43105d161bedde093431e61 ] + +When the binding was defined, I was not aware that mt2701 was an earlier +version of the SoC. For sake of consistency, the ethernet driver should +use mt2701 inside the compat string as this is the earliest SoC with the +ethernet core. + +The ethernet driver is currently of no real use until we finish and +upstream the DSA driver. There are no users of this binding yet. It should +be safe to fix this now before it is too late and we need to provide +backward compatibility for the mt7623-eth compat string. + +Reported-by: Sean Wang +Signed-off-by: John Crispin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c +@@ -2518,7 +2518,7 @@ static int mtk_remove(struct platform_de + } + + const struct of_device_id of_mtk_match[] = { +- { .compatible = "mediatek,mt7623-eth" }, ++ { .compatible = "mediatek,mt2701-eth" }, + {}, + }; + MODULE_DEVICE_TABLE(of, of_mtk_match); diff --git a/queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch b/queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch new file mode 100644 index 00000000000..23bfbe74677 --- /dev/null +++ b/queue-4.9/proc-add-a-schedule-point-in-proc_pid_readdir.patch @@ -0,0 +1,36 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Eric Dumazet +Date: Tue, 24 Jan 2017 15:18:07 -0800 +Subject: proc: add a schedule point in proc_pid_readdir() + +From: Eric Dumazet + + +[ Upstream commit 3ba4bceef23206349d4130ddf140819b365de7c8 ] + +We have seen proc_pid_readdir() invocations holding cpu for more than 50 +ms. Add a cond_resched() to be gentle with other tasks. + +[akpm@linux-foundation.org: coding style fix] +Link: http://lkml.kernel.org/r/1484238380.15816.42.camel@edumazet-glaptop3.roam.corp.google.com +Signed-off-by: Eric Dumazet +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/proc/base.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -3181,6 +3181,8 @@ int proc_pid_readdir(struct file *file, + iter.tgid += 1, iter = next_tgid(ns, iter)) { + char name[PROC_NUMBUF]; + int len; ++ ++ cond_resched(); + if (!has_pid_permissions(ns, iter.task, 2)) + continue; + diff --git a/queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch b/queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch new file mode 100644 index 00000000000..5adac5f9f9c --- /dev/null +++ b/queue-4.9/r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch @@ -0,0 +1,71 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: hayeswang +Date: Thu, 26 Jan 2017 09:38:32 +0800 +Subject: r8152: avoid start_xmit to schedule napi when napi is disabled + +From: hayeswang + + +[ Upstream commit de9bf29dd6e4a8a874cb92f8901aed50a9d0b1d3 ] + +Stop the tx when the napi is disabled to prevent napi_schedule() is +called. + +Signed-off-by: Hayes Wang +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/r8152.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/usb/r8152.c ++++ b/drivers/net/usb/r8152.c +@@ -3158,10 +3158,13 @@ static void set_carrier(struct r8152 *tp + if (!netif_carrier_ok(netdev)) { + tp->rtl_ops.enable(tp); + set_bit(RTL8152_SET_RX_MODE, &tp->flags); ++ netif_stop_queue(netdev); + napi_disable(&tp->napi); + netif_carrier_on(netdev); + rtl_start_rx(tp); + napi_enable(&tp->napi); ++ netif_wake_queue(netdev); ++ netif_info(tp, link, netdev, "carrier on\n"); + } + } else { + if (netif_carrier_ok(netdev)) { +@@ -3169,6 +3172,7 @@ static void set_carrier(struct r8152 *tp + napi_disable(&tp->napi); + tp->rtl_ops.disable(tp); + napi_enable(&tp->napi); ++ netif_info(tp, link, netdev, "carrier off\n"); + } + } + } +@@ -3518,12 +3522,12 @@ static int rtl8152_pre_reset(struct usb_ + if (!netif_running(netdev)) + return 0; + ++ netif_stop_queue(netdev); + napi_disable(&tp->napi); + clear_bit(WORK_ENABLE, &tp->flags); + usb_kill_urb(tp->intr_urb); + cancel_delayed_work_sync(&tp->schedule); + if (netif_carrier_ok(netdev)) { +- netif_stop_queue(netdev); + mutex_lock(&tp->control); + tp->rtl_ops.disable(tp); + mutex_unlock(&tp->control); +@@ -3551,10 +3555,10 @@ static int rtl8152_post_reset(struct usb + rtl_start_rx(tp); + rtl8152_set_rx_mode(netdev); + mutex_unlock(&tp->control); +- netif_wake_queue(netdev); + } + + napi_enable(&tp->napi); ++ netif_wake_queue(netdev); + usb_submit_urb(tp->intr_urb, GFP_KERNEL); + + if (!list_empty(&tp->rx_done)) diff --git a/queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch b/queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch new file mode 100644 index 00000000000..bd47d9dbb51 --- /dev/null +++ b/queue-4.9/romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch @@ -0,0 +1,96 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Coly Li +Date: Tue, 24 Jan 2017 15:18:46 -0800 +Subject: romfs: use different way to generate fsid for BLOCK or MTD + +From: Coly Li + + +[ Upstream commit f598f82e204ec0b17797caaf1b0311c52d43fb9a ] + +Commit 8a59f5d25265 ("fs/romfs: return f_fsid for statfs(2)") generates +a 64bit id from sb->s_bdev->bd_dev. This is only correct when romfs is +defined with CONFIG_ROMFS_ON_BLOCK. If romfs is only defined with +CONFIG_ROMFS_ON_MTD, sb->s_bdev is NULL, referencing sb->s_bdev->bd_dev +will triger an oops. + +Richard Weinberger points out that when CONFIG_ROMFS_BACKED_BY_BOTH=y, +both CONFIG_ROMFS_ON_BLOCK and CONFIG_ROMFS_ON_MTD are defined. +Therefore when calling huge_encode_dev() to generate a 64bit id, I use +the follow order to choose parameter, + +- CONFIG_ROMFS_ON_BLOCK defined + use sb->s_bdev->bd_dev +- CONFIG_ROMFS_ON_BLOCK undefined and CONFIG_ROMFS_ON_MTD defined + use sb->s_dev when, +- both CONFIG_ROMFS_ON_BLOCK and CONFIG_ROMFS_ON_MTD undefined + leave id as 0 + +When CONFIG_ROMFS_ON_MTD is defined and sb->s_mtd is not NULL, sb->s_dev +is set to a device ID generated by MTD_BLOCK_MAJOR and mtd index, +otherwise sb->s_dev is 0. + +This is a try-best effort to generate a uniq file system ID, if all the +above conditions are not meet, f_fsid of this romfs instance will be 0. +Generally only one romfs can be built on single MTD block device, this +method is enough to identify multiple romfs instances in a computer. + +Link: http://lkml.kernel.org/r/1482928596-115155-1-git-send-email-colyli@suse.de +Signed-off-by: Coly Li +Reported-by: Nong Li +Tested-by: Nong Li +Cc: Richard Weinberger +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/romfs/super.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/fs/romfs/super.c ++++ b/fs/romfs/super.c +@@ -74,6 +74,7 @@ + #include + #include + #include ++#include + #include "internal.h" + + static struct kmem_cache *romfs_inode_cachep; +@@ -416,7 +417,22 @@ static void romfs_destroy_inode(struct i + static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf) + { + struct super_block *sb = dentry->d_sb; +- u64 id = huge_encode_dev(sb->s_bdev->bd_dev); ++ u64 id = 0; ++ ++ /* When calling huge_encode_dev(), ++ * use sb->s_bdev->bd_dev when, ++ * - CONFIG_ROMFS_ON_BLOCK defined ++ * use sb->s_dev when, ++ * - CONFIG_ROMFS_ON_BLOCK undefined and ++ * - CONFIG_ROMFS_ON_MTD defined ++ * leave id as 0 when, ++ * - CONFIG_ROMFS_ON_BLOCK undefined and ++ * - CONFIG_ROMFS_ON_MTD undefined ++ */ ++ if (sb->s_bdev) ++ id = huge_encode_dev(sb->s_bdev->bd_dev); ++ else if (sb->s_dev) ++ id = huge_encode_dev(sb->s_dev); + + buf->f_type = ROMFS_MAGIC; + buf->f_namelen = ROMFS_MAXFN; +@@ -489,6 +505,11 @@ static int romfs_fill_super(struct super + sb->s_flags |= MS_RDONLY | MS_NOATIME; + sb->s_op = &romfs_super_ops; + ++#ifdef CONFIG_ROMFS_ON_MTD ++ /* Use same dev ID from the underlying mtdblock device */ ++ if (sb->s_mtd) ++ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, sb->s_mtd->index); ++#endif + /* read the image superblock and check it */ + rsb = kmalloc(512, GFP_KERNEL); + if (!rsb) diff --git a/queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch b/queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch new file mode 100644 index 00000000000..0a89df49d4b --- /dev/null +++ b/queue-4.9/sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch @@ -0,0 +1,44 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Xin Long +Date: Tue, 24 Jan 2017 14:05:16 +0800 +Subject: sctp: sctp gso should set feature with NETIF_F_SG when calling skb_segment + +From: Xin Long + + +[ Upstream commit 5207f3996338e1db71363fe381c81aaf1e54e4e3 ] + +Now sctp gso puts segments into skb's frag_list, then processes these +segments in skb_segment. But skb_segment handles them only when gs is +enabled, as it's in the same branch with skb's frags. + +Although almost all the NICs support sg other than some old ones, but +since commit 1e16aa3ddf86 ("net: gso: use feature flag argument in all +protocol gso handlers"), features &= skb->dev->hw_enc_features, and +xfrm_output_gso call skb_segment with features = 0, which means sctp +gso would call skb_segment with sg = 0, and skb_segment would not work +as expected. + +This patch is to fix it by setting features param with NETIF_F_SG when +calling skb_segment so that it can go the right branch to process the +skb's frag_list. + +Signed-off-by: Xin Long +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/offload.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sctp/offload.c ++++ b/net/sctp/offload.c +@@ -68,7 +68,7 @@ static struct sk_buff *sctp_gso_segment( + goto out; + } + +- segs = skb_segment(skb, features | NETIF_F_HW_CSUM); ++ segs = skb_segment(skb, features | NETIF_F_HW_CSUM | NETIF_F_SG); + if (IS_ERR(segs)) + goto out; + diff --git a/queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch b/queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch new file mode 100644 index 00000000000..5bd8641db4d --- /dev/null +++ b/queue-4.9/sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch @@ -0,0 +1,45 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Xin Long +Date: Tue, 24 Jan 2017 14:01:53 +0800 +Subject: sctp: sctp_addr_id2transport should verify the addr before looking up assoc + +From: Xin Long + + +[ Upstream commit 6f29a130613191d3c6335169febe002cba00edf5 ] + +sctp_addr_id2transport is a function for sockopt to look up assoc by +address. As the address is from userspace, it can be a v4-mapped v6 +address. But in sctp protocol stack, it always handles a v4-mapped +v6 address as a v4 address. So it's necessary to convert it to a v4 +address before looking up assoc by address. + +This patch is to fix it by calling sctp_verify_addr in which it can do +this conversion before calling sctp_endpoint_lookup_assoc, just like +what sctp_sendmsg and __sctp_connect do for the address from users. + +Signed-off-by: Xin Long +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -235,8 +235,12 @@ static struct sctp_transport *sctp_addr_ + sctp_assoc_t id) + { + struct sctp_association *addr_asoc = NULL, *id_asoc = NULL; +- struct sctp_transport *transport; ++ struct sctp_af *af = sctp_get_af_specific(addr->ss_family); + union sctp_addr *laddr = (union sctp_addr *)addr; ++ struct sctp_transport *transport; ++ ++ if (sctp_verify_addr(sk, laddr, af->sockaddr_len)) ++ return NULL; + + addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, + laddr, diff --git a/queue-4.9/series b/queue-4.9/series index c9615c4af79..434adc9176f 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -69,3 +69,23 @@ r8152-avoid-start_xmit-to-call-napi_schedule-during-autosuspend.patch r8152-check-rx-after-napi-is-enabled.patch r8152-re-schedule-napi-for-tx.patch r8152-fix-rtl8152_post_reset-function.patch +r8152-avoid-start_xmit-to-schedule-napi-when-napi-is-disabled.patch +net-next-ethernet-mediatek-change-the-compatible-string.patch +bnxt_en-fix-bnxt_reset-in-the-slow-path-task.patch +bnxt_en-enhance-autoneg-support.patch +bnxt_en-fix-rtnl-lock-usage-on-bnxt_update_link.patch +bnxt_en-fix-rtnl-lock-usage-on-bnxt_get_port_module_status.patch +sctp-sctp-gso-should-set-feature-with-netif_f_sg-when-calling-skb_segment.patch +sctp-sctp_addr_id2transport-should-verify-the-addr-before-looking-up-assoc.patch +usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch +mn10300-fix-build-error-of-missing-fpu_save.patch +romfs-use-different-way-to-generate-fsid-for-block-or-mtd.patch +frv-add-atomic64_add_unless.patch +frv-add-missing-atomic64-operations.patch +proc-add-a-schedule-point-in-proc_pid_readdir.patch +userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch +kernel-watchdog.c-move-hardlockup-detector-to-separate-file.patch +kernel-watchdog.c-move-shared-definitions-to-nmi.h.patch +kernel-watchdog-prevent-false-hardlockup-on-overloaded-system.patch +vhost-vsock-handle-vhost_vq_init_access-error.patch +arc-smp-boot-decouple-non-masters-waiting-api-from-jump-to-entry-point.patch diff --git a/queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch b/queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch new file mode 100644 index 00000000000..ae4724ec7b0 --- /dev/null +++ b/queue-4.9/usb-musb-fix-external-abort-on-non-linefetch-for-musb_irq_work.patch @@ -0,0 +1,57 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Tony Lindgren +Date: Tue, 24 Jan 2017 09:18:58 -0600 +Subject: usb: musb: Fix external abort on non-linefetch for musb_irq_work() + +From: Tony Lindgren + + +[ Upstream commit 3ba7b7795b7e8889af1377904c55c7fae9e0c775 ] + +While testing musb host mode cable plugging on a BeagleBone, I came across this +error: + +Unhandled fault: external abort on non-linefetch (0x1008) at 0xd1dcfc60 +... +[] (musb_default_readb [musb_hdrc]) from [] (musb_irq_work+0x1c/0x180 [musb_hdrc]) +[] (musb_irq_work [musb_hdrc]) from [] (process_one_work+0x2b4/0x808) +[] (process_one_work) from [] (worker_thread+0x3c/0x550) +[] (worker_thread) from [] (kthread+0x104/0x148) +[] (kthread) from [] (ret_from_fork+0x14/0x24) + +Signed-off-by: Tony Lindgren +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/musb/musb_core.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -1909,6 +1909,14 @@ static void musb_pm_runtime_check_sessio + static void musb_irq_work(struct work_struct *data) + { + struct musb *musb = container_of(data, struct musb, irq_work.work); ++ int error; ++ ++ error = pm_runtime_get_sync(musb->controller); ++ if (error < 0) { ++ dev_err(musb->controller, "Could not enable: %i\n", error); ++ ++ return; ++ } + + musb_pm_runtime_check_session(musb); + +@@ -1916,6 +1924,9 @@ static void musb_irq_work(struct work_st + musb->xceiv_old_state = musb->xceiv->otg->state; + sysfs_notify(&musb->controller->kobj, NULL, "mode"); + } ++ ++ pm_runtime_mark_last_busy(musb->controller); ++ pm_runtime_put_autosuspend(musb->controller); + } + + static void musb_recover_from_babble(struct musb *musb) diff --git a/queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch b/queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch new file mode 100644 index 00000000000..710f9e0cf0b --- /dev/null +++ b/queue-4.9/userfaultfd-fix-sigbus-resulting-from-false-rwsem-wakeups.patch @@ -0,0 +1,187 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Andrea Arcangeli +Date: Tue, 24 Jan 2017 15:17:59 -0800 +Subject: userfaultfd: fix SIGBUS resulting from false rwsem wakeups + +From: Andrea Arcangeli + + +[ Upstream commit 15a77c6fe494f4b1757d30cd137fe66ab06a38c3 ] + +With >=32 CPUs the userfaultfd selftest triggered a graceful but +unexpected SIGBUS because VM_FAULT_RETRY was returned by +handle_userfault() despite the UFFDIO_COPY wasn't completed. + +This seems caused by rwsem waking the thread blocked in +handle_userfault() and we can't run up_read() before the wait_event +sequence is complete. + +Keeping the wait_even sequence identical to the first one, would require +running userfaultfd_must_wait() again to know if the loop should be +repeated, and it would also require retaking the rwsem and revalidating +the whole vma status. + +It seems simpler to wait the targeted wakeup so that if false wakeups +materialize we still wait for our specific wakeup event, unless of +course there are signals or the uffd was released. + +Debug code collecting the stack trace of the wakeup showed this: + + $ ./userfaultfd 100 99999 + nr_pages: 25600, nr_pages_per_cpu: 800 + bounces: 99998, mode: racing ver poll, userfaults: 32 35 90 232 30 138 69 82 34 30 139 40 40 31 20 19 43 13 15 28 27 38 21 43 56 22 1 17 31 8 4 2 + bounces: 99997, mode: rnd ver poll, Bus error (core dumped) + + save_stack_trace+0x2b/0x50 + try_to_wake_up+0x2a6/0x580 + wake_up_q+0x32/0x70 + rwsem_wake+0xe0/0x120 + call_rwsem_wake+0x1b/0x30 + up_write+0x3b/0x40 + vm_mmap_pgoff+0x9c/0xc0 + SyS_mmap_pgoff+0x1a9/0x240 + SyS_mmap+0x22/0x30 + entry_SYSCALL_64_fastpath+0x1f/0xbd + 0xffffffffffffffff + FAULT_FLAG_ALLOW_RETRY missing 70 + CPU: 24 PID: 1054 Comm: userfaultfd Tainted: G W 4.8.0+ #30 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.9.3-0-ge2fc41e-prebuilt.qemu-project.org 04/01/2014 + Call Trace: + dump_stack+0xb8/0x112 + handle_userfault+0x572/0x650 + handle_mm_fault+0x12cb/0x1520 + __do_page_fault+0x175/0x500 + trace_do_page_fault+0x61/0x270 + do_async_page_fault+0x19/0x90 + async_page_fault+0x25/0x30 + +This always happens when the main userfault selftest thread is running +clone() while glibc runs either mprotect or mmap (both taking mmap_sem +down_write()) to allocate the thread stack of the background threads, +while locking/userfault threads already run at full throttle and are +susceptible to false wakeups that may cause handle_userfault() to return +before than expected (which results in graceful SIGBUS at the next +attempt). + +This was reproduced only with >=32 CPUs because the loop to start the +thread where clone() is too quick with fewer CPUs, while with 32 CPUs +there's already significant activity on ~32 locking and userfault +threads when the last background threads are started with clone(). + +This >=32 CPUs SMP race condition is likely reproducible only with the +selftest because of the much heavier userfault load it generates if +compared to real apps. + +We'll have to allow "one more" VM_FAULT_RETRY for the WP support and a +patch floating around that provides it also hidden this problem but in +reality only is successfully at hiding the problem. + +False wakeups could still happen again the second time +handle_userfault() is invoked, even if it's a so rare race condition +that getting false wakeups twice in a row is impossible to reproduce. +This full fix is needed for correctness, the only alternative would be +to allow VM_FAULT_RETRY to be returned infinitely. With this fix the WP +support can stick to a strict "one more" VM_FAULT_RETRY logic (no need +of returning it infinite times to avoid the SIGBUS). + +Link: http://lkml.kernel.org/r/20170111005535.13832-2-aarcange@redhat.com +Signed-off-by: Andrea Arcangeli +Reported-by: Shubham Kumar Sharma +Tested-by: Mike Kravetz +Acked-by: Hillf Danton +Cc: Michael Rapoport +Cc: "Dr. David Alan Gilbert" +Cc: Pavel Emelyanov +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/userfaultfd.c | 37 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 35 insertions(+), 2 deletions(-) + +--- a/fs/userfaultfd.c ++++ b/fs/userfaultfd.c +@@ -63,6 +63,7 @@ struct userfaultfd_wait_queue { + struct uffd_msg msg; + wait_queue_t wq; + struct userfaultfd_ctx *ctx; ++ bool waken; + }; + + struct userfaultfd_wake_range { +@@ -86,6 +87,12 @@ static int userfaultfd_wake_function(wai + if (len && (start > uwq->msg.arg.pagefault.address || + start + len <= uwq->msg.arg.pagefault.address)) + goto out; ++ WRITE_ONCE(uwq->waken, true); ++ /* ++ * The implicit smp_mb__before_spinlock in try_to_wake_up() ++ * renders uwq->waken visible to other CPUs before the task is ++ * waken. ++ */ + ret = wake_up_state(wq->private, mode); + if (ret) + /* +@@ -264,6 +271,7 @@ int handle_userfault(struct fault_env *f + struct userfaultfd_wait_queue uwq; + int ret; + bool must_wait, return_to_userland; ++ long blocking_state; + + BUG_ON(!rwsem_is_locked(&mm->mmap_sem)); + +@@ -333,10 +341,13 @@ int handle_userfault(struct fault_env *f + uwq.wq.private = current; + uwq.msg = userfault_msg(fe->address, fe->flags, reason); + uwq.ctx = ctx; ++ uwq.waken = false; + + return_to_userland = + (fe->flags & (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE)) == + (FAULT_FLAG_USER|FAULT_FLAG_KILLABLE); ++ blocking_state = return_to_userland ? TASK_INTERRUPTIBLE : ++ TASK_KILLABLE; + + spin_lock(&ctx->fault_pending_wqh.lock); + /* +@@ -349,8 +360,7 @@ int handle_userfault(struct fault_env *f + * following the spin_unlock to happen before the list_add in + * __add_wait_queue. + */ +- set_current_state(return_to_userland ? TASK_INTERRUPTIBLE : +- TASK_KILLABLE); ++ set_current_state(blocking_state); + spin_unlock(&ctx->fault_pending_wqh.lock); + + must_wait = userfaultfd_must_wait(ctx, fe->address, fe->flags, reason); +@@ -362,6 +372,29 @@ int handle_userfault(struct fault_env *f + wake_up_poll(&ctx->fd_wqh, POLLIN); + schedule(); + ret |= VM_FAULT_MAJOR; ++ ++ /* ++ * False wakeups can orginate even from rwsem before ++ * up_read() however userfaults will wait either for a ++ * targeted wakeup on the specific uwq waitqueue from ++ * wake_userfault() or for signals or for uffd ++ * release. ++ */ ++ while (!READ_ONCE(uwq.waken)) { ++ /* ++ * This needs the full smp_store_mb() ++ * guarantee as the state write must be ++ * visible to other CPUs before reading ++ * uwq.waken from other CPUs. ++ */ ++ set_current_state(blocking_state); ++ if (READ_ONCE(uwq.waken) || ++ READ_ONCE(ctx->released) || ++ (return_to_userland ? signal_pending(current) : ++ fatal_signal_pending(current))) ++ break; ++ schedule(); ++ } + } + + __set_current_state(TASK_RUNNING); diff --git a/queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch b/queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch new file mode 100644 index 00000000000..16a86a80f20 --- /dev/null +++ b/queue-4.9/vhost-vsock-handle-vhost_vq_init_access-error.patch @@ -0,0 +1,68 @@ +From foo@baz Thu Jun 15 16:23:30 CEST 2017 +From: Stefan Hajnoczi +Date: Thu, 19 Jan 2017 10:43:53 +0000 +Subject: vhost/vsock: handle vhost_vq_init_access() error + +From: Stefan Hajnoczi + + +[ Upstream commit 0516ffd88fa0d006ee80389ce14a9ca5ae45e845 ] + +Propagate the error when vhost_vq_init_access() fails and set +vq->private_data to NULL. + +Signed-off-by: Stefan Hajnoczi +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/vsock.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/vhost/vsock.c ++++ b/drivers/vhost/vsock.c +@@ -368,6 +368,7 @@ static void vhost_vsock_handle_rx_kick(s + + static int vhost_vsock_start(struct vhost_vsock *vsock) + { ++ struct vhost_virtqueue *vq; + size_t i; + int ret; + +@@ -378,19 +379,20 @@ static int vhost_vsock_start(struct vhos + goto err; + + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { +- struct vhost_virtqueue *vq = &vsock->vqs[i]; ++ vq = &vsock->vqs[i]; + + mutex_lock(&vq->mutex); + + if (!vhost_vq_access_ok(vq)) { + ret = -EFAULT; +- mutex_unlock(&vq->mutex); + goto err_vq; + } + + if (!vq->private_data) { + vq->private_data = vsock; +- vhost_vq_init_access(vq); ++ ret = vhost_vq_init_access(vq); ++ if (ret) ++ goto err_vq; + } + + mutex_unlock(&vq->mutex); +@@ -400,8 +402,11 @@ static int vhost_vsock_start(struct vhos + return 0; + + err_vq: ++ vq->private_data = NULL; ++ mutex_unlock(&vq->mutex); ++ + for (i = 0; i < ARRAY_SIZE(vsock->vqs); i++) { +- struct vhost_virtqueue *vq = &vsock->vqs[i]; ++ vq = &vsock->vqs[i]; + + mutex_lock(&vq->mutex); + vq->private_data = NULL;