Subject: Re: linux-next: manual merge of the akpm-current tree with the ftrace tree

From: Stephen Rothwell <[email-masked]>
Date: Mon, 3 Feb 2020 11:51:32 +1100

Hi all,

On Wed, 15 Jan 2020 16:47:08 +1100 Stephen Rothwell <[email-masked]> wrote:
>
> Hi all,
> 
> Today's linux-next merge of the akpm-current tree got a conflict in:
> 
>   init/main.c
> 
> between commit:
> 
>   0068c92a9270 ("init/main.c: Alloc initcall_command_line in do_initcall() and free it")
> 
> from the ftrace tree and commit:
> 
>   21cc5aef9811 ("init/main.c: remove unnecessary repair_env_string in do_initcall_level")
> 
> from the akpm-current tree.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> -- 
> Cheers,
> Stephen Rothwell
> 
> diff --cc init/main.c
> index 031723614b80,7dc422c6444a..000000000000
> --- a/init/main.c
> +++ b/init/main.c
> @@@ -249,143 -245,8 +249,142 @@@ static int __init loglevel(char *str
>   
>   early_param("loglevel", loglevel);
>   
>  +#ifdef CONFIG_BOOT_CONFIG
>  +
>  +char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
>  +
>  +#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
>  +
>  +static int __init xbc_snprint_cmdline(char *buf, size_t size,
>  +				      struct xbc_node *root)
>  +{
>  +	struct xbc_node *knode, *vnode;
>  +	char *end = buf + size;
>  +	char c = '\"';
>  +	const char *val;
>  +	int ret;
>  +
>  +	xbc_node_for_each_key_value(root, knode, val) {
>  +		ret = xbc_node_compose_key_after(root, knode,
>  +					xbc_namebuf, XBC_KEYLEN_MAX);
>  +		if (ret < 0)
>  +			return ret;
>  +
>  +		vnode = xbc_node_get_child(knode);
>  +		ret = snprintf(buf, rest(buf, end), "%s%c", xbc_namebuf,
>  +				vnode ? '=' : ' ');
>  +		if (ret < 0)
>  +			return ret;
>  +		buf += ret;
>  +		if (!vnode)
>  +			continue;
>  +
>  +		c = '\"';
>  +		xbc_array_for_each_value(vnode, val) {
>  +			ret = snprintf(buf, rest(buf, end), "%c%s", c, val);
>  +			if (ret < 0)
>  +				return ret;
>  +			buf += ret;
>  +			c = ',';
>  +		}
>  +		if (rest(buf, end) > 2)
>  +			strcpy(buf, "\" ");
>  +		buf += 2;
>  +	}
>  +
>  +	return buf - (end - size);
>  +}
>  +#undef rest
>  +
>  +/* Make an extra command line under given key word */
>  +static char * __init xbc_make_cmdline(const char *key)
>  +{
>  +	struct xbc_node *root;
>  +	char *new_cmdline;
>  +	int ret, len = 0;
>  +
>  +	root = xbc_find_node(key);
>  +	if (!root)
>  +		return NULL;
>  +
>  +	/* Count required buffer size */
>  +	len = xbc_snprint_cmdline(NULL, 0, root);
>  +	if (len <= 0)
>  +		return NULL;
>  +
>  +	new_cmdline = memblock_alloc(len + 1, SMP_CACHE_BYTES);
>  +	if (!new_cmdline) {
>  +		pr_err("Failed to allocate memory for extra kernel cmdline.\n");
>  +		return NULL;
>  +	}
>  +
>  +	ret = xbc_snprint_cmdline(new_cmdline, len + 1, root);
>  +	if (ret < 0 || ret > len) {
>  +		pr_err("Failed to print extra kernel cmdline.\n");
>  +		return NULL;
>  +	}
>  +
>  +	return new_cmdline;
>  +}
>  +
>  +u32 boot_config_checksum(unsigned char *p, u32 size)
>  +{
>  +	u32 ret = 0;
>  +
>  +	while (size--)
>  +		ret += *p++;
>  +
>  +	return ret;
>  +}
>  +
>  +static void __init setup_boot_config(void)
>  +{
>  +	u32 size, csum;
>  +	char *data, *copy;
>  +	u32 *hdr;
>  +
>  +	if (!initrd_end)
>  +		return;
>  +
>  +	hdr = (u32 *)(initrd_end - 8);
>  +	size = hdr[0];
>  +	csum = hdr[1];
>  +
>  +	if (size >= XBC_DATA_MAX)
>  +		return;
>  +
>  +	data = ((void *)hdr) - size;
>  +	if ((unsigned long)data < initrd_start)
>  +		return;
>  +
>  +	if (boot_config_checksum((unsigned char *)data, size) != csum)
>  +		return;
>  +
>  +	copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
>  +	if (!copy) {
>  +		pr_err("Failed to allocate memory for boot config\n");
>  +		return;
>  +	}
>  +
>  +	memcpy(copy, data, size);
>  +	copy[size] = '\0';
>  +
>  +	if (xbc_init(copy) < 0)
>  +		pr_err("Failed to parse boot config\n");
>  +	else {
>  +		pr_info("Load boot config: %d bytes\n", size);
>  +		/* keys starting with "kernel." are passed via cmdline */
>  +		extra_command_line = xbc_make_cmdline("kernel");
>  +		/* Also, "init." keys are init arguments */
>  +		extra_init_args = xbc_make_cmdline("init");
>  +	}
>  +}
>  +#else
>  +#define setup_boot_config()	do { } while (0)
>  +#endif
>  +
>   /* Change NUL term back to "=", to make "param" the whole string. */
> - static int __init repair_env_string(char *param, char *val,
> - 				    const char *unused, void *arg)
> + static void __init repair_env_string(char *param, char *val)
>   {
>   	if (val) {
>   		/* param=val or param="val"? */
> @@@ -1162,15 -990,22 +1161,21 @@@ static const char *initcall_level_names
>   	"late",
>   };
>   
> + static int __init ignore_unknown_bootoption(char *param, char *val,
> + 			       const char *unused, void *arg)
> + {
> + 	return 0;
> + }
> + 
>  -static void __init do_initcall_level(int level)
>  +static void __init do_initcall_level(int level, char *command_line)
>   {
>   	initcall_entry_t *fn;
>   
>  -	strcpy(initcall_command_line, saved_command_line);
>   	parse_args(initcall_level_names[level],
>  -		   initcall_command_line, __start___param,
>  +		   command_line, __start___param,
>   		   __stop___param - __start___param,
>   		   level, level,
> - 		   NULL, &repair_env_string);
> + 		   NULL, ignore_unknown_bootoption);
>   
>   	trace_initcall_level(initcall_level_names[level]);
>   	for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)

This is now a conflict between the ftrace tree and Linus' tree.

-- 
Cheers,
Stephen Rothwell