Re: [RFC PATCH 1/2] sg_ring instead of scatterlist chaining

From: Randy Dunlap
Date: Mon Nov 05 2007 - 11:46:32 EST


On Mon, 5 Nov 2007 17:11:55 +1100 Rusty Russell wrote:

> Hi all,
>
> This patch implements a header for a linked list of scatterlist
> arrays, rather than using an extra entry and low pointer bits to chain them
> together. I've tested that it's sane for virtio (which uses struct
> scatterlist).
>
> Features:
> 1) Neatens code by including length in structure.
> 2) Avoids end ambiguity by including maximum length too.
> 3) Works fine with old "sg is an array" interfaces.
> 4) Kinda icky for stack declaration, so hence a helper is created.
> 5) Lacks magic.
>
> I reverted (most of?) the scatterlist chaining changes to create these
> patches, so it won't apply to your kernels. The reversion patch isn't
> interesting, so I haven't posted it.
>
> Thanks,
> Rusty.
>
> diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
> index 4efbd9c..ce7e581 100644
> --- a/include/linux/scatterlist.h
> +++ b/include/linux/scatterlist.h
> @@ -5,6 +5,51 @@
> #include <linux/mm.h>
> #include <linux/string.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. */

Hi Rusty,

I don't know where these patches are going, but please put the
trailing */ in all of these kernel-doc descriptions (nice ones :)
on a separate line. Thanks.

> +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(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)
> +{
> + INIT_LIST_HEAD(&sg->list);
> + sg->max = max;
> +}
> +
> +/**
> + * sg_ring_next - next array in a scatterlist ring.
> + * @sg: the sg_ring.
> + *
> + * After initialization sg is alone in the ring. */
> +static inline struct sg_ring *sg_ring_next(struct sg_ring *sg)
> +{
> + return list_first_entry(&sg->list, struct sg_ring, list);
> +}
> +
> static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
> unsigned int buflen)
> {
> @@ -20,4 +65,20 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
> sg_set_buf(sg, buf, buflen);
> }
>
> +/**
> + * sg_init_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_init_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);
> +}
> +
> #endif /* _LINUX_SCATTERLIST_H */

---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/