diff mbox

mmc: block: cast a error log for unbalanced mmc_blk_{open, release}

Message ID 1501815102-19376-1-git-send-email-shawn.lin@rock-chips.com (mailing list archive)
State New, archived
Headers show

Commit Message

Shawn Lin Aug. 4, 2017, 2:51 a.m. UTC
The intention for this patch is to help folks debug the failure
like this:

dwmmc_rockchip fe320000.dwmmc: IDMAC supports 32-bit address mode.
dwmmc_rockchip fe320000.dwmmc: Using internal DMA controller.
dwmmc_rockchip fe320000.dwmmc: Version ID is 270a
dwmmc_rockchip fe320000.dwmmc: DW MMC controller at irq 28,32 bit
host data width,256 deep fifo
dwmmc_rockchip fe320000.dwmmc: Got CD GPIO
mmc_host mmc0: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual
400000HZ div = 0)
mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz,
actual 50000000HZ div = 0)
mmc0: new high speed SDHC card at address 0007
mmcblk: probe of mmc0:0007 failed with error -28

It's quite annoying that some buggy userspace deamon miss the disk remove
uevent sometimes so it would finally make the SD card not work. So from
the dmesg it only shows a errno of -28 but still don't understand what
happened.

For quick reproduce this, we could set max_devices to 8 and run

for i in $(seq 1 9); do
  echo "========================" $i
  echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/unbind
  sleep .5
  echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/bind
  sleep .5
  mount -t vfat /dev/mmcblk0 /mnt
  sleep .5
done

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
---

 drivers/mmc/core/block.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

Comments

