linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiang Liu <liuj97@gmail.com>
To: Vinod Koul <vinod.koul@intel.com>,
	Dan Williams <dan.j.williams@intel.com>
Cc: Jiang Liu <jiang.liu@huawei.com>,
	Keping Chen <chenkeping@huawei.com>,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	Jiang Liu <liuj97@gmail.com>
Subject: [PATCH v1 4/8] dmaengine: use atomic_t for struct dma_chan->client_count field
Date: Mon, 23 Apr 2012 21:51:45 +0800	[thread overview]
Message-ID: <1335189109-4871-5-git-send-email-jiang.liu@huawei.com> (raw)
In-Reply-To: <1335189109-4871-1-git-send-email-jiang.liu@huawei.com>

Use atomic_t for struct dma_chan->client_count field to prepare for
DMA device hotplug.

Signed-off-by: Jiang Liu <liuj97@gmail.com>
---
 drivers/dma/dmaengine.c   |   41 ++++++++++++++++++++++++++---------------
 include/linux/dmaengine.h |    4 ++++
 2 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 198d891..da7a683 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -62,6 +62,18 @@
 #include <linux/idr.h>
 #include <linux/slab.h>
 
+#ifndef	CONFIG_DMA_ENGINE_HOTPLUG
+#define	dma_chan_ref_read(chan)		((chan)->client_count)
+#define	dma_chan_ref_set(chan, v)	((chan)->client_count = (v))
+#define	dma_chan_ref_inc(chan)		((chan)->client_count++)
+#define	dma_chan_ref_dec_and_test(ch)	(--(chan)->client_count == 0)
+#else	/* CONFIG_DMA_ENGINE_HOTPLUG */
+#define	dma_chan_ref_read(chan)		atomic_read(&(chan)->client_count)
+#define	dma_chan_ref_set(chan, v)	atomic_set(&(chan)->client_count, (v))
+#define	dma_chan_ref_inc(chan)		atomic_inc(&(chan)->client_count)
+#define	dma_chan_ref_dec_and_test(ch)	atomic_dec_and_test(&(ch)->client_count)
+#endif	/* CONFIG_DMA_ENGINE_HOTPLUG */
+
 static DEFINE_MUTEX(dma_list_mutex);
 static DEFINE_IDR(dma_idr);
 static LIST_HEAD(dma_device_list);
@@ -132,7 +144,7 @@ static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, ch
 	mutex_lock(&dma_list_mutex);
 	chan = dev_to_dma_chan(dev);
 	if (chan)
-		err = sprintf(buf, "%d\n", chan->client_count);
+		err = sprintf(buf, "%d\n", dma_chan_ref_read(chan));
 	else
 		err = -ENODEV;
 	mutex_unlock(&dma_list_mutex);
@@ -201,15 +213,15 @@ static int dma_chan_get(struct dma_chan *chan)
 	if (!try_module_get(owner))
 		return -ENODEV;
 
-	chan->client_count++;
+	dma_chan_ref_inc(chan);
 
 	/* allocate upon first client reference */
-	if (chan->client_count == 1) {
+	if (dma_chan_ref_read(chan) == 1) {
 		int desc_cnt = chan->device->device_alloc_chan_resources(chan);
 
 		if (desc_cnt < 0) {
 			err = desc_cnt;
-			chan->client_count = 0;
+			dma_chan_ref_set(chan, 0);
 			module_put(owner);
 		}
 	}
@@ -225,9 +237,8 @@ static int dma_chan_get(struct dma_chan *chan)
  */
 static void dma_chan_put(struct dma_chan *chan)
 {
-	BUG_ON(chan->client_count <= 0);
-	chan->client_count--;
-	if (chan->client_count == 0)
+	BUG_ON(dma_chan_ref_read(chan) <= 0);
+	if (dma_chan_ref_dec_and_test(chan))
 		chan->device->device_free_chan_resources(chan);
 	module_put(dma_chan_to_owner(chan));
 }
@@ -341,7 +352,7 @@ void dma_issue_pending_all(void)
 		if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
 			continue;
 		list_for_each_entry(chan, &device->channels, device_node)
-			if (chan->client_count)
+			if (dma_chan_ref_read(chan))
 				device->device_issue_pending(chan);
 	}
 	rcu_read_unlock();
