Patch "xhci: Use delayed_work instead of timer for command timeout" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
xhci: Use delayed_work instead of timer for command timeout
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
cb4d5ce588c5ff68e0fdd30370a0e6bc2c0a736bMon Sep 17 00:00:00 2001
From: OGAWA Hirofumi <[email protected]>
Date: Tue, 3 Jan 2017 18:28:50 +0200
Subject: xhci: Use delayed_work instead of timer for command timeout
From: OGAWA Hirofumi <[email protected]>
commit cb4d5ce588c5ff68e0fdd30370a0e6bc2c0a736b upstream.
This is preparation to fix abort operation race (See "xhci: Fix race related to abort operation"). To make timeout sleepable, use delayed_work instead of timer.
--- drivers/usb/host/xhci-mem.c | 7 +++---- drivers/usb/host/xhci-ring.c | 26 ++++++++++++++++---------- drivers/usb/host/xhci.h | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-)
drivers/usb/host/xhci-mem.c +3 -4
@@ -1829,7 +1829,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xint size;int i, j, num_ports; -del_timer_sync (&xhci->cmd_timer); +cancel_delayed_work_sync (&xhci->cmd_timer);/* Free the Event Ring Segment Table and the actual Event Ring */ size =sizeof (struct xhci_erst_entry )*(xhci->erst.num_entries);
@@ -2395,9 +2395,8 @@ int xhci_mem_init(struct xhci_hcd *xhci,INIT_LIST_HEAD (&xhci->cmd_list); -/* init command timeout timer */ -setup_timer (&xhci->cmd_timer, xhci_handle_command_timeout, - (unsigned long )xhci); +/* init command timeout work */ +INIT_DELAYED_WORK (&xhci->cmd_timer, xhci_handle_command_timeout); page_size =readl (&xhci->op_regs->page_size); xhci_dbg_trace(xhci, trace_xhci_dbg_init,
drivers/usb/host/xhci-ring.c +16 -10
@@ -280,6 +280,11 @@ void xhci_ring_cmd_db(struct xhci_hcd *xreadl (&xhci->dba->doorbell[0 ]); } +static bool xhci_mod_cmd_timer (struct xhci_hcd *xhci,unsigned long delay) +{ +return mod_delayed_work (system_wq, &xhci->cmd_timer, delay); +} +static int xhci_abort_cmd_ring (struct xhci_hcd *xhci) {u64 temp_64;
@@ -296,7 +301,7 @@ static int xhci_abort_cmd_ring(struct xh* but the completion event in never sent. Use the cmd timeout timer to * handle those cases. Use twice the time to cover the bit polling retry */ -mod_timer (&xhci->cmd_timer, jiffies + (2 *XHCI_CMD_DEFAULT_TIMEOUT )); +xhci_mod_cmd_timer (xhci,2 *XHCI_CMD_DEFAULT_TIMEOUT );xhci_write_64 (xhci, temp_64 |CMD_RING_ABORT , &xhci->op_regs->cmd_ring);
@@ -321,7 +326,7 @@ static int xhci_abort_cmd_ring(struct xhxhci_err (xhci,"Stopped the command ring failed, " "maybe the host is dead\n" ); -del_timer (&xhci->cmd_timer); +cancel_delayed_work (&xhci->cmd_timer); xhci->xhc_state |=XHCI_STATE_DYING ;xhci_quiesce (xhci);xhci_halt (xhci);
@@ -1252,21 +1257,22 @@ static void xhci_handle_stopped_cmd_ringif ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && !(xhci->xhc_state &XHCI_STATE_DYING )) { xhci->current_cmd = cur_cmd; -mod_timer (&xhci->cmd_timer, jiffies +XHCI_CMD_DEFAULT_TIMEOUT ); +xhci_mod_cmd_timer (xhci,XHCI_CMD_DEFAULT_TIMEOUT );xhci_ring_cmd_db (xhci); }return ; } -void xhci_handle_command_timeout (unsigned long data) +void xhci_handle_command_timeout (struct work_struct *work) {struct xhci_hcd *xhci;int ret;unsigned long flags;u64 hw_ring_state;bool second_timeout = false; - xhci = (struct xhci_hcd *) data; + + xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer);spin_lock_irqsave (&xhci->lock, flags);
@@ -1274,7 +1280,7 @@ void xhci_handle_command_timeout(unsigne* If timeout work is pending, or current_cmd is NULL, it means we * raced with command completion. Command is handled so just return. */ -if (!xhci->current_cmd ||timer_pending (&xhci->cmd_timer)) { +if (!xhci->current_cmd ||delayed_work_pending (&xhci->cmd_timer)) {spin_unlock_irqrestore (&xhci->lock, flags);return ; }
@@ -1348,7 +1354,7 @@ static void handle_cmd_completion(struct cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); -del_timer (&xhci->cmd_timer); +cancel_delayed_work (&xhci->cmd_timer);trace_xhci_cmd_completion (cmd_trb, (struct xhci_generic_trb *) event);
@@ -1439,7 +1445,7 @@ static void handle_cmd_completion(structif (cmd->cmd_list.next != &xhci->cmd_list) { xhci->current_cmd =list_entry (cmd->cmd_list.next, struct xhci_command, cmd_list); -mod_timer (&xhci->cmd_timer, jiffies +XHCI_CMD_DEFAULT_TIMEOUT ); +xhci_mod_cmd_timer (xhci,XHCI_CMD_DEFAULT_TIMEOUT ); }else if (xhci->current_cmd == cmd) { xhci->current_cmd =NULL ; }
@@ -4074,9 +4080,9 @@ static int queue_command(struct xhci_hcd/* if there are no other commands queued we start the timeout timer */ if (xhci->cmd_list.next == &cmd->cmd_list && - !timer_pending (&xhci->cmd_timer)) { + !delayed_work_pending (&xhci->cmd_timer)) { xhci->current_cmd = cmd; -mod_timer (&xhci->cmd_timer, jiffies +XHCI_CMD_DEFAULT_TIMEOUT ); +xhci_mod_cmd_timer (xhci,XHCI_CMD_DEFAULT_TIMEOUT ); } queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
drivers/usb/host/xhci.h +2 -2
@@ -1552,7 +1552,7 @@ struct xhci_hcd {#define CMD_RING_STATE_STOPPED (1 << 2)struct list_head cmd_list;unsigned int cmd_ring_reserved_trbs; -struct timer_list cmd_timer; +struct delayed_work cmd_timer;struct xhci_command *current_cmd;struct xhci_ring *event_ring;struct xhci_erst erst;
@@ -1915,7 +1915,7 @@ void xhci_queue_config_ep_quirk(struct x unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state);void xhci_stop_endpoint_command_watchdog (unsigned long arg); -void xhci_handle_command_timeout (unsigned long data); +void xhci_handle_command_timeout (struct work_struct *work);void xhci_ring_ep_doorbell (struct xhci_hcd *xhci,unsigned int slot_id,unsigned int ep_index,unsigned int stream_id);
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/xhci-use-delayed_work-instead-of-timer-for-command-timeout.patch queue-4.4/xhci-fix-race-related-to-abort-operation.patch