[llvmlinux] Fwd: patch "usb: gadget: FunctionFS: Remove VLAIS usage from gadget code" added to usb tree

Tinti viniciustinti at gmail.com
Wed Jan 8 18:42:42 UTC 2014


Congratulation guys!!!


On Wed, Jan 8, 2014 at 4:38 PM, Behan Webster <behanw at converseincode.com>wrote:

>  Just FYI
>
> The VLAIS removal patch for USB gadget code is now in Greg KH's tree.
>
> Behan
>
> -------- Original Message --------  Subject: patch "usb: gadget:
> FunctionFS: Remove VLAIS usage from gadget code" added to usb tree  Date: Fri,
> 03 Jan 2014 12:23:09 -0800  From: <gregkh at linuxfoundation.org><gregkh at linuxfoundation.org>  To:
>
> andrzej.p at samsung.com,balbi at ti.com,behanw at converseincode.com,charlebm at gmail.com,kyungmin.park at samsung.com,mina86 at mina86.com
>
> This is a note to let you know that I've just added the patch titled
>
>     usb: gadget: FunctionFS: Remove VLAIS usage from gadget code
>
> to my usb git tree which can be found at
>     git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
> in the usb-next branch.
>
> The patch will show up in the next release of the linux-next tree
> (usually sometime within the next 24 hours during the week.)
>
> The patch will also be merged in the next major kernel release
> during the merge window.
>
> If you have any questions about this process, please let me know.
>
>
> From e6f3862fa1ecea6579dd1727869655e88be7a5ef Mon Sep 17 00:00:00 2001
> From: Andrzej Pietrasiewicz <andrzej.p at samsung.com> <andrzej.p at samsung.com>
> Date: Tue, 3 Dec 2013 15:15:30 +0100
> Subject: usb: gadget: FunctionFS: Remove VLAIS usage from gadget code
>
> The use of variable length arrays in structs (VLAIS) in the Linux Kernel code
> precludes the use of compilers which don't implement VLAIS (for instance the
> Clang compiler). This alternate patch calculates offsets into the kmalloc-ed
> memory buffer using macros. The previous patch required multiple kmalloc and
> kfree calls. This version uses "group" vs "struct" since it really is not a
> struct and is essentially a group of VLA in a common allocated block. This
> version also fixes the issues pointed out by Andrzej Pietrasiewicz and
> Michal Nazarewicz.
>
> Signed-off-by: Mark Charlebois <charlebm at gmail.com> <charlebm at gmail.com>
> Signed-off-by: Behan Webster <behanw at converseincode.com> <behanw at converseincode.com>
>
> [elimination of miexed declaration and code, checkpatch cleanup]
> [fixes after Michal's review]
> Signed-off-by: Andrzej Pietrasiewicz <andrzej.p at samsung.com> <andrzej.p at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com> <kyungmin.park at samsung.com>
> Acked-by: Michal Nazarewicz <mina86 at mina86.com> <mina86 at mina86.com>
> Signed-off-by: Felipe Balbi <balbi at ti.com> <balbi at ti.com>
> ---
>  drivers/usb/gadget/f_fs.c | 116 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 76 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
> index 34940439bb18..91b94b1dcfe3 100644
> --- a/drivers/usb/gadget/f_fs.c
> +++ b/drivers/usb/gadget/f_fs.c
> @@ -30,6 +30,31 @@
>
>  #define FUNCTIONFS_MAGIC	0xa647361 /* Chosen by a honest dice roll ;) */
>
> +/* Variable Length Array Macros **********************************************/
> +#define vla_group(groupname) size_t groupname##__next = 0
> +#define vla_group_size(groupname) groupname##__next
> +
> +#define vla_item(groupname, type, name, n) \
> +	size_t groupname##_##name##__offset = ({			       \
> +		size_t align_mask = __alignof__(type) - 1;		       \
> +		size_t offset = (groupname##__next + align_mask) & ~align_mask;\
> +		size_t size = (n) * sizeof(type);			       \
> +		groupname##__next = offset + size;			       \
> +		offset;							       \
> +	})
> +
> +#define vla_item_with_sz(groupname, type, name, n) \
> +	size_t groupname##_##name##__sz = (n) * sizeof(type);		       \
> +	size_t groupname##_##name##__offset = ({			       \
> +		size_t align_mask = __alignof__(type) - 1;		       \
> +		size_t offset = (groupname##__next + align_mask) & ~align_mask;\
> +		size_t size = groupname##_##name##__sz;			       \
> +		groupname##__next = offset + size;			       \
> +		offset;							       \
> +	})
> +
> +#define vla_ptr(ptr, groupname, name) \
> +	((void *) ((char *)ptr + groupname##_##name##__offset))
>
>  /* Debugging ****************************************************************/
>
> @@ -1902,30 +1927,34 @@ static int __ffs_data_got_strings(struct ffs_data *ffs,
>
>  	/* Allocate everything in one chunk so there's less maintenance. */
>  	{
> -		struct {
> -			struct usb_gadget_strings *stringtabs[lang_count + 1];
> -			struct usb_gadget_strings stringtab[lang_count];
> -			struct usb_string strings[lang_count*(needed_count+1)];
> -		} *d;
>  		unsigned i = 0;
> +		vla_group(d);
> +		vla_item(d, struct usb_gadget_strings *, stringtabs,
> +			lang_count + 1);
> +		vla_item(d, struct usb_gadget_strings, stringtab, lang_count);
> +		vla_item(d, struct usb_string, strings,
> +			lang_count*(needed_count+1));
>
> -		d = kmalloc(sizeof *d, GFP_KERNEL);
> -		if (unlikely(!d)) {
> +		char *vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
> +
> +		if (unlikely(!vlabuf)) {
>  			kfree(_data);
>  			return -ENOMEM;
>  		}
>
> -		stringtabs = d->stringtabs;
> -		t = d->stringtab;
> +		/* Initialize the VLA pointers */
> +		stringtabs = vla_ptr(vlabuf, d, stringtabs);
> +		t = vla_ptr(vlabuf, d, stringtab);
>  		i = lang_count;
>  		do {
>  			*stringtabs++ = t++;
>  		} while (--i);
>  		*stringtabs = NULL;
>
> -		stringtabs = d->stringtabs;
> -		t = d->stringtab;
> -		s = d->strings;
> +		/* stringtabs = vlabuf = d_stringtabs for later kfree */
> +		stringtabs = vla_ptr(vlabuf, d, stringtabs);
> +		t = vla_ptr(vlabuf, d, stringtab);
> +		s = vla_ptr(vlabuf, d, strings);
>  		strings = s;
>  	}
>
> @@ -2201,16 +2230,16 @@ static int ffs_func_bind(struct usb_configuration *c,
>  	int ret;
>
>  	/* Make it a single chunk, less management later on */
> -	struct {
> -		struct ffs_ep eps[ffs->eps_count];
> -		struct usb_descriptor_header
> -			*fs_descs[full ? ffs->fs_descs_count + 1 : 0];
> -		struct usb_descriptor_header
> -			*hs_descs[high ? ffs->hs_descs_count + 1 : 0];
> -		short inums[ffs->interfaces_count];
> -		char raw_descs[high ? ffs->raw_descs_length
> -				    : ffs->raw_fs_descs_length];
> -	} *data;
> +	vla_group(d);
> +	vla_item_with_sz(d, struct ffs_ep, eps, ffs->eps_count);
> +	vla_item_with_sz(d, struct usb_descriptor_header *, fs_descs,
> +		full ? ffs->fs_descs_count + 1 : 0);
> +	vla_item_with_sz(d, struct usb_descriptor_header *, hs_descs,
> +		high ? ffs->hs_descs_count + 1 : 0);
> +	vla_item_with_sz(d, short, inums, ffs->interfaces_count);
> +	vla_item_with_sz(d, char, raw_descs,
> +		high ? ffs->raw_descs_length : ffs->raw_fs_descs_length);
> +	char *vlabuf;
>
>  	ENTER();
>
> @@ -2218,21 +2247,28 @@ static int ffs_func_bind(struct usb_configuration *c,
>  	if (unlikely(!(full | high)))
>  		return -ENOTSUPP;
>
> -	/* Allocate */
> -	data = kmalloc(sizeof *data, GFP_KERNEL);
> -	if (unlikely(!data))
> +	/* Allocate a single chunk, less management later on */
> +	vlabuf = kmalloc(vla_group_size(d), GFP_KERNEL);
> +	if (unlikely(!vlabuf))
>  		return -ENOMEM;
>
>  	/* Zero */
> -	memset(data->eps, 0, sizeof data->eps);
> -	memcpy(data->raw_descs, ffs->raw_descs + 16, sizeof data->raw_descs);
> -	memset(data->inums, 0xff, sizeof data->inums);
> -	for (ret = ffs->eps_count; ret; --ret)
> -		data->eps[ret].num = -1;
> +	memset(vla_ptr(vlabuf, d, eps), 0, d_eps__sz);
> +	memcpy(vla_ptr(vlabuf, d, raw_descs), ffs->raw_descs + 16,
> +	       d_raw_descs__sz);
> +	memset(vla_ptr(vlabuf, d, inums), 0xff, d_inums__sz);
> +	for (ret = ffs->eps_count; ret; --ret) {
> +		struct ffs_ep *ptr;
> +
> +		ptr = vla_ptr(vlabuf, d, eps);
> +		ptr[ret].num = -1;
> +	}
>
> -	/* Save pointers */
> -	func->eps             = data->eps;
> -	func->interfaces_nums = data->inums;
> +	/* Save pointers
> +	 * d_eps == vlabuf, func->eps used to kfree vlabuf later
> +	*/
> +	func->eps             = vla_ptr(vlabuf, d, eps);
> +	func->interfaces_nums = vla_ptr(vlabuf, d, inums);
>
>  	/*
>  	 * Go through all the endpoint descriptors and allocate
> @@ -2240,10 +2276,10 @@ static int ffs_func_bind(struct usb_configuration *c,
>  	 * numbers without worrying that it may be described later on.
>  	 */
>  	if (likely(full)) {
> -		func->function.fs_descriptors = data->fs_descs;
> +		func->function.fs_descriptors = vla_ptr(vlabuf, d, fs_descs);
>  		ret = ffs_do_descs(ffs->fs_descs_count,
> -				   data->raw_descs,
> -				   sizeof data->raw_descs,
> +				   vla_ptr(vlabuf, d, raw_descs),
> +				   d_raw_descs__sz,
>  				   __ffs_func_bind_do_descs, func);
>  		if (unlikely(ret < 0))
>  			goto error;
> @@ -2252,10 +2288,10 @@ static int ffs_func_bind(struct usb_configuration *c,
>  	}
>
>  	if (likely(high)) {
> -		func->function.hs_descriptors = data->hs_descs;
> +		func->function.hs_descriptors = vla_ptr(vlabuf, d, hs_descs);
>  		ret = ffs_do_descs(ffs->hs_descs_count,
> -				   data->raw_descs + ret,
> -				   (sizeof data->raw_descs) - ret,
> +				   vla_ptr(vlabuf, d, raw_descs) + ret,
> +				   d_raw_descs__sz - ret,
>  				   __ffs_func_bind_do_descs, func);
>  		if (unlikely(ret < 0))
>  			goto error;
> @@ -2268,7 +2304,7 @@ static int ffs_func_bind(struct usb_configuration *c,
>  	 */
>  	ret = ffs_do_descs(ffs->fs_descs_count +
>  			   (high ? ffs->hs_descs_count : 0),
> -			   data->raw_descs, sizeof data->raw_descs,
> +			   vla_ptr(vlabuf, d, raw_descs), d_raw_descs__sz,
>  			   __ffs_func_bind_do_nums, func);
>  	if (unlikely(ret < 0))
>  		goto error;
> --
> 1.8.5.rc3
>
>
>
>
>
>
> _______________________________________________
> LLVMLinux mailing list
> LLVMLinux at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/llvmlinux
>



-- 
Simplicity is the ultimate sophistication
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/llvmlinux/attachments/20140108/3473c7d7/attachment.html>


More information about the LLVMLinux mailing list