Hi all, On Wed, 15 Jan 2020 16:47:08 +1100 Stephen Rothwell 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