Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758187Ab1FVPFh (ORCPT ); Wed, 22 Jun 2011 11:05:37 -0400 Received: from webbox687.server-home.net ([195.149.74.151]:41208 "EHLO webbox687.server-home.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758020Ab1FVPFf (ORCPT ); Wed, 22 Jun 2011 11:05:35 -0400 From: Alexander Stein To: Vinod Koul , Dan Williams Cc: linux-kernel@vger.kernel.org, Tomoya MORINAGA , Alexander Stein Subject: [PATCH] pch_dma: Fix channel locking Date: Wed, 22 Jun 2011 17:05:33 +0200 Message-Id: <1308755133-8605-1-git-send-email-alexander.stein@systec-electronic.com> X-Mailer: git-send-email 1.7.3.4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5994 Lines: 162 Fix for the following INFO message ================================= [ INFO: inconsistent lock state ] 2.6.39+ #89 --------------------------------- inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. rs232/822 [HC1[1]:SC0[0]:HE0:SE1] takes: (&(&pd_chan->lock)->rlock){?.....}, at: [] pdc_desc_get+0x16/0xab {HARDIRQ-ON-W} state was registered at: [] mark_irqflags+0xbd/0x11a [] __lock_acquire+0x501/0x6bb [] lock_acquire+0x63/0x7b [] _raw_spin_lock_bh+0x43/0x51 [] pd_alloc_chan_resources+0x92/0x11e [] dma_chan_get+0x9b/0x107 [] __dma_request_channel+0x61/0xdc [] pch_request_dma+0x61/0x19e [] pch_uart_startup+0x16a/0x1a2 [] uart_startup+0x87/0x147 [] uart_open+0x117/0x13e [] tty_open+0x23c/0x34c [] chrdev_open+0x140/0x15f [] __dentry_open.clone.14+0x14a/0x22b [] nameidata_to_filp+0x36/0x40 [] do_last+0x513/0x635 [] path_openat+0x9c/0x2aa [] do_filp_open+0x27/0x69 [] do_sys_open+0xfd/0x184 [] sys_open+0x24/0x2a [] sysenter_do_call+0x12/0x32 irq event stamp: 2522 hardirqs last enabled at (2521): [] _raw_spin_unlock_irqrestore+0x36/0x52 hardirqs last disabled at (2522): [] common_interrupt+0x27/0x34 softirqs last enabled at (2354): [] __do_softirq+0x10a/0x11a softirqs last disabled at (2299): [] do_softirq+0x57/0xa4 other info that might help us debug this: 2 locks held by rs232/822: #0: (&tty->atomic_write_lock){+.+.+.}, at: [] tty_write_lock+0x14/0x3c #1: (&port_lock_key){-.....}, at: [] pch_uart_interrupt+0x17/0x1e9 stack backtrace: Pid: 822, comm: rs232 Not tainted 2.6.39+ #89 Call Trace: [] ? printk+0x19/0x1b [] print_usage_bug+0x184/0x18f [] ? print_irq_inversion_bug+0x10e/0x10e [] mark_lock_irq+0xa5/0x1f6 [] mark_lock+0x208/0x2d7 [] mark_irqflags+0x55/0x11a [] __lock_acquire+0x501/0x6bb [] ? dump_trace+0x92/0xb6 [] lock_acquire+0x63/0x7b [] ? pdc_desc_get+0x16/0xab [] _raw_spin_lock+0x3e/0x4c [] ? pdc_desc_get+0x16/0xab [] pdc_desc_get+0x16/0xab [] ? __lock_acquire+0x653/0x6bb [] pd_prep_slave_sg+0x7c/0x1cb [] ? nommu_map_sg+0x6e/0x81 [] dma_handle_tx+0x2cf/0x344 [] ? pch_uart_interrupt+0x17/0x1e9 [] pch_uart_interrupt+0x160/0x1e9 [] handle_irq_event_percpu+0x25/0x127 [] handle_irq_event+0x2c/0x43 [] ? handle_fasteoi_irq+0x84/0x84 [] handle_edge_irq+0xac/0xce [] ? do_IRQ+0x38/0x9d [] ? common_interrupt+0x2e/0x34 [] ? __lock_acquire+0x1f6/0x6bb [] ? _raw_spin_unlock_irqrestore+0x38/0x52 [] ? uart_start+0x2d/0x32 [] ? uart_flush_chars+0x8/0xa [] ? n_tty_write+0x12c/0x1c6 [] ? try_to_wake_up+0x251/0x251 [] ? tty_write+0x169/0x1dc [] ? n_tty_ioctl+0xb7/0xb7 [] ? vfs_write+0x91/0x10d [] ? tty_write_lock+0x3c/0x3c [] ? sys_write+0x3e/0x63 [] ? sysenter_do_call+0x12/0x32 Signed-off-by: Alexander Stein --- I'm not exactly sure if the dmaengine functions are allowed to be called from IRQ context. But I found amba-pl011 which also calls device_prep_slave_sg from IRQ context. drivers/dma/pch_dma.c | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index ff5b38f..bfb0f19 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -495,11 +495,11 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) list_add_tail(&desc->desc_node, &tmp_list); } - spin_lock_bh(&pd_chan->lock); + spin_lock_irq(&pd_chan->lock); list_splice(&tmp_list, &pd_chan->free_list); pd_chan->descs_allocated = i; pd_chan->completed_cookie = chan->cookie = 1; - spin_unlock_bh(&pd_chan->lock); + spin_unlock_irq(&pd_chan->lock); pdc_enable_irq(chan, 1); @@ -517,10 +517,10 @@ static void pd_free_chan_resources(struct dma_chan *chan) BUG_ON(!list_empty(&pd_chan->active_list)); BUG_ON(!list_empty(&pd_chan->queue)); - spin_lock_bh(&pd_chan->lock); + spin_lock_irq(&pd_chan->lock); list_splice_init(&pd_chan->free_list, &tmp_list); pd_chan->descs_allocated = 0; - spin_unlock_bh(&pd_chan->lock); + spin_unlock_irq(&pd_chan->lock); list_for_each_entry_safe(desc, _d, &tmp_list, desc_node) pci_pool_free(pd->pool, desc, desc->txd.phys); @@ -536,10 +536,10 @@ static enum dma_status pd_tx_status(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t last_completed; int ret; - spin_lock_bh(&pd_chan->lock); + spin_lock_irq(&pd_chan->lock); last_completed = pd_chan->completed_cookie; last_used = chan->cookie; - spin_unlock_bh(&pd_chan->lock); + spin_unlock_irq(&pd_chan->lock); ret = dma_async_is_complete(cookie, last_completed, last_used); @@ -654,7 +654,7 @@ static int pd_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, if (cmd != DMA_TERMINATE_ALL) return -ENXIO; - spin_lock_bh(&pd_chan->lock); + spin_lock_irq(&pd_chan->lock); pdc_set_mode(&pd_chan->chan, DMA_CTL0_DISABLE); @@ -664,7 +664,7 @@ static int pd_device_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, list_for_each_entry_safe(desc, _d, &list, desc_node) pdc_chain_complete(pd_chan, desc); - spin_unlock_bh(&pd_chan->lock); + spin_unlock_irq(&pd_chan->lock); return 0; } -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/