All of lore.kernel.org
 help / color / mirror / Atom feed
From: Saravana Kannan <saravanak@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>
Cc: Saravana Kannan <saravanak@google.com>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Marc Zyngier <maz@kernel.org>,
	kernel-team@android.com, linux-kernel@vger.kernel.org
Subject: [TEST PATCH v1] driver: core: Make fw_devlink=on more forgiving
Date: Thu, 21 Jan 2021 00:22:47 -0800	[thread overview]
Message-ID: <20210121082248.883253-1-saravanak@google.com> (raw)
In-Reply-To: <20201218031703.3053753-6-saravanak@google.com>

This patch is for test purposes only and pretty experimental. Code might
not be optimized, clean, formatted properly, etc.

Please review it only for functional bugs like locking bugs, wrong
logic, etc.

It's basically trying to figure out which devices will never probe and
ignore them. Might not always work.

Marek, Geert, Marc,

Can you please try this patch INSTEAD of the other workarounds we found?

Jon, Michael,

I'm explicitly not including you in the "To" because this patch won't
work for your issues.

Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Marc Zyngier <maz@kernel.org>
Signed-off-by: Saravana Kannan <saravanak@google.com>
---
 drivers/base/base.h |   3 ++
 drivers/base/core.c | 117 +++++++++++++++++++++++++++++++++++++++++++-
 drivers/base/dd.c   |  24 +++++++++
 3 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/drivers/base/base.h b/drivers/base/base.h
index f5600a83124f..8d5fd95fa147 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -106,6 +106,9 @@ struct device_private {
 #define to_device_private_class(obj)	\
 	container_of(obj, struct device_private, knode_class)
 
+bool fw_devlink_is_permissive(void);
+bool fw_devlink_unblock_probe(struct device *dev);
+
 /* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e61e62b624ce..8528704bbb40 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -49,7 +49,6 @@ early_param("sysfs.deprecated", sysfs_deprecated_setup);
 static LIST_HEAD(deferred_sync);
 static unsigned int defer_sync_state_count = 1;
 static DEFINE_MUTEX(fwnode_link_lock);
-static bool fw_devlink_is_permissive(void);
 
 /**
  * fwnode_link_add - Create a link between two fwnode_handles.
@@ -1481,7 +1480,7 @@ u32 fw_devlink_get_flags(void)
 	return fw_devlink_flags;
 }
 
-static bool fw_devlink_is_permissive(void)
+bool fw_devlink_is_permissive(void)
 {
 	return fw_devlink_flags == FW_DEVLINK_FLAGS_PERMISSIVE;
 }
@@ -1552,6 +1551,120 @@ static int fw_devlink_relax_cycle(struct device *con, void *sup)
 	return ret;
 }
 
+static int __device_links_suppliers_available(struct device *dev)
+{
+	struct device_link *link;
+	int ret = 0;
+
+	if (dev->fwnode && !list_empty(&dev->fwnode->suppliers) &&
+	    !fw_devlink_is_permissive()) {
+		return -EPROBE_DEFER;
+	}
+
+	list_for_each_entry(link, &dev->links.suppliers, c_node) {
+		if (!(link->flags & DL_FLAG_MANAGED))
+			continue;
+
+		if (link->status != DL_STATE_AVAILABLE &&
+		    !(link->flags & DL_FLAG_SYNC_STATE_ONLY)) {
+			ret = -EPROBE_DEFER;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+bool fw_devlink_unblock_probe(struct device *dev)
+{
+	struct fwnode_link *link, *tmp;
+	struct device_link *dev_link, *dev_ln;
+	struct fwnode_handle *fwnode = dev->fwnode;
+	bool unblocked = false;
+
+	if (!fw_devlink_get_flags() || fw_devlink_is_permissive())
+		return false;
+
+	if (!fwnode)
+		return false;
+
+	mutex_lock(&fwnode_link_lock);
+
+	/* Delete questionable fwnode links */
+	list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) {
+		struct device *par_dev;
+		struct fwnode_handle *par;
+		bool bound;
+
+		/*
+		 * Walk up fwnode tree of supplier till we find a parent device
+		 * that has been added or a parent fwnode that has fwnode links
+		 * (this is a firmware node that is expected to be added as a
+		 * device in the future).
+		 */
+		par = fwnode_get_parent(link->supplier);
+		while (par && list_empty(&par->suppliers) && !par->dev)
+			par = fwnode_get_next_parent(par);
+
+		/* Supplier is waiting on parent device to be added. */
+		if (par && !par->dev) {
+			fwnode_handle_put(par);
+			continue;
+		}
+
+		if (par && par->dev) {
+			par_dev = get_dev_from_fwnode(fwnode);
+			device_lock(par_dev);
+			bound = device_is_bound(par_dev);
+			device_unlock(par_dev);
+			put_device(par_dev);
+
+			/* Supplier is waiting on parent device to be bound. */
+			if (!bound)
+				continue;
+		}
+
+		/*
+		 * Supplier has no parent or the immediate parent device has
+		 * been bound to a device. It should have been added by now.
+		 * So, this link is spurious. Delete it.
+		 */
+		dev_info(dev, "Deleting fwnode link to %pfwP\n",
+			 link->supplier);
+		list_del(&link->s_hook);
+		list_del(&link->c_hook);
+		kfree(link);
+		unblocked = true;
+	}
+
+	if (IS_ENABLED(CONFIG_MODULES))
+		goto out;
+
+	device_links_write_lock();
+
+	list_for_each_entry_safe(dev_link, dev_ln, &dev->links.suppliers,
+				 c_node) {
+		if (!(dev_link->flags & DL_FLAG_INFERRED) ||
+		    dev_link->flags & DL_FLAG_SYNC_STATE_ONLY ||
+		    dev_link->status != DL_STATE_DORMANT)
+			continue;
+
+		/* This supplier should have probed by now. */
+		if (!__device_links_suppliers_available(dev_link->supplier)) {
+			dev_info(dev, "Deleting dev link to %s\n",
+				 dev_name(dev_link->supplier));
+			device_link_drop_managed(dev_link);
+			unblocked = true;
+		}
+	}
+
+	device_links_write_unlock();
+
+out:
+	mutex_unlock(&fwnode_link_lock);
+	return unblocked;
+}
+
 /**
  * fw_devlink_create_devlink - Create a device link from a consumer to fwnode
  * @con - Consumer device for the device link
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 2f32f38a11ed..d4ccd2a2b6a4 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -301,6 +301,25 @@ static void deferred_probe_timeout_work_func(struct work_struct *work)
 }
 static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func);
 
+static bool deferred_probe_fw_devlink_unblock(void)
+{
+	struct device *dev;
+	struct device_private *private;
+	bool unblocked = false;
+
+	if (!fw_devlink_get_flags() || fw_devlink_is_permissive())
+		return false;
+
+	mutex_lock(&deferred_probe_mutex);
+	list_for_each_entry(private, &deferred_probe_pending_list, deferred_probe) {
+		dev = private->device;
+		unblocked |= fw_devlink_unblock_probe(dev);
+	}
+	mutex_unlock(&deferred_probe_mutex);
+
+	return unblocked;
+}
+
 /**
  * deferred_probe_initcall() - Enable probing of deferred devices
  *
@@ -317,6 +336,11 @@ static int deferred_probe_initcall(void)
 	driver_deferred_probe_trigger();
 	/* Sort as many dependencies as possible before exiting initcalls */
 	flush_work(&deferred_probe_work);
