2023-04-12 18:57:01

by Eddie James

[permalink] [raw]
Subject: [PATCH 0/2] fsi: core: Lock scan mutex for master index removal

If a master scan occurs while the master is being unregistered,
the devicecs may end up with incorrect and possibly duplicate names,
resulting in kernel warnings. Ensure the master index isn't changed
outside of the scan mutex.
In addition, add some trace events to debug any further issues in this
area.

Eddie James (2):
fsi: core: Lock scan mutex for master index removal
fsi: core: Add trace events for scan and unregister

drivers/fsi/fsi-core.c | 6 +++++-
include/trace/events/fsi.h | 31 +++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 1 deletion(-)

--
2.31.1


2023-04-12 18:57:05

by Eddie James

[permalink] [raw]
Subject: [PATCH 1/2] fsi: core: Lock scan mutex for master index removal

If a master scan occurs while the master is being unregistered,
the devicecs may end up with incorrect and possibly duplicate names,
resulting in kernel warnings. Ensure the master index isn't changed
outside of the scan mutex.

Signed-off-by: Eddie James <[email protected]>
---
drivers/fsi/fsi-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index fcbf0469ce3f..18d4d68482d7 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -1354,12 +1354,12 @@ EXPORT_SYMBOL_GPL(fsi_master_register);

