From: Rusty Russell <rusty@rustcorp.com.au>
To: linux-scsi@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Jens Axboe <jens.axboe@oracle.com>
Subject: [PATCH 1/5] sg_ring: sg_ring.h
Date: Thu, 20 Dec 2007 16:48:58 +1100 [thread overview]
Message-ID: <200712201648.58480.rusty@rustcorp.com.au> (raw)
In-Reply-To: <200712201645.19035.rusty@rustcorp.com.au>
(Updates since last time: const-safe iterators and sg_ring_num helper for
counting scatterlist entries across entire ring).
This patch introduces 'struct sg_ring', a layer on top of scatterlist
arrays. It meshes nicely with routines which expect a simple array of
'struct scatterlist' because it is easy to break down the ring into
its constituent arrays.
The sg_ring header also encodes the maximum number of entries, useful
for routines which populate an sg. We need never hand around a number
of elements any more.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
include/linux/sg_ring.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 74 insertions(+), 0 deletions(-)
create mode 100644 include/linux/sgring.h
diff --git a/include/linux/sg_ring.h b/include/linux/sg_ring.h
new file mode 100644
--- /dev/null
+++ b/include/linux/sg_ring.h
@@ -0,0 +1,124 @@
+#ifndef _LINUX_SG_RING_H
+#define _LINUX_SG_RING_H
+#include <linux/scatterlist.h>
+
+/**
+ * struct sg_ring - a ring of scatterlists
+ * @list: the list_head chaining them together
+ * @num: the number of valid sg entries
+ * @max: the maximum number of sg entries (size of the sg array).
+ * @sg: the array of scatterlist entries.
+ *
+ * This provides a convenient encapsulation of one or more scatter gather
+ * arrays.
+ */
+struct sg_ring
+{
+ struct list_head list;
+ unsigned int num, max;
+ struct scatterlist sg[0];
+};
+
+/* This helper declares an sg ring on the stack or in a struct. */
+#define DECLARE_SG_RING(name, max) \
+ struct { \
+ struct sg_ring ring; \
+ struct scatterlist sg[max]; \
+ } name
+
+/**
+ * sg_ring_init - initialize a scatterlist ring.
+ * @sg: the sg_ring.
+ * @max: the size of the trailing sg array.
+ *
+ * After initialization sg is alone in the ring.
+ */
+static inline void sg_ring_init(struct sg_ring *sg, unsigned int max)
+{
+#ifdef CONFIG_DEBUG_SG
+ unsigned int i;
+ for (i = 0; i < max; i++)
+ sg->sg[i].sg_magic = SG_MAGIC;
+#endif
+ INIT_LIST_HEAD(&sg->list);
+ sg->max = max;
+ /* FIXME: This is to clear the page bits. */
+ sg_init_table(sg->sg, sg->max);
+}
+
+/**
+ * sg_ring_single - initialize a one-element scatterlist ring.
+ * @sg: the sg_ring.
+ * @buf: the pointer to the buffer.
+ * @buflen: the length of the buffer.
+ *
+ * Does sg_ring_init and also sets up first (and only) sg element.
+ */
+static inline void sg_ring_single(struct sg_ring *sg,
+ const void *buf,
+ unsigned int buflen)
+{
+ sg_ring_init(sg, 1);
+ sg->num = 1;
+ sg_init_one(&sg->sg[0], buf, buflen);
+}
+
+/**
+ * sg_ring_next - next array in a scatterlist ring.
+ * @sg: the sg_ring.
+ * @head: the sg_ring head.
+ *
+ * This will return NULL once @sg has looped back around to @head.
+ */
+static inline struct sg_ring *sg_ring_next(const struct sg_ring *sg,
+ const struct sg_ring *head)
+{
+ sg = list_first_entry(&sg->list, struct sg_ring, list);
+ if (sg == head)
+ sg = NULL;
+ return (struct sg_ring *)sg;
+}
+
+/* Helper for writing for loops. */
+static inline struct sg_ring *sg_ring_iter(const struct sg_ring *head,
+ const struct sg_ring *sg,
+ unsigned int *i)
+{
+ (*i)++;
+ /* While loop lets us skip any zero-entry sg_ring arrays */
+ while (*i == sg->num) {
+ *i = 0;
+ sg = sg_ring_next(sg, head);
+ if (!sg)
+ break;
+ }
+ return (struct sg_ring *)sg;
+}
+
+/**
+ * sg_ring_for_each - iterate through an entire sg_ring ring
+ * @head: the head of the sg_ring.
+ * @sg: the sg_ring iterator.
+ * @i: an (unsigned) integer which refers to sg->sg[i].
+ *
+ * The current scatterlist element is sg->sg[i].
+ */
+#define sg_ring_for_each(head, sg, i) \
+ for (sg = head, i = 0; sg; sg = sg_ring_iter(head, sg, &i))
+
+/**
+ * sg_ring_num - how many struct scatterlists are used in this sg_ring.
+ * @head: the sg_ring
+ *
+ * Simple helper function to add up the number of scatterlists.
+ */
+static inline unsigned sg_ring_num(const struct sg_ring *head)
+{
+ unsigned int num = 0, i;
+ const struct sg_ring *sg;
+
+ sg_ring_for_each(head, sg, i)
+ num += sg->num;
+ return num;
+}
+#endif /* _LINUX_SG_RING_H */
next prev parent reply other threads:[~2007-12-20 5:49 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-20 5:45 [PATCH 0/5] sg_ring for scsi Rusty Russell
2007-12-20 5:48 ` Rusty Russell [this message]
2007-12-20 5:49 ` [PATCH 2/5] dma_map_sg_ring() helper Rusty Russell
2007-12-20 5:50 ` [PATCH 3/5] blk_rq_map_sg_ring as a counterpart to blk_rq_map_sg Rusty Russell
2007-12-20 5:51 ` [PATCH 4/5] sg_ring: Convert core scsi code to sg_ring Rusty Russell
2007-12-20 5:53 ` [PATCH 5/5] sg_ring: Convert scsi_debug Rusty Russell
2007-12-20 7:06 ` [PATCH 2/5] dma_map_sg_ring() helper FUJITA Tomonori
2007-12-20 7:42 ` David Miller
2007-12-20 22:58 ` Rusty Russell
2007-12-21 0:00 ` FUJITA Tomonori
2007-12-21 0:35 ` Rusty Russell
2007-12-21 0:40 ` David Miller
2007-12-21 2:22 ` FUJITA Tomonori
2007-12-21 2:47 ` Rusty Russell
2007-12-20 7:07 ` [PATCH 0/5] sg_ring for scsi FUJITA Tomonori
2007-12-20 7:53 ` Rusty Russell
2007-12-20 7:58 ` David Miller
2007-12-20 7:58 ` Jens Axboe
2007-12-20 23:13 ` Rusty Russell
2007-12-21 0:30 ` David Miller
2007-12-21 2:28 ` FUJITA Tomonori
2007-12-21 3:26 ` Rusty Russell
2007-12-21 4:37 ` FUJITA Tomonori
2007-12-26 0:27 ` Rusty Russell
2007-12-27 2:09 ` FUJITA Tomonori
2007-12-27 11:52 ` Rusty Russell
2007-12-21 12:13 ` Herbert Xu
2007-12-21 12:13 ` Herbert Xu
2007-12-20 7:58 ` Jens Axboe
2007-12-20 13:55 ` Boaz Harrosh
2007-12-20 13:55 ` Boaz Harrosh
2007-12-20 14:00 ` [PATCH 1/3] SG: Move functions to lib/scatterlist.c and add sg chaining allocator helpers Boaz Harrosh
2007-12-20 14:00 ` Boaz Harrosh
2007-12-20 14:21 ` Boaz Harrosh
2007-12-20 14:21 ` Boaz Harrosh
2007-12-21 12:15 ` Herbert Xu
2007-12-21 12:15 ` Herbert Xu
2007-12-20 14:03 ` [PATCH 2/3] SG: Convert SCSI to use scatterlist helpers for sg chaining Boaz Harrosh
2007-12-20 14:26 ` Boaz Harrosh
2007-12-20 14:06 ` [PATCH 3/3] SG: Update ide/ to use sg_table Boaz Harrosh
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=200712201648.58480.rusty@rustcorp.com.au \
--to=rusty@rustcorp.com.au \
--cc=jens.axboe@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@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.