All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jie Hai <haijie1@huawei.com>
To: <vkoul@kernel.org>
Cc: <dmaengine@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<liudongdong3@huawei.com>, <wangzhou1@hisilicon.com>
Subject: [PATCH] dmaengine: Fix refcount increasing in dma_chan_get
Date: Sat, 16 Jul 2022 10:44:53 +0800	[thread overview]
Message-ID: <20220716024453.1418259-1-haijie1@huawei.com> (raw)

When both hisi_dma.ko and async_tx.ko are loaded, you must first remove
async_tx if you want to remove hisi_dma. We expect to remove hisi_dma
successfully after doing so. In fact, hisi_dma is still referenced and
cannot be removed.

Module async_tx.ko references DMAEngine by dmaegnine_get(), which is
recorded by dmaengine_ref_count and it is the only module in the
current kernel that references dmaengine in this way. When the DMA
driver is loaded, the reference is reflected in the reference counts
of the driver and of the channels.

Load hisi_dma.ko and async_tx.ko in sequence, the reference count of
each DMA channel changes from zero to two. If only async_tx.ko is
unloaded, the reference count of each channel should be reduced to zero
again. However, that of each channel is still one without actually being
used.

The reference count of each channel is adjusted to dmaengine_ref_count
and then increased by one in dma_chan_get. This is the reason why the
reference count is greater than the actual reference by one.

This patch swaps the reference counting updating sequence. The
reference counting of each channel increases by one, and then adjusts.

Fixes: d2f4f99db3e9 ("dmaengine: Rework dma_chan_get")
Signed-off-by: Jie Hai <haijie1@huawei.com>
---
 drivers/dma/dmaengine.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 2cfa8458b51b..78f8a9f3ad82 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -451,7 +451,8 @@ static int dma_chan_get(struct dma_chan *chan)
 	/* The channel is already in use, update client count */
 	if (chan->client_count) {
 		__module_get(owner);
-		goto out;
+		chan->client_count++;
+		return 0;
 	}
 
 	if (!try_module_get(owner))
@@ -470,11 +471,11 @@ static int dma_chan_get(struct dma_chan *chan)
 			goto err_out;
 	}
 
+	chan->client_count++;
+
 	if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
 		balance_ref_count(chan);
 
-out:
-	chan->client_count++;
 	return 0;
 
 err_out:
-- 
2.30.0


                 reply	other threads:[~2022-07-16  2:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=20220716024453.1418259-1-haijie1@huawei.com \
    --to=haijie1@huawei.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liudongdong3@huawei.com \
    --cc=vkoul@kernel.org \
    --cc=wangzhou1@hisilicon.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.