]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Mar 2017 08:40:17 +0000 (10:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Mar 2017 08:40:17 +0000 (10:40 +0200)
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

queue-4.10/qla2xxx-allow-vref-count-to-timeout-on-vport-delete.patch [new file with mode: 0644]
queue-4.10/sched-rt-add-a-missing-rescheduling-point.patch [new file with mode: 0644]
queue-4.10/series
queue-4.10/usb-musb-fix-possible-spinlock-deadlock.patch [new file with mode: 0644]

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 (file)
index 0000000..33063f0
--- /dev/null
@@ -0,0 +1,122 @@
+From c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 Mon Sep 17 00:00:00 2001
+From: Joe Carnuccio <joe.carnuccio@cavium.com>
+Date: Wed, 15 Mar 2017 09:48:43 -0700
+Subject: qla2xxx: Allow vref count to timeout on vport delete.
+
+From: Joe Carnuccio <joe.carnuccio@cavium.com>
+
+commit c4a9b538ab2a109c5f9798bea1f8f4bf93aadfb9 upstream.
+
+Signed-off-by: Joe Carnuccio <joe.carnuccio@cavium.com>
+Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..bd0aaf0
--- /dev/null
@@ -0,0 +1,76 @@
+From 619bd4a71874a8fd78eb6ccf9f272c5e98bcc7b7 Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Tue, 24 Jan 2017 15:40:06 +0100
+Subject: sched/rt: Add a missing rescheduling point
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+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 <peterz@infradead.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+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 <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 */
+       }
+ }
index dc2f050f0ffb9917d7017e5468266a0de77d716a..818895bb97ddeb02399148f20f60f73481d5b3e9 100644 (file)
@@ -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 (file)
index 0000000..ce585af
--- /dev/null
@@ -0,0 +1,88 @@
+From bc1e2154542071e3cfe1734b143af9b8bdacf8bd Mon Sep 17 00:00:00 2001
+From: Bin Liu <b-liu@ti.com>
+Date: Fri, 10 Mar 2017 14:43:37 -0600
+Subject: usb: musb: fix possible spinlock deadlock
+
+From: Bin Liu <b-liu@ti.com>
+
+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: [<c01b8788>] del_timer_sync+0x0/0xd0
+[  126.464403]
+[  126.464403] but task is already holding lock:
+[  126.470511]  (&(&musb->lock)->rlock){-.-...}, at: [<bf30b7f8>] 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 <tony@atomide.com>
+Signed-off-by: Bin Liu <b-liu@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);