Re: [PATCH v6 12/12] FIT: add support to cache opened fit images
On 25-08-20, Marco Felsch wrote:
> Hi,
>
> On 25-08-20, Ahmad Fatoum wrote:
> > Hi,
> >
> > On 8/20/25 11:48, Marco Felsch wrote:
> > > Cache the FIT image fit_open() calls to avoid loading the same FIT image
> > > twice. This is very useful if the same FIT image is used to provide the
> > > base devicetree, kernel and initrd as well as devicetree overlays.
> >
> > Just curious, how much time does this save?
>
> This depends on the amount of overlays you're going to check/apply. But
> in my use-case it reduced the time from ~1sec to 200ms for ~10 overlays
> which are stored together with the boot image e.g. kernel, base-dt,
> initrd.
Sorry I remembered incorrectly. In the end it does not depend on the
overlays but on the FIT which supplies the overlays and the boot-image.
IIRC, we reduced the FIT load time from 1sec to 200ms because the same
FIT is used for the overlays and the boot-image, so we only need to
fit_open() the image once.
Before the caching we had to open it twice:
- 1nd time for the bootm bootm-image handling,
- 2st time for the overlay handling.
Regards,
Marco
>
> Regards,
> Marco
>
> >
> > Cheers,
> > Ahmad
> >
> > >
> > > Signed-off-by: Marco Felsch
> > > ---
> > > common/image-fit.c | 32
> > > include/image-fit.h | 4
> > > 2 files changed, 36 insertions(+)
> > >
> > > diff --git a/common/image-fit.c b/common/image-fit.c
> > > index
> > > c9d08d25f723665e5203d8e8372255a39bf739de..2cde844e46a61f412a46c2c7bb79d833153e5344
> > > 100644
> > > --- a/common/image-fit.c
> > > +++ b/common/image-fit.c
> > > @@ -16,6 +16,7 @@
> > > #include
> > > #include
> > > #include
> > > +#include
> > > #include
> > > #include
> > > #include
> > > @@ -33,6 +34,8 @@
> > > #define CHECK_LEVEL_SIG 2
> > > #define CHECK_LEVEL_MAX 3
> > >
> > > +static LIST_HEAD(open_fits);
> > > +
> > > static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int
> > > size)
> > > {
> > > dt += size;
> > > @@ -902,6 +905,18 @@ void *fit_open_configuration(struct fit_handle
> > > *handle, const char *name,
> > > return conf_node;
> > > }
> > >
> > > +static struct fit_handle *fit_get_handle(const char *filename)
> > > +{
> > > + struct fit_handle *handle;
> > > +
> > > + list_for_each_entry(handle, &open_fits, entry) {
> > > + if (!strcmp(filename, handle->filename))
> > > + return handle;
> > > + }
> > > +
> > > + return NULL;
> > > +}
> > > +
> > > static int fit_do_open(struct fit_handle *handle)
> > > {
> > > const char *desc = "(no description)";
> > > @@ -951,6 +966,8 @@ struct fit_handle *fit_open_buf(const void *buf,
> > > size_t size, bool verbose,
> > > handle->size = size;
> > > handle->verify = verify;
> > >
> > > + refcount_set(&handle->users, 1);
> > > +
> > > ret = fit_do_open(handle);
> > > if (ret) {
> > > fit_close(handle);
> > > @@ -985,6 +1002,12 @@ struct fit_handle *fit_open(const char *_filename,
> > > bool verbose,
> > > return ERR_PTR(-errno);
> > > }
> > >
> > > + handle = fit_get_handle(filename);
> > > + if (handle) {
> > > + refcount_inc(&handle->users);
> > > + return handle;
> > > + }
> > > +
> > > handle = xzalloc(sizeof(struct fit_handle));
> > >
> > > handle->verbose = verbose;
> > > @@ -1002,6 +1025,9 @@ struct fit_handle *fit_open(const char *_filename,
> > > bool verbose,
> > > handle->fit = handle->fit_alloc;
> > > handle->filename = filename;
> > >
> > > + refcount_set(&handle->users, 1);
> > > + list_add(&handle->entry, &open_fits);
> > > +
> > > ret = fit_do_open(handle);
> > > if (ret) {
> > > fit_close(handle);
> > > @@ -1013,9 +1039,15 @@ struct fit_handle *fit_open(const char *_filename,
> > > bool verbose,
> > >
> > > static void __fit_close(struct fit_handle *handle)
> > > {
> > > + if (!refcount_dec_and_test(&handle->users))
> > > + return;
> > > +
> > > if (handle->root)
> > > of_delete_node(handle->root);
> > >
> > > + if (handle->filename)
> > > + list_del(&handle->entry);
> > > +
> > > free(handle->filename);
> > > free(handle->fit_alloc);
> > > }
> > > diff --git a/include/image-fit.h b/include/image-fit.h
> > > index
> > > 68f70f4365cb7a650596263086f7de2209d5957e..f9791ff251c554eda56bf3af98c8abceb056a176
> > > 100644
> > > --- a/include/image-fit.h
> > > +++ b/include/image-fit.h
> > > @@ -7,6 +7,7 @@
> > > #define __IMAGE_FIT_H__
> > >
> > > #include
> > > +#include
> > > #include
> > >
> > > struct fit_handle {
> > > @@ -15,6 +16,9 @@ struct fit_handle {
> > > size_t size;
> > > char *filename;
> > >
> > > + struct list_head entry;
> > > + refcount_t users;
> > > +
> > > bool verbose;
> > > enum bootm_verify verify;
> > >
> > >
> >
> > --
> > Pengutronix e.K. | |
> > Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> > 31137 Hildesheim, G
Re: [PATCH v6 12/12] FIT: add support to cache opened fit images
On 25-08-20, Sascha Hauer wrote: > On Wed, Aug 20, 2025 at 11:48:44AM +0200, Marco Felsch wrote: > > Cache the FIT image fit_open() calls to avoid loading the same FIT image > > twice. This is very useful if the same FIT image is used to provide the > > base devicetree, kernel and initrd as well as devicetree overlays. > > > > Signed-off-by: Marco Felsch > > --- > > common/image-fit.c | 32 > > include/image-fit.h | 4 > > 2 files changed, 36 insertions(+) > > I merged the last three patches into one while applying. +1 wasn't sure if I shall squash them. Regards, Marco > > Sascha > > -- > Pengutronix e.K. | | > Steuerwalder Str. 21 | http://www.pengutronix.de/ | > 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | >
Re: [PATCH v6 12/12] FIT: add support to cache opened fit images
Hi,
On 25-08-20, Ahmad Fatoum wrote:
> Hi,
>
> On 8/20/25 11:48, Marco Felsch wrote:
> > Cache the FIT image fit_open() calls to avoid loading the same FIT image
> > twice. This is very useful if the same FIT image is used to provide the
> > base devicetree, kernel and initrd as well as devicetree overlays.
>
> Just curious, how much time does this save?
This depends on the amount of overlays you're going to check/apply. But
in my use-case it reduced the time from ~1sec to 200ms for ~10 overlays
which are stored together with the boot image e.g. kernel, base-dt,
initrd.
Regards,
Marco
>
> Cheers,
> Ahmad
>
> >
> > Signed-off-by: Marco Felsch
> > ---
> > common/image-fit.c | 32
> > include/image-fit.h | 4
> > 2 files changed, 36 insertions(+)
> >
> > diff --git a/common/image-fit.c b/common/image-fit.c
> > index
> > c9d08d25f723665e5203d8e8372255a39bf739de..2cde844e46a61f412a46c2c7bb79d833153e5344
> > 100644
> > --- a/common/image-fit.c
> > +++ b/common/image-fit.c
> > @@ -16,6 +16,7 @@
> > #include
> > #include
> > #include
> > +#include
> > #include
> > #include
> > #include
> > @@ -33,6 +34,8 @@
> > #define CHECK_LEVEL_SIG 2
> > #define CHECK_LEVEL_MAX 3
> >
> > +static LIST_HEAD(open_fits);
> > +
> > static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int
> > size)
> > {
> > dt += size;
> > @@ -902,6 +905,18 @@ void *fit_open_configuration(struct fit_handle
> > *handle, const char *name,
> > return conf_node;
> > }
> >
> > +static struct fit_handle *fit_get_handle(const char *filename)
> > +{
> > + struct fit_handle *handle;
> > +
> > + list_for_each_entry(handle, &open_fits, entry) {
> > + if (!strcmp(filename, handle->filename))
> > + return handle;
> > + }
> > +
> > + return NULL;
> > +}
> > +
> > static int fit_do_open(struct fit_handle *handle)
> > {
> > const char *desc = "(no description)";
> > @@ -951,6 +966,8 @@ struct fit_handle *fit_open_buf(const void *buf, size_t
> > size, bool verbose,
> > handle->size = size;
> > handle->verify = verify;
> >
> > + refcount_set(&handle->users, 1);
> > +
> > ret = fit_do_open(handle);
> > if (ret) {
> > fit_close(handle);
> > @@ -985,6 +1002,12 @@ struct fit_handle *fit_open(const char *_filename,
> > bool verbose,
> > return ERR_PTR(-errno);
> > }
> >
> > + handle = fit_get_handle(filename);
> > + if (handle) {
> > + refcount_inc(&handle->users);
> > + return handle;
> > + }
> > +
> > handle = xzalloc(sizeof(struct fit_handle));
> >
> > handle->verbose = verbose;
> > @@ -1002,6 +1025,9 @@ struct fit_handle *fit_open(const char *_filename,
> > bool verbose,
> > handle->fit = handle->fit_alloc;
> > handle->filename = filename;
> >
> > + refcount_set(&handle->users, 1);
> > + list_add(&handle->entry, &open_fits);
> > +
> > ret = fit_do_open(handle);
> > if (ret) {
> > fit_close(handle);
> > @@ -1013,9 +1039,15 @@ struct fit_handle *fit_open(const char *_filename,
> > bool verbose,
> >
> > static void __fit_close(struct fit_handle *handle)
> > {
> > + if (!refcount_dec_and_test(&handle->users))
> > + return;
> > +
> > if (handle->root)
> > of_delete_node(handle->root);
> >
> > + if (handle->filename)
> > + list_del(&handle->entry);
> > +
> > free(handle->filename);
> > free(handle->fit_alloc);
> > }
> > diff --git a/include/image-fit.h b/include/image-fit.h
> > index
> > 68f70f4365cb7a650596263086f7de2209d5957e..f9791ff251c554eda56bf3af98c8abceb056a176
> > 100644
> > --- a/include/image-fit.h
> > +++ b/include/image-fit.h
> > @@ -7,6 +7,7 @@
> > #define __IMAGE_FIT_H__
> >
> > #include
> > +#include
> > #include
> >
> > struct fit_handle {
> > @@ -15,6 +16,9 @@ struct fit_handle {
> > size_t size;
> > char *filename;
> >
> > + struct list_head entry;
> > + refcount_t users;
> > +
> > bool verbose;
> > enum bootm_verify verify;
> >
> >
>
> --
> Pengutronix e.K. | |
> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
>
>
Re: [PATCH v6 12/12] FIT: add support to cache opened fit images
On Wed, Aug 20, 2025 at 11:48:44AM +0200, Marco Felsch wrote: > Cache the FIT image fit_open() calls to avoid loading the same FIT image > twice. This is very useful if the same FIT image is used to provide the > base devicetree, kernel and initrd as well as devicetree overlays. > > Signed-off-by: Marco Felsch > --- > common/image-fit.c | 32 > include/image-fit.h | 4 > 2 files changed, 36 insertions(+) I merged the last three patches into one while applying. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
Re: [PATCH v6 12/12] FIT: add support to cache opened fit images
Hi,
On 8/20/25 11:48, Marco Felsch wrote:
> Cache the FIT image fit_open() calls to avoid loading the same FIT image
> twice. This is very useful if the same FIT image is used to provide the
> base devicetree, kernel and initrd as well as devicetree overlays.
Just curious, how much time does this save?
Cheers,
Ahmad
>
> Signed-off-by: Marco Felsch
> ---
> common/image-fit.c | 32
> include/image-fit.h | 4
> 2 files changed, 36 insertions(+)
>
> diff --git a/common/image-fit.c b/common/image-fit.c
> index
> c9d08d25f723665e5203d8e8372255a39bf739de..2cde844e46a61f412a46c2c7bb79d833153e5344
> 100644
> --- a/common/image-fit.c
> +++ b/common/image-fit.c
> @@ -16,6 +16,7 @@
> #include
> #include
> #include
> +#include
> #include
> #include
> #include
> @@ -33,6 +34,8 @@
> #define CHECK_LEVEL_SIG 2
> #define CHECK_LEVEL_MAX 3
>
> +static LIST_HEAD(open_fits);
> +
> static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int
> size)
> {
> dt += size;
> @@ -902,6 +905,18 @@ void *fit_open_configuration(struct fit_handle *handle,
> const char *name,
> return conf_node;
> }
>
> +static struct fit_handle *fit_get_handle(const char *filename)
> +{
> + struct fit_handle *handle;
> +
> + list_for_each_entry(handle, &open_fits, entry) {
> + if (!strcmp(filename, handle->filename))
> + return handle;
> + }
> +
> + return NULL;
> +}
> +
> static int fit_do_open(struct fit_handle *handle)
> {
> const char *desc = "(no description)";
> @@ -951,6 +966,8 @@ struct fit_handle *fit_open_buf(const void *buf, size_t
> size, bool verbose,
> handle->size = size;
> handle->verify = verify;
>
> + refcount_set(&handle->users, 1);
> +
> ret = fit_do_open(handle);
> if (ret) {
> fit_close(handle);
> @@ -985,6 +1002,12 @@ struct fit_handle *fit_open(const char *_filename, bool
> verbose,
> return ERR_PTR(-errno);
> }
>
> + handle = fit_get_handle(filename);
> + if (handle) {
> + refcount_inc(&handle->users);
> + return handle;
> + }
> +
> handle = xzalloc(sizeof(struct fit_handle));
>
> handle->verbose = verbose;
> @@ -1002,6 +1025,9 @@ struct fit_handle *fit_open(const char *_filename, bool
> verbose,
> handle->fit = handle->fit_alloc;
> handle->filename = filename;
>
> + refcount_set(&handle->users, 1);
> + list_add(&handle->entry, &open_fits);
> +
> ret = fit_do_open(handle);
> if (ret) {
> fit_close(handle);
> @@ -1013,9 +1039,15 @@ struct fit_handle *fit_open(const char *_filename,
> bool verbose,
>
> static void __fit_close(struct fit_handle *handle)
> {
> + if (!refcount_dec_and_test(&handle->users))
> + return;
> +
> if (handle->root)
> of_delete_node(handle->root);
>
> + if (handle->filename)
> + list_del(&handle->entry);
> +
> free(handle->filename);
> free(handle->fit_alloc);
> }
> diff --git a/include/image-fit.h b/include/image-fit.h
> index
> 68f70f4365cb7a650596263086f7de2209d5957e..f9791ff251c554eda56bf3af98c8abceb056a176
> 100644
> --- a/include/image-fit.h
> +++ b/include/image-fit.h
> @@ -7,6 +7,7 @@
> #define __IMAGE_FIT_H__
>
> #include
> +#include
> #include
>
> struct fit_handle {
> @@ -15,6 +16,9 @@ struct fit_handle {
> size_t size;
> char *filename;
>
> + struct list_head entry;
> + refcount_t users;
> +
> bool verbose;
> enum bootm_verify verify;
>
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH v6 12/12] FIT: add support to cache opened fit images
Cache the FIT image fit_open() calls to avoid loading the same FIT image
twice. This is very useful if the same FIT image is used to provide the
base devicetree, kernel and initrd as well as devicetree overlays.
Signed-off-by: Marco Felsch
---
common/image-fit.c | 32
include/image-fit.h | 4
2 files changed, 36 insertions(+)
diff --git a/common/image-fit.c b/common/image-fit.c
index
c9d08d25f723665e5203d8e8372255a39bf739de..2cde844e46a61f412a46c2c7bb79d833153e5344
100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -33,6 +34,8 @@
#define CHECK_LEVEL_SIG 2
#define CHECK_LEVEL_MAX 3
+static LIST_HEAD(open_fits);
+
static uint32_t dt_struct_advance(struct fdt_header *f, uint32_t dt, int size)
{
dt += size;
@@ -902,6 +905,18 @@ void *fit_open_configuration(struct fit_handle *handle,
const char *name,
return conf_node;
}
+static struct fit_handle *fit_get_handle(const char *filename)
+{
+ struct fit_handle *handle;
+
+ list_for_each_entry(handle, &open_fits, entry) {
+ if (!strcmp(filename, handle->filename))
+ return handle;
+ }
+
+ return NULL;
+}
+
static int fit_do_open(struct fit_handle *handle)
{
const char *desc = "(no description)";
@@ -951,6 +966,8 @@ struct fit_handle *fit_open_buf(const void *buf, size_t
size, bool verbose,
handle->size = size;
handle->verify = verify;
+ refcount_set(&handle->users, 1);
+
ret = fit_do_open(handle);
if (ret) {
fit_close(handle);
@@ -985,6 +1002,12 @@ struct fit_handle *fit_open(const char *_filename, bool
verbose,
return ERR_PTR(-errno);
}
+ handle = fit_get_handle(filename);
+ if (handle) {
+ refcount_inc(&handle->users);
+ return handle;
+ }
+
handle = xzalloc(sizeof(struct fit_handle));
handle->verbose = verbose;
@@ -1002,6 +1025,9 @@ struct fit_handle *fit_open(const char *_filename, bool
verbose,
handle->fit = handle->fit_alloc;
handle->filename = filename;
+ refcount_set(&handle->users, 1);
+ list_add(&handle->entry, &open_fits);
+
ret = fit_do_open(handle);
if (ret) {
fit_close(handle);
@@ -1013,9 +1039,15 @@ struct fit_handle *fit_open(const char *_filename, bool
verbose,
static void __fit_close(struct fit_handle *handle)
{
+ if (!refcount_dec_and_test(&handle->users))
+ return;
+
if (handle->root)
of_delete_node(handle->root);
+ if (handle->filename)
+ list_del(&handle->entry);
+
free(handle->filename);
free(handle->fit_alloc);
}
diff --git a/include/image-fit.h b/include/image-fit.h
index
68f70f4365cb7a650596263086f7de2209d5957e..f9791ff251c554eda56bf3af98c8abceb056a176
100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -7,6 +7,7 @@
#define __IMAGE_FIT_H__
#include
+#include
#include
struct fit_handle {
@@ -15,6 +16,9 @@ struct fit_handle {
size_t size;
char *filename;
+ struct list_head entry;
+ refcount_t users;
+
bool verbose;
enum bootm_verify verify;
--
2.39.5
