Re: 3.17-rc2: root=/dev/mmcblk0p2 command line parsing fails

From: Russell King - ARM Linux
Date: Wed Sep 17 2014 - 09:47:39 EST


On Wed, Sep 17, 2014 at 02:20:02PM +0100, Russell King - ARM Linux wrote:
> On Tue, Sep 09, 2014 at 01:49:41PM +0200, Pavel Machek wrote:
> > Bisect would be hard... and I believe the problem is somewhere in
> > block layer now -- not socfpga-specific.
>
> [Adding those on the commit mentioned below to this thread.]
>
> I just updated my nightly build system from -rc3 to -rc5, and I'm seeing
> this on the LDP3430 platform (but not the SDP4430) despite both using
> MMC rootfs.
>
> On SD4430, I see:
>
> Kernel command line: root=/dev/mmcblk0p2 rw mem=512M vmalloc=1G console=ttyO2,115200n8 rootdelay=2 debug
> ...
> mmc0: new high speed SD card at address 0002
> mmcblk0: mmc0:0002 00000 971 MiB
> mmcblk0: p1 p2
> leds_pwm pwmleds: unable to request PWM for omap4:green:chrg: -517
> platform pwmleds: Driver leds_pwm requests probe deferral
> Waiting 2 sec before mounting root device...
> mmc1: new high speed MMC card at address 0001
> mmcblk1: mmc1:0001 SEM08G 7.39 GiB
> mmcblk1boot0: mmc1:0001 SEM08G partition 1 1.00 MiB
> mmcblk1boot1: mmc1:0001 SEM08G partition 2 1.00 MiB
> mmcblk1: unknown partition table
> mmcblk1boot1: unknown partition table
> mmcblk1boot0: unknown partition table
> leds_pwm pwmleds: unable to request PWM for omap4:green:chrg: -517
> platform pwmleds: Driver leds_pwm requests probe deferral
> kjournald starting. Commit interval 5 seconds
> EXT3-fs (mmcblk0p2): warning: maximal mount count reached, running e2fsck is recommended
> EXT3-fs (mmcblk0p2): using internal journal
> EXT3-fs (mmcblk0p2): recovery complete
> EXT3-fs (mmcblk0p2): mounted filesystem with writeback data mode
> VFS: Mounted root (ext3 filesystem) on device 179:2.
>
> However, on LDP3430:
>
> Kernel command line: console=ttyO2,115200n8 noinitrd vmalloc=1G mem=128M root=/dev/mmcblk0p2 rw ip=none rootdelay=2 video=omap24xxfb:rotation=270
> ...
> mmc0: host does not support reading read-only switch. assuming write-enable.
> Waiting 2 sec before mounting root device...
> mmc0: new high speed SD card at address 0002
> mmcblk0: mmc0:0002 00000 971 MiB
> mmcblk0: p1 p2
> VFS: Cannot open root device "mmcblk0p2" or unknown-block(0,0): error -6
> Please append a correct "root=" boot option; here are the available partitions:
> b300 994816 mmcblk0 driver: mmcblk
> b301 72261 mmcblk0p1 0b4c6c45-01
> b302 915705 mmcblk0p2 0b4c6c45-02
> Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
>
> I think the problem may be 4dfe694f616e00e6fd83e5bbcd7a3c4d7113493d
> ("init: make rootdelay=N consistent with rootwait behaviour") which
> was merged during the recent window. This moved the delay after the
> saved_root_name[] handling. As we can see in the SDP4430 case, the
> order was:
>
> - mmcblk0p2 detected
> - delay message
> - rootfs failure
>
> and everything worked. However, in the LDP3430 case:
>
> - delay message
> - mmcblk0p2 detected
> - rootfs failure
>
> and it failed. If we look at the code as it stands today:
>
> if (saved_root_name[0]) {
> root_device_name = saved_root_name;
> if (!strncmp(root_device_name, "mtd", 3) ||
> !strncmp(root_device_name, "ubi", 3)) {
> mount_block_root(root_device_name, root_mountflags);
> goto out;
> }
> ROOT_DEV = name_to_dev_t(root_device_name);
> if (strncmp(root_device_name, "/dev/", 5) == 0)
> root_device_name += 5;
> }
>
> This tries to look up the root device name and translate to a dev_t.
> We know that "mmcblk0p2" doesn't exist at this point, so ROOT_DEV is
> zero here.
>
> if (initrd_load())
> goto out;
>
> if (root_delay) {
> pr_info("Waiting %d sec before mounting root device...\n",
> root_delay);
> ssleep(root_delay);
> }
>
> Here's our delay.
>
> /* wait for any asynchronous scanning to complete */
> if ((ROOT_DEV == 0) && root_wait) {
> printk(KERN_INFO "Waiting for root device %s...\n",
> saved_root_name);
> while (driver_probe_done() != 0 ||
> (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
> msleep(100);
> async_synchronize_full();
> }
>
> If ROOT_DEV was still zero, and root_wait was set (it isn't) we'd then
> try to re-evaluate ROOT_DEV. ROOT_DEV must be set to mount the rootfs,
> and we can see from the above failure messages that it was still zero.
> That works out, because this code would never be run with root_wait=false.
>
> The reason it used to work is because the delay came _before_ the first
> "if" above, so causing the first ROOT_DEV lookup to succeed.
>
> I think it may be better to move the root_delay handling either immediately
> after md_run_setup(), or we need to re-lookup ROOT_DEV after the delay.
> Paul, any thoughts?

Having discussed this with Paul on irc, I came up with this patch which
solves the problem for me.

One thing remaining from this is a question about whether we should wait
for a rootfs which we already have discovered (iow, ROOT_DEV != 0).
That's a separate issue which I do not intend to address.

8<====
From: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx>
Subject: [PATCH] Fix rootdelay wait causing rootfs mount failure

Using rootdelay in recent kernels causes the rootfs to fail if the
device being waited for appears during the wait. The problem is that
ROOT_DEV is not re-looked up after the wait expires, meaning that
ROOT_DEV is zero. This leads to failures such as:

mmc0: host does not support reading read-only switch. assuming write-enable.
Waiting 2 sec before mounting root device...
mmc0: new high speed SD card at address 0002
mmcblk0: mmc0:0002 00000 971 MiB
mmcblk0: p1 p2
VFS: Cannot open root device "mmcblk0p2" or unknown-block(0,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
b300 994816 mmcblk0 driver: mmcblk
b301 72261 mmcblk0p1 0b4c6c45-01
b302 915705 mmcblk0p2 0b4c6c45-02
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

Fix this by re-looking up the ROOT_DEV after the delay wait.

Fixes: 4dfe694f616e ("init: make rootdelay=N consistent with rootwait behaviour")
Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx>
---
init/do_mounts.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/init/do_mounts.c b/init/do_mounts.c
index b6237c31b0e2..1353f607b374 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -569,6 +569,8 @@ void __init prepare_namespace(void)
pr_info("Waiting %d sec before mounting root device...\n",
root_delay);
ssleep(root_delay);
+ /* Re-evaluate the root name to get the dev_t */
+ ROOT_DEV = name_to_dev_t(saved_root_name);
}

/* wait for any asynchronous scanning to complete */


--
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/