From: Tejun Heo <tj@kernel.org>
To: axboe@kernel.dk, bharrosh@panasas.com,
linux-kernel@vger.kernel.org, fujita.tomonori@lab.ntt.co.jp
Cc: Tejun Heo <tj@kernel.org>, Pierre Ossman <drzeus-mmc@drzeus.cx>
Subject: [PATCH 02/17] scatterlist: improve atomic mapping handling in mapping iterator
Date: Wed, 1 Apr 2009 22:44:17 +0900 [thread overview]
Message-ID: <1238593472-30360-3-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1238593472-30360-1-git-send-email-tj@kernel.org>
Impact: better atomic mapping handling
sg-miter supported atomic mapping using single flag - SG_MITER_ATOMIC.
It implicly used KM_BIO_SRC_IRQ and required irq to be disabled for
each iteration to protect the kernel mapping. This was too limiting
and didn't allow multiple iterators to be used concurrently (e.g. for
sgl -> sgl copying).
This patch adds a new interface sg_miter_start_atomic() which takes
km_type argument and drops @flags from sg_miter_start() so that
km_type can be specified by the caller for atomic iterators.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Pierre Ossman <drzeus-mmc@drzeus.cx>
---
drivers/mmc/host/sdhci.c | 4 +-
include/linux/scatterlist.h | 11 +++++++--
lib/scatterlist.c | 49 ++++++++++++++++++++++++++++++++----------
3 files changed, 47 insertions(+), 17 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592..559aca7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -704,8 +704,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
}
if (!(host->flags & SDHCI_REQ_USE_DMA)) {
- sg_miter_start(&host->sg_miter,
- data->sg, data->sg_len, SG_MITER_ATOMIC);
+ sg_miter_start_atomic(&host->sg_miter,
+ data->sg, data->sg_len, KM_BIO_SRC_IRQ);
host->blocks = data->blocks;
}
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index e599698..2249caa 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/string.h>
#include <asm/io.h>
+#include <asm/kmap_types.h>
struct sg_table {
struct scatterlist *sgl; /* the list */
@@ -254,11 +255,15 @@ struct sg_mapping_iter {
struct scatterlist *__sg; /* current entry */
unsigned int __nents; /* nr of remaining entries */
unsigned int __offset; /* offset within sg */
- unsigned int __flags;
+ unsigned int __flags; /* internal flags */
+ enum km_type __km_type; /* atomic kmap type to use */
};
-void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
- unsigned int nents, unsigned int flags);
+void sg_miter_start(struct sg_mapping_iter *miter,
+ struct scatterlist *sgl, unsigned int nents);
+void sg_miter_start_atomic(struct sg_mapping_iter *miter,
+ struct scatterlist *sgl, unsigned int nents,
+ enum km_type km_type);
bool sg_miter_next(struct sg_mapping_iter *miter);
void sg_miter_stop(struct sg_mapping_iter *miter);
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index a295e40..4158a7c 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -306,19 +306,41 @@ EXPORT_SYMBOL(sg_alloc_table);
* Context:
* Don't care.
*/
-void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
- unsigned int nents, unsigned int flags)
+void sg_miter_start(struct sg_mapping_iter *miter,
+ struct scatterlist *sgl, unsigned int nents)
{
memset(miter, 0, sizeof(struct sg_mapping_iter));
miter->__sg = sgl;
miter->__nents = nents;
miter->__offset = 0;
- miter->__flags = flags;
}
EXPORT_SYMBOL(sg_miter_start);
/**
+ * sg_miter_start_atomic - start atomic mapping iteration over a sg list
+ * @miter: sg mapping iter to be started
+ * @sgl: sg list to iterate over
+ * @nents: number of sg entries
+ * @idx: kmap type to use for atomic mapping
+ *
+ * Description:
+ * Starts atomic mapping iterator @miter.
+ *
+ * Context:
+ * Don't care.
+ */
+void sg_miter_start_atomic(struct sg_mapping_iter *miter,
+ struct scatterlist *sgl, unsigned int nents,
+ enum km_type km_type)
+{
+ sg_miter_start(miter, sgl, nents);
+ miter->__flags |= SG_MITER_ATOMIC;
+ miter->__km_type = km_type;
+}
+EXPORT_SYMBOL(sg_miter_start_atomic);
+
+/**
* sg_miter_next - proceed mapping iterator to the next mapping
* @miter: sg mapping iter to proceed
*
@@ -329,8 +351,11 @@ EXPORT_SYMBOL(sg_miter_start);
* current mapping.
*
* Context:
- * IRQ disabled if SG_MITER_ATOMIC. IRQ must stay disabled till
- * @miter@ is stopped. May sleep if !SG_MITER_ATOMIC.
+ * Atomic for atomic miters. Atomic state must be maintained till
+ * @miter@ is stopped. Note that the selected KM type limits which
+ * atomic (preempt, softirq or hardirq) contexts are allowed. The
+ * rules are identical to those of kmap_atomic(). May sleep for
+ * non-atomic miters.
*
* Returns:
* true if @miter contains the next mapping. false if end of sg
@@ -365,7 +390,7 @@ bool sg_miter_next(struct sg_mapping_iter *miter)
miter->consumed = miter->length;
if (miter->__flags & SG_MITER_ATOMIC)
- miter->addr = kmap_atomic(miter->page, KM_BIO_SRC_IRQ) + off;
+ miter->addr = kmap_atomic(miter->page, miter->__km_type) + off;
else
miter->addr = kmap(miter->page) + off;
@@ -384,7 +409,7 @@ EXPORT_SYMBOL(sg_miter_next);
* resources (kmap) need to be released during iteration.
*
* Context:
- * IRQ disabled if the SG_MITER_ATOMIC is set. Don't care otherwise.
+ * Atomic if the SG_MITER_ATOMIC is set. Don't care otherwise.
*/
void sg_miter_stop(struct sg_mapping_iter *miter)
{
@@ -394,10 +419,9 @@ void sg_miter_stop(struct sg_mapping_iter *miter)
if (miter->addr) {
miter->__offset += miter->consumed;
- if (miter->__flags & SG_MITER_ATOMIC) {
- WARN_ON(!irqs_disabled());
- kunmap_atomic(miter->addr, KM_BIO_SRC_IRQ);
- } else
+ if (miter->__flags & SG_MITER_ATOMIC)
+ kunmap_atomic(miter->addr, miter->__km_type);
+ else
kunmap(miter->page);
miter->page = NULL;
@@ -427,8 +451,9 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
struct sg_mapping_iter miter;
unsigned long flags;
- sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
+ sg_miter_start_atomic(&miter, sgl, nents, KM_BIO_SRC_IRQ);
+ /* dunno the context we're being called from, plug IRQ */
local_irq_save(flags);
while (sg_miter_next(&miter) && offset < buflen) {
--
1.6.0.2
next prev parent reply other threads:[~2009-04-01 13:47 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-01 13:44 [RFC PATCHSET block] block: blk-map updates and API cleanup Tejun Heo
2009-04-01 13:44 ` [PATCH 01/17] blk-map: move blk_rq_map_user() below blk_rq_map_user_iov() Tejun Heo
2009-04-01 13:44 ` Tejun Heo [this message]
2009-04-01 13:44 ` [PATCH 03/17] blk-map: improve alignment checking for blk_rq_map_user_iov() Tejun Heo
2009-04-01 13:44 ` [PATCH 04/17] bio: bio.h cleanup Tejun Heo
2009-04-01 13:44 ` [PATCH 05/17] bio: cleanup rw usage Tejun Heo
2009-04-02 8:36 ` Boaz Harrosh
2009-04-02 9:02 ` Tejun Heo
2009-04-02 9:07 ` Boaz Harrosh
2009-04-02 9:13 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 06/17] blk-map/bio: use struct iovec instead of sg_iovec Tejun Heo
2009-04-01 14:50 ` Boaz Harrosh
2009-04-01 15:32 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 07/17] blk-map/bio: rename stuff Tejun Heo
2009-04-01 13:44 ` [PATCH 08/17] bio: reimplement bio_copy_user_iov() Tejun Heo
2009-04-01 15:50 ` Boaz Harrosh
2009-04-01 23:57 ` Tejun Heo
2009-04-02 8:24 ` Boaz Harrosh
2009-04-02 8:59 ` Tejun Heo
2009-04-02 9:54 ` Boaz Harrosh
2009-04-02 1:38 ` Tejun Heo
2009-04-02 7:34 ` Boaz Harrosh
2009-04-02 7:51 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 09/17] bio: collapse __bio_map_user_iov(), __bio_unmap_user() and __bio_map_kern() Tejun Heo
2009-04-01 13:44 ` [PATCH 10/17] bio: use bio_create_from_sgl() in bio_map_user_iov() Tejun Heo
2009-04-01 16:33 ` Boaz Harrosh
2009-04-01 22:20 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 11/17] bio: add sgl source support to bci and implement bio_memcpy_sgl_sgl() Tejun Heo
2009-04-01 13:44 ` [PATCH 12/17] bio: implement bio_{map|copy}_kern_sgl() Tejun Heo
2009-04-01 13:44 ` [PATCH 13/17] blk-map: implement blk_rq_map_kern_sgl() Tejun Heo
2009-04-01 16:50 ` Boaz Harrosh
2009-04-01 22:25 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 14/17] scsi: replace custom rq mapping with blk_rq_map_kern_sgl() Tejun Heo
2009-04-01 17:00 ` Boaz Harrosh
2009-04-01 17:05 ` James Bottomley
2009-04-01 17:17 ` Boaz Harrosh
2009-04-13 7:42 ` FUJITA Tomonori
2009-04-13 9:38 ` Tejun Heo
2009-04-13 10:07 ` FUJITA Tomonori
2009-04-13 12:59 ` Borislav Petkov
2009-04-14 0:44 ` FUJITA Tomonori
2009-04-14 10:01 ` Borislav Petkov
2009-04-14 23:44 ` FUJITA Tomonori
2009-04-15 4:25 ` Tejun Heo
2009-04-15 7:26 ` Borislav Petkov
2009-04-15 7:48 ` FUJITA Tomonori
2009-04-15 8:13 ` Borislav Petkov
2009-04-16 3:06 ` Tejun Heo
2009-04-16 3:06 ` Tejun Heo
2009-04-16 5:44 ` Borislav Petkov
2009-04-16 6:07 ` Tejun Heo
2009-04-16 6:07 ` Tejun Heo
2009-04-16 6:29 ` Borislav Petkov
2009-04-16 6:30 ` Tejun Heo
2009-04-16 6:30 ` Tejun Heo
2009-04-16 5:53 ` [PATCH 1/3] ide: add helpers for preparing sense requests Borislav Petkov
2009-04-16 5:53 ` [PATCH 2/3] ide-cd: convert to using generic sense request Borislav Petkov
2009-04-16 5:54 ` [PATCH 3/3] ide-atapi: convert ide-{floppy,tape} to using preallocated sense buffer Borislav Petkov
2009-04-01 13:44 ` [PATCH 15/17] bio/blk-map: kill unused stuff and un-export internal functions Tejun Heo
2009-04-01 13:54 ` Boaz Harrosh
2009-04-01 14:06 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 16/17] blk-map/bio: remove superflous @len parameter from blk_rq_map_user_iov() Tejun Heo
2009-04-01 17:12 ` Boaz Harrosh
2009-04-01 22:17 ` Tejun Heo
2009-04-01 13:44 ` [PATCH 17/17] blk-map/bio: remove superflous @q from blk_rq_map_{user|kern}*() Tejun Heo
2009-04-01 17:05 ` Boaz Harrosh
2009-04-01 14:08 ` [RFC PATCHSET block] block: blk-map updates and API cleanup Tejun Heo
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=1238593472-30360-3-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=axboe@kernel.dk \
--cc=bharrosh@panasas.com \
--cc=drzeus-mmc@drzeus.cx \
--cc=fujita.tomonori@lab.ntt.co.jp \
--cc=linux-kernel@vger.kernel.org \
/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.