From: alexander.levin@verizon.com
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"stable@vger.kernel.org" <stable@vger.kernel.org>
Cc: Iago Abal <mail@iagoabal.eu>, Vinod Koul <vinod.koul@intel.com>,
alexander.levin@verizon.com
Subject: [PATCH AUTOSEL for 4.9 40/54] dmaengine: pl330: fix double lock
Date: Wed, 22 Nov 2017 22:24:01 +0000 [thread overview]
Message-ID: <20171122222344.19782-40-alexander.levin@verizon.com> (raw)
In-Reply-To: <20171122222344.19782-1-alexander.levin@verizon.com>
From: Iago Abal <mail@iagoabal.eu>
[ Upstream commit 91539eb1fda2d530d3b268eef542c5414e54bf1a ]
The static bug finder EBA (http://www.iagoabal.eu/eba/) reported the
following double-lock bug:
Double lock:
1. spin_lock_irqsave(pch->lock, flags) at pl330_free_chan_resources:2236;
2. call to function `pl330_release_channel' immediately after;
3. call to function `dma_pl330_rqcb' in line 1753;
4. spin_lock_irqsave(pch->lock, flags) at dma_pl330_rqcb:1505.
I have fixed it as suggested by Marek Szyprowski.
First, I have replaced `pch->lock' with `pl330->lock' in functions
`pl330_alloc_chan_resources' and `pl330_free_chan_resources'. This avoids
the double-lock by acquiring a different lock than `dma_pl330_rqcb'.
NOTE that, as a result, `pl330_free_chan_resources' executes
`list_splice_tail_init' on `pch->work_list' under lock `pl330->lock',
whereas in the rest of the code `pch->work_list' is protected by
`pch->lock'. I don't know if this may cause race conditions. Similarly
`pch->cyclic' is written by `pl330_alloc_chan_resources' under
`pl330->lock' but read by `pl330_tx_submit' under `pch->lock'.
Second, I have removed locking from `pl330_request_channel' and
`pl330_release_channel' functions. Function `pl330_request_channel' is
only called from `pl330_alloc_chan_resources', so the lock is already
held. Function `pl330_release_channel' is called from
`pl330_free_chan_resources', which already holds the lock, and from
`pl330_del'. Function `pl330_del' is called in an error path of
`pl330_probe' and at the end of `pl330_remove', but I assume that there
cannot be concurrent accesses to the protected data at those points.
Signed-off-by: Iago Abal <mail@iagoabal.eu>
Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
---
drivers/dma/pl330.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 9f3dbc8c63d2..fb2e7476d96b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -1694,7 +1694,6 @@ static bool _chan_ns(const struct pl330_dmac *pl330, int i)
static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
{
struct pl330_thread *thrd = NULL;
- unsigned long flags;
int chans, i;
if (pl330->state == DYING)
@@ -1702,8 +1701,6 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
chans = pl330->pcfg.num_chan;
- spin_lock_irqsave(&pl330->lock, flags);
-
for (i = 0; i < chans; i++) {
thrd = &pl330->channels[i];
if ((thrd->free) && (!_manager_ns(thrd) ||
@@ -1721,8 +1718,6 @@ static struct pl330_thread *pl330_request_channel(struct pl330_dmac *pl330)
thrd = NULL;
}
- spin_unlock_irqrestore(&pl330->lock, flags);
-
return thrd;
}
@@ -1740,7 +1735,6 @@ static inline void _free_event(struct pl330_thread *thrd, int ev)
static void pl330_release_channel(struct pl330_thread *thrd)
{
struct pl330_dmac *pl330;
- unsigned long flags;
if (!thrd || thrd->free)
return;
@@ -1752,10 +1746,8 @@ static void pl330_release_channel(struct pl330_thread *thrd)
pl330 = thrd->dmac;
- spin_lock_irqsave(&pl330->lock, flags);
_free_event(thrd, thrd->ev);
thrd->free = true;
- spin_unlock_irqrestore(&pl330->lock, flags);
}
/* Initialize the structure for PL330 configuration, that can be used
@@ -2120,20 +2112,20 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan)
struct pl330_dmac *pl330 = pch->dmac;
unsigned long flags;
- spin_lock_irqsave(&pch->lock, flags);
+ spin_lock_irqsave(&pl330->lock, flags);
dma_cookie_init(chan);
pch->cyclic = false;
pch->thread = pl330_request_channel(pl330);
if (!pch->thread) {
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
return -ENOMEM;
}
tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch);
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
return 1;
}
@@ -2236,12 +2228,13 @@ static int pl330_pause(struct dma_chan *chan)
static void pl330_free_chan_resources(struct dma_chan *chan)
{
struct dma_pl330_chan *pch = to_pchan(chan);
+ struct pl330_dmac *pl330 = pch->dmac;
unsigned long flags;
tasklet_kill(&pch->task);
pm_runtime_get_sync(pch->dmac->ddma.dev);
- spin_lock_irqsave(&pch->lock, flags);
+ spin_lock_irqsave(&pl330->lock, flags);
pl330_release_channel(pch->thread);
pch->thread = NULL;
@@ -2249,7 +2242,7 @@ static void pl330_free_chan_resources(struct dma_chan *chan)
if (pch->cyclic)
list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
- spin_unlock_irqrestore(&pch->lock, flags);
+ spin_unlock_irqrestore(&pl330->lock, flags);
pm_runtime_mark_last_busy(pch->dmac->ddma.dev);
pm_runtime_put_autosuspend(pch->dmac->ddma.dev);
}
--
2.11.0
next prev parent reply other threads:[~2017-11-22 22:26 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-22 22:23 [PATCH AUTOSEL for 4.9 01/54] dax: Avoid page invalidation races and unnecessary radix tree traversals alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 03/54] l2tp: take remote address into account in l2tp_ip and l2tp_ip6 socket lookups alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 04/54] dmaengine: stm32-dma: Set correct args number for DMA request from DT alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 02/54] net/mlx4_en: Fix type mismatch for 32-bit systems alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 06/54] usb: gadget: f_fs: Fix ExtCompat descriptor validation alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 08/54] net: systemport: Utilize skb_put_padto() alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 07/54] libcxgb: fix error check for ip6_route_output() alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 05/54] dmaengine: stm32-dma: Fix null pointer dereference in stm32_dma_tx_status alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 13/54] be2net: fix accesses to unicast list alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 09/54] net: systemport: Pad packet before inserting TSB alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 11/54] ARM: OMAP1: DMA: Correct the number of logical channels alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 10/54] ARM: OMAP2+: Fix WL1283 Bluetooth Baud Rate alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 12/54] vti6: fix device register to report IFLA_INFO_KIND alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 15/54] net/appletalk: Fix kernel memory disclosure alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 14/54] be2net: fix unicast list filling alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 19/54] mac80211: calculate min channel width correctly alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 16/54] libfs: Modify mount_pseudo_xattr to be clear it is not a userspace mount alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 17/54] net: qrtr: Mark 'buf' as little endian alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 18/54] mm: fix remote numa hits statistics alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 21/54] nfs: Don't take a reference on fl->fl_file for LOCK operation alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 22/54] drm/exynos/decon5433: update shadow registers iff there are active windows alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 23/54] drm/exynos/decon5433: set STANDALONE_UPDATE_F also if planes are disabled alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 20/54] ravb: Remove Rx overflow log messages alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 24/54] KVM: arm/arm64: Fix occasional warning from the timer work function alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 26/54] NFSv4: Fix client recovery when server reboots multiple times alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 27/54] perf/x86/intel: Account interrupts for PEBS errors alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 25/54] mac80211: prevent skb/txq mismatch alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 31/54] drm/exynos/decon5433: set STANDALONE_UPDATE_F on output enablement alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 29/54] qla2xxx: Fix wrong IOCB type assumption alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 28/54] powerpc/mm: Fix memory hotplug BUG() on radix alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 30/54] drm/amdgpu: fix bug set incorrect value to vce register alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 32/54] net: sctp: fix array overrun read on sctp_timer_tbl alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 34/54] drm/amdgpu: fix unload driver issue for virtual display alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 33/54] x86/fpu: Set the xcomp_bv when we fake up a XSAVES area alexander.levin
2017-11-22 22:23 ` [PATCH AUTOSEL for 4.9 35/54] mac80211: don't try to sleep in rate_control_rate_init() alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 38/54] tipc: fix nametbl_lock soft lockup at module exit alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 37/54] RDMA/qedr: Fix RDMA CM loopback alexander.levin
2017-11-23 6:11 ` Amrani, Ram
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 36/54] RDMA/qedr: Return success when not changing QP state alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 39/54] tipc: fix cleanup at module unload alexander.levin
2017-11-22 22:24 ` alexander.levin [this message]
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 41/54] tcp: correct memory barrier usage in tcp_check_space() alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 44/54] gtp: clear DF bit on GTP packet tx alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 42/54] i2c: i2c-cadence: Initialize configuration before probing devices alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 43/54] nvmet: cancel fatal error and flush async work before free controller alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 48/54] be2net: fix initial MAC setting alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 45/54] gtp: fix cross netns recv on gtp socket alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 47/54] net: thunderx: avoid dereferencing xcv when NULL alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 46/54] net: phy: micrel: KSZ8795 do not set SUPPORTED_[Asym_]Pause alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 50/54] mm: avoid returning VM_FAULT_RETRY from ->page_mkwrite handlers alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 49/54] vfio/spapr: Fix missing mutex unlock when creating a window alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 52/54] [media] cec: initiator should be the same as the destination for, poll alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 51/54] xen-netfront: Improve error handling during initialization alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 53/54] xen-netback: vif counters from int/long to u64 alexander.levin
2017-11-22 22:24 ` [PATCH AUTOSEL for 4.9 54/54] net: fec: fix multicast filtering hardware setup alexander.levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171122222344.19782-40-alexander.levin@verizon.com \
--to=alexander.levin@verizon.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mail@iagoabal.eu \
--cc=stable@vger.kernel.org \
--cc=vinod.koul@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®