Ulf Hansson Aug. 22, 2017, 8:43 a.m. UTC | #1
On 4 August 2017 at 04:51, Shawn Lin <shawn.lin@rock-chips.com> wrote:
> The intention for this patch is to help folks debug the failure
> like this:
>
> dwmmc_rockchip fe320000.dwmmc: IDMAC supports 32-bit address mode.
> dwmmc_rockchip fe320000.dwmmc: Using internal DMA controller.
> dwmmc_rockchip fe320000.dwmmc: Version ID is 270a
> dwmmc_rockchip fe320000.dwmmc: DW MMC controller at irq 28,32 bit
> host data width,256 deep fifo
> dwmmc_rockchip fe320000.dwmmc: Got CD GPIO
> mmc_host mmc0: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual
> 400000HZ div = 0)
> mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz,
> actual 50000000HZ div = 0)
> mmc0: new high speed SDHC card at address 0007
> mmcblk: probe of mmc0:0007 failed with error -28
>
> It's quite annoying that some buggy userspace deamon miss the disk remove
> uevent sometimes so it would finally make the SD card not work. So from
> the dmesg it only shows a errno of -28 but still don't understand what
> happened.
>
> For quick reproduce this, we could set max_devices to 8 and run
>
> for i in $(seq 1 9); do
>   echo "========================" $i
>   echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/unbind
>   sleep .5
>   echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/bind
>   sleep .5
>   mount -t vfat /dev/mmcblk0 /mnt
>   sleep .5
> done
>
> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
> ---
>
>  drivers/mmc/core/block.c | 18 +++++++++++++++++-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index a11bead..3ede32a 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -1985,8 +1985,24 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
>         int devidx, ret;
>
>         devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
> -       if (devidx < 0)
> +       if (devidx < 0) {
> +               /*
> +                * The reason for why we could get -ENOSPC here for
> +                * removable devices is that probably userspace mount
> +                * the partition but forget to umount it which makes
> +                * it fail to release md->usage via mmc_blk_release,
> +                * so as a result it leaks the device ID and finally
> +                * breaks the reference counting for mmc block layer.
> +                * It's uerspace's responsibility to guarantee it but
> +                * we could cast an explcit error log  here to clarify
> +                * the situation.
> +                */

I would re-phrase the above to something like this:

"We get -ENOSPC because there are no more any available devidx. The
reason may be that userspace haven't yet unmounted the partitions,
which postpones mmc_blk_release() from being called."

> +               if (mmc_card_is_removable(card->host) && devidx == -ENOSPC)

Why not print this error for all type of cards, it seems like relevant
information for the user.

> +                       dev_err(mmc_dev(card->host),
> +                               "possible unblanced mount/umount detected\n");
> +
>                 return ERR_PTR(devidx);
> +       }
>
>         md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
>         if (!md) {
> --
> 1.9.1

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Shawn Lin Aug. 22, 2017, 9:30 a.m. UTC | #2
On 2017/8/22 16:43, Ulf Hansson wrote:
> On 4 August 2017 at 04:51, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>> The intention for this patch is to help folks debug the failure
>> like this:
>>
>> dwmmc_rockchip fe320000.dwmmc: IDMAC supports 32-bit address mode.
>> dwmmc_rockchip fe320000.dwmmc: Using internal DMA controller.
>> dwmmc_rockchip fe320000.dwmmc: Version ID is 270a
>> dwmmc_rockchip fe320000.dwmmc: DW MMC controller at irq 28,32 bit
>> host data width,256 deep fifo
>> dwmmc_rockchip fe320000.dwmmc: Got CD GPIO
>> mmc_host mmc0: Bus speed (slot 0) = 400000Hz (slot req 400000Hz, actual
>> 400000HZ div = 0)
>> mmc_host mmc0: Bus speed (slot 0) = 50000000Hz (slot req 50000000Hz,
>> actual 50000000HZ div = 0)
>> mmc0: new high speed SDHC card at address 0007
>> mmcblk: probe of mmc0:0007 failed with error -28
>>
>> It's quite annoying that some buggy userspace deamon miss the disk remove
>> uevent sometimes so it would finally make the SD card not work. So from
>> the dmesg it only shows a errno of -28 but still don't understand what
>> happened.
>>
>> For quick reproduce this, we could set max_devices to 8 and run
>>
>> for i in $(seq 1 9); do
>>    echo "========================" $i
>>    echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/unbind
>>    sleep .5
>>    echo fe320000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/bind
>>    sleep .5
>>    mount -t vfat /dev/mmcblk0 /mnt
>>    sleep .5
>> done
>>
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>> ---
>>
>>   drivers/mmc/core/block.c | 18 +++++++++++++++++-
>>   1 file changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
>> index a11bead..3ede32a 100644
>> --- a/drivers/mmc/core/block.c
>> +++ b/drivers/mmc/core/block.c
>> @@ -1985,8 +1985,24 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
>>          int devidx, ret;
>>
>>          devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
>> -       if (devidx < 0)
>> +       if (devidx < 0) {
>> +               /*
>> +                * The reason for why we could get -ENOSPC here for
>> +                * removable devices is that probably userspace mount
>> +                * the partition but forget to umount it which makes
>> +                * it fail to release md->usage via mmc_blk_release,
>> +                * so as a result it leaks the device ID and finally
>> +                * breaks the reference counting for mmc block layer.
>> +                * It's uerspace's responsibility to guarantee it but
>> +                * we could cast an explcit error log  here to clarify
>> +                * the situation.
>> +                */
> 
> I would re-phrase the above to something like this:
> 
> "We get -ENOSPC because there are no more any available devidx. The
> reason may be that userspace haven't yet unmounted the partitions,
> which postpones mmc_blk_release() from being called."
> 

That sounds good.

>> +               if (mmc_card_is_removable(card->host) && devidx == -ENOSPC)
> 
> Why not print this error for all type of cards, it seems like relevant
> information for the user.

Only if we support booting rootfs from other media and that could
allow modular mmc-blk for non-removable devices. But then static
mmc_blk_ida would be freed anyway. So it won't face this situation?

> 
>> +                       dev_err(mmc_dev(card->host),
>> +                               "possible unblanced mount/umount detected\n");
>> +
>>                  return ERR_PTR(devidx);
>> +       }
>>
>>          md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
>>          if (!md) {
>> --
>> 1.9.1
> 
> Kind regards
> Uffe
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ulf Hansson Aug. 22, 2017, 10:14 a.m. UTC | #3
[...]

>
>>> +               if (mmc_card_is_removable(card->host) && devidx ==
>>> -ENOSPC)
>>
>>
>> Why not print this error for all type of cards, it seems like relevant
>> information for the user.
>
>
> Only if we support booting rootfs from other media and that could
> allow modular mmc-blk for non-removable devices. But then static
> mmc_blk_ida would be freed anyway. So it won't face this situation?

Well, I wasn't thinking about the behavior of userspace. Instead, the
information would be printed if the device had more partitions than
what we support...

>
>>
>>> +                       dev_err(mmc_dev(card->host),
>>> +                               "possible unblanced mount/umount
>>> detected\n");

..perhaps then also change this to "no more device IDs available".

>>> +
>>>                  return ERR_PTR(devidx);
>>> +       }
>>>
>>>          md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
>>>          if (!md) {
>>> --

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index a11bead..3ede32a 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1985,8 +1985,24 @@  static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
 	int devidx, ret;
 
 	devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
-	if (devidx < 0)
+	if (devidx < 0) {
+		/*
+		 * The reason for why we could get -ENOSPC here for
+		 * removable devices is that probably userspace mount
+		 * the partition but forget to umount it which makes
+		 * it fail to release md->usage via mmc_blk_release,
+		 * so as a result it leaks the device ID and finally
+		 * breaks the reference counting for mmc block layer.
+		 * It's uerspace's responsibility to guarantee it but
+		 * we could cast an explcit error log  here to clarify
+		 * the situation.
+		 */
+		if (mmc_card_is_removable(card->host) && devidx == -ENOSPC)
+			dev_err(mmc_dev(card->host),
+				"possible unblanced mount/umount detected\n");
+
 		return ERR_PTR(devidx);
+	}
 
 	md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
 	if (!md) {