void fsi_master_unregister(struct fsi_master *master)
{
+ mutex_lock(&master->scan_lock);
if (master->idx >= 0) {
ida_simple_remove(&master_ida, master->idx);
master->idx = -1;
}

- mutex_lock(&master->scan_lock);
fsi_master_unscan(master);
mutex_unlock(&master->scan_lock);
device_unregister(&master->dev);
--
2.31.1

2023-04-12 19:04:19

by Eddie James

[permalink] [raw]
Subject: [PATCH 2/2] fsi: core: Add trace events for scan and unregister

Add more trace events for the scanning and unregistration
functions for debug purposes.

Signed-off-by: Eddie James <[email protected]>
---
drivers/fsi/fsi-core.c | 4 ++++
include/trace/events/fsi.h | 31 +++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 18d4d68482d7..2dc119ab073c 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -1220,6 +1220,7 @@ static int fsi_master_scan(struct fsi_master *master)
{
int link, rc;

+ trace_fsi_master_scan(master, true);
for (link = 0; link < master->n_links; link++) {
rc = fsi_master_link_enable(master, link);
if (rc) {
@@ -1261,6 +1262,7 @@ static int fsi_master_remove_slave(struct device *dev, void *arg)

static void fsi_master_unscan(struct fsi_master *master)
{
+ trace_fsi_master_scan(master, false);
device_for_each_child(&master->dev, NULL, fsi_master_remove_slave);
}

@@ -1355,6 +1357,8 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
void fsi_master_unregister(struct fsi_master *master)
{
mutex_lock(&master->scan_lock);
+ trace_fsi_master_unregister(master);
+
if (master->idx >= 0) {
ida_simple_remove(&master_ida, master->idx);
master->idx = -1;
diff --git a/include/trace/events/fsi.h b/include/trace/events/fsi.h
index c9a72e8432b8..5ff15126ad9d 100644
--- a/include/trace/events/fsi.h
+++ b/include/trace/events/fsi.h
@@ -122,6 +122,37 @@ TRACE_EVENT(fsi_master_break,
)
);

+TRACE_EVENT(fsi_master_scan,
+ TP_PROTO(const struct fsi_master *master, bool scan),
+ TP_ARGS(master, scan),
+ TP_STRUCT__entry(
+ __field(int, master_idx)
+ __field(int, n_links)
+ __field(bool, scan)
+ ),
+ TP_fast_assign(
+ __entry->master_idx = master->idx;
+ __entry->n_links = master->n_links;
+ __entry->scan = scan;
+ ),
+ TP_printk("fsi%d (%d links) %s", __entry->master_idx, __entry->n_links,
+ __entry->scan ? "scan" : "unscan")
+);
+
+TRACE_EVENT(fsi_master_unregister,
+ TP_PROTO(const struct fsi_master *master),
+ TP_ARGS(master),
+ TP_STRUCT__entry(
+ __field(int, master_idx)
+ __field(int, n_links)
+ ),
+ TP_fast_assign(
+ __entry->master_idx = master->idx;
+ __entry->n_links = master->n_links;
+ ),
+ TP_printk("fsi%d (%d links)", __entry->master_idx, __entry->n_links)
+);
+
TRACE_EVENT(fsi_slave_init,
TP_PROTO(const struct fsi_slave *slave),
TP_ARGS(slave),
--
2.31.1

2023-05-31 02:08:56

by Joel Stanley

[permalink] [raw]
Subject: Re: [PATCH 2/2] fsi: core: Add trace events for scan and unregister

On Wed, 12 Apr 2023 at 18:56, Eddie James <[email protected]> wrote:
>
> Add more trace events for the scanning and unregistration
> functions for debug purposes.
>
> Signed-off-by: Eddie James <[email protected]>

Reviewed-by: Joel Stanley <[email protected]>

> ---
> drivers/fsi/fsi-core.c | 4 ++++
> include/trace/events/fsi.h | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 35 insertions(+)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index 18d4d68482d7..2dc119ab073c 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -1220,6 +1220,7 @@ static int fsi_master_scan(struct fsi_master *master)
> {
> int link, rc;
>
> + trace_fsi_master_scan(master, true);
> for (link = 0; link < master->n_links; link++) {
> rc = fsi_master_link_enable(master, link);
> if (rc) {
> @@ -1261,6 +1262,7 @@ static int fsi_master_remove_slave(struct device *dev, void *arg)
>
> static void fsi_master_unscan(struct fsi_master *master)
> {
> + trace_fsi_master_scan(master, false);
> device_for_each_child(&master->dev, NULL, fsi_master_remove_slave);
> }
>
> @@ -1355,6 +1357,8 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
> void fsi_master_unregister(struct fsi_master *master)
> {
> mutex_lock(&master->scan_lock);
> + trace_fsi_master_unregister(master);
> +
> if (master->idx >= 0) {
> ida_simple_remove(&master_ida, master->idx);
> master->idx = -1;
> diff --git a/include/trace/events/fsi.h b/include/trace/events/fsi.h
> index c9a72e8432b8..5ff15126ad9d 100644
> --- a/include/trace/events/fsi.h
> +++ b/include/trace/events/fsi.h
> @@ -122,6 +122,37 @@ TRACE_EVENT(fsi_master_break,
> )
> );
>
> +TRACE_EVENT(fsi_master_scan,
> + TP_PROTO(const struct fsi_master *master, bool scan),
> + TP_ARGS(master, scan),
> + TP_STRUCT__entry(
> + __field(int, master_idx)
> + __field(int, n_links)
> + __field(bool, scan)
> + ),
> + TP_fast_assign(
> + __entry->master_idx = master->idx;
> + __entry->n_links = master->n_links;
> + __entry->scan = scan;
> + ),
> + TP_printk("fsi%d (%d links) %s", __entry->master_idx, __entry->n_links,
> + __entry->scan ? "scan" : "unscan")
> +);
> +
> +TRACE_EVENT(fsi_master_unregister,
> + TP_PROTO(const struct fsi_master *master),
> + TP_ARGS(master),
> + TP_STRUCT__entry(
> + __field(int, master_idx)
> + __field(int, n_links)
> + ),
> + TP_fast_assign(
> + __entry->master_idx = master->idx;
> + __entry->n_links = master->n_links;
> + ),
> + TP_printk("fsi%d (%d links)", __entry->master_idx, __entry->n_links)
> +);
> +
> TRACE_EVENT(fsi_slave_init,
> TP_PROTO(const struct fsi_slave *slave),
> TP_ARGS(slave),
> --
> 2.31.1
>

2023-05-31 08:07:00

by Joel Stanley

[permalink] [raw]
Subject: Re: [PATCH 1/2] fsi: core: Lock scan mutex for master index removal

On Wed, 12 Apr 2023 at 18:56, Eddie James <[email protected]> wrote:
>
> If a master scan occurs while the master is being unregistered,
> the devicecs may end up with incorrect and possibly duplicate names,

typo: devices

> resulting in kernel warnings. Ensure the master index isn't changed
> outside of the scan mutex.
>
> Signed-off-by: Eddie James <[email protected]>
> ---
> drivers/fsi/fsi-core.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
> index fcbf0469ce3f..18d4d68482d7 100644
> --- a/drivers/fsi/fsi-core.c
> +++ b/drivers/fsi/fsi-core.c
> @@ -1354,12 +1354,12 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
>
> void fsi_master_unregister(struct fsi_master *master)
> {
> + mutex_lock(&master->scan_lock);

The ida functions are supposed to not require locking, but protecting
against the test and changing of ->idx makes sense.

Do you want to add a Fixes: line?

> if (master->idx >= 0) {
> ida_simple_remove(&master_ida, master->idx);

the ida_simple functions are depreciated, at some point we should
replace them with ida_alloc/ida_free.

> master->idx = -1;
> }
>
> - mutex_lock(&master->scan_lock);
> fsi_master_unscan(master);
> mutex_unlock(&master->scan_lock);
> device_unregister(&master->dev);
> --
> 2.31.1
>

2023-06-08 17:28:56

by Eddie James

[permalink] [raw]
Subject: Re: [PATCH 1/2] fsi: core: Lock scan mutex for master index removal


On 5/31/23 02:47, Joel Stanley wrote:
> On Wed, 12 Apr 2023 at 18:56, Eddie James <[email protected]> wrote:
>> If a master scan occurs while the master is being unregistered,
>> the devicecs may end up with incorrect and possibly duplicate names,
> typo: devices


Thanks...



>
>> resulting in kernel warnings. Ensure the master index isn't changed
>> outside of the scan mutex.
>>
>> Signed-off-by: Eddie James <[email protected]>
>> ---
>> drivers/fsi/fsi-core.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
>> index fcbf0469ce3f..18d4d68482d7 100644
>> --- a/drivers/fsi/fsi-core.c
>> +++ b/drivers/fsi/fsi-core.c
>> @@ -1354,12 +1354,12 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
>>
>> void fsi_master_unregister(struct fsi_master *master)
>> {
>> + mutex_lock(&master->scan_lock);
> The ida functions are supposed to not require locking, but protecting
> against the test and changing of ->idx makes sense.
>
> Do you want to add a Fixes: line?


Sure.


>
>> if (master->idx >= 0) {
>> ida_simple_remove(&master_ida, master->idx);
> the ida_simple functions are depreciated, at some point we should
> replace them with ida_alloc/ida_free.


OK, I'll see if it makes sense to do that now.

Thanks!

Eddie


>
>> master->idx = -1;
>> }
>>
>> - mutex_lock(&master->scan_lock);
>> fsi_master_unscan(master);
>> mutex_unlock(&master->scan_lock);
>> device_unregister(&master->dev);
>> --
>> 2.31.1
>>