Re: (EXT) Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-25 Thread Matthias Schiffer
On Tue, 2020-08-25 at 14:27 +0200, Ulf Hansson wrote:
> On Tue, 25 Aug 2020 at 14:00, Matthias Schiffer
>  wrote:
> > 
> > On Tue, 2020-08-25 at 11:39 +0200, Matthias Schiffer wrote:
> > > On Tue, 2020-08-25 at 11:14 +0200, Ulf Hansson wrote:
> > > > On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
> > > >  wrote:
> > > > > --- a/drivers/mmc/core/host.c
> > > > > +++ b/drivers/mmc/core/host.c
> > > > > @@ -387,6 +387,7 @@ struct mmc_host *mmc_alloc_host(int
> > > > > extra,
> > > > > struct device *dev)
> > > > >  {
> > > > > int err;
> > > > > struct mmc_host *host;
> > > > > +   int alias_id, min_idx, max_idx;
> > > > > 
> > > > > host = kzalloc(sizeof(struct mmc_host) + extra,
> > > > > GFP_KERNEL);
> > > > > if (!host)
> > > > > @@ -395,7 +396,18 @@ struct mmc_host *mmc_alloc_host(int
> > > > > extra,
> > > > > struct device *dev)
> > > > > /* scanning will be enabled when we're ready */
> > > > > host->rescan_disable = 1;
> > > > > 
> > > > > -   err = ida_simple_get(_host_ida, 0, 0,
> > > > > GFP_KERNEL);
> > > > > +   host->parent = dev;
> > > > > +
> > > > > +   alias_id = mmc_get_reserved_index(host);
> > > > > +   if (alias_id >= 0) {
> > > > > +   min_idx = alias_id;
> > > > > +   max_idx = alias_id + 1;
> > > > > +   } else {
> > > > > +   min_idx = mmc_first_nonreserved_index();
> > > > > +   max_idx = 0;
> > > > > +   }
> > > > > +
> > > > > +   err = ida_simple_get(_host_ida, min_idx, max_idx,
> > > > > GFP_KERNEL);
> > 
> > 
> > One more question I came across when reworking my patch: Do we need
> > a
> > fallback here for the case where the reserved index is already
> > taken?
> > To handle an SD card being replaced while still mounted?
> 
> Removal/insertion of an SD card should be fine, as that doesn't mean
> that the host is removed. In other words, host->index remains the
> same.
> 
> Although, for a bad DT configuration, where for example the same
> aliases id is used twice, a fallback could make sense. On the other
> hand, as such configuration would be wrong, we might as well just
> print a message and return an error.

I don't think this can happen as long as we don't have DTs changing at
runtime: Each alias is a DT property name in /aliases, which can only exist 
once.


> 
> [...]
> 
> Kind regards
> Uffe



Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-25 Thread Ulf Hansson
On Tue, 25 Aug 2020 at 14:00, Matthias Schiffer
 wrote:
>
> On Tue, 2020-08-25 at 11:39 +0200, Matthias Schiffer wrote:
> > On Tue, 2020-08-25 at 11:14 +0200, Ulf Hansson wrote:
> > > On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
> > >  wrote:
> > > > --- a/drivers/mmc/core/host.c
> > > > +++ b/drivers/mmc/core/host.c
> > > > @@ -387,6 +387,7 @@ struct mmc_host *mmc_alloc_host(int extra,
> > > > struct device *dev)
> > > >  {
> > > > int err;
> > > > struct mmc_host *host;
> > > > +   int alias_id, min_idx, max_idx;
> > > >
> > > > host = kzalloc(sizeof(struct mmc_host) + extra,
> > > > GFP_KERNEL);
> > > > if (!host)
> > > > @@ -395,7 +396,18 @@ struct mmc_host *mmc_alloc_host(int extra,
> > > > struct device *dev)
> > > > /* scanning will be enabled when we're ready */
> > > > host->rescan_disable = 1;
> > > >
> > > > -   err = ida_simple_get(_host_ida, 0, 0, GFP_KERNEL);
> > > > +   host->parent = dev;
> > > > +
> > > > +   alias_id = mmc_get_reserved_index(host);
> > > > +   if (alias_id >= 0) {
> > > > +   min_idx = alias_id;
> > > > +   max_idx = alias_id + 1;
> > > > +   } else {
> > > > +   min_idx = mmc_first_nonreserved_index();
> > > > +   max_idx = 0;
> > > > +   }
> > > > +
> > > > +   err = ida_simple_get(_host_ida, min_idx, max_idx,
> > > > GFP_KERNEL);
>
>
> One more question I came across when reworking my patch: Do we need a
> fallback here for the case where the reserved index is already taken?
> To handle an SD card being replaced while still mounted?

Removal/insertion of an SD card should be fine, as that doesn't mean
that the host is removed. In other words, host->index remains the
same.

Although, for a bad DT configuration, where for example the same
aliases id is used twice, a fallback could make sense. On the other
hand, as such configuration would be wrong, we might as well just
print a message and return an error.

[...]

Kind regards
Uffe


Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-25 Thread Matthias Schiffer
On Tue, 2020-08-25 at 11:39 +0200, Matthias Schiffer wrote:
> On Tue, 2020-08-25 at 11:14 +0200, Ulf Hansson wrote:
> > On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
> >  wrote:
> > > --- a/drivers/mmc/core/host.c
> > > +++ b/drivers/mmc/core/host.c
> > > @@ -387,6 +387,7 @@ struct mmc_host *mmc_alloc_host(int extra,
> > > struct device *dev)
> > >  {
> > > int err;
> > > struct mmc_host *host;
> > > +   int alias_id, min_idx, max_idx;
> > > 
> > > host = kzalloc(sizeof(struct mmc_host) + extra,
> > > GFP_KERNEL);
> > > if (!host)
> > > @@ -395,7 +396,18 @@ struct mmc_host *mmc_alloc_host(int extra,
> > > struct device *dev)
> > > /* scanning will be enabled when we're ready */
> > > host->rescan_disable = 1;
> > > 
> > > -   err = ida_simple_get(_host_ida, 0, 0, GFP_KERNEL);
> > > +   host->parent = dev;
> > > +
> > > +   alias_id = mmc_get_reserved_index(host);
> > > +   if (alias_id >= 0) {
> > > +   min_idx = alias_id;
> > > +   max_idx = alias_id + 1;
> > > +   } else {
> > > +   min_idx = mmc_first_nonreserved_index();
> > > +   max_idx = 0;
> > > +   }
> > > +
> > > +   err = ida_simple_get(_host_ida, min_idx, max_idx,
> > > GFP_KERNEL);


One more question I came across when reworking my patch: Do we need a
fallback here for the case where the reserved index is already taken?
To handle an SD card being replaced while still mounted?


> > > if (err < 0) {
> > > kfree(host);
> > > return NULL;
> > > @@ -406,7 +418,6 @@ struct mmc_host *mmc_alloc_host(int extra,
> > > struct device *dev)
> > > dev_set_name(>class_dev, "mmc%d", host->index);
> > > host->ws = wakeup_source_register(NULL, dev_name(
> > > > class_dev));
> > > 
> > > -   host->parent = dev;
> > > host->class_dev.parent = dev;
> > > host->class_dev.class = _host_class;
> > > device_initialize(>class_dev);
> > > --
> > > 2.17.1
> > > 
> > 
> > Kind regards
> > Uffe



Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-25 Thread Matthias Schiffer
On Tue, 2020-08-25 at 11:39 +0200, Matthias Schiffer wrote:
> On Tue, 2020-08-25 at 11:14 +0200, Ulf Hansson wrote:
> > On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
> >  wrote:
> > > +
> > > +static void __init mmc_of_reserve_idx(void)
> > > +{
> > > +   int max;
> > > +
> > > +   max = of_alias_get_highest_id("mmc");
> > 
> > Is calling of_alias_get_highest_id("mmc") costly from an execution
> > point of view?
> > 
> > If not, we might as well call it directly from mmc_alloc_host()
> > each
> > time a host is allocated instead, to simplify the code a bit.
> 
> It's not particularly costly (it just walks the list of aliases once
> and does a string comparison for each entry), but it does so while
> holding the of_mutex.
> 
> Both variants exist in the current kernel: The I2C core stores the
> hightest index in a global variable, while of_alias_get_highest_id()
> is
> called once for each registered SPI controller. I have a slight
> preference for the global variable solution.

Looking at this again, it's pretty much the same as of_alias_get_id().
I'll remove the extra functions and global variable.

Kind regards,
Matthias



Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-25 Thread Matthias Schiffer
On Tue, 2020-08-25 at 11:14 +0200, Ulf Hansson wrote:
> On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
>  wrote:
> > 
> > As with GPIO, UART and others, allow specifying the device index
> > via the
> > aliases node in the device tree.
> > 
> > On embedded devices, there is often a combination of removable
> > (e.g.
> > SD card) and non-removable MMC devices (e.g. eMMC).
> > Therefore the index might change depending on
> > 
> > * host of removable device
> > * removable card present or not
> > 
> > This makes it difficult to hardcode the root device, if it is on
> > the
> > non-removable device. E.g. if SD card is present eMMC will be
> > mmcblk1,
> > if SD card is not present at boot, eMMC will be mmcblk0.
> > 
> > All indices defined in the aliases node will be reserved for use by
> > the
> > respective MMC device, moving the indices of devices that don't
> > have an
> > alias up into the non-reserved range. If the aliases node is not
> > found,
> > the driver will act as before.
> > 
> > This is a rebased and slightly cleaned up version of
> > https://www.spinics.net/lists/linux-mmc/msg26588.html .
> > 
> > Based-on-patch-by: Sascha Hauer 
> > Link: https://lkml.org/lkml/2020/8/5/194
> > Signed-off-by: Matthias Schiffer  > >
> > ---
> > 
> > v2: fix missing symbols for modular mmcblock
> > 
> >  drivers/mmc/core/block.c | 13 +++--
> >  drivers/mmc/core/core.c  | 40
> > 
> >  drivers/mmc/core/core.h  |  3 +++
> >  drivers/mmc/core/host.c  | 15 +--
> >  4 files changed, 67 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> > index 7896952de1ac..4620afaf0e50 100644
> > --- a/drivers/mmc/core/block.c
> > +++ b/drivers/mmc/core/block.c
> > @@ -38,6 +38,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > 
> >  #include 
> >  #include 
> > @@ -2260,9 +2261,17 @@ static struct mmc_blk_data
> > *mmc_blk_alloc_req(struct mmc_card *card,
> >   int area_type)
> >  {
> > struct mmc_blk_data *md;
> > -   int devidx, ret;
> > +   int rsvidx, devidx = -1, ret;
> > +
> > +   rsvidx = mmc_get_reserved_index(card->host);
> > +   if (rsvidx >= 0)
> > +   devidx = ida_simple_get(_blk_ida, rsvidx,
> > rsvidx + 1,
> > +   GFP_KERNEL);
> > +   if (devidx < 0)
> > +   devidx = ida_simple_get(_blk_ida,
> > +   mmc_first_nonreserved_index
> > (),
> > +   max_devices, GFP_KERNEL);
> > 
> > -   devidx = ida_simple_get(_blk_ida, 0, max_devices,
> > GFP_KERNEL);
> 
> I am not sure why you need to change any of this. Currently we use
> the
> host->index, when creating the blockpartion name (dev.init_name).
> 
> This is done for both rpmb and regular partitions. Isn't that
> sufficient?

You are right, that should be sufficient.


> 
> > if (devidx < 0) {
> > /*
> >  * We get -ENOSPC because there are no more any
> > available
> > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> > index 8ccae6452b9c..5bce281a5faa 100644
> > --- a/drivers/mmc/core/core.c
> > +++ b/drivers/mmc/core/core.c
> > @@ -2419,10 +2419,50 @@ void mmc_unregister_pm_notifier(struct
> > mmc_host *host)
> >  }
> >  #endif
> > 
> > +static int mmc_max_reserved_idx = -1;
> > +
> > +/**
> > + * mmc_first_nonreserved_index() - get the first index that is not
> > reserved
> > + */
> > +int mmc_first_nonreserved_index(void)
> > +{
> > +   return mmc_max_reserved_idx + 1;
> > +}
> > +EXPORT_SYMBOL(mmc_first_nonreserved_index);
> > +
> > +/**
> > + * mmc_get_reserved_index() - get the index reserved for this MMC
> > host
> > + *
> > + * Returns:
> > + *   The index reserved for this host on success,
> > + *   negative error if no index is reserved for this host
> > + */
> > +int mmc_get_reserved_index(struct mmc_host *host)
> > +{
> > +   return of_alias_get_id(host->parent->of_node, "mmc");
> > +}
> > +EXPORT_SYMBOL(mmc_get_reserved_index);
> 
> I think you can drop this function, just call of_alias_get_id() from
> where it's needed.

Ok.

> 
> > +
> > +static void __init mmc_of_reserve_idx(void)
> > +{
> > +   int max;
> > +
> > +   max = of_alias_get_highest_id("mmc");
> 
> Is calling of_alias_get_highest_id("mmc") costly from an execution
> point of view?
> 
> If not, we might as well call it directly from mmc_alloc_host() each
> time a host is allocated instead, to simplify the code a bit.

It's not particularly costly (it just walks the list of aliases once
and does a string comparison for each entry), but it does so while
holding the of_mutex.

Both variants exist in the current kernel: The I2C core stores the
hightest index in a global variable, while of_alias_get_highest_id() is
called once for each registered SPI controller. I have a slight
preference for 

Re: (EXT) Re: [PATCH mmc-next v2] mmc: allow setting slot index via device tree alias

2020-08-24 Thread Matthias Schiffer
On Fri, 2020-08-21 at 13:39 +0200, Ulf Hansson wrote:
> On Thu, 20 Aug 2020 at 09:59, Matthias Schiffer
>  wrote:
> > 
> > As with GPIO, UART and others, allow specifying the device index
> > via the
> > aliases node in the device tree.
> > 
> > On embedded devices, there is often a combination of removable
> > (e.g.
> > SD card) and non-removable MMC devices (e.g. eMMC).
> > Therefore the index might change depending on
> > 
> > * host of removable device
> > * removable card present or not
> > 
> > This makes it difficult to hardcode the root device, if it is on
> > the
> > non-removable device. E.g. if SD card is present eMMC will be
> > mmcblk1,
> > if SD card is not present at boot, eMMC will be mmcblk0.
> 
> Can you please add some information why Part-UUID/labels don't work
> well to solve this problem on some embedded systems?
> 
> I think that deserves to be in the changelog, after all the long
> discussions we had in the history around this.

Makes sense. I'll wait for your review before I send a v3 with an
updated description.

Matthias


> 
> I will continue to review the code in a separate email, in a while.
> 
> Kind regards
> Uffe
> 
> > 
> > All indices defined in the aliases node will be reserved for use by
> > the
> > respective MMC device, moving the indices of devices that don't
> > have an
> > alias up into the non-reserved range. If the aliases node is not
> > found,
> > the driver will act as before.
> > 
> > This is a rebased and slightly cleaned up version of
> > https://www.spinics.net/lists/linux-mmc/msg26588.html .
> > 
> > Based-on-patch-by: Sascha Hauer 
> > Link: https://lkml.org/lkml/2020/8/5/194
> > Signed-off-by: Matthias Schiffer  > >
> > ---
> > 
> > v2: fix missing symbols for modular mmcblock
> > 
> >  drivers/mmc/core/block.c | 13 +++--
> >  drivers/mmc/core/core.c  | 40
> > 
> >  drivers/mmc/core/core.h  |  3 +++
> >  drivers/mmc/core/host.c  | 15 +--
> >  4 files changed, 67 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> > index 7896952de1ac..4620afaf0e50 100644
> > --- a/drivers/mmc/core/block.c
> > +++ b/drivers/mmc/core/block.c
> > @@ -38,6 +38,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > 
> >  #include 
> >  #include 
> > @@ -2260,9 +2261,17 @@ static struct mmc_blk_data
> > *mmc_blk_alloc_req(struct mmc_card *card,
> >   int area_type)
> >  {
> > struct mmc_blk_data *md;
> > -   int devidx, ret;
> > +   int rsvidx, devidx = -1, ret;
> > +
> > +   rsvidx = mmc_get_reserved_index(card->host);
> > +   if (rsvidx >= 0)
> > +   devidx = ida_simple_get(_blk_ida, rsvidx,
> > rsvidx + 1,
> > +   GFP_KERNEL);
> > +   if (devidx < 0)
> > +   devidx = ida_simple_get(_blk_ida,
> > +   mmc_first_nonreserved_index
> > (),
> > +   max_devices, GFP_KERNEL);
> 
> 
> 
> > 
> > -   devidx = ida_simple_get(_blk_ida, 0, max_devices,
> > GFP_KERNEL);
> > if (devidx < 0) {
> > /*
> >  * We get -ENOSPC because there are no more any
> > available
> > diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> > index 8ccae6452b9c..5bce281a5faa 100644
> > --- a/drivers/mmc/core/core.c
> > +++ b/drivers/mmc/core/core.c
> > @@ -2419,10 +2419,50 @@ void mmc_unregister_pm_notifier(struct
> > mmc_host *host)
> >  }
> >  #endif
> > 
> > +static int mmc_max_reserved_idx = -1;
> > +
> > +/**
> > + * mmc_first_nonreserved_index() - get the first index that is not
> > reserved
> > + */
> > +int mmc_first_nonreserved_index(void)
> > +{
> > +   return mmc_max_reserved_idx + 1;
> > +}
> > +EXPORT_SYMBOL(mmc_first_nonreserved_index);
> > +
> > +/**
> > + * mmc_get_reserved_index() - get the index reserved for this MMC
> > host
> > + *
> > + * Returns:
> > + *   The index reserved for this host on success,
> > + *   negative error if no index is reserved for this host
> > + */
> > +int mmc_get_reserved_index(struct mmc_host *host)
> > +{
> > +   return of_alias_get_id(host->parent->of_node, "mmc");
> > +}
> > +EXPORT_SYMBOL(mmc_get_reserved_index);
> > +
> > +static void __init mmc_of_reserve_idx(void)
> > +{
> > +   int max;
> > +
> > +   max = of_alias_get_highest_id("mmc");
> > +   if (max < 0)
> > +   return;
> > +
> > +   mmc_max_reserved_idx = max;
> > +
> > +   pr_debug("MMC: reserving %d slots for OF aliases\n",
> > +mmc_max_reserved_idx + 1);
> > +}
> > +
> >  static int __init mmc_init(void)
> >  {
> > int ret;
> > 
> > +   mmc_of_reserve_idx();
> > +
> > ret = mmc_register_bus();
> > if (ret)
> > return ret;
> > diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
> > index