From: Greg Kroah-Hartman Date: Thu, 30 Mar 2017 08:40:17 +0000 (+0200) Subject: 4.10-stable patches X-Git-Tag: v4.4.59~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=732f98bc8e57788ec8989e5619d59c0e6e0303e0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.10-stable patches added patches: qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch sched-rt-add-a-missing-rescheduling-point.patch usb-musb-fix-possible-spinlock-deadlock.patch --- diff --git a/queue-4.10/qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch b/queue-4.10/qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch new file mode 100644 index 00000000000..33063f004f4 --- /dev/null +++ b/queue-4.10/qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch @@ -0,0 +1,122 @@ +From c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 Mon Sep 17 00:00:00 2001 +From: Joe Carnuccio +Date: Wed, 15 Mar 2017 09:48:43 -0700 +Subject: qla2xxx: Allow vref count to timeout on vport delete. + +From: Joe Carnuccio + +commit c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 upstream. + +Signed-off-by: Joe Carnuccio +Signed-off-by: Himanshu Madhani +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_attr.c | 4 +--- + drivers/scsi/qla2xxx/qla_def.h | 6 +++++- + drivers/scsi/qla2xxx/qla_init.c | 1 + + drivers/scsi/qla2xxx/qla_mid.c | 14 ++++++++------ + drivers/scsi/qla2xxx/qla_os.c | 1 + + 5 files changed, 16 insertions(+), 10 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -2154,8 +2154,6 @@ qla24xx_vport_delete(struct fc_vport *fc + "Timer for the VP[%d] has stopped\n", vha->vp_idx); + } + +- BUG_ON(atomic_read(&vha->vref_count)); +- + qla2x00_free_fcports(vha); + + mutex_lock(&ha->vport_lock); +@@ -2163,7 +2161,7 @@ qla24xx_vport_delete(struct fc_vport *fc + clear_bit(vha->vp_idx, ha->vp_idx_map); + mutex_unlock(&ha->vport_lock); + +- if (vha->qpair->vp_idx == vha->vp_idx) { ++ if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) { + if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) + ql_log(ql_log_warn, vha, 0x7087, + "Queue Pair delete failed.\n"); +--- a/drivers/scsi/qla2xxx/qla_def.h ++++ b/drivers/scsi/qla2xxx/qla_def.h +@@ -3788,6 +3788,7 @@ typedef struct scsi_qla_host { + struct qla8044_reset_template reset_tmplt; + struct qla_tgt_counters tgt_counters; + uint16_t bbcr; ++ wait_queue_head_t vref_waitq; + } scsi_qla_host_t; + + struct qla27xx_image_status { +@@ -3843,14 +3844,17 @@ struct qla2_sgx { + mb(); \ + if (__vha->flags.delete_progress) { \ + atomic_dec(&__vha->vref_count); \ ++ wake_up(&__vha->vref_waitq); \ + __bail = 1; \ + } else { \ + __bail = 0; \ + } \ + } while (0) + +-#define QLA_VHA_MARK_NOT_BUSY(__vha) \ ++#define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ + atomic_dec(&__vha->vref_count); \ ++ wake_up(&__vha->vref_waitq); \ ++} while (0) \ + + #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ + atomic_inc(&__qpair->ref_count); \ +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -4352,6 +4352,7 @@ qla2x00_update_fcports(scsi_qla_host_t * + } + } + atomic_dec(&vha->vref_count); ++ wake_up(&vha->vref_waitq); + } + spin_unlock_irqrestore(&ha->vport_slock, flags); + } +--- a/drivers/scsi/qla2xxx/qla_mid.c ++++ b/drivers/scsi/qla2xxx/qla_mid.c +@@ -74,13 +74,14 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t + * ensures no active vp_list traversal while the vport is removed + * from the queue) + */ +- spin_lock_irqsave(&ha->vport_slock, flags); +- while (atomic_read(&vha->vref_count)) { +- spin_unlock_irqrestore(&ha->vport_slock, flags); +- +- msleep(500); ++ wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count), ++ 10*HZ); + +- spin_lock_irqsave(&ha->vport_slock, flags); ++ spin_lock_irqsave(&ha->vport_slock, flags); ++ if (atomic_read(&vha->vref_count)) { ++ ql_dbg(ql_dbg_vport, vha, 0xfffa, ++ "vha->vref_count=%u timeout\n", vha->vref_count.counter); ++ vha->vref_count = (atomic_t)ATOMIC_INIT(0); + } + list_del(&vha->list); + qlt_update_vp_map(vha, RESET_VP_IDX); +@@ -269,6 +270,7 @@ qla2x00_alert_all_vps(struct rsp_que *rs + + spin_lock_irqsave(&ha->vport_slock, flags); + atomic_dec(&vha->vref_count); ++ wake_up(&vha->vref_waitq); + } + i++; + } +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -4215,6 +4215,7 @@ struct scsi_qla_host *qla2x00_create_hos + + spin_lock_init(&vha->work_lock); + spin_lock_init(&vha->cmd_list_lock); ++ init_waitqueue_head(&vha->vref_waitq); + + sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); + ql_dbg(ql_dbg_init, vha, 0x0041, diff --git a/queue-4.10/sched-rt-add-a-missing-rescheduling-point.patch b/queue-4.10/sched-rt-add-a-missing-rescheduling-point.patch new file mode 100644 index 00000000000..bd0aaf0fa64 --- /dev/null +++ b/queue-4.10/sched-rt-add-a-missing-rescheduling-point.patch @@ -0,0 +1,76 @@ +From 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 Mon Sep 17 00:00:00 2001 +From: Sebastian Andrzej Siewior +Date: Tue, 24 Jan 2017 15:40:06 +0100 +Subject: sched/rt: Add a missing rescheduling point + +From: Sebastian Andrzej Siewior + +commit 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 upstream. + +Since the change in commit: + + fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() / prio_changed_rt() to balance callbacks") + +... we don't reschedule a task under certain circumstances: + +Lets say task-A, SCHED_OTHER, is running on CPU0 (and it may run only on +CPU0) and holds a PI lock. This task is removed from the CPU because it +used up its time slice and another SCHED_OTHER task is running. Task-B on +CPU1 runs at RT priority and asks for the lock owned by task-A. This +results in a priority boost for task-A. Task-B goes to sleep until the +lock has been made available. Task-A is already runnable (but not active), +so it receives no wake up. + +The reality now is that task-A gets on the CPU once the scheduler decides +to remove the current task despite the fact that a high priority task is +enqueued and waiting. This may take a long time. + +The desired behaviour is that CPU0 immediately reschedules after the +priority boost which made task-A the task with the lowest priority. + +Suggested-by: Peter Zijlstra +Signed-off-by: Sebastian Andrzej Siewior +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Thomas Gleixner +Fixes: fd7a4bed1835 ("sched, rt: Convert switched_{from, to}_rt() prio_changed_rt() to balance callbacks") +Link: http://lkml.kernel.org/r/20170124144006.29821-1-bigeasy@linutronix.de +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sched/deadline.c | 3 +-- + kernel/sched/rt.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +--- a/kernel/sched/deadline.c ++++ b/kernel/sched/deadline.c +@@ -1729,12 +1729,11 @@ static void switched_to_dl(struct rq *rq + #ifdef CONFIG_SMP + if (tsk_nr_cpus_allowed(p) > 1 && rq->dl.overloaded) + queue_push_tasks(rq); +-#else ++#endif + if (dl_task(rq->curr)) + check_preempt_curr_dl(rq, p, 0); + else + resched_curr(rq); +-#endif + } + } + +--- a/kernel/sched/rt.c ++++ b/kernel/sched/rt.c +@@ -2198,10 +2198,9 @@ static void switched_to_rt(struct rq *rq + #ifdef CONFIG_SMP + if (tsk_nr_cpus_allowed(p) > 1 && rq->rt.overloaded) + queue_push_tasks(rq); +-#else ++#endif /* CONFIG_SMP */ + if (p->prio < rq->curr->prio) + resched_curr(rq); +-#endif /* CONFIG_SMP */ + } + } + diff --git a/queue-4.10/series b/queue-4.10/series index dc2f050f0ff..818895bb97d 100644 --- a/queue-4.10/series +++ b/queue-4.10/series @@ -12,3 +12,6 @@ sparc-ptrace-preserve-previous-registers-for-short-regset-write.patch metag-ptrace-preserve-previous-registers-for-short-regset-write.patch metag-ptrace-provide-default-txstatus-for-short-nt_prstatus.patch metag-ptrace-reject-partial-nt_metag_rpipe-writes.patch +qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch +sched-rt-add-a-missing-rescheduling-point.patch +usb-musb-fix-possible-spinlock-deadlock.patch diff --git a/queue-4.10/usb-musb-fix-possible-spinlock-deadlock.patch b/queue-4.10/usb-musb-fix-possible-spinlock-deadlock.patch new file mode 100644 index 00000000000..ce585af8dfd --- /dev/null +++ b/queue-4.10/usb-musb-fix-possible-spinlock-deadlock.patch @@ -0,0 +1,88 @@ +From bc1e2154542071e3cfe1734b143af9b8bdacf8bd Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Fri, 10 Mar 2017 14:43:37 -0600 +Subject: usb: musb: fix possible spinlock deadlock + +From: Bin Liu + +commit bc1e2154542071e3cfe1734b143af9b8bdacf8bd upstream. + +The DSPS glue calls del_timer_sync() in its musb_platform_disable() +implementation, which requires the caller to not hold a lock. But +musb_remove() calls musb_platform_disable() will musb->lock held. This +could causes spinlock deadlock. + +So change musb_remove() to call musb_platform_disable() without holds +musb->lock. This doesn't impact the musb_platform_disable implementation +in other glue drivers. + +root@am335x-evm:~# modprobe -r musb-dsps +[ 126.134879] musb-hdrc musb-hdrc.1: remove, state 1 +[ 126.140465] usb usb2: USB disconnect, device number 1 +[ 126.146178] usb 2-1: USB disconnect, device number 2 +[ 126.416985] musb-hdrc musb-hdrc.1: USB bus 2 deregistered +[ 126.423943] +[ 126.425525] ====================================================== +[ 126.431997] [ INFO: possible circular locking dependency detected ] +[ 126.438564] 4.11.0-rc1-00003-g1557f13bca04-dirty #77 Not tainted +[ 126.444852] ------------------------------------------------------- +[ 126.451414] modprobe/778 is trying to acquire lock: +[ 126.456523] (((&glue->timer))){+.-...}, at: [] del_timer_sync+0x0/0xd0 +[ 126.464403] +[ 126.464403] but task is already holding lock: +[ 126.470511] (&(&musb->lock)->rlock){-.-...}, at: [] musb_remove+0x50/0x1 +30 [musb_hdrc] +[ 126.479965] +[ 126.479965] which lock already depends on the new lock. +[ 126.479965] +[ 126.488531] +[ 126.488531] the existing dependency chain (in reverse order) is: +[ 126.496368] +[ 126.496368] -> #1 (&(&musb->lock)->rlock){-.-...}: +[ 126.502968] otg_timer+0x80/0xec [musb_dsps] +[ 126.507990] call_timer_fn+0xb4/0x390 +[ 126.512372] expire_timers+0xf0/0x1fc +[ 126.516754] run_timer_softirq+0x80/0x178 +[ 126.521511] __do_softirq+0xc4/0x554 +[ 126.525802] irq_exit+0xe8/0x158 +[ 126.529735] __handle_domain_irq+0x58/0xb8 +[ 126.534583] __irq_usr+0x54/0x80 +[ 126.538507] +[ 126.538507] -> #0 (((&glue->timer))){+.-...}: +[ 126.544636] del_timer_sync+0x40/0xd0 +[ 126.549066] musb_remove+0x6c/0x130 [musb_hdrc] +[ 126.554370] platform_drv_remove+0x24/0x3c +[ 126.559206] device_release_driver_internal+0x14c/0x1e0 +[ 126.565225] bus_remove_device+0xd8/0x108 +[ 126.569970] device_del+0x1e4/0x308 +[ 126.574170] platform_device_del+0x24/0x8c +[ 126.579006] platform_device_unregister+0xc/0x20 +[ 126.584394] dsps_remove+0x14/0x30 [musb_dsps] +[ 126.589595] platform_drv_remove+0x24/0x3c +[ 126.594432] device_release_driver_internal+0x14c/0x1e0 +[ 126.600450] driver_detach+0x38/0x6c +[ 126.604740] bus_remove_driver+0x4c/0xa0 +[ 126.609407] SyS_delete_module+0x11c/0x1e4 +[ 126.614252] __sys_trace_return+0x0/0x10 + +Fixes: ea2f35c01d5ea ("usb: musb: Fix sleeping function called from invalid context for hdrc glue") +Acked-by: Tony Lindgren +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -2497,8 +2497,8 @@ static int musb_remove(struct platform_d + pm_runtime_get_sync(musb->controller); + musb_host_cleanup(musb); + musb_gadget_cleanup(musb); +- spin_lock_irqsave(&musb->lock, flags); + musb_platform_disable(musb); ++ spin_lock_irqsave(&musb->lock, flags); + musb_generic_disable(musb); + spin_unlock_irqrestore(&musb->lock, flags); + musb_writeb(musb->mregs, MUSB_DEVCTL, 0);