diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/Kconfig | 54 | ||||
-rw-r--r-- | init/do_mounts.c | 47 | ||||
-rw-r--r-- | init/do_mounts_rd.c | 12 | ||||
-rw-r--r-- | init/main.c | 60 |
4 files changed, 135 insertions, 38 deletions
diff --git a/init/Kconfig b/init/Kconfig index 18a98c8..296dfca 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -284,7 +284,7 @@ config AUDIT config AUDITSYSCALL bool "Enable system-call auditing support" - depends on AUDIT && (X86 || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT)) + depends on AUDIT && (X86 || PARISC || PPC || S390 || IA64 || UML || SPARC64 || SUPERH || (ARM && AEABI && !OABI_COMPAT)) default y if SECURITY_SELINUX help Enable low-overhead system-call auditing infrastructure that @@ -340,7 +340,8 @@ config VIRT_CPU_ACCOUNTING_NATIVE config VIRT_CPU_ACCOUNTING_GEN bool "Full dynticks CPU time accounting" - depends on HAVE_CONTEXT_TRACKING && 64BIT + depends on HAVE_CONTEXT_TRACKING + depends on HAVE_VIRT_CPU_ACCOUNTING_GEN select VIRT_CPU_ACCOUNTING select CONTEXT_TRACKING help @@ -456,6 +457,7 @@ config TREE_RCU config TREE_PREEMPT_RCU bool "Preemptible tree-based hierarchical RCU" depends on PREEMPT + select IRQ_WORK help This option selects the RCU implementation that is designed for very large SMP systems with hundreds or @@ -513,13 +515,29 @@ config RCU_USER_QS config CONTEXT_TRACKING_FORCE bool "Force context tracking" depends on CONTEXT_TRACKING - default CONTEXT_TRACKING + default y if !NO_HZ_FULL help - Probe on user/kernel boundaries by default in order to - test the features that rely on it such as userspace RCU extended - quiescent states. - This test is there for debugging until we have a real user like the - full dynticks mode. + The major pre-requirement for full dynticks to work is to + support the context tracking subsystem. But there are also + other dependencies to provide in order to make the full + dynticks working. + + This option stands for testing when an arch implements the + context tracking backend but doesn't yet fullfill all the + requirements to make the full dynticks feature working. + Without the full dynticks, there is no way to test the support + for context tracking and the subsystems that rely on it: RCU + userspace extended quiescent state and tickless cputime + accounting. This option copes with the absence of the full + dynticks subsystem by forcing the context tracking on all + CPUs in the system. + + Say Y only if you're working on the developpement of an + architecture backend for the context tracking. + + Say N otherwise, this option brings an overhead that you + don't want in production. + config RCU_FANOUT int "Tree-based hierarchical RCU fanout value" @@ -813,7 +831,7 @@ config NUMA_BALANCING_DEFAULT_ENABLED default y depends on NUMA_BALANCING help - If set, autonumic NUMA balancing will be enabled if running on a NUMA + If set, automatic NUMA balancing will be enabled if running on a NUMA machine. config NUMA_BALANCING @@ -824,7 +842,7 @@ config NUMA_BALANCING help This option adds support for automatic NUMA aware memory/task placement. The mechanism is quite primitive and is based on migrating memory when - it is references to the node the task is running on. + it has references to the node the task is running on. This system will be inactive on UMA systems. @@ -1092,7 +1110,6 @@ config IPC_NS config USER_NS bool "User namespace" - depends on UIDGID_CONVERTED select UIDGID_STRICT_TYPE_CHECKS default n @@ -1126,20 +1143,8 @@ config NET_NS endif # NAMESPACES -config UIDGID_CONVERTED - # True if all of the selected software conmponents are known - # to have uid_t and gid_t converted to kuid_t and kgid_t - # where appropriate and are otherwise safe to use with - # the user namespace. - bool - default y - - # Filesystems - depends on XFS_FS = n - config UIDGID_STRICT_TYPE_CHECKS bool "Require conversions between uid/gids and their internal representation" - depends on UIDGID_CONVERTED default n help While the nececessary conversions are being added to all subsystems this option allows @@ -1584,7 +1589,7 @@ endchoice config SLUB_CPU_PARTIAL default y - depends on SLUB + depends on SLUB && SMP bool "SLUB per cpu partial cache" help Per cpu partial caches accellerate objects allocation and freeing @@ -1652,6 +1657,7 @@ config BASE_SMALL menuconfig MODULES bool "Enable loadable module support" + option modules help Kernel modules are small pieces of compiled code which can be inserted in the running kernel, rather than being diff --git a/init/do_mounts.c b/init/do_mounts.c index 816014c..8e5addc 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -26,6 +26,8 @@ #include <linux/async.h> #include <linux/fs_struct.h> #include <linux/slab.h> +#include <linux/ramfs.h> +#include <linux/shmem_fs.h> #include <linux/nfs_fs.h> #include <linux/nfs_fs_sb.h> @@ -195,6 +197,8 @@ done: * is a zero-filled hex representation of the 1-based partition number. * 7) PARTUUID=<UUID>/PARTNROFF=<int> to select a partition in relation to * a partition with a known unique id. + * 8) <major>:<minor> major and minor number of the device separated by + * a colon. * * If name doesn't have fall into the categories above, we return (0,0). * block_class is used to check if something is a disk name. If the disk @@ -588,3 +592,46 @@ out: sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot("."); } + +static bool is_tmpfs; +static struct dentry *rootfs_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) +{ + static unsigned long once; + void *fill = ramfs_fill_super; + + if (test_and_set_bit(0, &once)) + return ERR_PTR(-ENODEV); + + if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) + fill = shmem_fill_super; + + return mount_nodev(fs_type, flags, data, fill); +} + +static struct file_system_type rootfs_fs_type = { + .name = "rootfs", + .mount = rootfs_mount, + .kill_sb = kill_litter_super, +}; + +int __init init_rootfs(void) +{ + int err = register_filesystem(&rootfs_fs_type); + + if (err) + return err; + + if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && + (!root_fs_names || strstr(root_fs_names, "tmpfs"))) { + err = shmem_init(); + is_tmpfs = true; + } else { + err = init_ramfs_fs(); + } + + if (err) + unregister_filesystem(&rootfs_fs_type); + + return err; +} diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 6be2879..7c098ac 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -57,6 +57,11 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco); * cramfs * squashfs * gzip + * bzip2 + * lzma + * xz + * lzo + * lz4 */ static int __init identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor) @@ -342,6 +347,13 @@ static int __init crd_load(int in_fd, int out_fd, decompress_fn deco) int result; crd_infd = in_fd; crd_outfd = out_fd; + + if (!deco) { + pr_emerg("Invalid ramdisk decompression routine. " + "Select appropriate config option.\n"); + panic("Could not decompress initial ramdisk image."); + } + result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); if (decompress_error) result = 1; diff --git a/init/main.c b/init/main.c index d03d2ec..febc511 100644 --- a/init/main.c +++ b/init/main.c @@ -75,6 +75,8 @@ #include <linux/blkdev.h> #include <linux/elevator.h> #include <linux/sched_clock.h> +#include <linux/context_tracking.h> +#include <linux/random.h> #include <asm/io.h> #include <asm/bugs.h> @@ -122,7 +124,6 @@ EXPORT_SYMBOL(system_state); extern void time_init(void); /* Default late time init is NULL. archs can override this later. */ void (*__initdata late_time_init)(void); -extern void softirq_init(void); /* Untouched command line saved by arch-specific code. */ char __initdata boot_command_line[COMMAND_LINE_SIZE]; @@ -130,11 +131,20 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE]; char *saved_command_line; /* Command line for parameter parsing */ static char *static_command_line; +/* Command line for per-initcall parameter parsing */ +static char *initcall_command_line; static char *execute_command; static char *ramdisk_execute_command; /* + * Used to generate warnings if static_key manipulation functions are used + * before jump_label_init is called. + */ +bool static_key_initialized __read_mostly = false; +EXPORT_SYMBOL_GPL(static_key_initialized); + +/* * If set, this is an indication to the drivers that reset the underlying * device before going ahead with the initialization otherwise driver might * rely on the BIOS and skip the reset operation. @@ -346,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { } static void __init setup_command_line(char *command_line) { saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); + initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1); static_command_line = alloc_bootmem(strlen (command_line)+1); strcpy (saved_command_line, boot_command_line); strcpy (static_command_line, command_line); @@ -545,6 +556,7 @@ asmlinkage void __init start_kernel(void) idr_init_cache(); rcu_init(); tick_nohz_init(); + context_tracking_init(); radix_tree_init(); /* init some links before init_ISA_irqs() */ early_irq_init(); @@ -690,7 +702,7 @@ int __init_or_module do_one_initcall(initcall_t fn) if (preempt_count() != count) { sprintf(msgbuf, "preemption imbalance "); - preempt_count() = count; + preempt_count_set(count); } if (irqs_disabled()) { strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf)); @@ -742,9 +754,9 @@ static void __init do_initcall_level(int level) extern const struct kernel_param __start___param[], __stop___param[]; initcall_t *fn; - strcpy(static_command_line, saved_command_line); + strcpy(initcall_command_line, saved_command_line); parse_args(initcall_level_names[level], - static_command_line, __start___param, + initcall_command_line, __start___param, __stop___param - __start___param, level, level, &repair_env_string); @@ -778,6 +790,7 @@ static void __init do_basic_setup(void) do_ctors(); usermodehelper_enable(); do_initcalls(); + random_int_secret_init(); } static void __init do_pre_smp_initcalls(void) @@ -807,10 +820,26 @@ static int run_init_process(const char *init_filename) (const char __user *const __user *)envp_init); } +static int try_to_run_init_process(const char *init_filename) +{ + int ret; + + ret = run_init_process(init_filename); + + if (ret && ret != -ENOENT) { + pr_err("Starting init: %s exists but couldn't execute it (error %d)\n", + init_filename, ret); + } + + return ret; +} + static noinline void __init kernel_init_freeable(void); static int __ref kernel_init(void *unused) { + int ret; + kernel_init_freeable(); /* need to finish all async __init code before freeing the memory */ async_synchronize_full(); @@ -822,9 +851,11 @@ static int __ref kernel_init(void *unused) flush_delayed_fput(); if (ramdisk_execute_command) { - if (!run_init_process(ramdisk_execute_command)) + ret = run_init_process(ramdisk_execute_command); + if (!ret) return 0; - pr_err("Failed to execute %s\n", ramdisk_execute_command); + pr_err("Failed to execute %s (error %d)\n", + ramdisk_execute_command, ret); } /* @@ -834,18 +865,19 @@ static int __ref kernel_init(void *unused) * trying to recover a really broken machine. */ if (execute_command) { - if (!run_init_process(execute_command)) + ret = run_init_process(execute_command); + if (!ret) return 0; - pr_err("Failed to execute %s. Attempting defaults...\n", - execute_command); + pr_err("Failed to execute %s (error %d). Attempting defaults...\n", + execute_command, ret); } - if (!run_init_process("/sbin/init") || - !run_init_process("/etc/init") || - !run_init_process("/bin/init") || - !run_init_process("/bin/sh")) + if (!try_to_run_init_process("/sbin/init") || + !try_to_run_init_process("/etc/init") || + !try_to_run_init_process("/bin/init") || + !try_to_run_init_process("/bin/sh")) return 0; - panic("No init found. Try passing init= option to kernel. " + panic("No working init found. Try passing init= option to kernel. " "See Linux Documentation/init.txt for guidance."); } |