+
+	while (deferred_probe_fw_devlink_unblock()) {
+		driver_deferred_probe_trigger();
+		flush_work(&deferred_probe_work);
+	}
 	initcalls_done = true;
 
 	/*
-- 
2.30.0.296.g2bfb1c46d8-goog


  parent reply	other threads:[~2021-01-21  8:25 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-18  3:16 [PATCH v1 0/5] Enable fw_devlink=on by default Saravana Kannan
2020-12-18  3:16 ` [PATCH v1 1/5] driver core: Add debug logs for device link related probe deferrals Saravana Kannan
2020-12-18  3:17 ` [PATCH v1 2/5] driver core: Add device link support for INFERRED flag Saravana Kannan
2020-12-18  3:17 ` [PATCH v1 3/5] driver core: Have fw_devlink use DL_FLAG_INFERRED Saravana Kannan
2020-12-18  3:17 ` [PATCH v1 4/5] driver core: Handle cycles in device links created by fw_devlink Saravana Kannan
2020-12-18  6:39   ` kernel test robot
2020-12-18  6:39     ` kernel test robot
2020-12-18  6:39   ` [RFC PATCH] driver core: fw_devlink_relax_cycle() can be static kernel test robot
2020-12-18  6:39     ` kernel test robot
2020-12-18  6:48   ` [PATCH v1 4/5] driver core: Handle cycles in device links created by fw_devlink kernel test robot
2020-12-18  6:48     ` kernel test robot
2020-12-18  7:12   ` kernel test robot
2020-12-18  7:12     ` kernel test robot
2020-12-18  3:17 ` [PATCH v1 5/5] driver core: Set fw_devlink=on by default Saravana Kannan
     [not found]   ` <CGME20210111111245eucas1p15acde7ecc2ca7f7782beb8ed74c72022@eucas1p1.samsung.com>
2021-01-11 11:12     ` Marek Szyprowski
     [not found]       ` <CGME20210111141814eucas1p1f388df07b789693a999042b27f0d8c2a@eucas1p1.samsung.com>
2021-01-11 14:18         ` Marek Szyprowski
2021-01-11 21:47           ` Saravana Kannan
2021-01-12  7:11             ` Marek Szyprowski
2021-01-12 20:51               ` Saravana Kannan
2021-01-13  7:04                 ` Marek Szyprowski
2021-01-13 19:23                   ` Saravana Kannan
2021-01-14  7:36                     ` Marek Szyprowski
2021-01-14 18:08                       ` Saravana Kannan
2021-01-18 17:43                 ` Geert Uytterhoeven
2021-01-17 23:01   ` Michael Walle
2021-01-18 21:01     ` Saravana Kannan
2021-01-19 10:41       ` Michael Walle
2021-01-20  0:00         ` Saravana Kannan
2021-01-18 17:39   ` Geert Uytterhoeven
2021-01-18 17:59     ` Marc Zyngier
2021-01-18 19:16       ` Geert Uytterhoeven
2021-01-18 19:30         ` Marc Zyngier
2021-01-18 21:18         ` Saravana Kannan
2021-01-19  9:05           ` Geert Uytterhoeven
2021-01-19 18:08             ` Saravana Kannan
2021-01-19 21:50               ` Saravana Kannan
2021-01-20  9:40                 ` Geert Uytterhoeven
2021-01-20 14:26                   ` Geert Uytterhoeven
2021-01-20 17:22                     ` Saravana Kannan
2021-01-21 16:04                       ` Geert Uytterhoeven
2021-01-25 23:30                         ` Saravana Kannan
2021-01-26  8:25                           ` Geert Uytterhoeven
2021-01-20  9:11               ` Geert Uytterhoeven
2021-01-21  8:22   ` Saravana Kannan [this message]
2021-01-21  8:27     ` [TEST PATCH v1] driver: core: Make fw_devlink=on more forgiving Saravana Kannan
2021-01-21 10:37       ` Geert Uytterhoeven
2021-01-22  1:07         ` Saravana Kannan
2021-01-21 10:33     ` Marek Szyprowski
2021-01-25 17:05   ` [PATCH v1 5/5] driver core: Set fw_devlink=on by default Tudor.Ambarus
2021-01-25 18:16     ` Saravana Kannan
2021-01-28 10:59       ` Tudor.Ambarus
2021-01-28 17:04         ` Saravana Kannan
2021-02-10  5:54   ` Guenter Roeck
2021-02-10  8:20     ` Saravana Kannan
2021-02-10 15:10       ` Guenter Roeck
2021-02-10 20:52         ` Saravana Kannan
2021-02-10 21:21           ` Guenter Roeck
2021-02-17  2:39             ` Saravana Kannan
2021-02-17  3:05               ` Guenter Roeck
2021-02-17  3:13                 ` Saravana Kannan
2020-12-18 21:11 ` [PATCH v1 0/5] Enable " Saravana Kannan
2020-12-21  8:18 ` Jisheng Zhang
     [not found]   ` <CAHp75VfqL1QuvjCZ7p23e_2qhY3DUgVNaS--Uk1mEoEHsD8GBA@mail.gmail.com>
2021-01-14 16:49     ` Saravana Kannan
2020-12-21  9:48 ` Rafael J. Wysocki
2021-01-07 20:05 ` Greg Kroah-Hartman
2021-01-07 21:53   ` Saravana Kannan
2021-01-13 11:11   ` Marc Zyngier
2021-01-13 15:27     ` Jon Hunter
2021-01-13 21:29       ` Saravana Kannan
2021-01-14 11:34         ` Jon Hunter
2021-01-14 16:40           ` Saravana Kannan
2021-01-14 16:47             ` Jon Hunter
2021-01-14 16:52               ` Saravana Kannan
2021-01-14 18:55                 ` Jon Hunter
2021-01-14 21:50                   ` Saravana Kannan
2021-01-15 16:12                     ` Jon Hunter
2021-01-15 17:44                       ` Saravana Kannan
2021-01-13 20:56     ` Saravana Kannan
2021-01-13 11:30 ` Jon Hunter
2021-01-13 21:26   ` Saravana Kannan
2021-01-14 16:11     ` Jon Hunter
2021-01-14 16:47       ` Saravana Kannan
2021-01-14 16:56         ` Jon Hunter
2021-01-28 15:03           ` Jon Hunter
2021-01-28 17:27             ` Saravana Kannan
2021-02-11  0:02             ` Saravana Kannan
2021-02-11 15:03               ` Rafael J. Wysocki
2021-02-11 17:14                 ` Saravana Kannan
2021-02-11 17:48                   ` Rafael J. Wysocki
2021-02-12  3:04                     ` Saravana Kannan
2021-01-13 11:44 ` Nicolas Saenz Julienne
2021-01-13 11:48   ` Marc Zyngier
2021-01-13 21:27     ` Saravana Kannan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210121082248.883253-1-saravanak@google.com \
    --to=saravanak@google.com \
    --cc=geert@linux-m68k.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=maz@kernel.org \
    --cc=rafael@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.