Hi Simon, How is this related to the bloblist patchset? Is it required or it can split of?
Regards /Ilias On Mon, 1 Nov 2021 at 03:19, Simon Glass <s...@chromium.org> wrote: > > Add a function that returns some basic stats about driver model. For now > we only have two. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > drivers/core/device.c | 11 ++++++++++ > drivers/core/root.c | 7 ++++++ > drivers/core/uclass.c | 13 ++++++++++++ > include/dm/device.h | 11 +++++++++- > include/dm/root.h | 8 +++++++ > include/dm/uclass-internal.h | 7 ++++++ > test/dm/core.c | 41 ++++++++++++++++++++++++++++++++++++ > 7 files changed, 97 insertions(+), 1 deletion(-) > > diff --git a/drivers/core/device.c b/drivers/core/device.c > index d7a778a2413..7d327aba49e 100644 > --- a/drivers/core/device.c > +++ b/drivers/core/device.c > @@ -723,6 +723,17 @@ int device_get_child_count(const struct udevice *parent) > return count; > } > > +int device_get_decendent_count(const struct udevice *parent) > +{ > + const struct udevice *dev; > + int count = 1; > + > + list_for_each_entry(dev, &parent->child_head, sibling_node) > + count += device_get_decendent_count(dev); > + > + return count; > +} > + > int device_find_child_by_seq(const struct udevice *parent, int seq, > struct udevice **devp) > { > diff --git a/drivers/core/root.c b/drivers/core/root.c > index 26b8195faa3..815173f86eb 100644 > --- a/drivers/core/root.c > +++ b/drivers/core/root.c > @@ -26,6 +26,7 @@ > #include <dm/read.h> > #include <dm/root.h> > #include <dm/uclass.h> > +#include <dm/uclass-internal.h> > #include <dm/util.h> > #include <linux/list.h> > > @@ -407,6 +408,12 @@ int dm_init_and_scan(bool pre_reloc_only) > return 0; > } > > +void dm_get_stats(int *device_countp, int *uclass_countp) > +{ > + *device_countp = device_get_decendent_count(gd->dm_root); > + *uclass_countp = uclass_get_count(); > +} > + > #ifdef CONFIG_ACPIGEN > static int root_acpi_get_name(const struct udevice *dev, char *out_name) > { > diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c > index c5a50952fd0..46b3e85fdbb 100644 > --- a/drivers/core/uclass.c > +++ b/drivers/core/uclass.c > @@ -638,6 +638,19 @@ int uclass_next_device_check(struct udevice **devp) > return device_probe(*devp); > } > > +int uclass_get_count(void) > +{ > + const struct uclass *uc; > + int count = 0; > + > + if (gd->dm_root) { > + list_for_each_entry(uc, gd->uclass_root, sibling_node) > + count++; > + } > + > + return count; > +} > + > int uclass_first_device_drvdata(enum uclass_id id, ulong driver_data, > struct udevice **devp) > { > diff --git a/include/dm/device.h b/include/dm/device.h > index 3028d002ab0..68e783ea409 100644 > --- a/include/dm/device.h > +++ b/include/dm/device.h > @@ -593,7 +593,7 @@ int device_get_child(const struct udevice *parent, int > index, > struct udevice **devp); > > /** > - * device_get_child_count() - Get the available child count of a device > + * device_get_child_count() - Get the child count of a device > * > * Returns the number of children to a device. > * > @@ -601,6 +601,15 @@ int device_get_child(const struct udevice *parent, int > index, > */ > int device_get_child_count(const struct udevice *parent); > > +/** > + * device_get_decendent_count() - Get the total number of decendents of a > device > + * > + * Returns the total number of decendents, including all children > + * > + * @parent: Parent device to check > + */ > +int device_get_decendent_count(const struct udevice *parent); > + > /** > * device_find_child_by_seq() - Find a child device based on a sequence > * > diff --git a/include/dm/root.h b/include/dm/root.h > index 42510b106ab..780f269db65 100644 > --- a/include/dm/root.h > +++ b/include/dm/root.h > @@ -131,4 +131,12 @@ int dm_remove_devices_flags(uint flags); > static inline int dm_remove_devices_flags(uint flags) { return 0; } > #endif > > +/** > + * dm_get_stats() - Get some stats for driver mode > + * > + * @device_countp: Returns total number of devices that are bound > + * @uclass_countp: Returns total number of uclasses in use > + */ > +void dm_get_stats(int *device_countp, int *uclass_countp); > + > #endif > diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h > index 57c664c6daa..c71d8b1de45 100644 > --- a/include/dm/uclass-internal.h > +++ b/include/dm/uclass-internal.h > @@ -294,6 +294,13 @@ int uclass_pre_remove_device(struct udevice *dev); > static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; } > #endif > > +/** > + * uclass_get_count() - Get the number of uclasses > + * > + * Returns the number of uclasses instantiated in driver model > + */ > +int uclass_get_count(void); > + > /** > * uclass_find() - Find uclass by its id > * > diff --git a/test/dm/core.c b/test/dm/core.c > index c9a7606666c..c76dfdb1651 100644 > --- a/test/dm/core.c > +++ b/test/dm/core.c > @@ -307,11 +307,15 @@ static int dm_test_lifecycle(struct unit_test_state > *uts) > { > int op_count[DM_TEST_OP_COUNT]; > struct udevice *dev, *test_dev; > + int start_dev_count, start_uc_count; > + int dev_count, uc_count; > int pingret; > int ret; > > memcpy(op_count, dm_testdrv_op_count, sizeof(op_count)); > > + dm_get_stats(&start_dev_count, &start_uc_count); > + > ut_assertok(device_bind_by_name(uts->root, false, &driver_info_manual, > &dev)); > ut_assert(dev); > @@ -319,6 +323,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts) > == op_count[DM_TEST_OP_BIND] + 1); > ut_assert(!dev_get_priv(dev)); > > + /* We should have one more device */ > + dm_get_stats(&dev_count, &uc_count); > + ut_asserteq(start_dev_count + 1, dev_count); > + ut_asserteq(start_uc_count, uc_count); > + > /* Probe the device - it should fail allocating private data */ > uts->force_fail_alloc = 1; > ret = device_probe(dev); > @@ -353,6 +362,11 @@ static int dm_test_lifecycle(struct unit_test_state *uts) > ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_UNBIND]); > ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_PRE_UNBIND]); > > + /* We should have one less device */ > + dm_get_stats(&dev_count, &uc_count); > + ut_asserteq(start_dev_count, dev_count); > + ut_asserteq(start_uc_count, uc_count); > + > return 0; > } > DM_TEST(dm_test_lifecycle, UT_TESTF_SCAN_PDATA | UT_TESTF_PROBE_TEST); > @@ -526,17 +540,31 @@ DM_TEST(dm_test_leak, 0); > /* Test uclass init/destroy methods */ > static int dm_test_uclass(struct unit_test_state *uts) > { > + int dev_count, uc_count; > struct uclass *uc; > > + /* We should have just the root device and uclass */ > + dm_get_stats(&dev_count, &uc_count); > + ut_asserteq(1, dev_count); > + ut_asserteq(1, uc_count); > + > ut_assertok(uclass_get(UCLASS_TEST, &uc)); > ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); > ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_DESTROY]); > ut_assert(uclass_get_priv(uc)); > > + dm_get_stats(&dev_count, &uc_count); > + ut_asserteq(1, dev_count); > + ut_asserteq(2, uc_count); > + > ut_assertok(uclass_destroy(uc)); > ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]); > ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_DESTROY]); > > + dm_get_stats(&dev_count, &uc_count); > + ut_asserteq(1, dev_count); > + ut_asserteq(1, uc_count); > + > return 0; > } > DM_TEST(dm_test_uclass, 0); > @@ -1217,3 +1245,16 @@ static int dm_test_dma_offset(struct unit_test_state > *uts) > } > DM_TEST(dm_test_dma_offset, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); > #endif > + > +/* Test dm_get_stats() */ > +static int dm_test_get_stats(struct unit_test_state *uts) > +{ > + int dev_count, uc_count; > + > + dm_get_stats(&dev_count, &uc_count); > + ut_assert(dev_count > 50); > + ut_assert(uc_count > 30); > + > + return 0; > +} > +DM_TEST(dm_test_get_stats, UT_TESTF_SCAN_FDT); > -- > 2.33.1.1089.g2158813163f-goog >