initcall: Move to inline function
authorAlexander Graf <agraf@suse.de>
Thu, 31 Jan 2019 15:06:23 +0000 (16:06 +0100)
committerTom Rini <trini@konsulko.com>
Sat, 9 Feb 2019 12:50:58 +0000 (07:50 -0500)
The board_r init function was complaining that we are looping through
an array, calling all our tiny init stubs sequentially via indirect
function calls (which can't be speculated, so they are slow).

The solution to that is pretty easy though. All we need to do is inline
the function that loops through the functions and the compiler will
automatically convert almost all indirect calls into direct inlined code.

With this patch, the overall code size drops (by 40 bytes on riscv64)
and boot time should become measurably faster for every target.

Signed-off-by: Alexander Graf <agraf@suse.de>
common/board_r.c
include/initcall.h
lib/Makefile
lib/initcall.c [deleted file]

index 5f3d27aa9f391b0b93b10795d2c20324112091ef..472987d5d52f83e64d62a892c4adc4ca9db3a4c2 100644 (file)
@@ -633,10 +633,7 @@ static int run_main_loop(void)
 }
 
 /*
- * Over time we hope to remove these functions with code fragments and
- * stub functions, and instead call the relevant function directly.
- *
- * We also hope to remove most of the driver-related init and do it if/when
+ * We hope to remove most of the driver-related init and do it if/when
  * the driver is later used.
  *
  * TODO: perhaps reset the watchdog in the initcall function after each call?
index 01f3f2833f10291429049ec346b407d405b97954..3ac01aa2cd2ce4420d4805dc2ccd982b3c9aa230 100644 (file)
@@ -8,6 +8,39 @@
 
 typedef int (*init_fnc_t)(void);
 
-int initcall_run_list(const init_fnc_t init_sequence[]);
+#include <common.h>
+#include <initcall.h>
+#include <efi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline int initcall_run_list(const init_fnc_t init_sequence[])
+{
+       const init_fnc_t *init_fnc_ptr;
+
+       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+               unsigned long reloc_ofs = 0;
+               int ret;
+
+               if (gd->flags & GD_FLG_RELOC)
+                       reloc_ofs = gd->reloc_off;
+#ifdef CONFIG_EFI_APP
+               reloc_ofs = (unsigned long)image_base;
+#endif
+               debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
+               if (gd->flags & GD_FLG_RELOC)
+                       debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
+               else
+                       debug("\n");
+               ret = (*init_fnc_ptr)();
+               if (ret) {
+                       printf("initcall sequence %p failed at call %p (err=%d)\n",
+                              init_sequence,
+                              (char *)*init_fnc_ptr - reloc_ofs, ret);
+                       return -1;
+               }
+       }
+       return 0;
+}
 
 #endif
index 61d7ff06783ed2bfd47a7e33aa52151fef441c12..47829bfed52d43132682802933b970ee146af87d 100644 (file)
@@ -35,7 +35,6 @@ obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
 obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
 obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
 obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
-obj-y += initcall.o
 obj-y += ldiv.o
 obj-$(CONFIG_MD5) += md5.o
 obj-y += net_utils.o
diff --git a/lib/initcall.c b/lib/initcall.c
deleted file mode 100644 (file)
index 8f1dac6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2013 The Chromium OS Authors.
- */
-
-#include <common.h>
-#include <initcall.h>
-#include <efi.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-int initcall_run_list(const init_fnc_t init_sequence[])
-{
-       const init_fnc_t *init_fnc_ptr;
-
-       for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-               unsigned long reloc_ofs = 0;
-               int ret;
-
-               if (gd->flags & GD_FLG_RELOC)
-                       reloc_ofs = gd->reloc_off;
-#ifdef CONFIG_EFI_APP
-               reloc_ofs = (unsigned long)image_base;
-#endif
-               debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
-               if (gd->flags & GD_FLG_RELOC)
-                       debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
-               else
-                       debug("\n");
-               ret = (*init_fnc_ptr)();
-               if (ret) {
-                       printf("initcall sequence %p failed at call %p (err=%d)\n",
-                              init_sequence,
-                              (char *)*init_fnc_ptr - reloc_ofs, ret);
-                       return -1;
-               }
-       }
-       return 0;
-}