From: Dan Williams <dan.j.williams@intel.com>
To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Cc: maciej.sosnowski@intel.com, hskinnemoen@atmel.com,
g.liakhovetski@gmx.de, nicolas.ferre@atmel.com
Subject: [PATCH 05/13] dmaengine: provide a common 'issue_pending_all' implementation
Date: Fri, 14 Nov 2008 14:34:42 -0700 [thread overview]
Message-ID: <20081114213442.32354.73916.stgit@dwillia2-linux.ch.intel.com> (raw)
In-Reply-To: <20081114213300.32354.1154.stgit@dwillia2-linux.ch.intel.com>
async_tx and net_dma each have open-coded versions of issue_pending_all,
so provide a common routine in dmaengine.
The implementation needs to walk the global device list, so implement
rcu to allow dma_issue_pending_all to run lockless. Clients protect
themselves from channel removal events by holding a dmaengine reference.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
crypto/async_tx/async_tx.c | 12 ------------
drivers/dma/dmaengine.c | 27 ++++++++++++++++++++++++---
include/linux/async_tx.h | 2 +-
include/linux/dmaengine.h | 1 +
net/core/dev.c | 9 +--------
5 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index b88bb1f..2cdf7a0 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -45,18 +45,6 @@ static DEFINE_SPINLOCK(async_tx_lock);
static LIST_HEAD(async_tx_master_list);
-/* async_tx_issue_pending_all - start all transactions on all channels */
-void async_tx_issue_pending_all(void)
-{
- struct dma_chan_ref *ref;
-
- rcu_read_lock();
- list_for_each_entry_rcu(ref, &async_tx_master_list, node)
- ref->chan->device->device_issue_pending(ref->chan);
- rcu_read_unlock();
-}
-EXPORT_SYMBOL_GPL(async_tx_issue_pending_all);
-
static void
free_dma_chan_ref(struct rcu_head *rcu)
{
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index c3e6fbb..ec483cc 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -70,6 +70,7 @@
#include <linux/rcupdate.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>
+#include <linux/rculist.h>
static DEFINE_MUTEX(dma_list_mutex);
static LIST_HEAD(dma_device_list);
@@ -354,6 +355,26 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
EXPORT_SYMBOL(dma_find_channel);
/**
+ * dma_issue_pending_all - flush all pending operations across all channels
+ */
+void dma_issue_pending_all(void)
+{
+ struct dma_device *device;
+ struct dma_chan *chan;
+
+ WARN_ONCE(dmaengine_ref_count == 0,
+ "client called %s without a reference", __func__);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(device, &dma_device_list, global_node)
+ list_for_each_entry(chan, &device->channels, device_node)
+ if (chan->client_count)
+ device->device_issue_pending(chan);
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL(dma_issue_pending_all);
+
+/**
* nth_chan - returns the nth channel of the given capability
* @cap: capability to match
* @n: nth channel desired
@@ -477,7 +498,7 @@ void dma_async_client_register(struct dma_client *client)
err = dma_chan_get(chan);
if (err == -ENODEV) {
/* module removed before we could use it */
- list_del_init(&device->global_node);
+ list_del_rcu(&device->global_node);
break;
} else if (err)
pr_err("dmaengine: failed to get %s: (%d)",
@@ -612,7 +633,7 @@ int dma_async_device_register(struct dma_device *device)
goto err_out;
}
}
- list_add_tail(&device->global_node, &dma_device_list);
+ list_add_tail_rcu(&device->global_node, &dma_device_list);
dma_channel_rebalance();
mutex_unlock(&dma_list_mutex);
@@ -654,7 +675,7 @@ void dma_async_device_unregister(struct dma_device *device)
struct dma_chan *chan;
mutex_lock(&dma_list_mutex);
- list_del(&device->global_node);
+ list_del_rcu(&device->global_node);
dma_channel_rebalance();
mutex_unlock(&dma_list_mutex);
diff --git a/include/linux/async_tx.h b/include/linux/async_tx.h
index 1c81677..45f6297 100644
--- a/include/linux/async_tx.h
+++ b/include/linux/async_tx.h
@@ -59,7 +59,7 @@ enum async_tx_flags {
};
#ifdef CONFIG_DMA_ENGINE
-void async_tx_issue_pending_all(void);
+#define async_tx_issue_pending_all dma_issue_pending_all
#ifdef CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL
#include <asm/async_tx.h>
#else
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index b466f02..57a43ad 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -471,6 +471,7 @@ int dma_async_device_register(struct dma_device *device);
void dma_async_device_unregister(struct dma_device *device);
void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
+void dma_issue_pending_all(void);
/* --- Helper iov-locking functions --- */
diff --git a/net/core/dev.c b/net/core/dev.c
index 9174c77..301a449 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2442,14 +2442,7 @@ out:
* There may not be any more sk_buffs coming right now, so push
* any pending DMA copies to hardware
*/
- if (!cpus_empty(net_dma.channel_mask)) {
- int chan_idx;
- for_each_cpu_mask_nr(chan_idx, net_dma.channel_mask) {
- struct dma_chan *chan = net_dma.channels[chan_idx];
- if (chan)
- dma_async_memcpy_issue_pending(chan);
- }
- }
+ dma_issue_pending_all();
#endif
return;
next prev parent reply other threads:[~2008-11-14 21:36 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-14 21:34 [PATCH 00/13] dmaengine redux Dan Williams
2008-11-14 21:34 ` [PATCH 01/13] async_tx, dmaengine: document channel allocation and api rework Dan Williams
2008-11-14 21:34 ` [PATCH 02/13] dmaengine: remove dependency on async_tx Dan Williams
2008-11-15 6:02 ` Andrew Morton
2008-11-17 23:44 ` Dan Williams
2008-11-14 21:34 ` [PATCH 03/13] dmaengine: up-level reference counting to the module level Dan Williams
2008-11-15 6:08 ` Andrew Morton
2008-11-18 3:42 ` Dan Williams
2008-12-04 16:56 ` Guennadi Liakhovetski
2008-12-04 18:51 ` Dan Williams
2008-12-04 19:28 ` Guennadi Liakhovetski
2008-12-08 22:39 ` Dan Williams
2008-12-12 14:28 ` Sosnowski, Maciej
2008-12-15 22:12 ` Dan Williams
2008-12-18 14:26 ` Sosnowski, Maciej
2008-11-14 21:34 ` [PATCH 04/13] dmaengine: centralize channel allocation, introduce dma_find_channel Dan Williams
2008-11-15 6:14 ` Andrew Morton
2008-11-18 5:59 ` Dan Williams
2008-11-14 21:34 ` Dan Williams [this message]
2008-11-14 21:34 ` [PATCH 06/13] net_dma: convert to dma_find_channel Dan Williams
2008-11-14 21:34 ` [PATCH 07/13] dmaengine: introduce dma_request_channel and private channels Dan Williams
2008-12-02 15:52 ` Guennadi Liakhovetski
2008-12-02 17:16 ` Dan Williams
2008-12-02 17:27 ` Guennadi Liakhovetski
2008-12-02 19:10 ` Dan Williams
2008-12-02 21:28 ` Guennadi Liakhovetski
2009-01-30 17:03 ` Atsushi Nemoto
2009-01-30 23:13 ` Dan Williams
2009-01-30 23:27 ` Guennadi Liakhovetski
2009-01-31 12:18 ` Atsushi Nemoto
2008-12-02 17:26 ` Nicolas Ferre
2008-12-12 14:29 ` Sosnowski, Maciej
2008-12-15 23:55 ` Dan Williams
2008-12-18 14:33 ` Sosnowski, Maciej
2008-12-18 17:27 ` Dan Williams
2009-02-06 16:58 ` Atsushi Nemoto
2008-11-14 21:34 ` [PATCH 08/13] dmatest: convert to dma_request_channel Dan Williams
2008-11-15 6:17 ` Andrew Morton
2008-11-18 18:24 ` Dan Williams
2008-11-18 20:58 ` Andrew Morton
2008-11-18 22:19 ` Dan Williams
2008-11-14 21:35 ` [PATCH 09/13] atmel-mci: convert to dma_request_channel and down-level dma_slave Dan Williams
2009-01-30 16:40 ` Atsushi Nemoto
2009-01-30 23:02 ` Dan Williams
2008-11-14 21:35 ` [PATCH 10/13] dmaengine: replace dma_async_client_register with dmaengine_get Dan Williams
2008-11-14 21:35 ` [PATCH 11/13] dmaengine: kill struct dma_client and supporting infrastructure Dan Williams
2008-12-12 14:29 ` Sosnowski, Maciej
2008-12-16 0:09 ` Dan Williams
2008-12-18 14:34 ` Sosnowski, Maciej
2008-11-14 21:35 ` [PATCH 12/13] dmaengine: remove 'bigref' infrastructure Dan Williams
2008-11-14 21:35 ` [PATCH 13/13] dmaengine: kill enum dma_state_client Dan Williams
2008-12-12 14:27 ` [PATCH 00/13] dmaengine redux Sosnowski, Maciej
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=20081114213442.32354.73916.stgit@dwillia2-linux.ch.intel.com \
--to=dan.j.williams@intel.com \
--cc=g.liakhovetski@gmx.de \
--cc=hskinnemoen@atmel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.sosnowski@intel.com \
--cc=netdev@vger.kernel.org \
--cc=nicolas.ferre@atmel.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).