[dahdi-commits] dahdi/linux.git branch "master" updated.

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Tue Jun 10 11:33:56 CDT 2014


branch "master" has been updated
       via  cb50ae150040465faa5e6e57e32ba8d8b6de3947 (commit)
       via  e9ec13dfa02cb424b0b85aae418bb813b98daf49 (commit)
      from  dfa8a0ebd329e1128786a637321804513e11803a (commit)

Summary of changes:
 drivers/dahdi/wctc4xxp/base.c |   88 +++++++++++++++++++++--------------------
 1 file changed, 45 insertions(+), 43 deletions(-)


- Log -----------------------------------------------------------------
commit cb50ae150040465faa5e6e57e32ba8d8b6de3947
Author: Shaun Ruffell <sruffell at digium.com>
Date:   Tue Jun 10 11:06:15 2014 -0500

    wctc4xxp: spin_lock() -> spin_lock_irqsave() in wctc4xxp_watchdog()
    
    Since commit (e10f740 "wctc4xxp: Service tx ring in interrupt handler."), it
    was possible to deadlock the system if the interrupt fires while the
    watchdog function is running in the context of the system timer.
    
    This was reported by lockdep.
    
    Signed-off-by: Shaun Ruffell <sruffell at digium.com>
    Signed-off-by: Russ Meyerriecks <rmeyerriecks at digium.com>

diff --git a/drivers/dahdi/wctc4xxp/base.c b/drivers/dahdi/wctc4xxp/base.c
index 77605cb..e04609e 100644
--- a/drivers/dahdi/wctc4xxp/base.c
+++ b/drivers/dahdi/wctc4xxp/base.c
@@ -3693,10 +3693,11 @@ wctc4xxp_watchdog(unsigned long data)
 	LIST_HEAD(cmds_to_retry);
 	const int MAX_RETRIES = 5;
 	int reschedule_timer = 0;
+	unsigned long flags;
 
 	service_tx_ring(wc);
 