@@ -460,12 +471,12 @@ static struct dma_chan *private_candidate(dma_cap_mask_t *mask, struct dma_devic
 	if (dev->chancnt > 1 && !dma_has_cap(DMA_PRIVATE, dev->cap_mask))
 		list_for_each_entry(chan, &dev->channels, device_node) {
 			/* some channels are already publicly allocated */
-			if (chan->client_count)
+			if (dma_chan_ref_read(chan))
 				return NULL;
 		}
 
 	list_for_each_entry(chan, &dev->channels, device_node) {
-		if (chan->client_count) {
+		if (dma_chan_ref_read(chan)) {
 			pr_debug("%s: %s busy\n",
 				 __func__, dma_chan_name(chan));
 			continue;
@@ -530,8 +541,8 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
 void dma_release_channel(struct dma_chan *chan)
 {
 	mutex_lock(&dma_list_mutex);
-	WARN_ONCE(chan->client_count != 1,
-		  "chan reference count %d != 1\n", chan->client_count);
+	WARN_ONCE(dma_chan_ref_read(chan) != 1,
+		  "chan reference count %d != 1\n", dma_chan_ref_read(chan));
 	dma_chan_put(chan);
 	/* drop PRIVATE cap enabled by __dma_request_channel() */
 	if (--chan->device->privatecnt == 0)
@@ -722,7 +733,7 @@ int dma_async_device_register(struct dma_device *device)
 			atomic_dec(idr_ref);
 			goto err_out;
 		}
-		chan->client_count = 0;
+		dma_chan_ref_set(chan, 0);
 	}
 	device->chancnt = chancnt;
 
@@ -784,9 +795,9 @@ void dma_async_device_unregister(struct dma_device *device)
 	}
 
 	list_for_each_entry(chan, &device->channels, device_node) {
-		WARN_ONCE(chan->client_count,
+		WARN_ONCE(dma_chan_ref_read(chan),
 			  "%s called while %d clients hold a reference\n",
-			  __func__, chan->client_count);
+			  __func__, dma_chan_ref_read(chan));
 		mutex_lock(&dma_list_mutex);
 		chan->dev->chan = NULL;
 		mutex_unlock(&dma_list_mutex);
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index f9a2e5e..d1532dc 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -279,7 +279,11 @@ struct dma_chan {
 
 	struct list_head device_node;
 	struct dma_chan_percpu __percpu *local;
+#ifdef	CONFIG_DMA_ENGINE_HOTPLUG
+	atomic_t client_count;
+#else
 	int client_count;
+#endif
 	int table_count;
 	void *private;
 };
-- 
1.7.5.4


  parent reply	other threads:[~2012-04-23 13:51 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-23 13:51 [PATCH v1 0/8] enhance dmaengine core to support DMA device hotplug Jiang Liu
2012-04-23 13:51 ` [PATCH v1 1/8] dmaengine: enhance DMA channel reference count management Jiang Liu
2012-04-23 13:51 ` [PATCH v1 2/8] dmaengine: rebalance DMA channels when CPU hotplug happens Jiang Liu
2012-04-23 13:51 ` [PATCH v1 3/8] dmaengine: introduce CONFIG_DMA_ENGINE_HOTPLUG for DMA device hotplug Jiang Liu
2012-04-23 13:51 ` Jiang Liu [this message]
2012-04-23 13:51 ` [PATCH v1 5/8] dmaengine: enhance dma_async_device_unregister() to be called by drv->remove() Jiang Liu
2012-04-23 13:51 ` [PATCH v1 6/8] dmaengine: enhance network subsystem to support DMA device hotplug Jiang Liu
2012-04-23 18:30   ` Dan Williams
2012-04-24  2:30     ` Jiang Liu
2012-04-24  3:09       ` Dan Williams
2012-04-24  3:56         ` Jiang Liu
2012-04-25 15:47         ` Jiang Liu
2012-04-23 13:51 ` [PATCH v1 7/8] dmaengine: enhance ASYNC_TX " Jiang Liu
2012-04-23 13:51 ` [RFC PATCH v1 8/8] dmaengine: assign DMA channel to CPU according to NUMA affinity Jiang Liu
2012-04-23 16:40 ` [PATCH v1 0/8] enhance dmaengine core to support DMA device hotplug Dan Williams

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=1335189109-4871-5-git-send-email-jiang.liu@huawei.com \
    --to=liuj97@gmail.com \
    --cc=chenkeping@huawei.com \
    --cc=dan.j.williams@intel.com \
    --cc=jiang.liu@huawei.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@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;
as well as URLs for NNTP newsgroup(s).