diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/do_mounts.c | 37 | ||||
-rw-r--r-- | init/main.c | 7 |
2 files changed, 36 insertions, 8 deletions
diff --git a/init/do_mounts.c b/init/do_mounts.c index c0851a8e030c..8959eb32e095 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -360,15 +360,42 @@ out: } #ifdef CONFIG_ROOT_NFS + +#define NFSROOT_TIMEOUT_MIN 5 +#define NFSROOT_TIMEOUT_MAX 30 +#define NFSROOT_RETRY_MAX 5 + static int __init mount_nfs_root(void) { char *root_dev, *root_data; + unsigned int timeout; + int try, err; - if (nfs_root_data(&root_dev, &root_data) != 0) - return 0; - if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0) + err = nfs_root_data(&root_dev, &root_data); + if (err != 0) return 0; - return 1; + + /* + * The server or network may not be ready, so try several + * times. Stop after a few tries in case the client wants + * to fall back to other boot methods. + */ + timeout = NFSROOT_TIMEOUT_MIN; + for (try = 1; ; try++) { + err = do_mount_root(root_dev, "nfs", + root_mountflags, root_data); + if (err == 0) + return 1; + if (try > NFSROOT_RETRY_MAX) + break; + + /* Wait, in case the server refused us immediately */ + ssleep(timeout); + timeout <<= 1; + if (timeout > NFSROOT_TIMEOUT_MAX) + timeout = NFSROOT_TIMEOUT_MAX; + } + return 0; } #endif @@ -405,7 +432,7 @@ void __init change_floppy(char *fmt, ...) void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { + if (ROOT_DEV == Root_NFS) { if (mount_nfs_root()) return; diff --git a/init/main.c b/init/main.c index d7211faed2ad..841e344d366e 100644 --- a/init/main.c +++ b/init/main.c @@ -549,9 +549,6 @@ asmlinkage void __init start_kernel(void) early_boot_irqs_disabled = false; local_irq_enable(); - /* Interrupts are enabled now so all GFP allocations are safe. */ - gfp_allowed_mask = __GFP_BITS_MASK; - kmem_cache_init_late(); /* @@ -783,6 +780,10 @@ static int __init kernel_init(void * unused) * Wait until kthreadd is all set-up. */ wait_for_completion(&kthreadd_done); + + /* Now the scheduler is fully set up and can do blocking allocations */ + gfp_allowed_mask = __GFP_BITS_MASK; + /* * init can allocate pages on any node */ |