-	spin_lock(&wc->cmd_list_lock);
+	spin_lock_irqsave(&wc->cmd_list_lock, flags);
 	/* Go through the list of messages that are waiting for responses from
 	 * the DTE, and complete or retry any that have timed out. */
 	list_for_each_entry_safe(cmd, temp,
@@ -3715,12 +3716,13 @@ wctc4xxp_watchdog(unsigned long data)
 
 				wctc4xxp_reset_processor(wc);
 				set_bit(DTE_SHUTDOWN, &wc->flags);
-				spin_unlock(&wc->cmd_list_lock);
+				spin_unlock_irqrestore(&wc->cmd_list_lock,
+						       flags);
 				_wctc4xxp_stop_dma(wc);
 				dev_err(&wc->pdev->dev,
 				  "Board malfunctioning. Halting operation.\n");
 				reschedule_timer = 0;
-				spin_lock(&wc->cmd_list_lock);
+				spin_lock_irqsave(&wc->cmd_list_lock, flags);
 				break;
 			}
 			/* ERROR:  We've retried the command and
@@ -3749,7 +3751,7 @@ wctc4xxp_watchdog(unsigned long data)
 			reschedule_timer = 1;
 		}
 	}
-	spin_unlock(&wc->cmd_list_lock);
+	spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
 
 	if (list_empty(&cmds_to_retry) && reschedule_timer)
 		mod_timer(&wc->watchdog, jiffies + HZ/2);

commit e9ec13dfa02cb424b0b85aae418bb813b98daf49
Author: Shaun Ruffell <sruffell at digium.com>
Date:   Tue Jun 10 11:03:34 2014 -0500

    wctc4xxp: Trivial reduction of indentation level in wctc4xxp_watchdog()
    
    Now use a continue after the check for cmd->timeout. This change is because I
    need to make another change but the deep indentation level would make it hard to
    stay within the 80 column limit.
    
    Signed-off-by: Shaun Ruffell <sruffell at digium.com>
    Signed-off-by: Russ Meyerriecks <rmeyerriecks at digium.com>

diff --git a/drivers/dahdi/wctc4xxp/base.c b/drivers/dahdi/wctc4xxp/base.c
index 24f8646..77605cb 100644
--- a/drivers/dahdi/wctc4xxp/base.c
+++ b/drivers/dahdi/wctc4xxp/base.c
@@ -3701,52 +3701,52 @@ wctc4xxp_watchdog(unsigned long data)
 	 * the DTE, and complete or retry any that have timed out. */
 	list_for_each_entry_safe(cmd, temp,
 		&wc->waiting_for_response_list, node) {
-		if (time_after(jiffies, cmd->timeout)) {
-			if (++cmd->retries > MAX_RETRIES) {
-				if (!(cmd->flags & TX_COMPLETE)) {
-
-					cmd->flags |= DTE_CMD_TIMEOUT;
-					list_del_init(&cmd->node);
-					if (cmd->complete)
-						complete(cmd->complete);
-
-					wctc4xxp_reset_processor(wc);
-					set_bit(DTE_SHUTDOWN, &wc->flags);
-					spin_unlock(&wc->cmd_list_lock);
-					_wctc4xxp_stop_dma(wc);
-					dev_err(&wc->pdev->dev,
-					  "Board malfunctioning.  " \
-					  "Halting operation.\n");
-					reschedule_timer = 0;
-					spin_lock(&wc->cmd_list_lock);
-					break;
-				}
-				/* ERROR:  We've retried the command and
-				 * haven't received the ACK or the response.
-				 */
+
+		if (!time_after(jiffies, cmd->timeout))
+			continue;
+
+		if (++cmd->retries > MAX_RETRIES) {
+			if (!(cmd->flags & TX_COMPLETE)) {
+
 				cmd->flags |= DTE_CMD_TIMEOUT;
 				list_del_init(&cmd->node);
 				if (cmd->complete)
 					complete(cmd->complete);
-			} else if (cmd->flags & TX_COMPLETE) {
-				/* Move this to the local list because we're
-				 * going to resend it once we free the locks
-				 */
-				list_move_tail(&cmd->node, &cmds_to_retry);
-				cmd->flags &= ~(TX_COMPLETE);
-			} else {
-				/* The command is still sitting on the tx
-				 * descriptor ring.  We don't want to move it
-				 * off any lists, lets just reset the timeout
-				 * and tell the hardware to look for another
-				 * command . */
-				dev_warn(&wc->pdev->dev,
-				  "Retrying command that was " \
-				  "still on descriptor list.\n");
-				cmd->timeout = jiffies + HZ/4;
-				wctc4xxp_transmit_demand_poll(wc);
-				reschedule_timer = 1;
+
+				wctc4xxp_reset_processor(wc);
+				set_bit(DTE_SHUTDOWN, &wc->flags);
+				spin_unlock(&wc->cmd_list_lock);
+				_wctc4xxp_stop_dma(wc);
+				dev_err(&wc->pdev->dev,
+				  "Board malfunctioning. Halting operation.\n");
+				reschedule_timer = 0;
+				spin_lock(&wc->cmd_list_lock);
+				break;
 			}
+			/* ERROR:  We've retried the command and
+			 * haven't received the ACK or the response.
+			 */
+			cmd->flags |= DTE_CMD_TIMEOUT;
+			list_del_init(&cmd->node);
+			if (cmd->complete)
+				complete(cmd->complete);
+		} else if (cmd->flags & TX_COMPLETE) {
+			/* Move this to the local list because we're
+			 * going to resend it once we free the locks
+			 */
+			list_move_tail(&cmd->node, &cmds_to_retry);
+			cmd->flags &= ~(TX_COMPLETE);
+		} else {
+			/* The command is still sitting on the tx
+			 * descriptor ring.  We don't want to move it
+			 * off any lists, lets just reset the timeout
+			 * and tell the hardware to look for another
+			 * command . */
+			dev_warn(&wc->pdev->dev,
+			  "Retrying command that was still on descriptor list.\n");
+			cmd->timeout = jiffies + HZ/4;
+			wctc4xxp_transmit_demand_poll(wc);
+			reschedule_timer = 1;
 		}
 	}
 	spin_unlock(&wc->cmd_list_lock);

-----------------------------------------------------------------------


-- 
dahdi/linux.git



More information about the dahdi-commits mailing list